/**************************************************
* *
* *
* Diva DRC Rules *
* *
* Modified by Fuding Ge based on NCSU Design Kit *
*******************************************************************/
let( ( lambda gridRes techdesc wellType submicronAvailable deepAvailable
cwellAvailable metal3Available metal4Available metal5Available metal6Available
metalcapAvailable hvAvailable npnAvailable ccdAvailable elecAvailable sblockAvailable
stackedViasAvailable highresAvailable PadType techfile modelPrefix errMesg )
;load( "/nfs/hrap_ckt3/atlasHarp/design/fge/NCSU_CDK_1p3_local/techfile/divaTechdesc.il" ) )
techdesc="AMI_ABN"
lambda = 0.8 ;added by Fuding
gridRes=0.4
wellType =t ;added by Fuding need to verify
submicronAvailable=nil
deepAvailable=nil
cwellAvailable=nil
metal3Available=nil
metal4Available=nil
metal5Available=nil
metal6Available=nil
metalcapAvailable=nil
hvAvailable=nil
npnAvailable=t
ccdAvailable=nil
elecAvailable=t
sblockAvailable=nil
stackedViasAvailable=nil
highresAvailable=nil
PadType=t
techfile="ami_16.tf"
modelPrefix="ami16"
errMesg
drcExtractRules(
; First load the Derived Layer Definition
/***********************************************************
* *
* *
* Diva Derived Layer Definitions *
* *
* * *******************************************************/
/*
* Note that some of these variables are set here and some are set
* above. The ones below are set here because any variable with the
* value nil becomes unbound when you enter the drcExtractRules()
* function. Some have to be set above because functions like
* error() can't be called inside drcExtractRules(). Weird.
*/
/*** ---Fuding
wellType = substring( NCSU_techData[ techdesc ]->mosisCode 3 1 )
submicronAvailable = NCSU_techData[ techdesc ]->submicronRules
deepAvailable = NCSU_techData[ techdesc ]->deepRules
stackedViasAvailable = NCSU_techData[ techdesc ]->stackedVias
lambda = atof( NCSU_techData[ techdesc ]->lambda )
gridRes = NCSU_techData[ techdesc ]->gridRes
modelPrefix = NCSU_techData[ techdesc ]->fetModelPrefix
***********/
/*
* we can't use getTechParam here, so do it another way.
* i know, this is a major kludge...
*/
techfile = techGetTechFile( geGetEditCellView() )
cwellAvailable = techGetLayerNum( techfile "cwell" )
polycapAvailable = techGetLayerNum( techfile "polycap" )
npnAvailable = techGetLayerNum( techfile "pbase" )
ccdAvailable = techGetLayerNum( techfile "ccd" )
metal3Available = techGetLayerNum( techfile "metal3" )
metal4Available = techGetLayerNum( techfile "metal4" )
metal5Available = techGetLayerNum( techfile "metal5" )
metal6Available = techGetLayerNum( techfile "metal6" )
metalcapAvailable = techGetLayerNum( techfile "metalcap" )
hvAvailable = techGetLayerNum( techfile "tactive" )
elecAvailable = techGetLayerNum( techfile "elec" )
memsAvailable = techGetLayerNum( techfile "pstop" )
sblockAvailable = techGetLayerNum( techfile "sblock" )
highresAvailable = techGetLayerNum( techfile "highres" )
/***************************
***************************
DERIVED LAYER DEFINITIONS
***************************
***************************/
ivIf( switch("drc?") then
nodrc = geomOr( "nodrc" )
)
ivIf( switch("extract?") then
nodrc = geomAndNot( "nodrc" "nodrc" )
)
bkgnd = geomBkgnd()
gwell = geomOr( geomAndNot( ( "gwell" "drawing" ) nodrc ) )
nwell = geomOr( geomAndNot( ( "nwell" "drawing" ) nodrc ) )
pwell = geomOr( geomAndNot( ( "pwell" "drawing" ) nodrc ) )
nactive = geomOr( geomAndNot( ( "nactive" "drawing" ) nodrc ) )
pactive = geomOr( geomAndNot( ( "pactive" "drawing" ) nodrc ) )
active = geomOr( geomAndNot( ( "active" "drawing" ) nodrc ) nactive pactive )
gselect = geomOr( geomAndNot( ( "gselect" "drawing" ) nodrc ) )
nselect = geomOr( geomAndNot( ( "nselect" "drawing" ) nodrc ) )
pselect = geomOr( geomAndNot( ( "pselect" "drawing" ) nodrc ) )
poly = geomOr( geomAndNot( ( "poly" "drawing" ) nodrc ) )
metal1 = geomOr( geomAndNot( ( "metal1" "drawing" ) nodrc ) )
cc = geomOr( geomAndNot( ( "cc" "drawing" ) nodrc ) )
metal2 = geomOr( geomAndNot( ( "metal2" "drawing" ) nodrc ) )
via = geomOr( geomAndNot( ( "via" "drawing" ) nodrc ) )
glass = geomOr( geomAndNot( ( "glass" "drawing" ) nodrc ) )
pad = geomOr( geomAndNot( ( "pad" "drawing" ) nodrc ) )
nolpe = geomOr( "nolpe" )
cap_id = geomOr( "cap_id" )
res_id = geomOr( "res_id" )
dio_id = geomOr( "dio_id" )
if( metal3Available then
metal3 = geomOr( geomAndNot( ( "metal3" "drawing" ) nodrc ) )
via2 = geomOr( geomAndNot( ( "via2" "drawing" ) nodrc ) )
)
if( metal4Available then
metal4 = geomOr( geomAndNot( ( "metal4" "drawing" ) nodrc ) )
via3 = geomOr( geomAndNot( ( "via3" "drawing" ) nodrc ) )
)
if( metal5Available then
metal5 = geomOr( geomAndNot( ( "metal5" "drawing" ) nodrc ) )
via4 = geomOr( geomAndNot( ( "via4" "drawing" ) nodrc ) )
)
if( metal6Available then
metal6 = geomOr( geomAndNot( ( "metal6" "drawing" ) nodrc ) )
via5 = geomOr( geomAndNot( ( "via5" "drawing" ) nodrc ) )
)
if( metalcapAvailable then
metalcap = geomOr( geomAndNot( ( "metalcap" "drawing" ) nodrc ) )
)
if( ccdAvailable then
ccd = geomOr( geomAndNot( ( "ccd" "drawing" ) nodrc ) )
)
if( cwellAvailable then
cwell = geomOr( geomAndNot( ( "cwell" "drawing" ) nodrc ) )
)
if( polycapAvailable then
polycap = geomOr( geomAndNot( ( "polycap" "drawing" ) nodrc ) )
cpolycap = geomAnd( polycap geomOr( cc cp ) )
)
if( sblockAvailable then
sblock = geomOr( geomAndNot( ( "sblock" "drawing" ) nodrc ) )
)
if( highresAvailable then
highres = geomOr( geomAndNot( ( "highres" "drawing" ) nodrc ) )
)
if( memsAvailable then
pstop = geomOr( geomAndNot( ( "pstop" "drawing" ) nodrc ) )
open = geomOr( geomAndNot( ( "open" "drawing" ) nodrc ) )
)
/*
* deriving specific contacts (ie, ce, cp, ca) from generic contact (cc) is a pain.
* make sure you account for multiple overlaps, eg, in case of poly-elec cap, suppose you use
* cc for the elec contact. this needs to be extracted as "ce" only, not "cp".
*
* the order of the rules below is important - ie, it goes top-down (elec -> poly -> active).
*/
if( elecAvailable then
elec = geomOr( geomAndNot( ( "elec" "drawing" ) nodrc ) )
ce = geomOr( geomOr( geomAndNot( ( "ce" "drawing" ) nodrc ) ) geomAnd( cc elec ) )
cp = geomOr( geomOr( geomAndNot( ( "cp" "drawing" ) nodrc ) ) geomAnd( cc geomAndNot( poly ce ) ) )
ca = geomOr( geomOr( geomAndNot( ( "ca" "drawing" ) nodrc ) ) geomAnd( cc geomAndNot( active geomOr( ce cp ) ) ) )
else
cp = geomOr( geomOr( geomAndNot( ( "cp" "drawing" ) nodrc ) ) geomAnd( cc poly ) )
ca = geomOr( geomOr( geomAndNot( ( "ca" "drawing" ) nodrc ) ) geomAnd( cc geomAndNot( active cp ) ) )
)
if( npnAvailable then
pbase = geomOr( geomAndNot( ( "pbase" "drawing" ) nodrc ) )
cactive = geomOr( geomAndNot( ( "cactive" "drawing" ) nodrc ) )
ca = geomOr( ca geomAnd( cc cactive ) )
)
nActive = geomAnd( active nselect )
pActive = geomAnd( active pselect )
if( ccdAvailable then
nActive = geomAndNot( nActive ccd )
pActive = geomAndNot( pActive ccd )
)
if( cwellAvailable then
nActive = geomAndNot( nActive cwell )
pActive = geomAndNot( pActive cwell )
)
if( hvAvailable then
tactive = geomOr( geomAndNot( ( "tactive" "drawing" ) nodrc ) )
)
/*
* This next section basically sets how the well enclosure of
* source/drain active, substrate/well contact and capacitor
* electrode are interpreted. In a pwell process, everything that
* doesn't have the "pwell" layer drawn on it is assumed to be
* N-type bulk. Similarly, in an nwell process, everything that
* doesn't have the "nwell" layer drawn on it is assumed to be
* P-type bulk. If it's an "either-well" process, only the areas
* with drawn "pwell" and "nwell" are assumed to be P-type bulk or
* N-type bulk, respectively.
*
* Since MOSIS only has N-type processes for now, this is assumed to
* be the default.
*/
case( wellType
( "P"
nBulk = geomOr( geomNot( pwell ) geomAndNot( nwell pwell ) )
pBulk = geomOr( pwell )
nOhmic = geomAndNot( nActive pwell )
pOhmic = geomAnd( pActive pwell )
nNotOhmic = geomAnd( nActive pwell )
pNotOhmic = geomAndNot( pActive pwell)
)
( "E"
nBulk = geomOr( nwell )
pBulk = geomOr( pwell )
nOhmic = geomAnd( nActive nwell )
pOhmic = geomAnd( pActive pwell )
nNotOhmic = geomAnd( nActive pwell )
pNotOhmic = geomAnd( pActive nwell)
)
( t
if( npnAvailable then
nBulk = geomOutside( nwell cactive )
else
nBulk = geomOr( nwell )
)
pBulk = geomOr( geomNot( nwell ) geomAndNot( pwell nwell ) )
nOhmic = geomAnd( nActive nwell )
pOhmic = geomAndNot( pActive nwell )
nNotOhmic = geomAndNot( nActive nwell )
pNotOhmic = geomAnd( pActive nwell)
)
)
if( elecAvailable then
nDiff = geomAndNot( nNotOhmic geomOr( poly elec ) )
pDiff = geomAndNot( pNotOhmic geomOr( poly elec ) )
nChannel = geomOutside( geomAnd( nNotOhmic poly ) elec )
pChannel = geomOutside( geomAnd( pNotOhmic poly ) elec )
nElecChannel = geomOutside( geomAnd( nNotOhmic elec ) poly )
pElecChannel = geomOutside( geomAnd( pNotOhmic elec ) poly )
nElecChannelTran = geomButting( nElecChannel nDiff keep == 2 )
pElecChannelTran = geomButting( pElecChannel pDiff keep == 2 )
nElecChannelCap = geomButting( nElecChannel nDiff keep == 1 )
pElecChannelCap = geomButting( pElecChannel pDiff keep == 1 )
Space = geomNot( geomOr( active poly elec ) )
else
nDiff = geomAndNot( nNotOhmic poly )
pDiff = geomAndNot( pNotOhmic poly )
nChannel = geomAnd( nNotOhmic poly )
pChannel = geomAnd( pNotOhmic poly )
Space = geomNot( geomOr( active poly ) )
)
nChannelTran = geomButting( nChannel nDiff keep == 2 )
pChannelTran = geomButting( pChannel pDiff keep == 2 )
nChannelCap = geomButting( nChannel nDiff keep == 1 )
pChannelCap = geomButting( pChannel pDiff keep == 1 )
if( hvAvailable then
hvnChannelTran = geomAnd( nChannelTran tactive )
nChannelTran = geomAndNot( nChannelTran hvnChannelTran )
hvpChannelTran = geomAnd( pChannelTran tactive )
pChannelTran = geomAndNot( pChannelTran hvpChannelTran )
)
nDiffContact = geomAnd( ca nDiff )
pDiffContact = geomAnd( ca pDiff )
nOhmicContact = geomAnd( ca nOhmic )
pOhmicContact = geomAnd( ca pOhmic )
Gate = geomAnd( geomOr( nNotOhmic pNotOhmic) poly )
fieldPoly = geomAvoiding( poly Gate )
m1pCap = geomAnd( geomAnd( poly metal1 ) cap_id )
m1sCap = geomAnd( geomAndNot( metal1 poly ) cap_id )
m2m1Cap = geomAnd( geomAnd( metal1 metal2 ) cap_id )
if( metal3Available then
m3m2Cap = geomAnd( geomAnd( metal2 metal3 ) cap_id )
)
if( metal4Available then
m4m3Cap = geomAnd( geomAnd( metal3 metal4 ) cap_id )
)
if( metal5Available then
m5m4Cap = geomAnd( geomAnd( metal4 metal5 ) cap_id )
)
if( metal6Available then
m6m5Cap = geomAnd( geomAnd( metal5 metal6 ) cap_id )
)
if( metalcapAvailable then
/*
* metalcap is between top-layer metal and next-to-top layer metal. for
* drc, we need the whole metal shape of the bottom plate, not just the
* metal-metalcap overlap.
*/
cond(
( metal6Available
metalcapBottom = geomStraddle( metal5 metalcap )
metalcapCap = geomAnd( metalcap metal5 )
via5metalcap = geomAnd( via5 metalcapBottom )
via5 = geomAndNot( via5 via5metalcap )
)
( metal5Available
metalcapBottom = geomStraddle( metal4 metalcap )
metalcapCap = geomAnd( metalcap metal4 )
via4metalcap = geomAnd( via4 metalcapBottom )
via4 = geomAndNot( via4 via4metalcap )
)
)
)
NPdiode = geomAnd( dio_id geomOutside( nNotOhmic poly ) )
PNdiode = geomAnd( dio_id geomOutside( pNotOhmic poly ) )
unless( wellType == "P" || wellType == "E"
NwPdiode = geomAnd( dio_id geomOutside( nwell pNotOhmic ) )
)
if( elecAvailable then
elecGate = geomAnd( geomOr( nNotOhmic pNotOhmic) elec )
fieldElec = geomAvoiding( elec elecGate )
CapacitorElec = geomInside( elec poly )
TransistorElec = geomOverlap( elec geomNot( poly ) )
)
if( polycapAvailable then
polycapCap = geomAnd( poly polycap )
)
if( sblockAvailable then
sGateWidthCheck = geomSize( geomSize( geomAnd( Gate sblock ) -2.9 ) 2.9 )
)
if( npnAvailable then
npnCollector = geomAnd( nwell geomAnd( nselect cactive ) )
npnCollectorContact = geomAnd( ca npnCollector )
npnBaseImplant = geomAnd( nwell pbase )
npnEmitter = geomAnd( nselect npnBaseImplant )
npnBase = geomAndNot( npnBaseImplant npnEmitter )
npnBaseTap = geomAnd( npnBase pselect )
npnBaseContact = geomAnd( geomOr( cc ca ) npnBaseTap )
npnEmitterContact = geomAnd( geomOr( cc ca ) npnEmitter )
npnTran = geomEnclose( nwell geomOr( npnCollector npnBase npnEmitter ) )
)
if( ccdAvailable then
ccdDiff = geomAnd( active ccd )
ccdContact = geomAnd( ca ccdDiff )
)
if( cwellAvailable then
; since the extractDevice for cwell caps uses "lcDiff" as negative
; terminal, and all caps in a single cwell need to have a common neg.
; term (the cwell itself) use the cwell as the lcDiff layer. the lcCap
; ANDs it with active & poly to get shape for calculating capacitance.
lcDiff = geomStraddle( cwell active )
lcContact = geomAnd( ca lcDiff )
lcCap = geomAnd( poly geomAnd( lcDiff active ) )
)
; recognize resistors: res_id/(poly|elec), sblock/poly, highres/elec, nwell/res_id
; res_id/poly, sblock/poly
if( sblockAvailable then
fieldPoly = geomAndNot( fieldPoly geomOr( sblock res_id ) )
polySRes = geomButting( geomAnd( sblock poly ) fieldPoly keep == 2 )
polyRes = geomButting( geomAndNot( geomAnd( res_id poly ) polySRes ) fieldPoly keep == 2 )
poly = geomAndNot( poly geomOr( sblock res_id ) )
else
fieldPoly = geomAndNot( fieldPoly res_id )
polyRes = geomButting( geomAnd( res_id poly ) fieldPoly keep == 2 )
poly = geomAndNot( poly res_id )
)
; res_id/elec
if( elecAvailable then
; currently can only do highres over elec (poly2)
if( highresAvailable then
fieldElec = geomAndNot( fieldElec geomOr( res_id highres ) )
elecRes = geomButting( geomAnd( res_id elec ) fieldElec keep == 2 )
elecHighres = geomButting( geomAnd( highres elec ) fieldElec keep == 2 )
elec = geomAndNot( elec geomOr( res_id highres ) )
else
fieldElec = geomAndNot( fieldElec res_id )
elecRes = geomButting( geomAnd( res_id elec ) fieldElec keep == 2 )
elec = geomAndNot( elec res_id )
)
)
; res_id/nwell
nBulk = geomAndNot( nBulk res_id )
nwellRes = geomButting( geomAnd( res_id nwell ) nBulk keep == 2 )
nwell = geomAndNot( nwell res_id ) ; w/o this, whole well is connected
cond(
( metal6Available
if( metalcapAvailable then
geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
via( pOhmicContact pOhmic pwell pBulk metal1 )
via( nDiffContact nDiff metal1 )
via( pDiffContact pDiff metal1 )
via( cp poly metal1 )
via( via metal1 metal2 )
via( via2 metal2 metal3 )
via( via3 metal3 metal4 )
via( via4 metal4 metal5 )
via( via5 metal5 metal6 )
via( via5metalcap metalcap metal6 )
label( "text" metal6 metalcap metal5 metal4 metal3 metal2 metal1 poly pDiff nDiff )
)
else
geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
via( pOhmicContact pOhmic pwell pBulk metal1 )
via( nDiffContact nDiff metal1 )
via( pDiffContact pDiff metal1 )
via( cp poly metal1 )
via( via metal1 metal2 )
via( via2 metal2 metal3 )
via( via3 metal3 metal4 )
via( via4 metal4 metal5 )
via( via5 metal5 metal6 )
label( "text" metal6 metal5 metal4 metal3 metal2 metal1 poly pDiff nDiff )
)
)
)
( metal5Available
if( metalcapAvailable then
geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
via( pOhmicContact pOhmic pwell pBulk metal1 )
via( nDiffContact nDiff metal1 )
via( pDiffContact pDiff metal1 )
via( cp poly metal1 )
via( via metal1 metal2 )
via( via2 metal2 metal3 )
via( via3 metal3 metal4 )
via( via4 metal4 metal5 )
via( via4metalcap metalcap metal5 )
label( "text" metal5 metalcap metal4 metal3 metal2 metal1 poly pDiff nDiff )
)
else
geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
via( pOhmicContact pOhmic pwell pBulk metal1 )
via( nDiffContact nDiff metal1 )
via( pDiffContact pDiff metal1 )
via( cp poly metal1 )
via( via metal1 metal2 )
via( via2 metal2 metal3 )
via( via3 metal3 metal4 )
via( via4 metal4 metal5 )
label( "text" metal5 metal4 metal3 metal2 metal1 poly pDiff nDiff )
)
)
)
( metal4Available
if( elecAvailable then
geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
via( pOhmicContact pOhmic pwell pBulk metal1 )
via( nDiffContact nDiff metal1 )
via( pDiffContact pDiff metal1 )
via( cp poly metal1 )
via( ce elec metal1 )
via( via metal1 metal2 )
via( via2 metal2 metal3 )
via( via3 metal3 metal4 )
label( "text" metal4 metal3 metal2 metal1 elec poly pDiff nDiff )
)
else
geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
via( pOhmicContact pOhmic pwell pBulk metal1 )
via( nDiffContact nDiff metal1 )
via( pDiffContact pDiff metal1 )
via( cp poly metal1 )
via( via metal1 metal2 )
via( via2 metal2 metal3 )
via( via3 metal3 metal4 )
label( "text" metal4 metal3 metal2 metal1 poly pDiff nDiff )
)
)
)
( metal3Available && cwellAvailable
geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
via( pOhmicContact pOhmic pwell pBulk metal1 )
via( nDiffContact nDiff metal1 )
via( pDiffContact pDiff metal1 )
via( lcContact lcDiff metal1 )
via( cp poly metal1 )
via( via metal1 metal2 )
via( via2 metal2 metal3 )
label( "text" metal3 metal2 metal1 poly lcDiff pDiff nDiff )
)
)
( metal3Available && elecAvailable
geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
via( pOhmicContact pOhmic pwell pBulk metal1 )
via( nDiffContact nDiff metal1 )
via( pDiffContact pDiff metal1 )
via( cp poly metal1 )
via( ce elec metal1 )
via( via metal1 metal2 )
via( via2 metal2 metal3 )
label( "text" metal3 metal2 metal1 elec poly pDiff nDiff )
)
)
( metal3Available
geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
via( pOhmicContact pOhmic pwell pBulk metal1 )
via( nDiffContact nDiff metal1 )
via( pDiffContact pDiff metal1 )
via( cp poly metal1 )
via( via metal1 metal2 )
via( via2 metal2 metal3 )
label( "text" metal3 metal2 metal1 poly pDiff nDiff )
)
)
( npnAvailable && ccdAvailable && elecAvailable
geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
via( pOhmicContact pOhmic pwell pBulk metal1 )
via( nDiffContact nDiff metal1 )
via( pDiffContact pDiff metal1 )
via( ccdContact ccdDiff metal1 )
via( npnEmitterContact npnEmitter metal1 )
via( npnBaseContact npnBaseTap npnBase metal1 )
via( npnCollectorContact npnCollector metal1 )
via( cp poly metal1 )
via( ce elec metal1 )
via( via metal1 metal2 )
label( "text" metal2 metal1 elec poly pDiff nDiff ccdDiff npnCollector npnEmitter npnBase )
)
)
( npnAvailable && elecAvailable
geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
via( pOhmicContact pOhmic pwell pBulk metal1 )
via( nDiffContact nDiff metal1 )
via( pDiffContact pDiff metal1 )
via( npnEmitterContact npnEmitter metal1 )
via( npnBaseContact npnBaseTap npnBase metal1 )
via( npnCollectorContact npnCollector metal1 )
via( cp poly metal1 )
via( ce elec metal1 )
via( via metal1 metal2 )
label( "text" metal2 metal1 elec poly pDiff nDiff npnCollector npnEmitter npnBase )
)
)
( polycapAvailable
geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
via( pOhmicContact pOhmic pwell pBulk metal1 )
via( nDiffContact nDiff metal1 )
via( pDiffContact pDiff metal1 )
via( cp poly metal1 )
via( cpolycap polycap metal1 )
via( via metal1 metal2 )
label( "text" metal2 metal1 poly polycap pDiff nDiff )
)
)
( t
geomConnect( via( nOhmicContact nOhmic nwell nBulk metal1 )
via( pOhmicContact pOhmic pwell pBulk metal1 )
via( nDiffContact nDiff metal1 )
via( pDiffContact pDiff metal1 )
via( cp poly metal1 )
via( via metal1 metal2 )
label( "text" metal2 metal1 poly pDiff nDiff )
)
)
)
ivIf( switch("drc?") then
ivIf( ( !switch("hier?") || switch("currentCell?") ) then
dubiousData( ( "gwell" "drawing" ) "Improperly formed shape - gwell" )
dubiousData( ( "nwell" "drawing" ) "Improperly formed shape - nwell" )
dubiousData( ( "pwell" "drawing" ) "Improperly formed shape - pwell" )
dubiousData( ( "active" "drawing" ) "Improperly formed shape - active, nactive or pactive" )
dubiousData( ( "gselect" "drawing" ) "Improperly formed shape - gselect" )
dubiousData( ( "nselect" "drawing" ) "Improperly formed shape - nselect" )
dubiousData( ( "pselect" "drawing" ) "Improperly formed shape - pselect" )
dubiousData( ( "poly" "drawing" ) "Improperly formed shape - poly" )
dubiousData( ( "metal1" "drawing" ) "Improperly formed shape - metal1" )
dubiousData( ( "ca" "drawing" ) "Improperly formed shape - ca" )
dubiousData( ( "cp" "drawing" ) "Improperly formed shape - cp" )
dubiousData( ( "metal2" "drawing" ) "Improperly formed shape - metal2" )
dubiousData( ( "via" "drawing" ) "Improperly formed shape - via" )
dubiousData( ( "glass" "drawing" ) "Improperly formed shape - glass" )
saveDerived( geomGetNon45( gwell ) "Non-Manhattan shape - gwell" )
saveDerived( geomGetNon45( nwell ) "Non-Manhattan shape - nwell" )
saveDerived( geomGetNon45( pwell ) "Non-Manhattan shape - pwell" )
saveDerived( geomGetNon45( active ) "Non-Manhattan shape - active, nactive or pactive" )
saveDerived( geomGetNon45( gselect ) "Non-Manhattan shape - gselect" )
saveDerived( geomGetNon45( nselect ) "Non-Manhattan shape - nselect" )
saveDerived( geomGetNon45( pselect ) "Non-Manhattan shape - pselect" )
saveDerived( geomGetNon45( poly ) "Non-Manhattan shape - poly" )
saveDerived( geomGetNon45( metal1 ) "Non-Manhattan shape - metal1" )
saveDerived( geomGetNon45( ca ) "Non-Manhattan shape - ca" )
saveDerived( geomGetNon45( cp ) "Non-Manhattan shape - cp" )
saveDerived( geomGetNon45( metal2 ) "Non-Manhattan shape - metal2" )
saveDerived( geomGetNon45( via ) "Non-Manhattan shape - via" )
/**********
; allow round glass cuts for solder bumps
unless( padType == "Area array"
saveDerived( geomGetNon45( glass ) "Non-Manhattan shape - glass" )
)
*********/
saveDerived( geomGetNon45( glass ) "Non-Manhattan shape - glass" ) ;Added by Fuding
;saveDerived( geomGetAngledEdge( active angle == 45 ) )
/***************** delete this offgrid check
offGrid( gwell gridRes "(SCMOS Inst) Edge not on grid" )
offGrid( nwell gridRes "(SCMOS Inst) Edge not on grid" )
offGrid( pwell gridRes "(SCMOS Inst) Edge not on grid" )
offGrid( active gridRes "(SCMOS Inst) Edge not on grid" )
offGrid( gselect gridRes "(SCMOS Inst) Edge not on grid" )
offGrid( nselect gridRes "(SCMOS Inst) Edge not on grid" )
offGrid( pselect gridRes "(SCMOS Inst) Edge not on grid" )
offGrid( poly gridRes "(SCMOS Inst) Edge not on grid" )
offGrid( metal1 gridRes "(SCMOS Inst) Edge not on grid" )
offGrid( ca gridRes "(SCMOS Inst) Edge not on grid" )
offGrid( cp gridRes "(SCMOS Inst) Edge not on grid" )
offGrid( metal2 gridRes "(SCMOS Inst) Edge not on grid" )
offGrid( via gridRes "(SCMOS Inst) Edge not on grid" )
unless( padType== "Area array"
(offGrid glass gridRes "(SCMOS Inst) Edge not on grid" )
)
*********************/
if( npnAvailable then
dubiousData( ( "pbase" "drawing" ) "Improperly formed shape - pbase" )
saveDerived( geomGetNon45( pbase ) "Non-Manhattan shape - pbase" )
; offGrid( pbase gridRes "(SCMOS Inst) Edge not on grid" )
dubiousData( ( "cactive" "drawing" ) "Improperly formed shape - cactive" )
saveDerived( geomGetNon45( cactive ) "Non-Manhattan shape - cactive" )
;offGrid( cactive gridRes "(SCMOS Inst) Edge not on grid" )
)
if( ccdAvailable then
dubiousData( ( "ccd" "drawing" ) "Improperly formed shape - ccd" )
saveDerived( geomGetNon45( ccd ) "Non-Manhattan shape - ccd" )
;offGrid( ccd gridRes "(SCMOS Inst) Edge not on grid" )
)
/******************
if( metal3Available then
dubiousData( ( "metal3" "drawing" ) "Improperly formed shape - metal3" )
dubiousData( ( "via2" "drawing" ) "Improperly formed shape - via2" )
saveDerived( geomGetNon45( metal3 ) "Non-Manhattan shape - metal3" )
saveDerived( geomGetNon45( via2 ) "Non-Manhattan shape - via2" )
;offGrid( metal3 gridRes "(SCMOS Inst) Edge not on grid" )
;offGrid( via2 gridRes "(SCMOS Inst) Edge not on grid" )
)
if( metal4Available then
dubiousData( ( "metal4" "drawing" ) "Improperly formed shape - metal4" )
dubiousData( ( "via3" "drawing" ) "Improperly formed shape - via3" )
saveDerived( geomGetNon45( metal4 ) "Non-Manhattan shape - metal4" )
saveDerived( geomGetNon45( via3 ) "Non-Manhattan shape - via3" )
;offGrid( metal4 gridRes "(SCMOS Inst) Edge not on grid" )
;offGrid( via3 gridRes "(SCMOS Inst) Edge not on grid" )
)
if( metal5Available then
dubiousData( ( "metal5" "drawing" ) "Improperly formed shape - metal5" )
dubiousData( ( "via4" "drawing" ) "Improperly formed shape - via4" )
saveDerived( geomGetNon45( metal5 ) "Non-Manhattan shape - metal5" )
saveDerived( geomGetNon45( via4 ) "Non-Manhattan shape - via4" )
offGrid( metal5 gridRes "(SCMOS Inst) Edge not on grid" )
offGrid( via4 gridRes "(SCMOS Inst) Edge not on grid" )
)
if( metal6Available then
dubiousData( ( "metal6" "drawing" ) "Improperly formed shape - metal6" )
dubiousData( ( "via5" "drawing" ) "Improperly formed shape - via5" )
saveDerived( geomGetNon45( metal6 ) "Non-Manhattan shape - metal6" )
saveDerived( geomGetNon45( via5 ) "Non-Manhattan shape - via5" )
offGrid( metal6 gridRes "(SCMOS Inst) Edge not on grid" )
offGrid( via5 gridRes "(SCMOS Inst) Edge not on grid" )
)
if( metalcapAvailable then
dubiousData( ( "metalcap" "drawing" ) "Improperly formed shape - metalcap" )
saveDerived( geomGetNon45( metalcap ) "Non-Manhattan shape - metalcap" )
offGrid( metalcap gridRes "(SCMOS Inst) Edge not on grid" )
)
****************/
if( elecAvailable then
dubiousData( ( "elec" "drawing" ) "Improperly formed shape - elec" )
dubiousData( ( "ce" "drawing" ) "Improperly formed shape - ce" )
saveDerived( geomGetNon45( elec ) "Non-Manhattan shape - elec" )
saveDerived( geomGetNon45( ce ) "Non-Manhattan shape - ce" )
;offGrid( elec gridRes "(SCMOS Inst) Edge not on grid" )
;offGrid( ce gridRes "(SCMOS Inst) Edge not on grid" )
)
)
gwellEdge = geomGetEdge( gwell )
nwellEdge = geomGetEdge( nwell )
pwellEdge = geomGetEdge( pwell )
activeEdge = geomGetEdge( active )
gselectEdge = geomGetEdge( gselect )
nselectEdge = geomGetEdge( nselect )
pselectEdge = geomGetEdge( pselect )
polyEdge = geomGetEdge( poly )
metal1Edge = geomGetEdge( metal1 )
ccEdge = geomGetEdge( cc )
caEdge = geomGetEdge( ca )
cpEdge = geomGetEdge( cp )
metal2Edge = geomGetEdge( metal2 )
viaEdge = geomGetEdge( via )
glassEdge = geomGetEdge( glass )
padEdge = geomGetEdge( pad )
if( cwellAvailable then
cwellEdge = geomGetEdge( cwell )
)
if( npnAvailable then
pbaseEdge = geomGetEdge( pbase )
cactiveEdge = geomGetEdge( cactive )
)
if( ccdAvailable then
ccdEdge = geomGetEdge( ccd )
)
if( polycapAvailable then
polycapEdge = geomGetEdge( polycap )
cpolycapEdge = geomGetEdge( cpolycap )
)
if( sblockAvailable then
sblockEdge = geomGetEdge( sblock )
)
if( highresAvailable then
highresEdge = geomGetEdge( highres )
)
if( memsAvailable then
pstopEdge = geomGetEdge( pstop )
openEdge = geomGetEdge( open )
)
if( elecAvailable then
ceEdge = geomGetEdge( ce )
elecEdge = geomGetEdge( elec )
)
if( metal3Available then
metal3Edge = geomGetEdge( metal3 )
via2Edge = geomGetEdge( via2 )
)
if( metal4Available then
metal4Edge = geomGetEdge( metal4 )
via3Edge = geomGetEdge( via3 )
)
if( metal5Available then
metal5Edge = geomGetEdge( metal5 )
via4Edge = geomGetEdge( via4 )
)
if( metal6Available then
metal6Edge = geomGetEdge( metal6 )
via5Edge = geomGetEdge( via5 )
)
if( metalcapAvailable then
metalcapEdge = geomGetEdge( metalcap )
metalcapBottomEdge = geomGetEdge( metalcapBottom )
metalcapCapEdge = geomGetEdge( metalcapCap )
cond(
( metal6Available
via5metalcapEdge = geomGetEdge( via5metalcap )
)
( metal5Available
via4metalcapEdge = geomGetEdge( via4metalcap )
)
)
)
if( hvAvailable then
tactiveEdge = geomGetEdge( tactive )
)
nBulkEdge = geomGetEdge( nBulk )
pBulkEdge = geomGetEdge( pBulk )
nOhmicEdge = geomGetEdge( nOhmic )
pOhmicEdge = geomGetEdge( pOhmic )
nNotOhmicEdge = geomGetEdge( nNotOhmic )
pNotOhmicEdge = geomGetEdge( pNotOhmic )
GateEdge = geomGetEdge( Gate )
fieldPolyEdge = geomGetEdge( fieldPoly )
if( elecAvailable then
CapacitorElecEdge = geomGetEdge( CapacitorElec )
TransistorElecEdge = geomGetEdge( TransistorElec )
)
if( npnAvailable then
npnCollectorEdge = geomGetEdge( npnCollector )
npnCollectorContactEdge = geomGetEdge( npnCollectorContact )
npnBaseImplantEdge = geomGetEdge( npnBaseImplant )
npnEmitterEdge = geomGetEdge( npnEmitter )
npnBaseEdge = geomGetEdge( npnBase )
npnBaseTapEdge = geomGetEdge( npnBaseTap )
npnBaseContactEdge = geomGetEdge( npnBaseContact )
npnEmitterContactEdge = geomGetEdge( npnEmitterContact )
)
if( ccdAvailable then
ccdDiffEdge = geomGetEdge( ccdDiff )
ccdContactEdge = geomGetEdge( ccdContact )
)
if( cwellAvailable then
lcDiffEdge = geomGetEdge( lcDiff )
lcCapEdge = geomGetEdge( lcCap )
)
if( polycapAvailable then
polycapCapEdge = geomGetEdge( polycapCap )
)
if( sblockAvailable then
sGateWidthCheckEdge = geomGetEdge( sGateWidthCheck )
)
if( sblockAvailable then
polySResEdge = geomGetEdge( polySRes )
)
polyResEdge = geomGetEdge( polyRes coincident poly )
nwellResEdge = geomGetEdge( nwellRes coincident nwell )
if( elecAvailable && highresAvailable then
elecHighresEdge = geomGetEdge( elecRes coincident elec )
)
) ; close ivIf( switch( "?drc" ) )
; vim:ts=4:columns=132:set tw=0:
/***************************
***************************
SCMOS DRC RULES
***************************
***************************/
techdesc="AMI_ABN"
lambda = 0.8 ;added by Fuding
gridRes=0.4
wellType =t ;added by Fuding need to verify
submicronAvailable=nil
deepAvailable=nil
cwellAvailable=nil
metal3Available=nil
metal4Available=nil
metal5Available=nil
metal6Available=nil
metalcapAvailable=nil
hvAvailable=nil
npnAvailable=t
ccdAvailable=nil
elecAvailable=t
sblockAvailable=nil
stackedViasAvailable=nil
highresAvailable=nil
PadType=t
techfile="ami_16.tf"
modelPrefix="ami16"
errMesg
ivIf( ( !switch( "hier?" ) || !switch( "topCell?" ) ) then
/* DBM rules - not listed in the official SCMOS rules but should be followed anyway... */
if( wellType == "E" then
saveDerived( geomAndNot( active geomOr( nwell pwell ) ) "(DBM Rule 1.0) Active must be inside well")
)
cond(
( ccdAvailable && cwellAvailable
saveDerived( geomAndNot( active geomOr( nselect pselect ccd cwell ) )
"(DBM Rule 1.1) Active must be inside select, ccd or cwell")
)
( cwellAvailable
saveDerived( geomAndNot( active geomOr( nselect pselect cwell ) )
"(DBM Rule 1.1) Active must be inside select or cwell")
)
( ccdAvailable
saveDerived( geomAndNot( active geomOr( nselect pselect ccd ) )
"(DBM Rule 1.1) Active must be inside select or ccd")
)
( t
saveDerived( geomAndNot( active geomOr( nselect pselect ) )
"(DBM Rule 1.1) Active must be inside select")
)
)
if( cwellAvailable then
saveDerived( geomAnd( cwell pselect ) "(DBM Rule 1.2) Pselect not allowed inside cwell" )
)
saveDerived( geomAnd( poly nOhmic ) "(DBM Rule 2.0) Poly cannot overlap ohmic diffusion" )
saveDerived( geomAnd( poly pOhmic ) "(DBM Rule 2.0) Poly cannot overlap ohmic diffusion" )
if( elecAvailable then
saveDerived( geomAnd( elec nOhmic ) "(DBM Rule 2.1) Elec cannot overlap ohmic diffusion" )
saveDerived( geomAnd( elec pOhmic ) "(DBM Rule 2.1) Elec cannot overlap ohmic diffusion" )
)
saveDerived( geomAnd( pactive nselect ) "(DBM Rule 3.1) Pactive and Nselect may not overlap" )
saveDerived( geomAnd( nactive pselect ) "(DBM Rule 3.2) Nactive and Pselect may not overlap" )
/*
* Can't use elec in these processes to make transistors
* From http://www.mosis.org/Whatsnew/1999/990301-ami-c5.html:
*
* "The AMI C5N poly2 can be used to build capacitors in a style identical to
* SCNE (as for AMI 1.2u, Orbit 2u and TSMC 0.35u), but not transistors (same as
* TSMC 0.35u)."
*/
)
/* official SCMOS rules */
;; SCMOS 1. WELL (NWELL, PWELL)
ivIf( ( !switch("hier?") || !switch("topCell?") ) then
;; 1.1 - modified for DEEP
; if( ( submicronAvailable || deepAvailable ) then
; sprintf( errMesg "(SCMOS_SUBM Rule 1.1) well width: %.2f um" (lambda*12.0) )
; drc( nwellEdge width < (lambda * 12.0) errMesg )
; drc( pwellEdge width < (lambda * 12.0) errMesg )
;else
sprintf( errMesg "(SCMOS Rule 1.1) well width: %.2f um" (lambda*10.0) )
drc( nwellEdge width < (lambda * 10.0) errMesg )
drc( pwellEdge width < (lambda * 10.0) errMesg )
;)
;; 1.2 - modified for DEEP
sprintf( errMesg "(SCMOS Rule 1.2) well spacing, different potential: %.2f um" (lambda*9.0))
drc( nwell sep < (lambda * 9.0) diffNet errMesg )
drc( pwell sep < (lambda * 9.0) diffNet errMesg )
;; 1.3
sprintf( errMesg "(SCMOS Rule 1.3) well spacing, same potential: 0 or %.2f um" (lambda*6.0))
drc( nwell sep < (lambda * 6.0) sameNet errMesg )
drc( pwell sep < (lambda * 6.0) sameNet errMesg )
drc( nwellEdge notch < (lambda * 6.0) errMesg )
drc( pwellEdge notch < (lambda * 6.0) errMesg )
;; 1 note
saveDerived( geomAnd( nwell pwell) "(SCMOS Rule 1 note) n-wells and p-wells may not overlap")
)
;; SCMOS 2. ACTIVE
ivIf( ( !switch("hier?") || !switch("topCell?") ) then
;; 2.1
if( techdesc == "AMI_ABN" then
sprintf( errMesg "(SCMOS Rule 2.1) active width: %.2f um" (lambda*5.0))
drc( activeEdge width < (lambda * 5.0) errMesg )
else
sprintf( errMesg "(SCMOS Rule 2.1) active width: %.2f um" (lambda*3.0))
drc( activeEdge width < (lambda * 3.0) errMesg )
)
;; 2.2
sprintf( errMesg "(SCMOS Rule 2.2) active spacing: %.2f um" (lambda*3.0))
drc( activeEdge sep < (lambda * 3.0) errMesg )
drc( activeEdge notch < (lambda * 3.0) errMesg )
;; 2.3 - modified for DEEP
sprintf( errMesg "(SCMOS Rule 2.3) source/drain active to well edge: %.2f um" (lambda*5.0))
drc( nNotOhmicEdge nBulkEdge sep < (lambda * 5.0) errMesg )
drc( pNotOhmicEdge pBulkEdge sep < (lambda * 5.0) errMesg )
drc( pBulkEdge nNotOhmicEdge enc < (lambda * 5.0) errMesg )
drc( nBulkEdge pNotOhmicEdge enc < (lambda * 5.0) errMesg )
;; 2.4
sprintf( errMesg "(SCMOS Rule 2.4) substrate/well contact active to well edge: %.2f um" (lambda*3.0))
drc( nBulkEdge nOhmicEdge enc < (lambda * 3.0) errMesg )
drc( nOhmicEdge pBulkEdge sep < (lambda * 3.0) errMesg )
drc( pOhmicEdge nBulkEdge sep < (lambda * 3.0) errMesg )
drc( pBulkEdge pOhmicEdge enc < (lambda * 3.0) errMesg )
;; 2.5
sprintf( errMesg "(SCMOS Rule 2.5) active of different implant spacing: 0 or %.2f um" (lambda*4.0))
drc( nNotOhmicEdge pOhmicEdge 0 < sep < (lambda * 4.0) errMesg )
drc( pNotOhmicEdge nOhmicEdge 0 < sep < (lambda * 4.0) errMesg )
)
;; SCMOS 3. POLY
ivIf( ( !switch("hier?") || !switch("topCell?") ) then
;; 3.1
sprintf( errMesg "(SCMOS Rule 3.1) poly width: %.2f um" (lambda*2.0))
drc( polyEdge width < (lambda * 2.0) errMesg )
;; 3.2 - modified for DEEP
if( submicronAvailable then
sprintf( errMesg "(SCMOS_SUBM Rule 3.2) poly spacing: %.2f um" (lambda*3.0))
drc( polyEdge sep < (lambda * 3.0) errMesg )
drc( polyEdge notch < (lambda * 3.0) errMesg )
else if( deepAvailable then
sprintf( errMesg "(SCMOS_SUBM Rule 3.2) poly spacing: %.2f um" (lambda*4.0))
drc( polyEdge sep < (lambda * 4.0) errMesg )
drc( polyEdge notch < (lambda * 4.0) errMesg )
else
sprintf( errMesg "(SCMOS Rule 3.2) poly spacing: %.2f um" (lambda*2.0))
drc( polyEdge sep < (lambda * 2.0) errMesg )
drc( polyEdge notch < (lambda * 2.0) errMesg )
) ) ;;
;; 3.3 - modified for DEEP
sprintf( errMesg "(SCMOS Rule 3.3) gate enclosure of active: %.2f um" (lambda*2.0))
drc( polyEdge activeEdge enc < (lambda * 2.0) errMesg )
;; 3.4 - modified for DEEP
sprintf( errMesg "(SCMOS Rule 3.4) active enclosure of gate: %.2f um" (lambda*3.0))
drc( activeEdge polyEdge enc < (lambda * 3.0) errMesg )
;;
;; 3.5
sprintf( errMesg "(SCMOS Rule 3.5) field poly to active spacing: %.2f um" (lambda*1.0))
drc( polyEdge activeEdge sep < (lambda * 1.0) errMesg )
)
;; SCMOS 4. SELECT (PSELECT, NSELECT)
ivIf( ( !switch("hier?") || !switch("topCell?") ) then
;; 4.1
sprintf( errMesg "(SCMOS Rule 4.1) n select to channel spacing: %.2f um" (lambda*3.0))
drc( nselectEdge geomGetEdge( polyEdge inside pNotOhmic) sep < (lambda * 3.0) app > 0 errMesg )
drc( nselectEdge geomGetEdge( polyEdge inside nNotOhmic) enc < (lambda * 3.0) app > 0 errMesg )
sprintf( errMesg "(SCMOS Rule 4.1) p select to channel spacing: %.2f um" (lambda*3.0))
drc( pselectEdge geomGetEdge( polyEdge inside nNotOhmic) sep < (lambda * 3.0) app > 0 errMesg )
drc( pselectEdge geomGetEdge( polyEdge inside pNotOhmic) enc < (lambda * 3.0) app > 0 errMesg )
;; 4.2
sprintf( errMesg "(SCMOS Rule 4.2) select overlap of active: %.2f um" (lambda*2.0))
drc( geomOr( nselectEdge pselectEdge ) activeEdge sep < (lambda * 2.0) errMesg )
drc( geomOr( nselectEdge pselectEdge ) activeEdge enc < (lambda * 2.0) errMesg )
;; 4.3 - modified for DEEP
sprintf( errMesg "(SCMOS Rule 4.3) n select to active contact spacing: %.2f um" (lambda*1.0))
drc( nselectEdge caEdge sep < (lambda * 1.0) errMesg )
drc( nselectEdge caEdge enc < (lambda * 1.0) errMesg )
sprintf( errMesg "(SCMOS Rule 4.3) p select to active contact spacing: %.2f um" (lambda*1.0))
drc( pselectEdge caEdge sep < (lambda * 1.0) errMesg )
drc( pselectEdge caEdge enc < (lambda * 1.0) errMesg )
sprintf( errMesg "(SCMOS Rule 4.3) select overlap of active contact: %.2f um" (lambda*1.0))
saveDerived( geomButting( geomAnd( ca nselect ) geomAnd( ca pselect ) ) errMesg )
;; 4.4 - modified for DEEP
sprintf( errMesg "(SCMOS Rule 4.4) n select width: %.2f um" (lambda*2.0))
drc( nselectEdge width < (lambda * 2.0) errMesg )
sprintf( errMesg "(SCMOS Rule 4.4) p select width: %.2f um" (lambda*2.0))
drc( pselectEdge width < (lambda * 2.0) errMesg )
sprintf( errMesg "(SCMOS Rule 4.4) n select spacing: %.2f um" (lambda*2.0))
drc( nselectEdge sep < (lambda * 2.0) errMesg )
drc( nselectEdge notch < (lambda * 2.0) errMesg )
sprintf( errMesg "(SCMOS Rule 4.4) p select spacing: %.2f um" (lambda*2.0))
drc( pselectEdge sep < (lambda * 2.0) errMesg )
drc( pselectEdge notch < (lambda * 2.0) errMesg )
sprintf( errMesg "(SCMOS Rule 4.4) n select and p select may not overlap" )
saveDerived( geomAnd( nselect pselect ) errMesg )
)
;; SCMOS 5B. DENSER CONTACT TO POLY
ivIf( ( !switch("hier?") || !switch("topCell?") ) then
;; 5.1
sprintf( errMesg "(SCMOS Rule 5.1) poly contact size, exactly: %.2f x %.2f um" (lambda*2.0) (lambda*2.0))
drc( cpEdge width < (lambda * 2.0) errMesg )
drc( cp area > ( (lambda * 2.0) * (lambda * 2.0) + (lambda * 0.1) * (lambda * 0.1) ) errMesg )
;; 5.2.b
sprintf( errMesg "(SCMOS Rule 5.2.b) poly enclosure of contact: %.2f um" (lambda*1.0))
drc( polyEdge cpEdge enc < (lambda * 1.0) errMesg )
saveDerived( geomAndNot( cp poly) errMesg )
;; 5.3 - modified for DEEP
sprintf( errMesg "(SCMOS Rule 5.3) poly contact spacing: %.2f um" (lambda*2.0))
drc( cpEdge sep < (lambda * 2.0) errMesg )
drc( cpEdge notch < (lambda * 2.0) errMesg )
;;
;; 5.4
sprintf( errMesg "(SCMOS Rule 5.4) poly contact to gate spacing: %.2f um" (lambda*2.0))
drc( cpEdge GateEdge sep < (lambda * 2.0) errMesg )
;; 5.5.b
/*
* ftp://ftp.mosis.org/pub/mosis/magic/new/beta/CHANGELOG
*
* 990318 release 99c:
*
* SCN5M_SUBM.15.*tech27:
*
* removed the poly-to-poly-contact spacing rule:
*
* Poly spacing to Poly contact < 4 (Mosis #5.5.b)
*
* since rule 5.5.b is not actually required for the tsmc25
* process. Again (see 5.5.b discussion below), you would need
* to add this rule to create full SCMOS_SUBM rule-conforming
* layout.
*
* Also:
*
* SCN3M*.tech27: (all techfiles for HP cmos26 and cmos14 processes)
*
* Commented out the poly-to-poly-contact spacing rule:
*
* Poly spacing to Poly contact < 4 (Mosis #5.5.b)
*
* (see lines starting with #PSC (for "poly space-to contact"))
* since rule 5.5.b is only actually required for hpcmos10
* processes. Again, you would need to uncomment this rule to
* create full SCMOS rule-conforming layout.
*/
sprintf( errMesg "(SCMOS Rule 5.5.b) poly contact to poly spacing: %.2f um" (lambda*4.0))
drc( cpEdge polyEdge sep < (lambda * 4.0) errMesg )
;; 5.6.b
sprintf( errMesg "(SCMOS Rule 5.6.b) poly contact to active spacing: %.2f um" (lambda*2.0))
drc( cpEdge activeEdge sep < (lambda * 2.0) errMesg )
saveDerived( geomAnd( cp active) errMesg )
;; 5.7.b
sprintf( errMesg "(SCMOS Rule 5.7.b) poly contact to active spacing, many contacts: %.2f um" (lambda*3.0))
saveDerived( geomGetLength( drc(cpEdge activeEdge sep < (lambda * 3.0)) length > (lambda * 7.0) fig ) errMesg )
)
;; SCMOS 6B. DENSER CONTACT TO ACTIVE
ivIf( ( !switch("hier?") || !switch("topCell?") ) then
;; 6.1
sprintf( errMesg "(SCMOS Rule 6.1) active contact size, exactly: %.2f x %.2f um" (lambda*2.0) (lambda*2.0))
drc( caEdge width < (lambda * 2.0) errMesg )
drc( ca area > ( (lambda * 2.0) * (lambda * 2.0) + (lambda * 0.1) * (lambda * 0.1) ) errMesg )
;; 6.2.b
sprintf( errMesg "(SCMOS Rule 6.2.b) active enclosure of contact: %.2f um" (lambda*1.5))
drc( activeEdge caEdge enc < (lambda * 1.5) errMesg )
saveDerived( geomAnd( geomAndNot( ca cactive ) geomAndNot( ca active ) ) errMesg )
;; 6.3 - modified for DEEP
sprintf( errMesg "(SCMOS Rule 6.3) active contact spacing: %.2f um" (lambda*2.0))
drc( caEdge sep < (lambda * 2.0) errMesg )
drc( caEdge notch < (lambda * 2.0) errMesg )
;;
;; 6.4
sprintf( errMesg "(SCMOS Rule 6.4) active contact to transistor gate spacing: %.2f um" (lambda*2.0) )
drc( caEdge GateEdge sep < (lambda * 2.0) errMesg )
saveDerived( geomAnd( ca Gate) errMesg )
;; 6.5.b
sprintf( errMesg "(SCMOS Rule 6.5.b) active contact to active spacing: %.2f um" (lambda*5.0))
drc( caEdge activeEdge sep < (lambda * 5.0) errMesg )
;; 6.6.b
sprintf( errMesg "(SCMOS Rule 6.6.b) active contact to field poly spacing: %.2f um" (lambda*2.0))
drc( caEdge fieldPolyEdge sep < (lambda * 2.0) errMesg )
saveDerived( geomAnd( ca fieldPoly) errMesg )
;; 6.7.b
sprintf( errMesg "(SCMOS Rule 6.7.b) active contact to field poly spacing, many contacts: %.2f um" (lambda*3.0))
saveDerived( geomGetLength( drc(caEdge fieldPolyEdge sep < (lambda * 3.0)) length > (lambda * 7.0) fig ) errMesg )
;; 6.8.b
sprintf( errMesg "(SCMOS Rule 6.8.b) active contact to poly contact spacing: %.2f um" (lambda*4.0))
drc( caEdge cpEdge sep < (lambda * 4.0) errMesg )
saveDerived( geomAnd( ca cp) errMesg )
)
;; SCMOS 7. METAL1
ivIf( ( !switch("hier?") || !switch("topCell?") ) then
;; 7.1
sprintf( errMesg "(SCMOS Rule 7.1) metal1 width: %.2f um" (lambda*3.0))
drc( metal1Edge width < (lambda * 3.0) errMesg )
;; 7.2 - modified for DEEP
sprintf( errMesg "(SCMOS Rule 7.2) metal1 spacing: %.2f um" (lambda*2.0))
drc( metal1Edge sep < (lambda * 2.0) errMesg )
drc( metal1Edge notch < (lambda * 2.0) errMesg )
;; 7.3
sprintf( errMesg "(SCMOS Rule 7.3) metal1 enclosure of contact: %.2f um" (lambda*1.0))
drc( metal1Edge cpEdge enc < (lambda * 1.0) errMesg )
drc( metal1Edge caEdge enc < (lambda * 1.0) errMesg )
saveDerived( geomAndNot( cp metal1) errMesg )
saveDerived( geomAndNot( ca metal1) errMesg )
;; 7.4
;; Metal1 wide metal (>10*lambda) rule not implemented
)
;; SCMOS 8. VIA
ivIf( ( !switch("hier?") || !switch("topCell?") ) then
;; 8.1 - modified for DEEP
sprintf( errMesg "(SCMOS Rule 8.1) via size, exactly: %.2f x %.2f um" (lambda*2.0) (lambda*2.0))
drc( viaEdge width < (lambda * 2.0) errMesg )
drc( via area > ( (lambda * 2.0) * (lambda * 2.0) + (lambda * 0.1) * (lambda * 0.1) ) errMesg )
;; 8.2
sprintf( errMesg "(SCMOS Rule 8.2) via spacing: %.2f um" (lambda*3.0))
drc( viaEdge sep < (lambda * 3.0) errMesg )
;; 8.3
sprintf( errMesg "(SCMOS Rule 8.3) metal1 enclosure of via: %.2f um" (lambda*1.0))
drc( metal1Edge viaEdge enc < (lambda * 1.0) errMesg )
saveDerived( geomAndNot( via metal1) errMesg )
;; 8.4
sprintf( errMesg "(SCMOS Rule 8.4) via to contact spacing: %.2f um" (lambda*2.0))
drc( viaEdge caEdge sep < (lambda * 2.0) errMesg )
drc( viaEdge cpEdge sep < (lambda * 2.0) errMesg )
saveDerived( geomAnd( via geomOr( ca cp)) errMesg )
;; 8.5 (doesn't apply to SCMOS_SUBM; see Table 4 in SCMOS Rules Manual, v.7.3) - modified for DEEP
sprintf( errMesg "(SCMOS Rule 8.5) via to poly edge spacing: %.2f um" (lambda*2.0))
drc( polyEdge viaEdge sep < (lambda * 2.0) errMesg )
drc( polyEdge viaEdge enc < (lambda * 2.0) errMesg )
saveDerived( geomStraddle( via poly) errMesg )
sprintf( errMesg "(SCMOS Rule 8.5) via to active edge spacing: %.2f um" (lambda*2.0))
drc( activeEdge viaEdge sep < (lambda * 2.0) errMesg )
drc( activeEdge viaEdge enc < (lambda * 2.0) errMesg )
saveDerived( geomStraddle( via active) errMesg )
sprintf( errMesg "(SCMOS Rule 8.5) via to cactive edge spacing: %.2f um" (lambda*2.0))
drc( cactiveEdge viaEdge sep < (lambda * 2.0) errMesg )
drc( cactiveEdge viaEdge enc < (lambda * 2.0) errMesg )
saveDerived( geomStraddle( via cactive) errMesg )
)
;; SCMOS 9. METAL2
ivIf( ( !switch("hier?") || !switch("topCell?") ) then
;; 9.1
sprintf( errMesg "(SCMOS Rule 9.1) metal2 width: %.2f um" (lambda*3.0))
drc( metal2Edge width < (lambda * 3.0) errMesg )
;; 9.2 - modified for DEEP
sprintf( errMesg "(SCMOS Rule 9.2.a) metal2 spacing: %.2f um" (lambda*4.0))
drc( metal2Edge sep < (lambda * 4.0) errMesg )
drc( metal2Edge notch < (lambda * 4.0) errMesg )
;;
;; 9.3
sprintf( errMesg "(SCMOS Rule 9.3) metal2 enclosure of via: %.2f um" (lambda*1.0))
drc( metal2Edge viaEdge enc < (lambda * 1.0) errMesg )
saveDerived( geomAndNot( via metal2) errMesg )
;; 9.4
;; Metal2 wide metal (>10*lambda) rule not implemented
)
;; SCMOS 10. OVERGLASS
ivIf( !switch("allowTinyPads?") &&
!switch("AreaPads?") &&
( !switch("hier?") || switch("topCell?") ) then
saveDerived( geomStraddle( glass pad))
BondingGlass = geomInside( glass pad)
ProbeGlass = geomOutside( glass pad)
BondingPad = geomAndNot( geomSize( BondingGlass 6.0) geomHoles( BondingGlass))
ProbePad = geomAndNot( geomSize( ProbeGlass 6.0) geomHoles( ProbeGlass))
Pad = geomOr( BondingPad ProbePad)
BondingPadEdge = geomGetEdge( BondingPad not_over "nodrc")
ProbePadEdge = geomGetEdge( ProbePad not_over "nodrc")
PadEdge = geomGetEdge( Pad not_over "nodrc")
Metal2EdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "metal2" "glass" 36.0)) not_over "nodrc")
Metal1EdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "metal1" "glass" 21.0)) not_over "nodrc")
PolyEdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "poly" "glass" 21.0)) not_over "nodrc")
ActiveEdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "active" "glass" 21.0)) not_over "nodrc")
ElecEdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "elec" "glass" 21.0)) not_over "nodrc")
;; 10.1
drc( BondingPadEdge width < 60.0 "(SCMOS Rule 10.1) bonding pad width: 60 um")
;; 10.2
drc( ProbePadEdge width < 20.0 "(SCMOS Rule 10.2) probe pad width: 20 um")
;; 10.3
drc( Metal2EdgeNearPad glassEdge enc < 6.0 "(SCMOS Rule 10.3) pad enclosure of glass: 6 um")
saveDerived( geomAndNot( glass metal2) "(SCMOS Rule 10.3) pad enclosure of glass: 6 um")
;; 10.4
drc( PadEdge Metal2EdgeNearPad sep < 30.0 "(SCMOS Rule 10.4) pad to unrelated metal2 spacing: 30 um")
;; 10.5
drc( PadEdge Metal1EdgeNearPad sep < 15.0 "(SCMOS Rule 10.5) pad to unrelated metal1 spacing: 15 um")
drc( PadEdge PolyEdgeNearPad sep < 15.0 "(SCMOS Rule 10.5) pad to unrelated poly spacing: 15 um")
drc( PadEdge ActiveEdgeNearPad sep < 15.0 "(SCMOS Rule 10.5) pad to unrelated active spacing: 15 um")
drc( PadEdge ElecEdgeNearPad sep < 15.0 "(SCMOS Rule 10.5) pad to unrelated elec spacing: 15 um")
)
;; This set of overglass rules allows for very small probe pads
;; also for area array pads
ivIf( ( switch("allowTinyPads?") || switch("AreaPads?") ) &&
( !switch("hier?") || switch("topCell?") ) then
saveDerived( geomStraddle( glass pad))
BondingGlass = geomInside( glass pad)
BondingPad = geomAndNot( geomSize( BondingGlass 6.0) geomHoles( BondingGlass))
BondingPadEdge = geomGetEdge( BondingPad not_over "nodrc")
Metal2EdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "metal2" "glass" 36.0)) not_over "nodrc")
Metal1EdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "metal1" "glass" 21.0)) not_over "nodrc")
PolyEdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "poly" "glass" 21.0)) not_over "nodrc")
ActiveEdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "active" "glass" 21.0)) not_over "nodrc")
ElecEdgeNearPad = geomGetEdge( geomOr( geomGetByLayer( "elec" "glass" 21.0)) not_over "nodrc")
)
;; SCMOS 11. ELECTRODE for CAPACITORS
ivIf( ( !switch("hier?") || !switch("topCell?") ) then
;; 11.1 - modified for DEEP
sprintf( errMesg "(SCMOS Rule 11.1) capacitor electrode width: %.2f um" (lambda*3.0))
drc( CapacitorElecEdge width < (lambda * 3.0) errMesg )
;; 11.2
sprintf( errMesg "(SCMOS Rule 11.2) capacitor electrode spacing: %.2f um" (lambda*3.0))
drc( CapacitorElecEdge sep < (lambda * 3.0) errMesg )
drc( CapacitorElecEdge notch < (lambda * 3.0) errMesg )
;; 11.3 - modified for DEEP
sprintf( errMesg "(SCMOS Rule 11.3) poly enclosure of capacitor electrode: %.2f um" (lambda*2.0))
drc( polyEdge CapacitorElecEdge enc < (lambda * 2.0) errMesg )
;; 11.4
sprintf( errMesg "(SCMOS Rule 11.4) capacitor electrode to bulk spacing: %.2f um" (lambda*2.0))
drc( CapacitorElecEdge nBulkEdge sep < (lambda * 2.0) errMesg )
drc( CapacitorElecEdge pBulkEdge sep < (lambda * 2.0) errMesg )
saveDerived( geomStraddle( CapacitorElec nBulk) errMesg )
saveDerived( geomStraddle( CapacitorElec pBulk) errMesg )
sprintf( errMesg "(SCMOS Rule 11.4) bulk enclosure of capacitor electrode: %.2f um" (lambda*2.0))
drc( nBulkEdge CapacitorElecEdge enc < (lambda * 2.0) errMesg )
drc( pBulkEdge CapacitorElecEdge enc < (lambda * 2.0) errMesg )
sprintf( errMesg "(SCMOS Rule 11.4) capacitor electrode to active spacing: %.2f um" (lambda*2.0))
drc( CapacitorElecEdge activeEdge sep < (lambda * 2.0) errMesg )
saveDerived( geomAnd( CapacitorElec active) errMesg )
;; 11.5 - modified for DEEP
sprintf( errMesg "(SCMOS Rule 11.5) capacitor electrode to poly contact spacing: %.2f um" (lambda*3.0))
drc( CapacitorElecEdge cpEdge sep < (lambda * 3.0) errMesg )
;; 11.6
sprintf( errMesg "(SCMOS Rule 11.6) poly2 to unrelated metal2 spacing: %.2f um" (lambda*2.0))
drc( geomGetEdge( "elec" ) geomGetEdge( "metal2" ) sep < (lambda * 2.0) errMesg )
saveDerived( geomOverlap( metal2 elec diffNet ) errMesg )
sprintf( errMesg "(SCMOS Rule 11.6) poly2 to unrelated metal1 spacing: %.2f um" (lambda*2.0))
drc( geomGetEdge( "elec" ) geomGetEdge( "metal1" ) sep < (lambda * 2.0) errMesg )
saveDerived( geomOverlap( metal1 elec diffNet ) errMesg )
)
;; SCMOS 12. ELECTRODE for TRANSISTORS
ivIf( ( !switch("hier?") || !switch("topCell?") ) then
;; 12.1
sprintf( errMesg "(SCMOS Rule 12.1) transistor electrode width: %.2f um" (lambda*2.0))
drc( TransistorElecEdge width < (lambda * 2.0) errMesg )
;; 12.2
sprintf( errMesg "(SCMOS Rule 12.2) transistor electrode spacing: %.2f um" (lambda*3.0))
drc( TransistorElecEdge sep < (lambda * 3.0) errMesg )
drc( TransistorElecEdge notch < (lambda * 3.0) errMesg )
;; 12.3
sprintf( errMesg "(SCMOS Rule 12.3) gate enclosure of active: %.2f um" (lambda*2.0))
drc( TransistorElecEdge activeEdge enc < (lambda * 2.0) errMesg )
;; 12.4
sprintf( errMesg "(SCMOS Rule 12.4) transistor electrode to active spacing: %.2f um" (lambda*1.0))
drc( TransistorElecEdge activeEdge sep < (lambda * 1.0) errMesg )
;; 12.5
sprintf( errMesg "(SCMOS Rule 12.5) transistor electrode to poly spacing: %.2f um" (lambda*2.0))
drc( TransistorElecEdge polyEdge sep < (lambda * 2.0) errMesg )
sprintf( errMesg "(SCMOS Rule 12.5) transistor electrode overlap of poly: %.2f um" (lambda*2.0))
drc( TransistorElecEdge polyEdge ovlp < (lambda * 2.0) errMesg )
;; 12.6
sprintf( errMesg "(SCMOS Rule 12.6) transistor electrode to poly contact spacing: %.2f um" (lambda*3.0))
drc( TransistorElecEdge cpEdge sep < (lambda * 3.0) errMesg )
saveDerived( geomAnd( TransistorElec cp) errMesg )
sprintf( errMesg "(SCMOS Rule 12.6) transistor electrode to active contact spacing: %.2f um" (lambda*3.0))
drc( TransistorElecEdge caEdge sep < (lambda * 3.0) errMesg )
saveDerived( geomAnd( TransistorElec ca) errMesg )
)
;; SCMOS 13. ELECTRODE CONTACT
ivIf( ( !switch("hier?") || !switch("topCell?") ) then
;; 13.1
sprintf( errMesg "(SCMOS Rule 13.1) contact size, exactly: %.2f x %.2f um" (lambda*2.0) (lambda*2.0))
drc( ceEdge width < (lambda * 2.0) errMesg )
drc( ce area > ( (lambda * 2.0) * (lambda * 2.0) + (lambda * 0.1) * (lambda * 0.1) ) errMesg )
;; 13.2
sprintf( errMesg "(SCMOS Rule 13.2) contact spacing: %.2f um" (lambda*2.0))
drc( ceEdge sep < (lambda * 2.0) errMesg )
drc( ceEdge notch < (lambda * 2.0) errMesg )
;; 13.3
sprintf( errMesg "(SCMOS Rule 13.3) capacitor electrode enclosure of contact: %.2f um" (lambda*3.0))
drc( CapacitorElecEdge ceEdge enc < (lambda * 3.0) errMesg )
;; 13.4
sprintf( errMesg "(SCMOS Rule 13.4) electrode enclosure of contact (not on capacitor): %.2f um" (lambda*2.0))
drc( TransistorElecEdge ceEdge enc < (lambda * 2.0) errMesg )
saveDerived( geomAndNot( ce elec) "(SCMOS Rules 13.3,13.4) electrode enclosure of contact" )
;; 13.5
sprintf( errMesg "(SCMOS Rule 13.5) electrode contact to poly spacing: %.2f um" (lambda*3.0))
drc( ceEdge polyEdge sep < (lambda * 3.0) errMesg )
saveDerived( geomOutside( geomAnd( ce poly) CapacitorElec) errMesg )
sprintf( errMesg "(SCMOS Rule 13.5) electrode contact to active spacing: %.2f um" (lambda*3.0))
drc( ceEdge activeEdge sep < (lambda * 3.0) errMesg )
saveDerived( geomAnd( ce active) errMesg )
)
;; SCMOS 14. VIA2
;; SCMOS 15. METAL3
;; SCMOS 16. NPN BIPOLAR TRANSISTOR (ANALOG OPTION)
ivIf( ( !switch("hier?") || !switch("topCell?") ) then
;; if( npnAvailable then
;; 16.1
sprintf( errMesg "(SCMOS Rule 16.1) collector contact, exactly: %.2f x %.2f um" (lambda*2.0) (lambda*2.0))
drc( npnCollectorContactEdge width < (lambda * 2.0) errMesg )
drc( npnCollectorContact area > ( (lambda * 2.0) * (lambda * 2.0) + (lambda * 0.1) * (lambda * 0.1) ) errMesg )
sprintf( errMesg "(SCMOS Rule 16.1) emitter contact, exactly: %.2f x %.2f um" (lambda*2.0) (lambda*2.0))
drc( npnEmitterContactEdge width < (lambda * 2.0) errMesg )
drc( npnEmitterContact area > ( (lambda * 2.0) * (lambda * 2.0) + (lambda * 0.1) * (lambda * 0.1) ) errMesg )
sprintf( errMesg "(SCMOS Rule 16.1) base contact, exactly: %.2f x %.2f um" (lambda*2.0) (lambda*2.0))
drc( npnBaseContactEdge width < (lambda * 2.0) errMesg )
drc( npnBaseContact area > ( (lambda * 2.0) * (lambda * 2.0) + (lambda * 0.1) * (lambda * 0.1) ) errMesg )
;; 16.2
sprintf( errMesg "(SCMOS Rule 16.2) emitter sel enclosure of contact: %.2f um" (lambda*3.0) )
drc( npnEmitterEdge npnEmitterContactEdge enc < (lambda * 3.0) errMesg )
;; 16.3
sprintf( errMesg "(SCMOS Rule 16.3) pbase enclosure of emitter select: %.2f um" (lambda*2.0) )
drc( pbaseEdge npnEmitterEdge enc < (lambda * 2.0) errMesg )
;; 16.4
sprintf( errMesg "(SCMOS Rule 16.4) emitter sel to base sel spacing: %.2f um" (lambda*4.0) )
drc( npnEmitterEdge npnBaseTapEdge sep < (lambda * 4.0) errMesg )
;; 16.5
sprintf( errMesg "(SCMOS Rule 16.5) pbase enclosure of base select: %.2f um" (lambda*2.0) )
drc( pbaseEdge npnBaseTapEdge enc < (lambda * 2.0) errMesg )
;; 16.6
sprintf( errMesg "(SCMOS Rule 16.6) base sel enclosure of contact: %.2f um" (lambda*2.0) )
drc( npnBaseTapEdge npnBaseContactEdge enc < (lambda * 2.0) errMesg )
;; 16.7
sprintf( errMesg "(SCMOS Rule 16.7) nwell enclosure of pbase: %.2f um" (lambda*6.0) )
drc( nwellEdge pbaseEdge enc < (lambda * 6.0) errMesg )
saveDerived( geomAndNot( pbase nwell ) errMesg )
;; 16.8
sprintf( errMesg "(SCMOS Rule 16.8) pbase to collector active spacing: %.2f um" (lambda*4.0) )
drc( npnCollectorEdge pbaseEdge sep < (lambda * 4.0) errMesg )
;; 16.9
sprintf( errMesg "(SCMOS Rule 16.9) coll active enclosure of contact: %.2f um" (lambda*2.0) )
drc( npnCollectorEdge npnCollectorContactEdge enc < (lambda * 2.0) errMesg )
;; 16.10
sprintf( errMesg "(SCMOS Rule 16.10) nwell enclosure of coll active: %.2f um" (lambda*3.0) )
drc( nwellEdge npnCollectorEdge enc < (lambda * 3.0) errMesg )
saveDerived( geomAndNot( cactive nwell ) errMesg )
;; 16.11
sprintf( errMesg "(SCMOS Rule 16.11) nselect enclosure of coll active: %.2f um" (lambda*2.0) )
drc( nselectEdge npnCollectorEdge enc < (lambda * 2.0) errMesg )
saveDerived( geomAndNot( cactive nselect ) errMesg )
)
;; SCMOS 17. CAPACITOR WELL
;; SCMOS 18. LINEAR CAPACITOR (POLY TO N-DIFFUSION)
;; SCMOS 19. BURIED CHANNEL CCD
;; SCMOS 20. SILICIDE BLOCK
;; SCMOS 21. VIA3
;; SCMOS 22. METAL4
;; SCMOS 23. SCNPC WITH POLYCAP
ivIf( ( !switch("hier?") || !switch("topCell?") ) then
if( polycapAvailable then
;; 23.1
sprintf( errMesg "(SCMOS Rule 23.1) minimum polycap width: %.2f um" (lambda*8.0) )
drc( polycapEdge width < (lambda * 8.0) errMesg )
;; 23.2
sprintf( errMesg "(SCMOS Rule 23.2) polycap spacing: %.2f um" (lambda*4.0) )
drc( polycapEdge sep < (lambda * 4.0) errMesg )
drc( polycapEdge notch < (lambda * 4.0) errMesg )
;; 23.3
sprintf( errMesg "(SCMOS Rule 23.3) polycap to active spacing: %.2f um" (lambda*8.0) )
drc( polycapEdge activeEdge sep < (lambda * 8.0) errMesg )
sprintf( errMesg "(SCMOS Rule 23.3) all capacitors must be over field" )
saveDerived( geomAnd( polycap active ) errMesg )
;; 23.4
sprintf( errMesg "(SCMOS Rule 23.4) polycap enclosure of poly: %.2f um" (lambda*3.0) )
drc( polycapEdge polyEdge enc < (lambda * 3.0) errMesg )
;; 23.5
sprintf( errMesg "(SCMOS Rule 23.5) polycap enclosure of contact: %.2f um" (lambda*2.0) )
drc( polycapEdge cpolycapEdge enc < (lambda * 2.0) errMesg )
;; 23.6
sprintf( errMesg "(SCMOS Rule 23.6) poly enclosure of contact in capacitor: %.2f um" (lambda*2.0) )
drc( polycapCapEdge cpEdge enc < (lambda * 2.0) errMesg )
;; 23.7
sprintf( errMesg "(SCMOS Rule 23.7) poly to polycap-contact spacing: %.2f um" (lambda*2.0) )
drc( polycapCapEdge cpolycapEdge sep < (lambda * 2.0) errMesg )
;; 23.8
sprintf( errMesg "(SCMOS Rule 23.8) polycap to metal1 spacing: %.2f um" (lambda*4.0) )
drc( polycapEdge metal1Edge sep < (lambda * 4.0) diffNet errMesg )
saveDerived( geomOverlap( metal1 polycap diffNet ) errMesg )
;; 23.9
sprintf( errMesg "(SCMOS Rule 23.9) polycap to metal2 spacing: %.2f um" (lambda*2.0) )
drc( polycapEdge metal2Edge sep < (lambda * 2.0) errMesg )
saveDerived( geomOverlap( metal2 polycap diffNet ) errMesg )
)
)
;; SCMOS 24. THICK ACTIVE
;; SCMOS 26. METAL5
;; SCMOS 27. HIGHRES POLY
;; SCMOS 28. METALCAP (MOSIS CAP_TOP_METAL)
;; SCMOS 29. VIA5
;; SCMOS 30. METAL6
;; SCMOS EXP-98. MEMS OPEN
;; SCMOS EXP-99. MEMS PSTOP
) ; drcExtractRules
) ; let
; vim:ts=4:columns=132:set tw=0:
Text file Source (historic): geocities.com/fudinggecircuit/layout
geocities.com/fudinggecircuit(to report bad content: archivehelp @ gmail)
|
|
|
|
|