This Text file is old! In a 🏛️Museum, an unsorted archive of (user-)pages. (Saved from Geocities in Oct-2009. The archival story: oocities.org)
--------------------------------------- (To 🚫report any bad content: archivehelp @ gmail.com)
>

/**************************************************
*                                                                 *
*                                                                 *
*                                Diva DRC Rules                   *
*                                                                 *
* Modified by Fuding Ge based on NCSU Design Kit                  *
*******************************************************************/


let( ( lambda gridRes techdesc wellType submicronAvailable deepAvailable
       cwellAvailable metal3Available metal4Available metal5Available metal6Available
       metalcapAvailable hvAvailable npnAvailable ccdAvailable elecAvailable sblockAvailable 
       stackedViasAvailable highresAvailable PadType techfile modelPrefix errMesg )

;load( "/nfs/hrap_ckt3/atlasHarp/design/fge/NCSU_CDK_1p3_local/techfile/divaTechdesc.il" ) )

	techdesc="AMI_ABN"
    	lambda = 0.8        ;added by Fuding
    	gridRes=0.4
	wellType =t		;added by Fuding need to verify
    	submicronAvailable=nil
	deepAvailable=nil
	cwellAvailable=nil
	metal3Available=nil
	metal4Available=nil
 	metal5Available=nil
	metal6Available=nil
	metalcapAvailable=nil
	hvAvailable=nil
	npnAvailable=t
	ccdAvailable=nil
	elecAvailable=t
	sblockAvailable=nil
	stackedViasAvailable=nil
	highresAvailable=nil
	PadType=t
	techfile="ami_16.tf"
	modelPrefix="ami16"
	errMesg
	
drcExtractRules(

; First load the Derived Layer Definition
/***********************************************************
*                                                          *
*                                                          *
*                        Diva Derived Layer Definitions    *
*                                                          *
*                                                          * *******************************************************/


    /* 
     * Note that some of these variables are set here and some are set
     * above. The ones below are set here because any variable with the
     * value nil becomes unbound when you enter the drcExtractRules()
     * function. Some have to be set above because functions like
     * error() can't be called inside drcExtractRules(). Weird. 
     */
    /*** ---Fuding
    wellType = substring( NCSU_techData[ techdesc ]->mosisCode 3 1 )
    submicronAvailable = NCSU_techData[ techdesc ]->submicronRules
    deepAvailable = NCSU_techData[ techdesc ]->deepRules
    stackedViasAvailable = NCSU_techData[ techdesc ]->stackedVias
    lambda = atof( NCSU_techData[ techdesc ]->lambda )
    gridRes = NCSU_techData[ techdesc ]->gridRes
    modelPrefix = NCSU_techData[ techdesc ]->fetModelPrefix 
    ***********/
    

    /*
     * we can't use getTechParam here, so do it another way.
     * i know, this is a major kludge...
     */

    techfile = techGetTechFile( geGetEditCellView() )
    cwellAvailable    = techGetLayerNum( techfile "cwell" )
    polycapAvailable  = techGetLayerNum( techfile "polycap" )
    npnAvailable      = techGetLayerNum( techfile "pbase" )
    ccdAvailable      = techGetLayerNum( techfile "ccd" )
    metal3Available   = techGetLayerNum( techfile "metal3" )
    metal4Available   = techGetLayerNum( techfile "metal4" )
    metal5Available   = techGetLayerNum( techfile "metal5" )
    metal6Available   = techGetLayerNum( techfile "metal6" )
    metalcapAvailable = techGetLayerNum( techfile "metalcap" )
    hvAvailable       = techGetLayerNum( techfile "tactive" )
    elecAvailable     = techGetLayerNum( techfile "elec" )
    memsAvailable     = techGetLayerNum( techfile "pstop" )
    sblockAvailable   = techGetLayerNum( techfile "sblock" )
    highresAvailable  = techGetLayerNum( techfile "highres" )

    /***************************
     ***************************

     DERIVED LAYER DEFINITIONS

     ***************************
     ***************************/


    ivIf( switch("drc?") then
        nodrc   = geomOr( "nodrc" )
    )

    ivIf( switch("extract?") then
        nodrc   = geomAndNot( "nodrc" "nodrc" )
    )


    bkgnd   = geomBkgnd()
    gwell   = geomOr( geomAndNot( ( "gwell" "drawing" ) nodrc )   )
    nwell   = geomOr( geomAndNot( ( "nwell" "drawing" ) nodrc )   )
    pwell   = geomOr( geomAndNot( ( "pwell" "drawing" ) nodrc )   )
    nactive = geomOr( geomAndNot( ( "nactive" "drawing" ) nodrc ) )
    pactive = geomOr( geomAndNot( ( "pactive" "drawing" ) nodrc ) )
    active  = geomOr( geomAndNot( ( "active" "drawing" ) nodrc ) nactive pactive )
    gselect = geomOr( geomAndNot( ( "gselect" "drawing" ) nodrc ) )
    nselect = geomOr( geomAndNot( ( "nselect" "drawing" ) nodrc ) )
    pselect = geomOr( geomAndNot( ( "pselect" "drawing" ) nodrc ) )
    poly    = geomOr( geomAndNot( ( "poly" "drawing" ) nodrc )    )
    metal1  = geomOr( geomAndNot( ( "metal1" "drawing" ) nodrc )  )
    cc      = geomOr( geomAndNot( ( "cc" "drawing" ) nodrc )      )
    metal2  = geomOr( geomAndNot( ( "metal2" "drawing" ) nodrc )  )
    via     = geomOr( geomAndNot( ( "via" "drawing" ) nodrc )     )
    glass   = geomOr( geomAndNot( ( "glass" "drawing" ) nodrc )   )
    pad     = geomOr( geomAndNot( ( "pad" "drawing" ) nodrc )     )
    nolpe   = geomOr( "nolpe"   )
    cap_id  = geomOr( "cap_id"  )
    res_id  = geomOr( "res_id"  )
    dio_id  = geomOr( "dio_id"  )
    if( metal3Available then
        metal3 = geomOr( geomAndNot( ( "metal3" "drawing" ) nodrc ) )
        via2   = geomOr( geomAndNot( ( "via2" "drawing" ) nodrc )   )
    )
    if( metal4Available then
        metal4 = geomOr( geomAndNot( ( "metal4" "drawing" ) nodrc ) )
        via3   = geomOr( geomAndNot( ( "via3" "drawing" ) nodrc )   )
    )
    if( metal5Available then
        metal5 = geomOr( geomAndNot( ( "metal5" "drawing" ) nodrc ) )
        via4   = geomOr( geomAndNot( ( "via4" "drawing" ) nodrc )   )
    )
    if( metal6Available then
        metal6 = geomOr( geomAndNot( ( "metal6" "drawing" ) nodrc ) )
        via5   = geomOr( geomAndNot( ( "via5" "drawing" ) nodrc )   )
    )
    if( metalcapAvailable then
        metalcap = geomOr( geomAndNot( ( "metalcap" "drawing" ) nodrc ) )
    )
    if( ccdAvailable then
        ccd = geomOr( geomAndNot( ( "ccd" "drawing" ) nodrc ) )
    )
    if( cwellAvailable then
        cwell = geomOr( geomAndNot( ( "cwell" "drawing" ) nodrc ) )
    )
    if( polycapAvailable then
        polycap  = geomOr( geomAndNot( ( "polycap" "drawing" ) nodrc ) )
        cpolycap = geomAnd( polycap geomOr( cc cp ) )
    )
    if( sblockAvailable then
        sblock  = geomOr( geomAndNot( ( "sblock" "drawing" ) nodrc ) )
    )
    if( highresAvailable then
        highres = geomOr( geomAndNot( ( "highres" "drawing" ) nodrc ) )
    )
    if( memsAvailable then
        pstop = geomOr( geomAndNot( ( "pstop" "drawing" ) nodrc ) )
        open = geomOr( geomAndNot( ( "open" "drawing" ) nodrc ) )
    )
    /* 
     * deriving specific contacts (ie, ce, cp, ca) from generic contact (cc) is a pain.
     * make sure you account for multiple overlaps, eg, in case of poly-elec cap, suppose you use
     * cc for the elec contact. this needs to be extracted as "ce" only, not "cp".
     *
     * the order of the rules below is important - ie, it goes top-down (elec -> poly -> active).
     */
    if( elecAvailable then
        elec = geomOr( geomAndNot( ( "elec" "drawing" ) nodrc ) )
        ce   = geomOr( geomOr( geomAndNot( ( "ce" "drawing" ) nodrc ) ) geomAnd( cc elec ) )
        cp   = geomOr( geomOr( geomAndNot( ( "cp" "drawing" ) nodrc ) ) geomAnd( cc geomAndNot( poly ce ) ) )
        ca   = geomOr( geomOr( geomAndNot( ( "ca" "drawing" ) nodrc ) ) geomAnd( cc geomAndNot( active geomOr( ce cp ) ) ) )
    else
        cp   = geomOr( geomOr( geomAndNot( ( "cp" "drawing" ) nodrc ) ) geomAnd( cc poly ) )
        ca   = geomOr( geomOr( geomAndNot( ( "ca" "drawing" ) nodrc ) ) geomAnd( cc geomAndNot( active cp ) ) )
    )
    if( npnAvailable then
        pbase = geomOr( geomAndNot( ( "pbase" "drawing" ) nodrc ) )
        cactive = geomOr( geomAndNot( ( "cactive" "drawing" ) nodrc ) )
        ca = geomOr( ca geomAnd( cc cactive ) )
    )

    nActive = geomAnd( active nselect )
    pActive = geomAnd( active pselect )
    if( ccdAvailable then
        nActive = geomAndNot( nActive ccd )
        pActive = geomAndNot( pActive ccd )
    )
    if( cwellAvailable then
        nActive = geomAndNot( nActive cwell )
        pActive = geomAndNot( pActive cwell )
    )
    if( hvAvailable then
        tactive = geomOr( geomAndNot( ( "tactive" "drawing" ) nodrc ) )
    )

    /*
     * This next section basically sets how the well enclosure of
     * source/drain active, substrate/well contact and capacitor
     * electrode are interpreted. In a pwell process, everything that
     * doesn't have the "pwell" layer drawn on it is assumed to be
     * N-type bulk. Similarly, in an nwell process, everything that
     * doesn't have the "nwell" layer drawn on it is assumed to be
     * P-type bulk. If it's an "either-well" process, only the areas
     * with drawn "pwell" and "nwell" are assumed to be P-type bulk or
     * N-type bulk, respectively.
     *
     * Since MOSIS only has N-type processes for now, this is assumed to
     * be the default.
     */

    case( wellType
        ( "P"
            nBulk = geomOr( geomNot( pwell ) geomAndNot( nwell pwell ) )
            pBulk = geomOr( pwell )
            nOhmic = geomAndNot( nActive pwell )
            pOhmic = geomAnd( pActive pwell )
            nNotOhmic = geomAnd( nActive pwell )
            pNotOhmic = geomAndNot( pActive pwell)
        )
        ( "E"
            nBulk = geomOr( nwell )
            pBulk = geomOr( pwell )
            nOhmic = geomAnd( nActive nwell )
            pOhmic = geomAnd( pActive pwell )
            nNotOhmic = geomAnd( nActive pwell )
            pNotOhmic = geomAnd( pActive nwell)
        )
        ( t
            if( npnAvailable then
                nBulk = geomOutside( nwell cactive )
            else
                nBulk = geomOr( nwell )
            )
            pBulk = geomOr( geomNot( nwell ) geomAndNot( pwell nwell ) )
            nOhmic = geomAnd( nActive nwell )
            pOhmic = geomAndNot( pActive nwell )
            nNotOhmic = geomAndNot( nActive nwell )
            pNotOhmic = geomAnd( pActive nwell)
        )
    )

    if( elecAvailable then
        nDiff = geomAndNot( nNotOhmic geomOr( poly elec ) )
        pDiff = geomAndNot( pNotOhmic geomOr( poly elec ) )
        nChannel = geomOutside( geomAnd( nNotOhmic poly ) elec )
        pChannel = geomOutside( geomAnd( pNotOhmic poly ) elec )
        nElecChannel = geomOutside( geomAnd( nNotOhmic elec ) poly )
        pElecChannel = geomOutside( geomAnd( pNotOhmic elec ) poly )
        nElecChannelTran = geomButting( nElecChannel nDiff keep == 2 )
        pElecChannelTran = geomButting( pElecChannel pDiff keep == 2 )
        nElecChannelCap = geomButting( nElecChannel nDiff keep == 1 )
        pElecChannelCap = geomButting( pElecChannel pDiff keep == 1 )
        Space = geomNot( geomOr( active poly elec ) )
    else
        nDiff = geomAndNot( nNotOhmic poly )
        pDiff = geomAndNot( pNotOhmic poly )
        nChannel = geomAnd( nNotOhmic poly )
        pChannel = geomAnd( pNotOhmic poly )
        Space = geomNot( geomOr( active poly ) ) 
    )
    nChannelTran = geomButting( nChannel nDiff keep == 2 )
    pChannelTran = geomButting( pChannel pDiff keep == 2 )
    nChannelCap = geomButting( nChannel nDiff keep == 1 )
    pChannelCap = geomButting( pChannel pDiff keep == 1 )
    if( hvAvailable then
        hvnChannelTran = geomAnd( nChannelTran tactive )
        nChannelTran = geomAndNot( nChannelTran hvnChannelTran )
        hvpChannelTran = geomAnd( pChannelTran tactive )
        pChannelTran = geomAndNot( pChannelTran hvpChannelTran )
    )

    nDiffContact   = geomAnd( ca nDiff )
    pDiffContact   = geomAnd( ca pDiff )
    nOhmicContact  = geomAnd( ca nOhmic )
    pOhmicContact  = geomAnd( ca pOhmic )
    Gate           = geomAnd( geomOr( nNotOhmic pNotOhmic) poly )
    fieldPoly      = geomAvoiding( poly Gate )
    m1pCap         = geomAnd( geomAnd( poly metal1 ) cap_id )
    m1sCap         = geomAnd( geomAndNot( metal1 poly ) cap_id )
    m2m1Cap        = geomAnd( geomAnd( metal1 metal2 ) cap_id )
    if( metal3Available then
        m3m2Cap        = geomAnd( geomAnd( metal2 metal3 ) cap_id )
    )
    if( metal4Available then
        m4m3Cap        = geomAnd( geomAnd( metal3 metal4 ) cap_id )
    )
    if( metal5Available then
        m5m4Cap        = geomAnd( geomAnd( metal4 metal5 ) cap_id )
    )
    if( metal6Available then
        m6m5Cap        = geomAnd( geomAnd( metal5 metal6 ) cap_id )
    )
    if( metalcapAvailable then
        /*
         * metalcap is between top-layer metal and next-to-top layer metal. for
         * drc, we need the whole metal shape of the bottom plate, not just the
         * metal-metalcap overlap.
         */
        cond( 
            ( metal6Available
                metalcapBottom = geomStraddle( metal5 metalcap )
                metalcapCap = geomAnd( metalcap metal5 )
                via5metalcap = geomAnd( via5 metalcapBottom )
                via5 = geomAndNot( via5 via5metalcap )
            )
            ( metal5Available
                metalcapBottom = geomStraddle( metal4 metalcap )
                metalcapCap = geomAnd( metalcap metal4 )
                via4metalcap = geomAnd( via4 metalcapBottom )
                via4 = geomAndNot( via4 via4metalcap )
            )
        )
    )
    NPdiode = geomAnd( dio_id geomOutside( nNotOhmic poly ) )
    PNdiode = geomAnd( dio_id geomOutside( pNotOhmic poly ) )
    unless( wellType == "P" || wellType == "E"
        NwPdiode = geomAnd( dio_id geomOutside( nwell pNotOhmic ) )
    )
    if( elecAvailable then
        elecGate       = geomAnd( geomOr( nNotOhmic pNotOhmic) elec )
        fieldElec      = geomAvoiding( elec elecGate )
        CapacitorElec  = geomInside( elec poly )
        TransistorElec = geomOverlap( elec geomNot( poly ) )
    )
    if( polycapAvailable then
        polycapCap = geomAnd( poly polycap )
    )
    if( sblockAvailable then
        sGateWidthCheck = geomSize( geomSize( geomAnd( Gate sblock ) -2.9 ) 2.9 )
    )
    if( npnAvailable then
        npnCollector        = geomAnd( nwell geomAnd( nselect cactive ) )
        npnCollectorContact = geomAnd( ca npnCollector )
        npnBaseImplant      = geomAnd( nwell pbase )
        npnEmitter          = geomAnd( nselect npnBaseImplant )
        npnBase             = geomAndNot( npnBaseImplant npnEmitter )
        npnBaseTap          = geomAnd( npnBase pselect )
        npnBaseContact      = geomAnd( geomOr( cc ca ) npnBaseTap )
        npnEmitterContact   = geomAnd( geomOr( cc ca ) npnEmitter )
        npnTran             = geomEnclose( nwell geomOr( npnCollector npnBase npnEmitter ) )
    )
    if( ccdAvailable then
        ccdDiff           = geomAnd( active ccd )
        ccdContact        = geomAnd( ca ccdDiff )
    )
    if( cwellAvailable then
        ; since the extractDevice for cwell caps uses "lcDiff" as negative
        ; terminal, and all caps in a single cwell need to have a common neg.
        ; term (the cwell itself) use the cwell as the lcDiff layer. the lcCap
        ; ANDs it with active & poly to get shape for calculating capacitance.
        lcDiff         = geomStraddle( cwell active )
        lcContact      = geomAnd( ca lcDiff )
        lcCap          = geomAnd( poly geomAnd( lcDiff active ) )
    )

    ; recognize resistors: res_id/(poly|elec), sblock/poly, highres/elec, nwell/res_id

    ; res_id/poly, sblock/poly
    if( sblockAvailable then
        fieldPoly = geomAndNot( fieldPoly geomOr( sblock res_id ) )
        polySRes = geomButting( geomAnd( sblock poly ) fieldPoly keep == 2 )
        polyRes = geomButting( geomAndNot( geomAnd( res_id poly ) polySRes ) fieldPoly keep == 2 )
        poly = geomAndNot( poly geomOr( sblock res_id ) )
    else
        fieldPoly = geomAndNot( fieldPoly res_id )
        polyRes = geomButting( geomAnd( res_id poly ) fieldPoly keep == 2 )
        poly = geomAndNot( poly res_id )
    )

    ; res_id/elec
    if( elecAvailable then
        ; currently can only do highres over elec (poly2)
        if( highresAvailable then
            fieldElec = geomAndNot( fieldElec geomOr( res_id highres ) )
            elecRes = geomButting( geomAnd( res_id elec ) fieldElec keep == 2 )
            elecHighres = geomButting( geomAnd( highres elec ) fieldElec keep == 2 )
            elec = geomAndNot( elec geomOr( res_id highres ) )
        else
            fieldElec = geomAndNot( fieldElec res_id )
            elecRes = geomButting( geomAnd( res_id elec ) fieldElec keep == 2 )
            elec = geomAndNot( elec res_id )
        )
    )

    ; res_id/nwell
    nBulk = geomAndNot( nBulk res_id )
    nwellRes = geomButting( geomAnd( res_id nwell ) nBulk keep == 2 )
    nwell = geomAndNot( nwell res_id ) ; w/o this, whole well is connected 

    cond( 
        ( metal6Available
            if( metalcapAvailable then
                geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
                             via( pOhmicContact pOhmic pwell pBulk metal1 )
                             via( nDiffContact nDiff metal1 )
                             via( pDiffContact pDiff metal1 )
                             via( cp poly metal1 )
                             via( via metal1 metal2 )
                             via( via2 metal2 metal3 )
                             via( via3 metal3 metal4 )
                             via( via4 metal4 metal5 )
                             via( via5 metal5 metal6 )
                             via( via5metalcap metalcap metal6 )
                             label( "text" metal6 metalcap metal5 metal4 metal3 metal2 metal1 poly pDiff nDiff )
                )
            else
                geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
                             via( pOhmicContact pOhmic pwell pBulk metal1 )
                             via( nDiffContact nDiff metal1 )
                             via( pDiffContact pDiff metal1 )
                             via( cp poly metal1 )
                             via( via metal1 metal2 )
                             via( via2 metal2 metal3 )
                             via( via3 metal3 metal4 )
                             via( via4 metal4 metal5 )
                             via( via5 metal5 metal6 )
                             label( "text" metal6 metal5 metal4 metal3 metal2 metal1 poly pDiff nDiff )
                )
            )
        )
        ( metal5Available
            if( metalcapAvailable then
                geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
                             via( pOhmicContact pOhmic pwell pBulk metal1 )
                             via( nDiffContact nDiff metal1 )
                             via( pDiffContact pDiff metal1 )
                             via( cp poly metal1 )
                             via( via metal1 metal2 )
                             via( via2 metal2 metal3 )
                             via( via3 metal3 metal4 )
                             via( via4 metal4 metal5 )
                             via( via4metalcap metalcap metal5 )
                             label( "text" metal5 metalcap metal4 metal3 metal2 metal1 poly pDiff nDiff )
                )
            else
                geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
                             via( pOhmicContact pOhmic pwell pBulk metal1 )
                             via( nDiffContact nDiff metal1 )
                             via( pDiffContact pDiff metal1 )
                             via( cp poly metal1 )
                             via( via metal1 metal2 )
                             via( via2 metal2 metal3 )
                             via( via3 metal3 metal4 )
                             via( via4 metal4 metal5 )
                             label( "text" metal5 metal4 metal3 metal2 metal1 poly pDiff nDiff )
                )
            )
        )
        ( metal4Available
            if( elecAvailable then
                geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
                             via( pOhmicContact pOhmic pwell pBulk metal1 )
                             via( nDiffContact nDiff metal1 )
                             via( pDiffContact pDiff metal1 )
                             via( cp poly metal1 )
                             via( ce elec metal1 )
                             via( via metal1 metal2 )
                             via( via2 metal2 metal3 )
                             via( via3 metal3 metal4 )
                             label( "text" metal4 metal3 metal2 metal1 elec poly pDiff nDiff )
                )
            else
                geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
                             via( pOhmicContact pOhmic pwell pBulk metal1 )
                             via( nDiffContact nDiff metal1 )
                             via( pDiffContact pDiff metal1 )
                             via( cp poly metal1 )
                             via( via metal1 metal2 )
                             via( via2 metal2 metal3 )
                             via( via3 metal3 metal4 )
                             label( "text" metal4 metal3 metal2 metal1 poly pDiff nDiff )
                )
            )
        )
        ( metal3Available && cwellAvailable
            geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
                         via( pOhmicContact pOhmic pwell pBulk metal1 )
                         via( nDiffContact nDiff metal1 )
                         via( pDiffContact pDiff metal1 )
                         via( lcContact lcDiff metal1 )
                         via( cp poly metal1 )
                         via( via metal1 metal2 )
                         via( via2 metal2 metal3 )
                         label( "text" metal3 metal2 metal1 poly lcDiff pDiff nDiff )
            ) 
        )
        ( metal3Available && elecAvailable
            geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
                         via( pOhmicContact pOhmic pwell pBulk metal1 )
                         via( nDiffContact nDiff metal1 )
                         via( pDiffContact pDiff metal1 )
                         via( cp poly metal1 )
                         via( ce elec metal1 )
                         via( via metal1 metal2 )
                         via( via2 metal2 metal3 )
                         label( "text" metal3 metal2 metal1 elec poly pDiff nDiff )
            ) 
        )
        ( metal3Available
            geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
                         via( pOhmicContact pOhmic pwell pBulk metal1 )
                         via( nDiffContact nDiff metal1 )
                         via( pDiffContact pDiff metal1 )
                         via( cp poly metal1 )
                         via( via metal1 metal2 )
                         via( via2 metal2 metal3 )
                         label( "text" metal3 metal2 metal1 poly pDiff nDiff )
            ) 
        )
        ( npnAvailable && ccdAvailable && elecAvailable
            geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
                         via( pOhmicContact pOhmic pwell pBulk metal1 )
                         via( nDiffContact nDiff metal1 )
                         via( pDiffContact pDiff metal1 )
                         via( ccdContact ccdDiff metal1 )
                         via( npnEmitterContact npnEmitter metal1 )
                         via( npnBaseContact npnBaseTap npnBase metal1 )
                         via( npnCollectorContact npnCollector metal1 )
                         via( cp poly metal1 )
                         via( ce elec metal1 )
                         via( via metal1 metal2 )
                         label( "text" metal2 metal1 elec poly pDiff nDiff ccdDiff npnCollector npnEmitter npnBase )
            ) 
        )
        ( npnAvailable && elecAvailable
            geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
                         via( pOhmicContact pOhmic pwell pBulk metal1 )
                         via( nDiffContact nDiff metal1 )
                         via( pDiffContact pDiff metal1 )
                         via( npnEmitterContact npnEmitter metal1 )
                         via( npnBaseContact npnBaseTap npnBase metal1 )
                         via( npnCollectorContact npnCollector metal1 )
                         via( cp poly metal1 )
                         via( ce elec metal1 )
                         via( via metal1 metal2 )
                         label( "text" metal2 metal1 elec poly pDiff nDiff npnCollector npnEmitter npnBase )
            ) 
        )
        ( polycapAvailable
            geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
                         via( pOhmicContact pOhmic pwell pBulk metal1 )
                         via( nDiffContact nDiff metal1 )
                         via( pDiffContact pDiff metal1 )
                         via( cp poly metal1 )
                         via( cpolycap polycap metal1 )
                         via( via metal1 metal2 )
                         label( "text" metal2 metal1 poly polycap pDiff nDiff )
            ) 
        )
        ( t
            geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
                         via( pOhmicContact pOhmic pwell pBulk metal1 )
                         via( nDiffContact nDiff metal1 )
                         via( pDiffContact pDiff metal1 )
                         via( cp poly metal1 )
                         via( via metal1 metal2 )
                         label( "text" metal2 metal1 poly pDiff nDiff )
            ) 
        )
    )

    ivIf( switch("drc?") then
    
    ivIf( ( !switch("hier?") || switch("currentCell?") ) then

        dubiousData( ( "gwell" "drawing" )   "Improperly formed shape - gwell" )
        dubiousData( ( "nwell" "drawing" )   "Improperly formed shape - nwell" )
        dubiousData( ( "pwell" "drawing" )   "Improperly formed shape - pwell" )
        dubiousData( ( "active" "drawing" )  "Improperly formed shape - active, nactive or pactive" )
        dubiousData( ( "gselect" "drawing" ) "Improperly formed shape - gselect" )
        dubiousData( ( "nselect" "drawing" ) "Improperly formed shape - nselect" )
        dubiousData( ( "pselect" "drawing" ) "Improperly formed shape - pselect" )
        dubiousData( ( "poly" "drawing" )    "Improperly formed shape - poly" )
        dubiousData( ( "metal1" "drawing" )  "Improperly formed shape - metal1" )
        dubiousData( ( "ca" "drawing" )      "Improperly formed shape - ca" )
        dubiousData( ( "cp" "drawing" )      "Improperly formed shape - cp" )
        dubiousData( ( "metal2" "drawing" )  "Improperly formed shape - metal2" )
        dubiousData( ( "via" "drawing" )     "Improperly formed shape - via" )
        dubiousData( ( "glass" "drawing" )   "Improperly formed shape - glass" )

        saveDerived( geomGetNon45( gwell )   "Non-Manhattan shape - gwell" )
        saveDerived( geomGetNon45( nwell )   "Non-Manhattan shape - nwell" )
        saveDerived( geomGetNon45( pwell )   "Non-Manhattan shape - pwell" )
        saveDerived( geomGetNon45( active )  "Non-Manhattan shape - active, nactive or pactive" )
        saveDerived( geomGetNon45( gselect ) "Non-Manhattan shape - gselect" )
        saveDerived( geomGetNon45( nselect ) "Non-Manhattan shape - nselect" )
        saveDerived( geomGetNon45( pselect ) "Non-Manhattan shape - pselect" )
        saveDerived( geomGetNon45( poly )    "Non-Manhattan shape - poly" )
        saveDerived( geomGetNon45( metal1 )  "Non-Manhattan shape - metal1" )
        saveDerived( geomGetNon45( ca )      "Non-Manhattan shape - ca" )
        saveDerived( geomGetNon45( cp )      "Non-Manhattan shape - cp" )
        saveDerived( geomGetNon45( metal2 )  "Non-Manhattan shape - metal2" )
        saveDerived( geomGetNon45( via )     "Non-Manhattan shape - via" )

/**********
        ; allow round glass cuts for solder bumps
        unless( padType == "Area array"
             saveDerived( geomGetNon45( glass ) "Non-Manhattan shape - glass" )
        )
*********/
	     saveDerived( geomGetNon45( glass ) "Non-Manhattan shape - glass" ) ;Added by Fuding

        ;saveDerived( geomGetAngledEdge( active angle == 45 ) )


/***************** delete this offgrid check
        offGrid( gwell gridRes "(SCMOS Inst) Edge not on grid" )
        offGrid( nwell gridRes "(SCMOS Inst) Edge not on grid" )
        offGrid( pwell gridRes "(SCMOS Inst) Edge not on grid" )
        offGrid( active gridRes "(SCMOS Inst) Edge not on grid" )
        offGrid( gselect gridRes "(SCMOS Inst) Edge not on grid" )
        offGrid( nselect gridRes "(SCMOS Inst) Edge not on grid" )
        offGrid( pselect gridRes "(SCMOS Inst) Edge not on grid" )
        offGrid( poly gridRes "(SCMOS Inst) Edge not on grid" )                                  
        offGrid( metal1 gridRes "(SCMOS Inst) Edge not on grid" )
        offGrid( ca gridRes "(SCMOS Inst) Edge not on grid" )
        offGrid( cp gridRes "(SCMOS Inst) Edge not on grid" )
        offGrid( metal2 gridRes "(SCMOS Inst) Edge not on grid" )
        offGrid( via gridRes "(SCMOS Inst) Edge not on grid" )
	
        unless( padType== "Area array"
            (offGrid glass gridRes "(SCMOS Inst) Edge not on grid" )
        )
	
*********************/


        if( npnAvailable then
            dubiousData( ( "pbase" "drawing" )   "Improperly formed shape - pbase" )
            saveDerived( geomGetNon45( pbase )   "Non-Manhattan shape - pbase" )
           ; offGrid( pbase gridRes "(SCMOS Inst) Edge not on grid" )
            dubiousData( ( "cactive" "drawing" )   "Improperly formed shape - cactive" )
            saveDerived( geomGetNon45( cactive )   "Non-Manhattan shape - cactive" )
            ;offGrid( cactive gridRes "(SCMOS Inst) Edge not on grid" )
        )
        if( ccdAvailable then
            dubiousData( ( "ccd" "drawing" )     "Improperly formed shape - ccd" )
            saveDerived( geomGetNon45( ccd )     "Non-Manhattan shape - ccd" )
            ;offGrid( ccd gridRes "(SCMOS Inst) Edge not on grid" )
        )
/******************	
        if( metal3Available then
            dubiousData( ( "metal3" "drawing" )  "Improperly formed shape - metal3" )
            dubiousData( ( "via2" "drawing" )    "Improperly formed shape - via2" )
            saveDerived( geomGetNon45( metal3 )  "Non-Manhattan shape - metal3" )
            saveDerived( geomGetNon45( via2 )    "Non-Manhattan shape - via2" )
            ;offGrid( metal3 gridRes "(SCMOS Inst) Edge not on grid" )
            ;offGrid( via2 gridRes "(SCMOS Inst) Edge not on grid" )
        )
        if( metal4Available then
            dubiousData( ( "metal4" "drawing" )  "Improperly formed shape - metal4" )
            dubiousData( ( "via3" "drawing" )    "Improperly formed shape - via3" )
            saveDerived( geomGetNon45( metal4 )  "Non-Manhattan shape - metal4" )
            saveDerived( geomGetNon45( via3 )    "Non-Manhattan shape - via3" )
            ;offGrid( metal4 gridRes "(SCMOS Inst) Edge not on grid" )
            ;offGrid( via3 gridRes "(SCMOS Inst) Edge not on grid" )
        )
        if( metal5Available then
            dubiousData( ( "metal5" "drawing" )  "Improperly formed shape - metal5" )
            dubiousData( ( "via4" "drawing" )    "Improperly formed shape - via4" )
            saveDerived( geomGetNon45( metal5 )  "Non-Manhattan shape - metal5" )
            saveDerived( geomGetNon45( via4 )    "Non-Manhattan shape - via4" )
            offGrid( metal5 gridRes "(SCMOS Inst) Edge not on grid" )
            offGrid( via4 gridRes "(SCMOS Inst) Edge not on grid" )
        )
        if( metal6Available then
            dubiousData( ( "metal6" "drawing" )  "Improperly formed shape - metal6" )
            dubiousData( ( "via5" "drawing" )    "Improperly formed shape - via5" )
            saveDerived( geomGetNon45( metal6 )  "Non-Manhattan shape - metal6" )
            saveDerived( geomGetNon45( via5 )    "Non-Manhattan shape - via5" )
            offGrid( metal6 gridRes "(SCMOS Inst) Edge not on grid" )
            offGrid( via5 gridRes "(SCMOS Inst) Edge not on grid" )
        )
        if( metalcapAvailable then
            dubiousData( ( "metalcap" "drawing" )  "Improperly formed shape - metalcap" )
            saveDerived( geomGetNon45( metalcap )  "Non-Manhattan shape - metalcap" )
            offGrid( metalcap gridRes "(SCMOS Inst) Edge not on grid" )
        )
****************/
	
        if( elecAvailable then
            dubiousData( ( "elec" "drawing" )    "Improperly formed shape - elec" )
            dubiousData( ( "ce" "drawing" )      "Improperly formed shape - ce" )
            saveDerived( geomGetNon45( elec )    "Non-Manhattan shape - elec" )
            saveDerived( geomGetNon45( ce )      "Non-Manhattan shape - ce" )
            ;offGrid( elec gridRes "(SCMOS Inst) Edge not on grid" )
            ;offGrid( ce gridRes "(SCMOS Inst) Edge not on grid" )
        )
		
    )

    gwellEdge          = geomGetEdge( gwell   )
    nwellEdge          = geomGetEdge( nwell   )
    pwellEdge          = geomGetEdge( pwell   )
    activeEdge         = geomGetEdge( active  )
    gselectEdge        = geomGetEdge( gselect )
    nselectEdge        = geomGetEdge( nselect )
    pselectEdge        = geomGetEdge( pselect )
    polyEdge           = geomGetEdge( poly    )
    metal1Edge         = geomGetEdge( metal1  )
    ccEdge             = geomGetEdge( cc      )
    caEdge             = geomGetEdge( ca      )
    cpEdge             = geomGetEdge( cp      )
    metal2Edge         = geomGetEdge( metal2  )
    viaEdge            = geomGetEdge( via     )
    glassEdge          = geomGetEdge( glass   )
    padEdge            = geomGetEdge( pad     )

    if( cwellAvailable then
        cwellEdge          = geomGetEdge( cwell    )
    )
    if( npnAvailable then
        pbaseEdge          = geomGetEdge( pbase    )
        cactiveEdge        = geomGetEdge( cactive  )
    )
    if( ccdAvailable then
        ccdEdge            = geomGetEdge( ccd      )
    )
    if( polycapAvailable then
        polycapEdge        = geomGetEdge( polycap  )
        cpolycapEdge       = geomGetEdge( cpolycap )
    )
    if( sblockAvailable then
        sblockEdge         = geomGetEdge( sblock   )
    )
    if( highresAvailable then
        highresEdge        = geomGetEdge( highres    )
    )
    if( memsAvailable then
        pstopEdge          = geomGetEdge( pstop    )
        openEdge           = geomGetEdge( open     )
    )
    if( elecAvailable then
        ceEdge             = geomGetEdge( ce       )
        elecEdge           = geomGetEdge( elec     )
    )
    if( metal3Available then
        metal3Edge         = geomGetEdge( metal3   )
        via2Edge           = geomGetEdge( via2     )
    )
    if( metal4Available then
        metal4Edge         = geomGetEdge( metal4   )
        via3Edge           = geomGetEdge( via3     )
    )
    if( metal5Available then
        metal5Edge         = geomGetEdge( metal5   )
        via4Edge           = geomGetEdge( via4     )
    )
    if( metal6Available then
        metal6Edge         = geomGetEdge( metal6   )
        via5Edge           = geomGetEdge( via5     )
    )
    if( metalcapAvailable then
        metalcapEdge       = geomGetEdge( metalcap )
        metalcapBottomEdge = geomGetEdge( metalcapBottom )
        metalcapCapEdge    = geomGetEdge( metalcapCap )
        cond(
            ( metal6Available
                via5metalcapEdge = geomGetEdge( via5metalcap )
            )
            ( metal5Available
                via4metalcapEdge = geomGetEdge( via4metalcap )
            )
        )
    )
    if( hvAvailable then
        tactiveEdge        = geomGetEdge( tactive  )
    )

    nBulkEdge          = geomGetEdge( nBulk     )
    pBulkEdge          = geomGetEdge( pBulk     )
    nOhmicEdge         = geomGetEdge( nOhmic    )
    pOhmicEdge         = geomGetEdge( pOhmic    )
    nNotOhmicEdge      = geomGetEdge( nNotOhmic )
    pNotOhmicEdge      = geomGetEdge( pNotOhmic )
    GateEdge           = geomGetEdge( Gate      )
    fieldPolyEdge      = geomGetEdge( fieldPoly )
    if( elecAvailable then
        CapacitorElecEdge  = geomGetEdge( CapacitorElec  )
        TransistorElecEdge = geomGetEdge( TransistorElec )
    )
    if( npnAvailable then
        npnCollectorEdge        = geomGetEdge( npnCollector        )
        npnCollectorContactEdge = geomGetEdge( npnCollectorContact )
        npnBaseImplantEdge      = geomGetEdge( npnBaseImplant      )
        npnEmitterEdge          = geomGetEdge( npnEmitter          )
        npnBaseEdge             = geomGetEdge( npnBase             )
        npnBaseTapEdge          = geomGetEdge( npnBaseTap          )
        npnBaseContactEdge      = geomGetEdge( npnBaseContact      )
        npnEmitterContactEdge   = geomGetEdge( npnEmitterContact   )
    )
    if( ccdAvailable then
        ccdDiffEdge        = geomGetEdge( ccdDiff    )
        ccdContactEdge     = geomGetEdge( ccdContact )
    )
    if( cwellAvailable then
        lcDiffEdge         = geomGetEdge( lcDiff     )
        lcCapEdge          = geomGetEdge( lcCap      )
    )
    if( polycapAvailable then
        polycapCapEdge     = geomGetEdge( polycapCap )
    )
    if( sblockAvailable then
        sGateWidthCheckEdge = geomGetEdge( sGateWidthCheck )
    )

    if( sblockAvailable then
        polySResEdge = geomGetEdge( polySRes )
    )
    polyResEdge = geomGetEdge( polyRes coincident poly )
    nwellResEdge = geomGetEdge( nwellRes coincident nwell )
    if( elecAvailable && highresAvailable then
        elecHighresEdge = geomGetEdge( elecRes coincident elec )
    )

    ) ; close ivIf( switch( "?drc" ) )

; vim:ts=4:columns=132:set tw=0:









/***************************
***************************

           SCMOS DRC RULES

***************************
***************************/
	techdesc="AMI_ABN"
    	lambda = 0.8        ;added by Fuding
    	gridRes=0.4
	wellType =t		;added by Fuding need to verify
    	submicronAvailable=nil
	deepAvailable=nil
	cwellAvailable=nil
	metal3Available=nil
	metal4Available=nil
 	metal5Available=nil
	metal6Available=nil
	metalcapAvailable=nil
	hvAvailable=nil
	npnAvailable=t
	ccdAvailable=nil
	elecAvailable=t
	sblockAvailable=nil
	stackedViasAvailable=nil
	highresAvailable=nil
	PadType=t
	techfile="ami_16.tf"
	modelPrefix="ami16"
	errMesg

    ivIf( ( !switch( "hier?" ) || !switch( "topCell?" ) ) then

    /* DBM rules - not listed in the official SCMOS rules but should be followed anyway... */


        if( wellType == "E" then
            saveDerived( geomAndNot( active geomOr( nwell pwell ) ) "(DBM Rule 1.0) Active must be inside well")
        )

        cond(
            ( ccdAvailable && cwellAvailable 
                saveDerived( geomAndNot( active geomOr( nselect pselect ccd cwell ) )
                    "(DBM Rule 1.1) Active must be inside select, ccd or cwell") 
            )
            ( cwellAvailable
                saveDerived( geomAndNot( active geomOr( nselect pselect cwell ) )
                    "(DBM Rule 1.1) Active must be inside select or cwell") 
            )
            ( ccdAvailable
                saveDerived( geomAndNot( active geomOr( nselect pselect ccd ) )
                    "(DBM Rule 1.1) Active must be inside select or ccd") 
            )
            ( t
                saveDerived( geomAndNot( active geomOr( nselect pselect ) )
                    "(DBM Rule 1.1) Active must be inside select") 
            )
        )
        if( cwellAvailable then
            saveDerived( geomAnd( cwell pselect ) "(DBM Rule 1.2) Pselect not allowed inside cwell" )
        )

        saveDerived( geomAnd( poly nOhmic ) "(DBM Rule 2.0) Poly cannot overlap ohmic diffusion" )
        saveDerived( geomAnd( poly pOhmic ) "(DBM Rule 2.0) Poly cannot overlap ohmic diffusion" )

        if( elecAvailable then
            saveDerived( geomAnd( elec nOhmic ) "(DBM Rule 2.1) Elec cannot overlap ohmic diffusion" )
            saveDerived( geomAnd( elec pOhmic ) "(DBM Rule 2.1) Elec cannot overlap ohmic diffusion" )
        )
        saveDerived( geomAnd( pactive nselect ) "(DBM Rule 3.1) Pactive and Nselect may not overlap" )
        saveDerived( geomAnd( nactive pselect ) "(DBM Rule 3.2) Nactive and Pselect may not overlap" )

        /*
         * Can't use elec in these processes to make transistors
         * From http://www.mosis.org/Whatsnew/1999/990301-ami-c5.html:
         *
         * "The AMI C5N poly2 can be used to build capacitors in a style identical to
         * SCNE (as for AMI 1.2u, Orbit 2u and TSMC 0.35u), but not transistors (same as
         * TSMC 0.35u)."
         */


    )

    /* official SCMOS rules */

    ;; SCMOS 1. WELL (NWELL, PWELL)

    ivIf( ( !switch("hier?") || !switch("topCell?") ) then

        ;; 1.1 - modified for DEEP
        
        ;    if( ( submicronAvailable || deepAvailable ) then
        ;    sprintf( errMesg "(SCMOS_SUBM Rule 1.1) well width: %.2f um" (lambda*12.0) )
        ;    drc( nwellEdge width < (lambda * 12.0) errMesg )
        ;    drc( pwellEdge width < (lambda * 12.0) errMesg ) 
        ;else
            sprintf( errMesg "(SCMOS Rule 1.1) well width: %.2f um" (lambda*10.0) )
            drc( nwellEdge width < (lambda * 10.0) errMesg )
            drc( pwellEdge width < (lambda * 10.0) errMesg ) 
        ;)
        

        ;; 1.2 - modified for DEEP
        
            sprintf( errMesg "(SCMOS Rule 1.2) well spacing, different potential: %.2f um" (lambda*9.0))
            drc( nwell sep < (lambda * 9.0) diffNet errMesg )
            drc( pwell sep < (lambda * 9.0) diffNet errMesg )
        

        ;; 1.3
        sprintf( errMesg "(SCMOS Rule 1.3) well spacing, same potential: 0 or %.2f um" (lambda*6.0))
        drc( nwell sep < (lambda * 6.0) sameNet errMesg )
        drc( pwell sep < (lambda * 6.0) sameNet errMesg )
        drc( nwellEdge notch < (lambda * 6.0) errMesg )
        drc( pwellEdge notch < (lambda * 6.0) errMesg )

        ;; 1 note
        saveDerived( geomAnd( nwell pwell) "(SCMOS Rule 1 note) n-wells and p-wells may not overlap")

    )

    ;; SCMOS 2. ACTIVE

    ivIf( ( !switch("hier?") || !switch("topCell?") ) then

        ;; 2.1
        if( techdesc == "AMI_ABN" then
           sprintf( errMesg "(SCMOS Rule 2.1) active width: %.2f um" (lambda*5.0))
           drc( activeEdge width < (lambda * 5.0)  errMesg )
        else 
           sprintf( errMesg "(SCMOS Rule 2.1) active width: %.2f um" (lambda*3.0))
           drc( activeEdge width < (lambda * 3.0)  errMesg )
        )
           
        ;; 2.2
        sprintf( errMesg "(SCMOS Rule 2.2) active spacing: %.2f um" (lambda*3.0))
        drc( activeEdge sep < (lambda * 3.0) errMesg )
        drc( activeEdge notch < (lambda * 3.0) errMesg )

        ;; 2.3 - modified for DEEP
        
            sprintf( errMesg "(SCMOS Rule 2.3) source/drain active to well edge: %.2f um" (lambda*5.0))
            drc( nNotOhmicEdge nBulkEdge sep < (lambda * 5.0) errMesg )
            drc( pNotOhmicEdge pBulkEdge sep < (lambda * 5.0) errMesg )
            drc( pBulkEdge nNotOhmicEdge enc < (lambda * 5.0) errMesg )
            drc( nBulkEdge pNotOhmicEdge enc < (lambda * 5.0) errMesg )

        ;; 2.4
        sprintf( errMesg "(SCMOS Rule 2.4) substrate/well contact active to well edge: %.2f um" (lambda*3.0))
        drc( nBulkEdge nOhmicEdge enc < (lambda * 3.0) errMesg )
        drc( nOhmicEdge pBulkEdge sep < (lambda * 3.0) errMesg )
        drc( pOhmicEdge nBulkEdge sep < (lambda * 3.0) errMesg )
        drc( pBulkEdge pOhmicEdge enc < (lambda * 3.0) errMesg )

        ;; 2.5
        sprintf( errMesg "(SCMOS Rule 2.5) active of different implant spacing: 0 or %.2f um" (lambda*4.0))
        drc( nNotOhmicEdge pOhmicEdge 0 < sep < (lambda * 4.0) errMesg )
        drc( pNotOhmicEdge nOhmicEdge 0 < sep < (lambda * 4.0) errMesg )

    )

    ;; SCMOS 3. POLY

    ivIf( ( !switch("hier?") || !switch("topCell?") ) then

        ;; 3.1
        sprintf( errMesg "(SCMOS Rule 3.1) poly width: %.2f um" (lambda*2.0))
        drc( polyEdge width < (lambda * 2.0)  errMesg )

        ;; 3.2 - modified for DEEP
        if( submicronAvailable then
            sprintf( errMesg "(SCMOS_SUBM Rule 3.2) poly spacing: %.2f um" (lambda*3.0))
            drc( polyEdge sep < (lambda * 3.0) errMesg )
            drc( polyEdge notch < (lambda * 3.0) errMesg )
        else if( deepAvailable then
            sprintf( errMesg "(SCMOS_SUBM Rule 3.2) poly spacing: %.2f um" (lambda*4.0))
            drc( polyEdge sep < (lambda * 4.0) errMesg )
            drc( polyEdge notch < (lambda * 4.0) errMesg )
	else
            sprintf( errMesg "(SCMOS Rule 3.2) poly spacing: %.2f um" (lambda*2.0))
            drc( polyEdge sep < (lambda * 2.0) errMesg )
            drc( polyEdge notch < (lambda * 2.0) errMesg )
        ) ) ;;

        ;; 3.3 - modified for DEEP

            sprintf( errMesg "(SCMOS Rule 3.3) gate enclosure of active: %.2f um" (lambda*2.0))
            drc( polyEdge activeEdge enc < (lambda * 2.0) errMesg )
        

        ;; 3.4 - modified for DEEP
        
            sprintf( errMesg "(SCMOS Rule 3.4) active enclosure of gate: %.2f um" (lambda*3.0))
            drc( activeEdge polyEdge enc < (lambda * 3.0) errMesg )
        ;;

        ;; 3.5
        sprintf( errMesg "(SCMOS Rule 3.5) field poly to active spacing: %.2f um" (lambda*1.0))
        drc( polyEdge activeEdge sep < (lambda * 1.0) errMesg )

    )

    ;; SCMOS 4. SELECT (PSELECT, NSELECT)

    ivIf( ( !switch("hier?") || !switch("topCell?") ) then

        ;; 4.1
        sprintf( errMesg "(SCMOS Rule 4.1) n select to channel spacing: %.2f um" (lambda*3.0))
        drc( nselectEdge geomGetEdge( polyEdge inside pNotOhmic) sep < (lambda * 3.0) app > 0 errMesg )
        drc( nselectEdge geomGetEdge( polyEdge inside nNotOhmic) enc < (lambda * 3.0) app > 0 errMesg )
        sprintf( errMesg "(SCMOS Rule 4.1) p select to channel spacing: %.2f um" (lambda*3.0))
        drc( pselectEdge geomGetEdge( polyEdge inside nNotOhmic) sep < (lambda * 3.0) app > 0 errMesg )
        drc( pselectEdge geomGetEdge( polyEdge inside pNotOhmic) enc < (lambda * 3.0) app > 0 errMesg )

        ;; 4.2
        sprintf( errMesg "(SCMOS Rule 4.2) select overlap of active: %.2f um" (lambda*2.0))
        drc( geomOr( nselectEdge pselectEdge ) activeEdge sep < (lambda * 2.0) errMesg )
        drc( geomOr( nselectEdge pselectEdge ) activeEdge enc < (lambda * 2.0) errMesg )

           ;; 4.3 - modified for DEEP
        
            sprintf( errMesg "(SCMOS Rule 4.3) n select to active contact spacing: %.2f um" (lambda*1.0))
            drc( nselectEdge caEdge sep < (lambda * 1.0) errMesg )
            drc( nselectEdge caEdge enc < (lambda * 1.0) errMesg )
            sprintf( errMesg "(SCMOS Rule 4.3) p select to active contact spacing: %.2f um" (lambda*1.0))
            drc( pselectEdge caEdge sep < (lambda * 1.0) errMesg )
            drc( pselectEdge caEdge enc < (lambda * 1.0) errMesg )
            sprintf( errMesg "(SCMOS Rule 4.3) select overlap of active contact: %.2f um" (lambda*1.0))
            saveDerived( geomButting( geomAnd( ca nselect ) geomAnd( ca pselect ) ) errMesg )
        

        ;; 4.4 - modified for DEEP
        
            sprintf( errMesg "(SCMOS Rule 4.4) n select width: %.2f um" (lambda*2.0))
            drc( nselectEdge width < (lambda * 2.0)  errMesg )
            sprintf( errMesg "(SCMOS Rule 4.4) p select width: %.2f um" (lambda*2.0))
            drc( pselectEdge width < (lambda * 2.0)  errMesg )

            sprintf( errMesg "(SCMOS Rule 4.4) n select spacing: %.2f um" (lambda*2.0))
            drc( nselectEdge sep < (lambda * 2.0) errMesg )
            drc( nselectEdge notch < (lambda * 2.0) errMesg )
            sprintf( errMesg "(SCMOS Rule 4.4) p select spacing: %.2f um" (lambda*2.0))
            drc( pselectEdge sep < (lambda * 2.0) errMesg )
            drc( pselectEdge notch < (lambda * 2.0) errMesg )
        

        sprintf( errMesg "(SCMOS Rule 4.4) n select and p select may not overlap" )
        saveDerived( geomAnd( nselect pselect ) errMesg )
     )

    ;; SCMOS 5B. DENSER CONTACT TO POLY

    ivIf( ( !switch("hier?") || !switch("topCell?") ) then

        ;; 5.1
        sprintf( errMesg "(SCMOS Rule 5.1) poly contact size, exactly: %.2f x %.2f um" (lambda*2.0) (lambda*2.0))
        drc( cpEdge width < (lambda * 2.0) errMesg )
        drc( cp area > ( (lambda * 2.0) * (lambda * 2.0) + (lambda * 0.1) * (lambda * 0.1) ) errMesg )

        ;; 5.2.b
        sprintf( errMesg "(SCMOS Rule 5.2.b) poly enclosure of contact: %.2f um" (lambda*1.0))
        drc( polyEdge cpEdge enc < (lambda * 1.0) errMesg )
        saveDerived( geomAndNot( cp poly) errMesg )
        
	;; 5.3 - modified for DEEP
        
            sprintf( errMesg "(SCMOS Rule 5.3) poly contact spacing: %.2f um" (lambda*2.0))
            drc( cpEdge sep < (lambda * 2.0) errMesg )
            drc( cpEdge notch < (lambda * 2.0) errMesg )
        ;;


        ;; 5.4
        sprintf( errMesg "(SCMOS Rule 5.4) poly contact to gate spacing: %.2f um" (lambda*2.0))
        drc( cpEdge GateEdge sep < (lambda * 2.0) errMesg )

        ;; 5.5.b

        /*         
         * ftp://ftp.mosis.org/pub/mosis/magic/new/beta/CHANGELOG
         *
         * 990318 release 99c:
         *
         *        SCN5M_SUBM.15.*tech27:
         *
         *          removed the poly-to-poly-contact spacing rule:
         *
         *                    Poly spacing to Poly contact < 4 (Mosis #5.5.b)
         *
         *          since rule 5.5.b is not actually required for the tsmc25
         *          process.  Again (see 5.5.b discussion below), you would need
         *          to add this rule to create full SCMOS_SUBM rule-conforming
         *          layout.
         *
         * Also:
         *
         * SCN3M*.tech27: (all techfiles for HP cmos26 and cmos14 processes)
         *
         *         Commented out the poly-to-poly-contact spacing rule:
         *
         *             Poly spacing to Poly contact < 4 (Mosis #5.5.b)
         *
         *         (see lines starting with #PSC (for "poly space-to contact"))
         *         since rule 5.5.b is only actually required for hpcmos10
         *         processes.  Again, you would need to uncomment this rule to
         *         create full SCMOS rule-conforming layout.
         */

        
            sprintf( errMesg "(SCMOS Rule 5.5.b) poly contact to poly spacing: %.2f um" (lambda*4.0))
            drc( cpEdge polyEdge sep < (lambda * 4.0) errMesg )
        

        ;; 5.6.b
        sprintf( errMesg "(SCMOS Rule 5.6.b) poly contact to active spacing: %.2f um" (lambda*2.0))
        drc( cpEdge activeEdge sep < (lambda * 2.0) errMesg )
        saveDerived( geomAnd( cp active) errMesg )

        ;; 5.7.b
        sprintf( errMesg "(SCMOS Rule 5.7.b) poly contact to active spacing, many contacts: %.2f um" (lambda*3.0))
        saveDerived( geomGetLength( drc(cpEdge activeEdge sep < (lambda * 3.0)) length > (lambda * 7.0) fig ) errMesg )
    )

    ;; SCMOS 6B. DENSER CONTACT TO ACTIVE

    ivIf( ( !switch("hier?") || !switch("topCell?") ) then

        ;; 6.1
        sprintf( errMesg "(SCMOS Rule 6.1) active contact size, exactly: %.2f x %.2f um" (lambda*2.0) (lambda*2.0))
        drc( caEdge width < (lambda * 2.0) errMesg )
        drc( ca area > ( (lambda * 2.0) * (lambda * 2.0) + (lambda * 0.1) * (lambda * 0.1) ) errMesg )

        ;; 6.2.b
        sprintf( errMesg "(SCMOS Rule 6.2.b) active enclosure of contact: %.2f um" (lambda*1.5))
        drc( activeEdge caEdge enc < (lambda * 1.5) errMesg )
        
            saveDerived( geomAnd( geomAndNot( ca cactive ) geomAndNot( ca active ) ) errMesg )
        

         ;; 6.3 - modified for DEEP
        
            sprintf( errMesg "(SCMOS Rule 6.3) active contact spacing: %.2f um" (lambda*2.0))
            drc( caEdge sep < (lambda * 2.0) errMesg )
            drc( caEdge notch < (lambda * 2.0) errMesg )
         ;;
	
        ;; 6.4
        sprintf( errMesg "(SCMOS Rule 6.4) active contact to transistor gate spacing: %.2f um" (lambda*2.0) )
        drc( caEdge GateEdge sep < (lambda * 2.0) errMesg )
        saveDerived( geomAnd( ca Gate) errMesg )

        ;; 6.5.b
        sprintf( errMesg "(SCMOS Rule 6.5.b) active contact to active spacing: %.2f um" (lambda*5.0))
        drc( caEdge activeEdge sep < (lambda * 5.0) errMesg )

        ;; 6.6.b
        sprintf( errMesg "(SCMOS Rule 6.6.b) active contact to field poly spacing: %.2f um" (lambda*2.0))
        drc( caEdge fieldPolyEdge sep < (lambda * 2.0) errMesg )
        saveDerived( geomAnd( ca fieldPoly) errMesg )

        ;; 6.7.b
        sprintf( errMesg "(SCMOS Rule 6.7.b) active contact to field poly spacing, many contacts: %.2f um" (lambda*3.0))
        saveDerived( geomGetLength( drc(caEdge fieldPolyEdge sep < (lambda * 3.0)) length > (lambda * 7.0) fig ) errMesg )

        ;; 6.8.b
        sprintf( errMesg "(SCMOS Rule 6.8.b) active contact to poly contact spacing: %.2f um" (lambda*4.0))
        drc( caEdge cpEdge sep < (lambda * 4.0) errMesg )
        saveDerived( geomAnd( ca cp) errMesg )

    )


    ;; SCMOS 7. METAL1

    ivIf( ( !switch("hier?") || !switch("topCell?") ) then

        ;; 7.1
        sprintf( errMesg "(SCMOS Rule 7.1) metal1 width: %.2f um" (lambda*3.0))
        drc( metal1Edge width < (lambda * 3.0)  errMesg )

        ;; 7.2 - modified for DEEP
        
            sprintf( errMesg "(SCMOS Rule 7.2) metal1 spacing: %.2f um" (lambda*2.0))
            drc( metal1Edge sep < (lambda * 2.0) errMesg )
            drc( metal1Edge notch < (lambda * 2.0) errMesg )
        

        ;; 7.3
        sprintf( errMesg "(SCMOS Rule 7.3) metal1 enclosure of contact: %.2f um" (lambda*1.0))
        drc( metal1Edge cpEdge enc < (lambda * 1.0) errMesg )
        drc( metal1Edge caEdge enc < (lambda * 1.0) errMesg )
        saveDerived( geomAndNot( cp metal1) errMesg )
        saveDerived( geomAndNot( ca metal1) errMesg )
        
        ;; 7.4
        ;; Metal1 wide metal (>10*lambda) rule not implemented
   )

    ;; SCMOS 8. VIA

    ivIf( ( !switch("hier?") || !switch("topCell?") ) then

        ;; 8.1 - modified for DEEP
        
            sprintf( errMesg "(SCMOS Rule 8.1) via size, exactly: %.2f x %.2f um" (lambda*2.0) (lambda*2.0))
            drc( viaEdge width < (lambda * 2.0) errMesg )
            drc( via area > ( (lambda * 2.0) * (lambda * 2.0) + (lambda * 0.1) * (lambda * 0.1) ) errMesg )
        

        ;; 8.2
        sprintf( errMesg "(SCMOS Rule 8.2) via spacing: %.2f um" (lambda*3.0))
        drc( viaEdge sep < (lambda * 3.0) errMesg )

        ;; 8.3
        sprintf( errMesg "(SCMOS Rule 8.3) metal1 enclosure of via: %.2f um" (lambda*1.0))
        drc( metal1Edge viaEdge enc < (lambda * 1.0) errMesg )
        saveDerived( geomAndNot( via metal1) errMesg )

        ;; 8.4
        
            sprintf( errMesg "(SCMOS Rule 8.4) via to contact spacing: %.2f um" (lambda*2.0))
            drc( viaEdge caEdge sep < (lambda * 2.0) errMesg )
            drc( viaEdge cpEdge sep < (lambda * 2.0) errMesg )
            saveDerived( geomAnd( via geomOr( ca cp)) errMesg )
        

        ;; 8.5 (doesn't apply to SCMOS_SUBM; see Table 4 in SCMOS Rules Manual, v.7.3) - modified for DEEP
        
            sprintf( errMesg "(SCMOS Rule 8.5) via to poly edge spacing: %.2f um" (lambda*2.0))
            drc( polyEdge viaEdge sep < (lambda * 2.0) errMesg )
            drc( polyEdge viaEdge enc < (lambda * 2.0) errMesg )
            saveDerived( geomStraddle( via poly) errMesg )

            sprintf( errMesg "(SCMOS Rule 8.5) via to active edge spacing: %.2f um" (lambda*2.0))
            drc( activeEdge viaEdge sep < (lambda * 2.0) errMesg )
            drc( activeEdge viaEdge enc < (lambda * 2.0) errMesg )
            saveDerived( geomStraddle( via active) errMesg )
            
                sprintf( errMesg "(SCMOS Rule 8.5) via to cactive edge spacing: %.2f um" (lambda*2.0))
                drc( cactiveEdge viaEdge sep < (lambda * 2.0) errMesg )
                drc( cactiveEdge viaEdge enc < (lambda * 2.0) errMesg )
                saveDerived( geomStraddle( via cactive) errMesg )
            
        
    )

    ;; SCMOS 9. METAL2

    ivIf( ( !switch("hier?") || !switch("topCell?") ) then

        ;; 9.1
        sprintf( errMesg "(SCMOS Rule 9.1) metal2 width: %.2f um" (lambda*3.0))
        drc( metal2Edge width < (lambda * 3.0)  errMesg )

        ;; 9.2 - modified for DEEP
        
            sprintf( errMesg "(SCMOS Rule 9.2.a) metal2 spacing: %.2f um" (lambda*4.0))
            drc( metal2Edge sep < (lambda * 4.0) errMesg )
            drc( metal2Edge notch < (lambda * 4.0) errMesg )
         ;;

        ;; 9.3
        sprintf( errMesg "(SCMOS Rule 9.3) metal2 enclosure of via: %.2f um" (lambda*1.0))
        drc( metal2Edge viaEdge enc < (lambda * 1.0) errMesg )
        saveDerived( geomAndNot( via metal2) errMesg )
 
        ;; 9.4
        ;; Metal2 wide metal (>10*lambda) rule not implemented
    )


    ;; SCMOS 10. OVERGLASS

    ivIf( !switch("allowTinyPads?") &&
          !switch("AreaPads?") &&
          ( !switch("hier?") || switch("topCell?") ) then

        saveDerived( geomStraddle( glass pad))

        BondingGlass = geomInside( glass pad)
        ProbeGlass = geomOutside( glass pad)

        BondingPad = geomAndNot( geomSize( BondingGlass 6.0) geomHoles( BondingGlass))
        ProbePad = geomAndNot( geomSize( ProbeGlass 6.0) geomHoles( ProbeGlass))
        Pad = geomOr( BondingPad ProbePad)

        BondingPadEdge = geomGetEdge( BondingPad not_over "nodrc")
        ProbePadEdge = geomGetEdge( ProbePad not_over "nodrc")
        PadEdge = geomGetEdge( Pad not_over "nodrc")

        
        Metal2EdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "metal2" "glass" 36.0)) not_over "nodrc")
        Metal1EdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "metal1" "glass" 21.0)) not_over "nodrc")
        PolyEdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "poly" "glass" 21.0)) not_over "nodrc")
        ActiveEdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "active" "glass" 21.0)) not_over "nodrc")
        
            ElecEdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "elec" "glass" 21.0)) not_over "nodrc")
        

        ;; 10.1
        drc( BondingPadEdge width < 60.0 "(SCMOS Rule 10.1) bonding pad width: 60 um")

        ;; 10.2
        drc( ProbePadEdge width < 20.0 "(SCMOS Rule 10.2) probe pad width: 20 um")

        ;; 10.3
        
                drc( Metal2EdgeNearPad glassEdge enc < 6.0 "(SCMOS Rule 10.3) pad enclosure of glass: 6 um")
                saveDerived( geomAndNot( glass metal2) "(SCMOS Rule 10.3) pad enclosure of glass: 6 um")
            
        

        ;; 10.4

        drc( PadEdge Metal2EdgeNearPad sep < 30.0 "(SCMOS Rule 10.4) pad to unrelated metal2 spacing: 30 um")

        ;; 10.5
        drc( PadEdge Metal1EdgeNearPad sep < 15.0 "(SCMOS Rule 10.5) pad to unrelated metal1 spacing: 15 um")
        drc( PadEdge PolyEdgeNearPad   sep < 15.0 "(SCMOS Rule 10.5) pad to unrelated poly spacing: 15 um")
        drc( PadEdge ActiveEdgeNearPad sep < 15.0 "(SCMOS Rule 10.5) pad to unrelated active spacing: 15 um")
       
            drc( PadEdge ElecEdgeNearPad   sep < 15.0 "(SCMOS Rule 10.5) pad to unrelated elec spacing: 15 um")
        
    )

    ;; This set of overglass rules allows for very small probe pads
    ;; also for area array pads

    ivIf( ( switch("allowTinyPads?") || switch("AreaPads?") ) &&
          ( !switch("hier?") || switch("topCell?") ) then

        saveDerived( geomStraddle( glass pad))

            BondingGlass = geomInside( glass pad)
        
        BondingPad = geomAndNot( geomSize( BondingGlass 6.0) geomHoles( BondingGlass))
        BondingPadEdge = geomGetEdge( BondingPad not_over "nodrc")


        Metal2EdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "metal2" "glass" 36.0)) not_over "nodrc")
        Metal1EdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "metal1" "glass" 21.0)) not_over "nodrc")
        PolyEdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "poly" "glass" 21.0)) not_over "nodrc")
        ActiveEdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "active" "glass" 21.0)) not_over "nodrc")
       
            ElecEdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "elec" "glass" 21.0)) not_over "nodrc")

    )

    ;; SCMOS 11. ELECTRODE for CAPACITORS

    ivIf( ( !switch("hier?") || !switch("topCell?") ) then

            ;; 11.1 - modified for DEEP
           
                sprintf( errMesg "(SCMOS Rule 11.1) capacitor electrode width: %.2f um" (lambda*3.0))
                drc( CapacitorElecEdge width < (lambda * 3.0)  errMesg )

            ;; 11.2
            sprintf( errMesg "(SCMOS Rule 11.2) capacitor electrode spacing: %.2f um" (lambda*3.0))
            drc( CapacitorElecEdge sep < (lambda * 3.0) errMesg )
            drc( CapacitorElecEdge notch < (lambda * 3.0) errMesg )
            ;; 11.3 - modified for DEEP
                sprintf( errMesg "(SCMOS Rule 11.3) poly enclosure of capacitor electrode: %.2f um" (lambda*2.0))
                drc( polyEdge CapacitorElecEdge enc < (lambda * 2.0) errMesg )
            

            ;; 11.4
            sprintf( errMesg "(SCMOS Rule 11.4) capacitor electrode to bulk spacing: %.2f um" (lambda*2.0))
            drc( CapacitorElecEdge nBulkEdge sep < (lambda * 2.0) errMesg )
            drc( CapacitorElecEdge pBulkEdge sep < (lambda * 2.0) errMesg )
            saveDerived( geomStraddle( CapacitorElec nBulk) errMesg )
            saveDerived( geomStraddle( CapacitorElec pBulk) errMesg )

            sprintf( errMesg "(SCMOS Rule 11.4) bulk enclosure of capacitor electrode: %.2f um" (lambda*2.0))
            drc( nBulkEdge CapacitorElecEdge enc < (lambda * 2.0) errMesg )
            drc( pBulkEdge CapacitorElecEdge enc < (lambda * 2.0) errMesg )

            sprintf( errMesg "(SCMOS Rule 11.4) capacitor electrode to active spacing: %.2f um" (lambda*2.0))
            drc( CapacitorElecEdge activeEdge sep < (lambda * 2.0) errMesg )
            saveDerived( geomAnd( CapacitorElec active) errMesg )

            ;; 11.5 - modified for DEEP
                sprintf( errMesg "(SCMOS Rule 11.5) capacitor electrode to poly contact spacing: %.2f um" (lambda*3.0))
                drc( CapacitorElecEdge cpEdge sep < (lambda * 3.0) errMesg )

            ;; 11.6
            sprintf( errMesg "(SCMOS Rule 11.6) poly2 to unrelated metal2 spacing: %.2f um" (lambda*2.0))
            drc( geomGetEdge( "elec" ) geomGetEdge( "metal2" ) sep < (lambda * 2.0) errMesg )
            saveDerived( geomOverlap( metal2 elec diffNet ) errMesg )
           
            sprintf( errMesg "(SCMOS Rule 11.6) poly2 to unrelated metal1 spacing: %.2f um" (lambda*2.0))
            drc( geomGetEdge( "elec" ) geomGetEdge( "metal1" ) sep < (lambda * 2.0) errMesg )
            saveDerived( geomOverlap( metal1 elec diffNet ) errMesg )
        
    )

    ;; SCMOS 12. ELECTRODE for TRANSISTORS

    ivIf( ( !switch("hier?") || !switch("topCell?") ) then

          
            ;; 12.1
            sprintf( errMesg "(SCMOS Rule 12.1) transistor electrode width: %.2f um" (lambda*2.0))
            drc( TransistorElecEdge width < (lambda * 2.0)  errMesg )

            ;; 12.2
            sprintf( errMesg "(SCMOS Rule 12.2) transistor electrode spacing: %.2f um" (lambda*3.0))
            drc( TransistorElecEdge sep < (lambda * 3.0) errMesg )
            drc( TransistorElecEdge notch < (lambda * 3.0) errMesg )

            ;; 12.3
            sprintf( errMesg "(SCMOS Rule 12.3) gate enclosure of active: %.2f um" (lambda*2.0))
            drc( TransistorElecEdge activeEdge enc < (lambda * 2.0) errMesg )

            ;; 12.4
            sprintf( errMesg "(SCMOS Rule 12.4) transistor electrode to active spacing: %.2f um" (lambda*1.0))
            drc( TransistorElecEdge activeEdge sep < (lambda * 1.0) errMesg )

            ;; 12.5
            sprintf( errMesg "(SCMOS Rule 12.5) transistor electrode to poly spacing: %.2f um" (lambda*2.0))
            drc( TransistorElecEdge polyEdge sep < (lambda * 2.0) errMesg )

            sprintf( errMesg "(SCMOS Rule 12.5) transistor electrode overlap of poly: %.2f um" (lambda*2.0))
            drc( TransistorElecEdge polyEdge ovlp < (lambda * 2.0) errMesg )

            ;; 12.6
            sprintf( errMesg "(SCMOS Rule 12.6) transistor electrode to poly contact spacing: %.2f um" (lambda*3.0))
            drc( TransistorElecEdge cpEdge sep < (lambda * 3.0) errMesg )
            saveDerived( geomAnd( TransistorElec cp) errMesg )

            sprintf( errMesg "(SCMOS Rule 12.6) transistor electrode to active contact spacing: %.2f um" (lambda*3.0))
            drc( TransistorElecEdge caEdge sep < (lambda * 3.0) errMesg )
            saveDerived( geomAnd( TransistorElec ca) errMesg )
        
    )

    ;; SCMOS 13. ELECTRODE CONTACT

    ivIf( ( !switch("hier?") || !switch("topCell?") ) then

 
            ;; 13.1
            sprintf( errMesg "(SCMOS Rule 13.1) contact size, exactly: %.2f x %.2f um" (lambda*2.0) (lambda*2.0))
            drc( ceEdge width < (lambda * 2.0) errMesg )
            drc( ce area > ( (lambda * 2.0) * (lambda * 2.0) + (lambda * 0.1) * (lambda * 0.1) ) errMesg )

            ;; 13.2
            
                sprintf( errMesg "(SCMOS Rule 13.2) contact spacing: %.2f um" (lambda*2.0))
                drc( ceEdge sep < (lambda * 2.0) errMesg )
                drc( ceEdge notch < (lambda * 2.0) errMesg )
            
            ;; 13.3
            sprintf( errMesg "(SCMOS Rule 13.3) capacitor electrode enclosure of contact: %.2f um" (lambda*3.0))
            drc( CapacitorElecEdge ceEdge enc < (lambda * 3.0) errMesg )

            ;; 13.4
            sprintf( errMesg "(SCMOS Rule 13.4) electrode enclosure of contact (not on capacitor): %.2f um" (lambda*2.0))
            drc( TransistorElecEdge ceEdge enc < (lambda * 2.0) errMesg )
            saveDerived( geomAndNot( ce elec) "(SCMOS Rules 13.3,13.4) electrode enclosure of contact" )

            ;; 13.5
            sprintf( errMesg "(SCMOS Rule 13.5) electrode contact to poly spacing: %.2f um" (lambda*3.0))
            drc( ceEdge polyEdge sep < (lambda * 3.0) errMesg )
            saveDerived( geomOutside( geomAnd( ce poly) CapacitorElec) errMesg )

            sprintf( errMesg "(SCMOS Rule 13.5) electrode contact to active spacing: %.2f um" (lambda*3.0))
            drc( ceEdge activeEdge sep < (lambda * 3.0) errMesg )
            saveDerived( geomAnd( ce active) errMesg )
        
    )

    ;; SCMOS 14. VIA2

    ;; SCMOS 15. METAL3
    ;; SCMOS 16. NPN BIPOLAR TRANSISTOR (ANALOG OPTION)
    ivIf( ( !switch("hier?") || !switch("topCell?") ) then

       ;; if( npnAvailable then
            ;; 16.1
            sprintf( errMesg "(SCMOS Rule 16.1) collector contact, exactly: %.2f x %.2f um" (lambda*2.0) (lambda*2.0))
            drc( npnCollectorContactEdge width < (lambda * 2.0) errMesg )
            drc( npnCollectorContact area > ( (lambda * 2.0) * (lambda * 2.0) + (lambda * 0.1) * (lambda * 0.1) ) errMesg )

            sprintf( errMesg "(SCMOS Rule 16.1) emitter contact, exactly: %.2f x %.2f um" (lambda*2.0) (lambda*2.0))
            drc( npnEmitterContactEdge width < (lambda * 2.0) errMesg )
            drc( npnEmitterContact area > ( (lambda * 2.0) * (lambda * 2.0) + (lambda * 0.1) * (lambda * 0.1) ) errMesg )

            sprintf( errMesg "(SCMOS Rule 16.1) base contact, exactly: %.2f x %.2f um" (lambda*2.0) (lambda*2.0))
            drc( npnBaseContactEdge width < (lambda * 2.0) errMesg )
            drc( npnBaseContact area > ( (lambda * 2.0) * (lambda * 2.0) + (lambda * 0.1) * (lambda * 0.1) ) errMesg )

            ;; 16.2
            sprintf( errMesg "(SCMOS Rule 16.2) emitter sel enclosure of contact: %.2f um" (lambda*3.0) )
            drc( npnEmitterEdge npnEmitterContactEdge enc < (lambda * 3.0) errMesg )

            ;; 16.3
            sprintf( errMesg "(SCMOS Rule 16.3) pbase enclosure of emitter select: %.2f um" (lambda*2.0) )
            drc( pbaseEdge npnEmitterEdge enc < (lambda * 2.0) errMesg )

            ;; 16.4
            sprintf( errMesg "(SCMOS Rule 16.4) emitter sel to base sel spacing: %.2f um" (lambda*4.0) )
            drc( npnEmitterEdge npnBaseTapEdge sep < (lambda * 4.0) errMesg )

            ;; 16.5
            sprintf( errMesg "(SCMOS Rule 16.5) pbase enclosure of base select: %.2f um" (lambda*2.0) )
            drc( pbaseEdge npnBaseTapEdge enc < (lambda * 2.0) errMesg )

            ;; 16.6
            sprintf( errMesg "(SCMOS Rule 16.6) base sel enclosure of contact: %.2f um" (lambda*2.0) )
            drc( npnBaseTapEdge npnBaseContactEdge enc < (lambda * 2.0) errMesg )

            ;; 16.7
            sprintf( errMesg "(SCMOS Rule 16.7) nwell enclosure of pbase: %.2f um" (lambda*6.0) )
            drc( nwellEdge pbaseEdge enc < (lambda * 6.0) errMesg )
            saveDerived( geomAndNot( pbase nwell ) errMesg )

            ;; 16.8
            sprintf( errMesg "(SCMOS Rule 16.8) pbase to collector active spacing: %.2f um" (lambda*4.0) )
            drc( npnCollectorEdge pbaseEdge sep < (lambda * 4.0) errMesg )

            ;; 16.9 
            sprintf( errMesg "(SCMOS Rule 16.9) coll active enclosure of contact: %.2f um" (lambda*2.0) )
            drc( npnCollectorEdge npnCollectorContactEdge enc < (lambda * 2.0) errMesg )

            ;; 16.10
            sprintf( errMesg "(SCMOS Rule 16.10) nwell enclosure of coll active: %.2f um" (lambda*3.0) )
            drc( nwellEdge npnCollectorEdge enc < (lambda * 3.0) errMesg )
            saveDerived( geomAndNot( cactive nwell ) errMesg )

            ;; 16.11
            sprintf( errMesg "(SCMOS Rule 16.11) nselect enclosure of coll active: %.2f um" (lambda*2.0) )
            drc( nselectEdge npnCollectorEdge enc < (lambda * 2.0) errMesg )
            saveDerived( geomAndNot( cactive nselect ) errMesg )
        
    )

    ;; SCMOS 17. CAPACITOR WELL
    ;; SCMOS 18. LINEAR CAPACITOR (POLY TO N-DIFFUSION) 
    ;; SCMOS 19. BURIED CHANNEL CCD
    ;; SCMOS 20. SILICIDE BLOCK
    ;; SCMOS 21. VIA3
    ;; SCMOS 22. METAL4
    ;; SCMOS 23. SCNPC WITH POLYCAP

    ivIf( ( !switch("hier?") || !switch("topCell?") ) then

        if( polycapAvailable then
        ;; 23.1
        sprintf( errMesg "(SCMOS Rule 23.1) minimum polycap width: %.2f um" (lambda*8.0) )
        drc( polycapEdge width < (lambda * 8.0) errMesg )

        ;; 23.2
        sprintf( errMesg "(SCMOS Rule 23.2) polycap spacing: %.2f um" (lambda*4.0) )
        drc( polycapEdge sep < (lambda * 4.0) errMesg )
        drc( polycapEdge notch < (lambda * 4.0) errMesg )

        ;; 23.3
        sprintf( errMesg "(SCMOS Rule 23.3) polycap to active spacing: %.2f um" (lambda*8.0) )
        drc( polycapEdge activeEdge sep < (lambda * 8.0) errMesg )
        sprintf( errMesg "(SCMOS Rule 23.3) all capacitors must be over field" )
        saveDerived( geomAnd( polycap active ) errMesg )

        ;; 23.4
        sprintf( errMesg "(SCMOS Rule 23.4) polycap enclosure of poly: %.2f um" (lambda*3.0) )
        drc( polycapEdge polyEdge enc < (lambda * 3.0) errMesg )

        ;; 23.5
        sprintf( errMesg "(SCMOS Rule 23.5) polycap enclosure of contact: %.2f um" (lambda*2.0) )
        drc( polycapEdge cpolycapEdge enc < (lambda * 2.0) errMesg )

        ;; 23.6
        sprintf( errMesg "(SCMOS Rule 23.6) poly enclosure of contact in capacitor: %.2f um" (lambda*2.0) )
        drc( polycapCapEdge cpEdge enc < (lambda * 2.0) errMesg )

        ;; 23.7
        sprintf( errMesg "(SCMOS Rule 23.7) poly to polycap-contact spacing: %.2f um" (lambda*2.0) )
        drc( polycapCapEdge cpolycapEdge sep < (lambda * 2.0) errMesg )

        ;; 23.8
        sprintf( errMesg "(SCMOS Rule 23.8) polycap to metal1 spacing: %.2f um" (lambda*4.0) )
        drc( polycapEdge metal1Edge sep < (lambda * 4.0) diffNet errMesg )
        saveDerived( geomOverlap( metal1 polycap diffNet ) errMesg )

        ;; 23.9
        sprintf( errMesg "(SCMOS Rule 23.9) polycap to metal2 spacing: %.2f um" (lambda*2.0) )
        drc( polycapEdge metal2Edge sep < (lambda * 2.0) errMesg )
        saveDerived( geomOverlap( metal2 polycap diffNet ) errMesg )
        )
    )


    ;; SCMOS 24. THICK ACTIVE
    ;; SCMOS 26. METAL5
    ;; SCMOS 27. HIGHRES POLY
    ;; SCMOS 28. METALCAP (MOSIS CAP_TOP_METAL)
    ;; SCMOS 29. VIA5
    ;; SCMOS 30. METAL6
    ;; SCMOS EXP-98. MEMS OPEN
    ;; SCMOS EXP-99. MEMS PSTOP

) ; drcExtractRules
) ; let

; vim:ts=4:columns=132:set tw=0:

Text file Source (historic): geocities.com/fudinggecircuit/layout

geocities.com/fudinggecircuit

(to report bad content: archivehelp @ gmail)