/************************************************** * * * * * 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: