/******************************************************
* 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:
Text file Source (historic): geocities.com/fudinggecircuit/layout
geocities.com/fudinggecircuit(to report bad content: archivehelp @ gmail)
|
|
|
|
|