/****************************************************** * Diva Extraction Rules * * * * * Midified by Fuding Ge based on NCSU Design Kit *************************************************************************/ let( ( lambda gridRes techdesc wellType submicronAvailable cwellAvailable metal3Available metal4Available metal5Available metal6Available metalcapAvailable npnAvailable ccdAvailable elecAvailable sblockAvailable PadType highresAvailable stackedViasAvailable techfile modelPrefix errMesg useCapIVPcell ) lamda=0.8 techdesc="AMI_ABN" wellType="t" submicronAvailable=nil cwellAvailable=nil gridRes=0.4 techfile="ami_16.tf" elecAvailable=t npnAvailable=t metal3Available=nil metal4Available=nil metal5Available=nil metal6Available=nil metalcapAvailable=nil cdAvailable=nil sblockAvailable=nil ighresAvailable=nil stackedViasAvailable=nil ;modelPrefix="ami16" useCapIVPcell=t ;prependNCSUCDKInstallPath=/nfs/hrap_ckt3/atlasHarp/design/fge/NCSU_CDK_1p3_local ;load( "/nfs/hrap_ckt3/atlasHarp/design/fge/NCSU_CDK_1p3_local/skill/globalData.il") ; Following are some from globalData.il NCSU_CDK_version = "NCSU_CDK.1.3" /* * Create global to hold model suffixes for CDFs and extract rules */ NCSU_modelSuffix = makeTable( "fetModelSuffix" "" ) NCSU_modelSuffix[ "nmos" ] = "N" NCSU_modelSuffix[ "pmos" ] = "P" NCSU_modelSuffix[ "nmos_hv" ] = "Nhv" ; high-voltage device NCSU_modelSuffix[ "pmos_hv" ] = "Phv" ; high-voltage device NCSU_modelSuffix[ "nelec" ] = "NE" ; poly2 gate device NCSU_modelSuffix[ "pelec" ] = "PE" ; poly2 gate device NCSU_modelSuffix[ "npdiode" ] = "NP" ; N+-p[well|sub] diode NCSU_modelSuffix[ "pndiode" ] = "PN" ; P+-n[well|sub] diode NCSU_modelSuffix[ "nwpdiode" ] = "NwP" ; nwell-psub diode /* * tell DLE (Device Level Editor) to use our pCells */ NCSU_dleCellName = makeTable( "dleCellName" "" ) NCSU_dleCellName[ "nmos" ] = "nmos" NCSU_dleCellName[ "pmos" ] = "pmos" NCSU_dleCellName[ "nmos_hv" ] = "nmos_hv" NCSU_dleCellName[ "pmos_hv" ] = "pmos_hv" NCSU_dleCellName[ "nelec" ] = "nmos_elec" NCSU_dleCellName[ "pelec" ] = "pmos_elec" /* * Point to the sitewide "user menu" file. See * local/skill/menus/ncsu/userMenu.il for more detail. */ ;NCSU_siteMenuFile = ("/nfs/ch/proj/hcke/ch_hcke_ckt1/alliance/hancecreek/A0/fge/cadence/NCSU_CDK_1p3_local/cdssetup/cdksitemenu" ) /* * These strings are used in at least diva(EXT|DRC).rul and * layerDefinitions.tf to identify the current process. If any of these * strings are changed (which they probably shouldn't be), the same * change must be made in the above listed places as well. */ defstruct( globalEntry description techFile techLib mosisCode lambda minL minW gridRes deepRules submicronRules fetModelPrefix stackedVias active ) NCSU_techData = makeTable( "globalTechData" nil ) /* *********************************************** * * Active processes * *********************************************** */ ; http://www.mosis.org/Technical/Processes/proc-ami-abn.html NCSU_techData[ "AMI_ABN" ] = make_globalEntry( ?description "AMI 1.6u ABN (2P, NPN)" ?techFile "ami_16.tf" ?techLib "NCSU_TechLib_ami16" ?mosisCode "SCNA" ?lambda "0.8" ?minL 1.6 ?minW 4.0 ; note 5 lambda min width (see the Web page) ?gridRes 0.4 ?submicronRules nil ?fetModelPrefix "ami16" ?stackedVias nil ?active t ) /* * Default layer for creating labels in Virtuoso * (see /local/skill/menus/virtuoso/createLabel.il) */ NCSU_defLabelLayer = list( "text" "drawing" ) /* * Threshold below which extracted parasitic caps are ignored * (see /local/techfile/divaEXT.rul) */ NCSU_parasiticCapIgnoreThreshold = 2.0e-15 /* * amount by which resistor/capacitor values can differ in layout and * schematic and still pass LVS */ NCSU_LVSResSlack = 0.1 ; 10% NCSU_LVSCapSlack = 0.1 ; 10% /* * default names for the CIF/GDSII layer map files */ ;NCSU_cifInLayermapFile=("/nfs/ch/proj/hcke/ch_hcke_ckt1/alliance/hancecreek/A0/fge/cadence/NCSU_CDK_1p3_local/pipo/cifInLayermap" ) ;NCSU_cifOutLayermapFile=("/nfs/ch/proj/hcke/ch_hcke_ckt1/alliance/hancecreek/A0/fge/cadence/NCSU_CDK_1p3_local/pipo/cifOutLayermap" ) ;NCSU_streamInLayermapFile=("/nfs/ch/proj/hcke/ch_hcke_ckt1/alliance/hancecreek/A0/fge/cadence/NCSU_CDK_1p3_local/pipo/streamInLayermap" ) drcExtractRules( ;load( "/nfs/hrap_ckt3/atlasHarp/design/fge/NCSU_CDK_1p3_local/techfile/divaLayerDef.il") ;The following is the modofied file: ;========================================================================== ; ; $Id: divaLayerDef.il,v 1.33 2001/02/20 22:41:48 jtschaff Exp $ ; ;-------------------------------------------------------------------------- /******************************************************************************** * * * * * 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( geomGetAngledEdge( active angle == 45 ) ) 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" ) ) if( cwellAvailable then dubiousData( ( "cwell" "drawing" ) "Improperly formed shape - cwell" ) saveDerived( geomGetNon45( cwell ) "Non-Manhattan shape - cwell" ) offGrid( cwell gridRes "(SCMOS Inst) Edge not on grid" ) ) if( polycapAvailable then dubiousData( ( "polycap" "drawing" ) "Improperly formed shape - polycap" ) saveDerived( geomGetNon45( polycap ) "Non-Manhattan shape - polycap" ) offGrid( polycap gridRes "(SCMOS Inst) Edge not on grid" ) ) if( sblockAvailable then dubiousData( ( "sblock" "drawing" ) "Improperly formed shape - sblock" ) saveDerived( geomGetNon45( sblock ) "Non-Manhattan shape - sblock" ) offGrid( sblock gridRes "(SCMOS Inst) Edge not on grid" ) ) if( memsAvailable then dubiousData( ( "pstop" "drawing" ) "Improperly formed shape - pstop" ) saveDerived( geomGetNon45( pstop ) "Non-Manhattan shape - pstop" ) offGrid( pstop gridRes "(SCMOS Inst) Edge not on grid" ) dubiousData( ( "open" "drawing" ) "Improperly formed shape - open" ) saveDerived( geomGetNon45( open ) "Non-Manhattan shape - open" ) offGrid( open gridRes "(SCMOS Inst) Edge not on grid" ) ) if( hvAvailable then dubiousData( ( "tactive" "drawing" ) "Improperly formed shape - tactive" ) saveDerived( geomGetNon45( tactive ) "Non-Manhattan shape - tactive" ) offGrid( tactive 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" ) ) ;--------------------------------------------------------------------- ; End of divaLayerDef.il ;---------------------------------------------------------------------- ;------------------------------------------------------------------------ ; mosfets ;------------------------------------------------------------------------ extractMOS( nChannelTran poly("G") nDiff("S" "D") pBulk("B") "nmos4 ivpcell NCSU_Analog_Parts" "l" "w" 1.0e-6 ) saveProperty( nChannelTran "model" "N" ) extractMOS( pChannelTran poly("G") pDiff("S" "D") nBulk("B") "pmos4 ivpcell NCSU_Analog_Parts" "l" "w" 1.0e-6 ) saveProperty( pChannelTran "model" "P" ) /*************************************** if( hvAvailable then extractMOS( hvnChannelTran poly("G") nDiff("S" "D") pBulk("B") "nmos4_hv ivpcell NCSU_Analog_Parts" "l" "w" 1.0e-6 ) saveProperty( hvnChannelTran "model" strcat( modelPrefix NCSU_modelSuffix["nmos_hv"] ) ) extractMOS( hvpChannelTran poly("G") pDiff("S" "D") nBulk("B") "pmos4_hv ivpcell NCSU_Analog_Parts" "l" "w" 1.0e-6 ) saveProperty( hvpChannelTran "model" strcat( modelPrefix NCSU_modelSuffix["pmos_hv"] ) ) ) ******************************/ if( elecAvailable then unless( member( techdesc list( "TSMC_CMOS035_4M2P" "TSMC_CMOS035_3M2P" "AMI_C5N" ) ) extractMOS( nElecChannelTran elec( "G" ) nDiff( "S" "D" ) pBulk( "B" ) "nmos4_elec ivpcell NCSU_Analog_Parts" "l" "w" 1.0e-6 ) saveProperty( nElecChannelTran "model" "nmos_elec" ) extractMOS( pElecChannelTran elec( "G" ) nDiff( "S" "D" ) nBulk( "B" ) "pmos4_elec ivpcell NCSU_Analog_Parts" "l" "w" 1.0e-6 ) saveProperty( pElecChannelTran "model" "pmos_elec" ) ) ) nDiffArea = measureParasitic( area (nDiff not_over nolpe) 1.0e-12 figure ) attachParasitic( nDiffArea ("as" "S") ("ad" "D") nChannelTran shared ) pDiffArea = measureParasitic( area (pDiff not_over nolpe) 1.0e-12 figure ) attachParasitic( pDiffArea ("as" "S") ("ad" "D") pChannelTran shared ) if( hvAvailable then attachParasitic( nDiffArea ("as" "S") ("ad" "D") hvnChannelTran shared ) attachParasitic( pDiffArea ("as" "S") ("ad" "D") hvpChannelTran shared ) ) ; could have problem here if there's a process w/both elec and hv, ; and it allows elec transistors if( elecAvailable && (member( techdesc list( "TSMC_CMOS035_4M2P" "TSMC_CMOS035_3M2P" "AMI_C5N" ) ) == nil) then attachParasitic( nDiffArea ("as" "S") ("ad" "D") nElecChannelTran shared ) attachParasitic( pDiffArea ("as" "S") ("ad" "D") pElecChannelTran shared ) nDiffPerimeter = measureParasitic( length (nDiff outside poly outside elec not_over nolpe) 1.0e-6 figure ) attachParasitic( nDiffPerimeter ("ps" "S") ("pd" "D") nChannelTran shared ) attachParasitic( nDiffPerimeter ("ps" "S") ("pd" "D") nElecChannelTran shared ) pDiffPerimeter = measureParasitic( length (pDiff outside poly outside elec not_over nolpe) 1.0e-6 figure ) attachParasitic( pDiffPerimeter ("ps" "S") ("pd" "D") pChannelTran shared ) attachParasitic( pDiffPerimeter ("ps" "S") ("pd" "D") pElecChannelTran shared ) else nDiffPerimeter = measureParasitic( length (nDiff outside poly not_over nolpe) 1.0e-6 figure ) attachParasitic( nDiffPerimeter ("ps" "S") ("pd" "D") nChannelTran shared ) pDiffPerimeter = measureParasitic( length (pDiff outside poly not_over nolpe) 1.0e-6 figure ) attachParasitic( pDiffPerimeter ("ps" "S") ("pd" "D") pChannelTran shared ) if( hvAvailable then attachParasitic( nDiffPerimeter ("ps" "S") ("pd" "D") hvnChannelTran shared ) attachParasitic( pDiffPerimeter ("ps" "S") ("pd" "D") hvpChannelTran shared ) ) ) ;------------------------------------------------------------------------ ; npns ;------------------------------------------------------------------------ ; hardcode the NPN model name to "Generic_NPN", since generally ; different models are used for different geometry BJTs the user ; will have to edit the netlist and replace it with the correct ; model name (a tip of the hat to John Galbraith at Arizona for his ; help with this issue) if( npnAvailable then extractDevice( npnTran (npnCollector "C") (npnBaseTap "B") (npnEmitter "E") "npn ivpcell NCSU_Analog_Parts" ) saveProperty( npnTran "model" "Generic_NPN" ) ) ;------------------------------------------------------------------------ ; resistors ;------------------------------------------------------------------------ ; poly/elec extractDevice( polyRes (poly "PLUS" "MINUS") "res ivpcell NCSU_Analog_Parts" ) if( sblockAvailable then extractDevice( polySRes (poly "PLUS" "MINUS") "res ivpcell NCSU_Analog_Parts" ) ) if( elecAvailable then extractDevice( elecRes (elec "PLUS" "MINUS") "res ivpcell NCSU_Analog_Parts" ) ) if( highresAvailable then extractDevice( elecHighres (elec "PLUS" "MINUS") "res ivpcell NCSU_Analog_Parts" ) ) ; nwell extractDevice( nwellRes (nBulk "PLUS" "MINUS") "res ivpcell NCSU_Analog_Parts" ) ; saveRecognition( nwellRes "res_id" ) ; resistor parameter extraction let( (sheetRes resWidth resPerim resLength res fullCorners) ; for each full corner (ie, 90 degree turn), subtract 0.5 a square ; of resistance (see W&E 2nd ed, p.178) ; poly sheetRes = techGetLayerProp( techfile list( "poly" "drawing") "sheetResistance" ) when( sheetRes resWidth = measureParameter( length (polyRes butting poly) 1.0e-6 ) resPerim = measureParameter( perimeter polyRes 1.0e-6 ) resLength = calculateParameter( (resPerim - resWidth) / 2.0 ) fullCorners = measureParameter( bends_full polyRes ) res = calculateParameter( sheetRes * (resLength/(resWidth/2.0) - fullCorners*0.5) ) saveParameter( res "r" ) ) ; poly + sblock if( sblockAvailable then sheetRes = techGetLayerProp( techfile list( "sblock" "drawing") "sheetResistance" ) when( sheetRes resWidth = measureParameter( length (polySRes butting poly) 1.0e-6 ) resPerim = measureParameter( perimeter polySRes 1.0e-6 ) resLength = calculateParameter( (resPerim - resWidth) / 2.0 ) fullCorners = measureParameter( bends_full polySRes ) res = calculateParameter( sheetRes * (resLength/(resWidth/2.0) - fullCorners*0.5) ) saveParameter( res "r" ) ) ) ; elec if( elecAvailable then ; regular sheetRes = techGetLayerProp( techfile list( "elec" "drawing") "sheetResistance" ) when( sheetRes resWidth = measureParameter( length (elecRes butting elec) 1.0e-6 ) resPerim = measureParameter( perimeter elecRes 1.0e-6 ) resLength = calculateParameter( (resPerim - resWidth) / 2.0 ) fullCorners = measureParameter( bends_full elecRes ) res = calculateParameter( sheetRes * (resLength/(resWidth/2.0) - fullCorners*0.5) ) saveParameter( res "r" ) ) ; high-resistance if( highresAvailable then sheetRes = techGetLayerProp( techfile list( "highres" "drawing") "sheetResistance" ) when( sheetRes resWidth = measureParameter( length (elecHighres butting elec) 1.0e-6 ) resPerim = measureParameter( perimeter elecHighres 1.0e-6 ) resLength = calculateParameter( (resPerim - resWidth) / 2.0 ) fullCorners = measureParameter( bends_full elecHighres ) res = calculateParameter( sheetRes * (resLength/(resWidth/2.0) - fullCorners*0.5) ) saveParameter( res "r" ) ) ) ) ; nwell ; sheetRes = techGetLayerProp( techfile list( "nwell" "drawing") "sheetResistance" ) sheetRes = 1638 when( sheetRes resWidth = measureParameter( length (nwellRes butting nBulk) 1.0e-6 ) resPerim = measureParameter( perimeter nwellRes 1.0e-6 ) resLength = calculateParameter( (resPerim - resWidth) / 2.0 ); fullCorners = measureParameter( bends_full nwellRes ) res = calculateParameter( sheetRes * (resLength/(resWidth/2.0) - fullCorners*0.5) ) saveParameter( res "r" ) ) ) ;------------------------------------------------------------------------ ; capacitors ;------------------------------------------------------------------------ ; first we do all the caps that use process-optional layers. we ; always extract these, since we assume they're "intentional". ; poly - polycap capacitors if( polycapAvailable then extractDevice( polycapCap (poly "PLUS") (polycap "MINUS") "cap ivpcell NCSU_Analog_Parts") saveRecognition( polycapCap "poly" ) let( ( areaCap capacitance ) areaCap = techGetTwoLayerProp( techfile list( "polycap" "drawing") list( "poly" "drawing") "areaCap" ) when( areaCap capacitance = measureParameter( area polycapCap 1.0e-18 * areaCap ) saveParameter( capacitance "c" ) ) ) ) ; metal - metalcap capacitors if( metalcapAvailable then let( ( areaCap capacitance ) cond( ( metal6Available extractDevice( metalcapCap (metalcap "PLUS") (metal5 "MINUS") "cap ivpcell NCSU_Analog_Parts") saveRecognition( metalcapCap "metalcap" ) areaCap = techGetTwoLayerProp( techfile list( "metal5" "drawing") list( "metalcap" "drawing") "areaCap" ) ) ( metal5Available extractDevice( metalcapCap (metalcap "PLUS") (metal4 "MINUS") "cap ivpcell NCSU_Analog_Parts") saveRecognition( metalcapCap "metalcap" ) areaCap = techGetTwoLayerProp( techfile list( "metal4" "drawing") list( "metalcap" "drawing") "areaCap" ) ) ) when( areaCap capacitance = measureParameter( area metalcapCap 1.0e-18 * areaCap ) saveParameter( capacitance "c" ) ) ) ) ; poly - cwell thinox capacitors if( cwellAvailable then extractDevice( lcCap (poly "PLUS") (lcDiff "MINUS") "cap ivpcell NCSU_Analog_Parts") saveRecognition( lcCap "poly" ) let( ( areaCap capacitance ) areaCap = techGetTwoLayerProp( techfile list( "poly" "drawing") list( "cwell" "drawing") "areaCap" ) when( areaCap capacitance = measureParameter( area lcCap 1.0e-18 * areaCap ) saveParameter( capacitance "c" ) ) ) ) ; poly - elec caps if( elecAvailable then extractDevice( CapacitorElec (elec "PLUS") (poly "MINUS") "cap ivpcell NCSU_Analog_Parts" ) saveRecognition( CapacitorElec "elec" ) let( ( areaCap capacitance ) areaCap = techGetTwoLayerProp( techfile list( "elec" "drawing") list( "poly" "drawing") "areaCap" ) when( areaCap capacitance = measureParameter( area CapacitorElec 1.0e-18*areaCap ) saveParameter( capacitance "c" ) ) ) ) ; The rest of the capacitance extraction (including "intentional" ; plain old metal caps and parasitic caps) is performed in the file ; divaMultiLevel.il via the multiLevelParasitic command. ; ; The regular metal, poly, and other layers are modified below ; according to the Extract_parasitic_caps switch. It is these ; modified layers on which the multiLevelParasitic command operates. ; ; Make scale factor specify values in aF/um^2 for areacaps and aF/um ; for perimcaps. This will make it easier to read values straight ; from MOSIS parametric reports and Magic tech files. ; ; See local/techfile/layerDefintions.tf for the actual value of the ; parasitic capacitances. ; "intentional" caps (i.e. metal with cap_id over it) are always extracted if( metal6Available then metal6_ext = geomAnd( metal6 cap_id ) ) if( metal5Available then metal5_ext = geomAnd( metal5 cap_id ) ) if( metal4Available then metal4_ext = geomAnd( metal4 cap_id ) ) if( metal3Available then metal3_ext = geomAnd( metal3 cap_id ) ) if( elecAvailable then elec_ext = geomAnd( elec cap_id ) ) metal2_ext = geomAnd( metal2 cap_id ) metal1_ext = geomAnd( metal1 cap_id ) poly_ext = geomAnd( poly cap_id ) nDiff_ext = geomAnd( nDiff cap_id ) pDiff_ext = geomAnd( pDiff cap_id ) nOhmic_ext = geomAnd( nOhmic cap_id ) pOhmic_ext = geomAnd( pOhmic cap_id ) nNotOhmic_ext = geomAnd( nNotOhmic cap_id ) pNotOhmic_ext = geomAnd( pNotOhmic cap_id ) nBulk_ext = geomAnd( nBulk cap_id ) pBulk_ext = geomAnd( pBulk cap_id ) useCapIVPcell = t load( "/nfs/ch/proj/hcke/ch_hcke_ckt1/alliance/hancecreek/A0/fge/cadence/NCSU_CDK_1p3_local/techfile/divaMultiLevel.il" ) ; for any time when Extract_parasitic_caps is selected. note that we ; don't want to extract any "intentional" caps as parasitics ivIf( switch("Extract_parasitic_caps") then if( metal6Available then metal6_ext = geomAndNot( metal6 geomOr( nolpe cap_id ) ) ) if( metal5Available then metal5_ext = geomAndNot( metal5 geomOr( nolpe cap_id ) ) ) if( metal4Available then metal4_ext = geomAndNot( metal4 geomOr( nolpe cap_id ) ) ) if( metal3Available then metal3_ext = geomAndNot( metal3 geomOr( nolpe cap_id ) ) ) if( elecAvailable then elec_ext = geomAndNot( elec geomOr( nolpe cap_id ) ) ) metal2_ext = geomAndNot( metal2 geomOr( nolpe cap_id ) ) metal1_ext = geomAndNot( metal1 geomOr( nolpe cap_id ) ) poly_ext = geomAndNot( poly geomOr( nolpe cap_id ) ) nDiff_ext = geomAndNot( nDiff geomOr( nolpe cap_id ) ) pDiff_ext = geomAndNot( pDiff geomOr( nolpe cap_id ) ) nOhmic_ext = geomAndNot( nOhmic geomOr( nolpe cap_id ) ) pOhmic_ext = geomAndNot( pOhmic geomOr( nolpe cap_id ) ) nNotOhmic_ext = geomAndNot( nNotOhmic geomOr( nolpe cap_id ) ) pNotOhmic_ext = geomAndNot( pNotOhmic geomOr( nolpe cap_id ) ) nBulk_ext = geomAndNot( nBulk geomOr( nolpe cap_id ) ) pBulk_ext = geomAndNot( pBulk geomOr( nolpe cap_id ) ) useCapIVPcell = nil load( "/nfs/ch/proj/hcke/ch_hcke_ckt1/alliance/hancecreek/A0/fge/cadence/NCSU_CDK_1p3_local/techfile/divaMultiLevel.il" ) ) ;------------------------------------------------------------------------ ; diodes ;------------------------------------------------------------------------ ; nwell/psub extractDevice( NwPdiode (pBulk "PLUS") (nwell "MINUS") "diode ivpcell NCSU_Analog_Parts" ) ; saveProperty( NwPdiode "model" strcat( modelPrefix NCSU_modelSuffix["nwpdiode"] ) ) saveProperty( NwPdiode "model" "NwP" ) nwpArea = measureParameter( area NwPdiode 1.0e-12 ) nwpPerimeter = measureParameter( perimeter NwPdiode 1.0e-12 ) saveParameter( nwpArea "area" ) saveParameter( nwpPerimeter "pj" ) ; n+/psub extractDevice( NPdiode (pBulk "PLUS") (nDiff "MINUS") "diode ivpcell NCSU_Analog_Parts" ) ; saveProperty( NPdiode "model" strcat( modelPrefix NCSU_modelSuffix["npdiode"] ) ) saveProperty( NPdiode "model" "NP" ) npArea = measureParameter( area NPdiode 1.0e-12 ) npPerimeter = measureParameter( perimeter NPdiode 1.0e-12 ) saveParameter( npArea "area" ) saveParameter( npPerimeter "pj" ) ; p+/nwell extractDevice( PNdiode (pDiff "PLUS") (nBulk "MINUS") "diode ivpcell NCSU_Analog_Parts" ) ; saveProperty( PNdiode "model" strcat( modelPrefix NCSU_modelSuffix["pndiode"] ) ) saveProperty( PNdiode "model" "PN" ) pnArea = measureParameter( area PNdiode 1.0e-12 ) pnPerimeter = measureParameter( perimeter PNdiode 1.0e-12 ) saveParameter( pnArea "area" ) saveParameter( pnPerimeter "pj" ) ;------------------------------------------------------------------------ ; old-style moscap extraction (deprecated) ;------------------------------------------------------------------------ ivIf( switch("Use_old_moscap_extraction") then extractDevice( nChannelCap (poly "G") (nDiff "S") (pBulk "B") "nmoscap ivpcell NCSU_Analog_Parts" ) let( ( capWidth capArea capLength ) capArea = measureParameter( area nChannelCap 1.0e-12 ) capWidth = measureParameter( length (nChannelCap coincident poly) 1.0e-6 ) capLength = calculateParameter( 2 * capArea / capWidth ) saveProperty( nChannelCap "m" 0.5) saveParameter( capWidth "w" ) saveParameter( capLength "l" ) ) extractDevice( pChannelCap (poly "G") (pDiff "S") (nBulk "B") "pmoscap ivpcell NCSU_Analog_Parts" ) let( ( capWidth capArea capLength ) capArea = measureParameter( area pChannelCap 1.0e-12 ) capWidth = measureParameter( length (pChannelCap coincident poly) 1.0e-6 ) capLength = calculateParameter( 2 * capArea / capWidth ) saveProperty( pChannelCap "m" 0.5) saveParameter( capWidth "w" ) saveParameter( capLength "l" ) ) ; if( !cwellAvailable then ; ; saveProperty( nChannelCap "model" "nmos4" ) ; saveProperty( pChannelCap "model" "pmos4" ) ; ) if( elecAvailable then extractDevice( nElecChannelCap (elec "G") (nDiff "S") (pBulk "B") "nmoscap ivpcell NCSU_Analog_Parts" ) let( ( capWidth capLength capArea ) capArea = measureParameter( area nElecChannelCap 1.0e-12 ) capWidth = measureParameter( length (nElecChannelCap coincident poly) 1.0e-6 ) capLength = calculateParameter( 2 * capArea / capWidth ) saveProperty( nElecChannelCap "m" 0.5) saveParameter( capWidth "w" ) saveParameter( capLength "l" ) ) saveProperty( nElecChannelCap "model" strcat( modelPrefix NCSU_modelSuffix["nmos_elec"] ) ) extractDevice( pElecChannelCap (elec "G") (nDiff "S") (nBulk "B") "pmoscap ivpcell NCSU_Analog_Parts" ) let( ( capWidth capLength capArea ) capArea = measureParameter( area pElecChannelCap 1.0e-12 ) capWidth = measureParameter( length (pElecChannelCap coincident poly) 1.0e-6 ) capLength = calculateParameter( 2 * capArea / capWidth ) saveProperty( pElecChannelCap "m" 0.5 ) saveParameter( capWidth "w" ) saveParameter( capLength "l" ) ) saveProperty( pElecChannelCap "model" strcat( modelPrefix NCSU_modelSuffix["pmos_elec"] ) ) ) ) ;------------------------------------------------------------------------ ; saveRecognition and saveInterconnect statements for everything ;------------------------------------------------------------------------ saveRecognition( nChannelTran "poly" ) saveRecognition( pChannelTran "poly" ) if( hvAvailable then saveRecognition( hvnChannelTran "poly" ) saveRecognition( hvpChannelTran "poly" ) ) if( elecAvailable then unless( member( techdesc list( "TSMC_CMOS035_4M2P" "TSMC_CMOS035_3M2P" "AMI_C5N" ) ) saveRecognition( nElecChannelTran "elec" ) saveRecognition( pElecChannelTran "elec" ) ) saveInterconnect( (elec "elec") ) saveInterconnect( (ce "cc") ) ) if( npnAvailable then saveInterconnect( (npnCollectorContact "cc") ) saveInterconnect( (npnCollector "nwell") ) saveInterconnect( (npnEmitterContact "cc") ) saveInterconnect( (npnBaseContact "cc") ) saveInterconnect( (npnBase "pbase") ) ) case( wellType ( "P" saveInterconnect( (pBulk "pwell")) ) ( "E" saveInterconnect( (nBulk "nwell")) saveInterconnect( (pBulk "pwell")) ) ( t saveInterconnect( (nBulk "nwell")) ) ) saveInterconnect( (nOhmic "active") ) saveInterconnect( (pOhmic "active") ) saveInterconnect( (nDiff "active") ) saveInterconnect( (pDiff "active") ) saveInterconnect( (poly "poly") ) saveInterconnect( (metal1 "metal1") ) saveInterconnect( (nOhmicContact "cc") ) saveInterconnect( (pOhmicContact "cc") ) saveInterconnect( (nDiffContact "cc") ) saveInterconnect( (pDiffContact "cc") ) saveInterconnect( (cp "cc") ) saveInterconnect( (metal2 "metal2") ) saveInterconnect( (via "via") ) if( cwellAvailable then saveInterconnect( (lcDiff "active") ) saveInterconnect( (lcContact "cc") ) ) if( metal3Available then saveInterconnect( (metal3 "metal3") ) saveInterconnect( (via2 "via2") ) ) if( metal4Available then saveInterconnect( (metal4 "metal4") ) saveInterconnect( (via3 "via3") ) ) if( metal5Available then saveInterconnect( (metal5 "metal5") ) saveInterconnect( (via4 "via4") ) ) if( metal6Available then saveInterconnect( (metal6 "metal6") ) saveInterconnect( (via5 "via5") ) ) saveInterconnect( (nwellRes "res_id") ) saveInterconnect( (polyRes "res_id") ) if( sblockAvailable then saveInterconnect( (polySRes "res_id") ) ) if( elecAvailable then saveInterconnect( (elecRes "res_id") ) ) if( highresAvailable then saveInterconnect( (elecHighres "res_id") ) ) ;------------------------------------------------------------------------ ; Add some layers to the "excell" view for hierarchical extraction. ; This makes it easier to connect upper level "paint" to the pins ; of a lower-level cell, since more of the lower-level cell shows ; up in the upper-level cell's extracted cellview. ;------------------------------------------------------------------------ saveDerived( metal1 ("metal1" "net") cell_view ) saveDerived( metal2 ("metal2" "net") cell_view ) saveDerived( via ("via" "net") cell_view ) if( metal3Available then saveDerived( metal3 ("metal3" "net") cell_view ) saveDerived( via2 ("via2" "net") cell_view ) ) if( metal4Available then saveDerived( metal4 ("metal4" "net") cell_view ) saveDerived( via3 ("via3" "net") cell_view ) ) if( metal5Available then saveDerived( metal5 ("metal5" "net") cell_view ) saveDerived( via4 ("via4" "net") cell_view ) ) if( metal6Available then saveDerived( metal6 ("metal6" "net") cell_view ) saveDerived( via5 ("via5" "net") cell_view ) ) ;------------------------------------------------------------------------ ; Some routines to convert back and forth between the mask layers ; and convenience layers and to create select layers from the ; convenience layers... ;------------------------------------------------------------------------ ivIf( switch("Layer_create_select_around_field_poly") then let( ( fieldpoly ) fieldpoly = geomSize( "poly" (lambda * 1.0) raw ) saveDerived( geomAnd( nBulk geomAndNot( fieldpoly geomOr( "pselect" "nselect" ) ) ) ("pselect" "drawing") ) saveDerived( geomAnd( pBulk geomAndNot( fieldpoly geomOr( "pselect" "nselect" ) ) ) ("nselect" "drawing") ) ) ) ivIf( switch("Layer_convert_[np]active_to_active") then saveDerived( geomCat("nactive" "pactive") ("active" "drawing") ) geomErase( "nactive" "drawing") geomErase( "pactive" "drawing") ) ivIf( switch("Layer_create_nselect_around_nactive") then let( ( nactive ) nactive = geomSize( "nactive" (lambda * 2.0) raw ) saveDerived( geomCat( geomOutside( nactive "pactive") geomAndNot( geomStraddle( nactive "pactive") "pactive") ) ("nselect" "drawing") ) ) ) ivIf( switch("Layer_create_pselect_around_pactive") then let( ( pactive ) pactive = geomSize( "pactive" (lambda * 2.0) raw ) saveDerived( geomCat( geomOutside( pactive "nactive") geomAndNot( geomStraddle( pactive "nactive") "nactive") ) ("pselect" "drawing") ) ) ) ivIf( switch("Layer_convert_active_to_[np]active") then case( wellType ( "P" saveDerived( geomCat( geomOutside( "active" "pselect") geomAndNot( geomStraddle( "active" "pselect") "pselect") ) ("nactive" "drawing") ) ) ( t saveDerived( geomCat( geomInside( "active" "nselect") geomAnd( geomStraddle( "active" "nselect") "nselect") ) ("nactive" "drawing") ) ) ) case( wellType ( "N" saveDerived( geomCat( geomOutside( "active" "nselect") geomAndNot( geomStraddle( "active" "nselect") "nselect") ) ("pactive" "drawing") ) ) ( t saveDerived( geomCat( geomInside( "active" "pselect") geomAnd( geomStraddle( "active" "pselect") "pselect") ) ("pactive" "drawing") ) ) ) ) ;------------------------------------------------------------------------ ; have (text) labels show up in extracted view ;------------------------------------------------------------------------ ivIf( switch("Keep_labels_in_extracted_view") then copyGraphics( ("text" "drawing") all ) ) ) ; drcExtractRules ) ; let ; vim:ts=4:columns=132:set tw=0: