blob: 456ca5e0b22313391ef42e8f361116c59b83d360 [file] [log] [blame]
/*==============================================================================
File: S130rpoly_hpPcell.il
Purpose: Pcell code for layout and symbols, and cdf setup for hrpoly &
uhrpoly resistors for Skywater S130 Pcells
Created: Mar 12, 2020 Madek Graham
Description: Pcell code to create the high precision poly resistors
Devices/views: rpoly_hp / layout symbol auCdl auLvs spectre
rpoly_hp2K / layout symbol auCdl auLvs spectre
------------------------------------------------------------
Modifications:
- Mar 12, 2020 MSG
Added the wellType parameter to the auCdl siminfo so the model can change
accordingly
- Mar 17, 2020 MSG
added nf to cdl netlisting to spit out as segments
- Mar 23, 2020 MSG
Fixed lvs model on placement
- Mar 26, 2020 MSG
Added option to turn on/off metal1 connections
- Jun 27, 2020 MSG
Changed hvi layer to thkox to accomodate change in PDK
- Sep 06, 2020 MSG
Moved let statements to inside pcell def
Adjusted pin labels so they weren't huge and rotated them
Fixed bug with one of the align commands
==============================================================================*/
/*==============================================================================
This file only needs to be loaded once to create the pcells and cdf information
for the hrResDevices set within the S130techData.il file
==============================================================================*/
let( ( libName )
libName = "S130"
foreach( device hrResDevices
printf("Creating device %s in %s library\n" device->deviceName libName )
;===========================================================
;***** Define Layout Pcell *****
;===========================================================
pcDefinePCell( list( ddGetObj(libName) device->deviceName "layout" )
; formal parameters name value pairs
(
( devInfo "ilList" device )
( rules "ilList" designRules )
( grid "float" techGetMfgGridResolution(techGetTechFile(ddGetObj(libName))) )
( rCalcMethod "string" "Resistance" ) ;; values are "Resistance", "Length"
( rType "string" "Series" ) ;; values are "Series", "Parallel", "Serpentine"
( res "string" sprintf(nil "%.3f" device->defRes ))
( segW "string" sprintf(nil "%.3f" device->defW ))
( segL "string" sprintf(nil "%.3f" device->defL ))
( segments "int" 1 )
( segmentSP "string" sprintf( nil "%.3f" device->defSegSP ))
( wellType "string" "Pwell" ) ;; values are "Pwell" or "Nwell"
( vType "string" "1.8V") ;; values are "1.8V", "5V", "12V", "20V"
( contRows "int" 1 )
( metCont "boolean" t)
( tapTop "boolean" nil)
( tapTopCnt "boolean" t)
( tapBottom "boolean" nil)
( tapBottomCnt "boolean" t)
( tapRight "boolean" nil)
( tapRightCnt "boolean" t)
( tapLeft "boolean" t)
( tapLeftCnt "boolean" t)
; informational for user
( sheetRho "string" sprintf(nil "%.3f" device->sheetRho ))
( segRes "string" sprintf(nil "%.5f" device->defSegRes ))
( headRes "string" sprintf(nil "%.5f" device->defHeadRes ))
)
let(( allPresShapes botHead botHeadLi1 botHeadLicon1 botHeadMcon botHeadMet1 cv
headL headLi1L headLi1W headLicon1Xadj headLicon1Yadj headLicon1sTotalL
headLicon1sTotalW headMconXadj headMconYadj headMconsTotalL headMconsTotalW
headMet1L headMet1W headW headXadj headYadj hvi hviBbox imp1L imp1OLresL
imp1OLresW imp1W imp2L imp2OLresL imp2OLresW imp2W imp3L imp3OLresL imp3OLresW
imp3W lppShapes minLi1L minLi1W minMet1L minMet1W numXHeadLicon1s numXHeadMcons
numYHeadMcons nwell nwellBot nwellLft nwellRht nwellTop pinAdj presBotEdge presLftEdge
presRhtEdge presTopEdge resBody resImp1 resImp1Adjtb resImp1Adjlr resImp1Shape resImp2
resImp3 resMark resMinContW resTotalL resTotalW segmentL segmentW
tapBotAdjL tapBotAdjR tapBotEncPath tapBotL tapBotPath tapBotSubRect tapEncPath
tapEncPathWithCnt tapImp tapImpOLtap tapLftAdjB tapLftAdjT tapLftEncPath tapLftL tapLftPath
tapLftSubRect tapMetOLcont tapOLcont tapRhtAdjB tapRhtAdjT tapRhtEncPath tapRhtL tapRhtPath
tapRhtSubRect taptbSPres taplrSPres tapSubRect tapSubRectWithCnt tapTopAdjL tapTopAdjR tapTopEncPath
tapTopL tapTopPath tapTopSubRect tapW temp topHead topHeadLi1 topHeadLicon1 topHeadMcon
topHeadMet1 uhvi uhviBbox vhvi vhviBbox )
cv = pcCellView
segmentW = cdfParseFloatString(segW)
segmentL = cdfParseFloatString(segL)
segmentSP = cdfParseFloatString(segmentSP)
headL = rules->pres->contL + rules->pres->polyOLScont +
(contRows - 1)*(rules->pres->contL + rules->pres->contSP)
when( rType == "Serpentine" && segments > 1
segmentL = segmentL-2*headL
); when Serpentine
; create the segments
for( segment 1 segments
resBody = rodCreateRect(
?cvId cv
?name sprintf( nil "res%d" segment )
?layer devInfo->resLay
?width segmentW
?length segmentL
?origin (segment-1)*(segmentW + segmentSP) : 0
)
resMark = rodCreateRect(
?cvId cv
?layer devInfo->mrk1Lay
?bBox list( resBody->lowerLeft resBody->upperRight )
?origin (segment-1)*(segmentW + segmentSP) : 0
)
); end for 1 to segments
; create Headers
resMinContW = rules->pres->contW + 2*rules->pres->polyOLLcont
; figure out how many and how wide/long all the licon1s will be for fillRect later
headXadj = 0.0
headYadj = 0.0
; dogbone check and adjustments, & get headLicon numbers needed
if( segmentW < resMinContW then
headW = resMinContW
; needed to move the serpentine heads over
; parallel and series the segment spacing will be adjusted in the cdf
when( rType == "Serpentine" && segments > 1
headXadj = resMinContW - segmentW
); end when serpentine
headYadj = rules->pres->polyOLScont
headL = headL + headYadj
numXHeadLicon1s = 1
headLicon1sTotalW = rules->pres->contW
headLicon1sTotalL = rules->pres->contL + (contRows - 1)*(rules->pres->contL +
rules->pres->contSP)
else
headW = segmentW
numXHeadLicon1s = 1 + floor( (segmentW - 2*rules->pres->polyOLLcont -
rules->pres->contW)/(rules->pres->contW + rules->pres->contSP))
headLicon1sTotalW = rules->pres->contW + (numXHeadLicon1s-1)*(rules->pres->contW +
rules->pres->contSP)
; ensure the licon1 to licon1 on different segments don't cause a violation, if so, reduce the number of
; licon1s by 1
when( segments > 1 &&
segmentSP+(segmentW-headLicon1sTotalW) < rules->licon1->minSPslot &&
numXHeadLicon1s > 1
numXHeadLicon1s = numXHeadLicon1s - 1
headLicon1sTotalW = rules->pres->contW + (numXHeadLicon1s-1)*(rules->pres->contW +
rules->pres->contSP)
); end when
headLicon1sTotalL = rules->pres->contL + (contRows-1)*(rules->pres->contL +
rules->pres->contSP)
); end if segmentW < room for one contact
; need to make sure we have some minimums to check against
minLi1W = 2*max(rules->li1->minOLLlicon1 rules->li1->minOLLmcon) + rules->pres->contW
minLi1L = 2*max(rules->li1->minOLSlicon1 rules->li1->minOLSmcon) + rules->pres->contL
minMet1W = 2*rules->met1->minOLLmcon + rules->pres->contW
minMet1L = 2*rules->met1->minOLSmcon + rules->pres->contL
; li1 width and length
headLi1W = max(minLi1W,2*max(rules->li1->minOLLlicon1,rules->li1->minOLLmcon) +
headLicon1sTotalW)
headLi1L = max(minLi1L,2*max(rules->li1->minOLSlicon1,rules->li1->minOLSmcon) +
headLicon1sTotalL)
headLicon1Xadj = 0.5*(headLi1W - headLicon1sTotalW)
headLicon1Yadj = 0.5*(headLi1L - headLicon1sTotalL)
; figure out how many and how wide/long all the mcons will be for fillRect later
if( numXHeadLicon1s == 1 then
numXHeadMcons = 1
else
numXHeadMcons = 1 + floor( (headLi1W - 2*rules->li1->minOLLmcon - rules->mcon->minW)/
(rules->mcon->minW + rules->mcon->minSP) )
); end if numXHeadLicon1s
numYHeadMcons = 1 + floor( (headLi1L - 2*rules->li1->minOLSmcon - rules->mcon->minW)/
(rules->mcon->minW + rules->mcon->minSP) )
headMconsTotalW = rules->mcon->minW + (numXHeadMcons-1)*(rules->mcon->minW +
rules->mcon->minSP)
headMconsTotalL = rules->mcon->minW + (numYHeadMcons-1)*(rules->mcon->minW +
rules->mcon->minSP)
; met1 width and length
headMet1W = headMconsTotalW + 2*rules->met1->minOLLmcon
headMet1L = headMconsTotalL + 2*rules->met1->minOLSmcon
headMconXadj = 0.5*(headMet1W - headMconsTotalW)
headMconYadj = 0.5*(headMet1L - headMconsTotalL)
for( segment 1 segments
; bottom headers
botHead = rodCreateRect(
?cvId cv
?name sprintf( nil "botHead%d" segment )
?layer devInfo->resLay
?width if( rType != "Serpentine" then
headW
else
if( segment == 1 || (evenp(segments) && segment == segments) then
headW
else
segmentW
)
)
?length headL
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "botHead%d" segment ) cv )
?alignHandle if( (segment == 1 || segment == segments) && rType == "Serpentine" && segments > 1 then
if( segment == 1 then "upperRight" else "upperLeft" )
else "upperCenter" )
?refObj rodGetObj( sprintf( nil "res%d" segment ) cv )
?refHandle if( (segment == 1 || segment == segments) && rType == "Serpentine" && segments > 1 then
if( segment == 1 then "lowerRight" else "lowerLeft" )
else "lowerCenter" )
?ySep headYadj
)
; top headers
topHead = rodCreateRect(
?cvId cv
?name sprintf( nil "topHead%d" segment )
?layer devInfo->resLay
?width if( rType != "Serpentine" then
headW
else
if( oddp(segments) && segment == segments then headW else segmentW )
)
?length headL
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "topHead%d" segment ) cv )
?alignHandle if( oddp(segments) && segment == segments && rType == "Serpentine" && segments > 1 then
"lowerLeft"
else
"lowerCenter"
)
?refObj rodGetObj( sprintf( nil "res%d" segment ) cv )
?refHandle if( oddp(segments) && segment == segments && rType == "Serpentine" && segments > 1 then
"upperLeft"
else
"upperCenter"
)
?ySep -headYadj
)
; for types other than Serpentine, we'll need contacts and metal on all headers
if( rType != "Serpentine" then
; bottom headers metal and contacts
; could add a contact on/off option here
botHeadLi1 = rodCreateRect(
?cvId cv
?name sprintf( nil "botHeadLi1%d" segment )
?layer rules->li1->layer
?width headLi1W
?length headLi1L
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "botHeadLi1%d" segment ) cv )
?alignHandle "upperCenter"
?refObj rodGetObj( sprintf( nil "botHead%d" segment ) cv )
?refHandle "upperCenter"
?ySep max(rules->li1->minOLSlicon1,rules->li1->minOLSmcon)-headYadj
)
botHeadLicon1 = rodFillBBoxWithRects(
?cvId cv
?layer rules->licon1->layer
?fillBBox list(
rodAddToY(rodAddToX(botHeadLi1->lowerLeft headLicon1Xadj) headLicon1Yadj)
rodAddToY(rodAddToX(botHeadLi1->upperRight -headLicon1Xadj) -headLicon1Yadj)
)
?width rules->pres->contW
?length rules->pres->contL
?gap "minimum"
?spaceX rules->pres->contSP
?spaceY rules->pres->contSP
)
when( metCont
botHeadMet1 = rodCreateRect(
?cvId cv
?name sprintf( nil "botHeadMet1%d" segment )
?layer rules->met1->layer
?width headMet1W
?length headMet1L
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "botHeadMet1%d" segment ) cv )
?alignHandle "centerCenter"
?refObj rodGetObj( sprintf( nil "botHeadLi1%d" segment ) cv )
?refHandle "centerCenter"
)
botHeadMcon = rodFillBBoxWithRects(
?cvId cv
?layer rules->mcon->layer
?fillBBox list(
rodAddToY(rodAddToX(botHeadMet1->lowerLeft headMconXadj) headMconYadj)
rodAddToY(rodAddToX(botHeadMet1->upperRight -headMconXadj) -headMconYadj)
)
?width rules->mcon->minW
?length rules->mcon->minW
?gap "minimum"
?spaceX rules->mcon->minSP
?spaceY rules->mcon->minSP
)
); when metCont
; top headers metal and contacts
topHeadLi1 = rodCreateRect(
?cvId cv
?name sprintf( nil "topHeadLi1%d" segment )
?layer rules->li1->layer
?width headLi1W
?length headLi1L
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "topHeadLi1%d" segment ) cv )
?alignHandle "lowerCenter"
?refObj rodGetObj( sprintf( nil "topHead%d" segment ) cv )
?refHandle "lowerCenter"
?ySep -max(rules->li1->minOLSlicon1,rules->li1->minOLSmcon)+headYadj
)
topHeadLicon1 = rodFillBBoxWithRects(
?cvId cv
?layer rules->licon1->layer
?fillBBox list(
rodAddToY(rodAddToX(topHeadLi1->lowerLeft headLicon1Xadj) headLicon1Yadj)
rodAddToY(rodAddToX(topHeadLi1->upperRight -headLicon1Xadj) -headLicon1Yadj)
)
?width rules->pres->contW
?length rules->pres->contL
?gap "minimum"
?spaceX rules->pres->contSP
?spaceY rules->pres->contSP
)
when( metCont
topHeadMet1 = rodCreateRect(
?cvId cv
?name sprintf( nil "topHeadMet1%d" segment )
?layer rules->met1->layer
?width headMet1W
?length headMet1L
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "topHeadMet1%d" segment ) cv )
?alignHandle "centerCenter"
?refObj rodGetObj( sprintf( nil "topHeadLi1%d" segment ) cv )
?refHandle "centerCenter"
)
topHeadMcon = rodFillBBoxWithRects(
?cvId cv
?layer rules->mcon->layer
?fillBBox list(
rodAddToY(rodAddToX(topHeadMet1->lowerLeft headMconXadj) headMconYadj)
rodAddToY(rodAddToX(topHeadMet1->upperRight -headMconXadj) -headMconYadj)
)
?width rules->mcon->minW
?length rules->mcon->minW
?gap "minimum"
?spaceX rules->mcon->minSP
?spaceY rules->mcon->minSP
)
); when metCont
else
when( segment == 1
botHeadLi1 = rodCreateRect(
?cvId cv
?name sprintf( nil "botHeadLi1%d" segment )
?layer rules->li1->layer
?width headLi1W
?length headLi1L
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "botHeadLi1%d" segment ) cv )
?alignHandle "upperCenter"
?refObj rodGetObj( sprintf( nil "botHead%d" segment ) cv )
?refHandle "upperCenter"
?ySep max(rules->li1->minOLSlicon1,rules->li1->minOLSmcon)-headYadj
)
botHeadLicon1 = rodFillBBoxWithRects(
?cvId cv
?layer rules->licon1->layer
?fillBBox list(
rodAddToY(rodAddToX(botHeadLi1->lowerLeft headLicon1Xadj) headLicon1Yadj)
rodAddToY(rodAddToX(botHeadLi1->upperRight -headLicon1Xadj) -headLicon1Yadj)
)
?width rules->pres->contW
?length rules->pres->contL
?gap "minimum"
?spaceX rules->pres->contSP
?spaceY rules->pres->contSP
)
when( metCont
botHeadMet1 = rodCreateRect(
?cvId cv
?name sprintf( nil "botHeadMet1%d" segment )
?layer rules->met1->layer
?width headMet1W
?length headMet1L
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "botHeadMet1%d" segment ) cv )
?alignHandle "centerCenter"
?refObj rodGetObj( sprintf( nil "botHeadLi1%d" segment ) cv )
?refHandle "centerCenter"
)
botHeadMcon = rodFillBBoxWithRects(
?cvId cv
?layer rules->mcon->layer
?fillBBox list(
rodAddToY(rodAddToX(botHeadMet1->lowerLeft headMconXadj) headMconYadj)
rodAddToY(rodAddToX(botHeadMet1->upperRight -headMconXadj) -headMconYadj)
)
?width rules->mcon->minW
?length rules->mcon->minW
?gap "minimum"
?spaceX rules->mcon->minSP
?spaceY rules->mcon->minSP
)
); when metCont
); end when
when( segment == segments
if( oddp(segments) then
topHeadLi1 = rodCreateRect(
?cvId cv
?name sprintf( nil "topHeadLi1%d" segment )
?layer rules->li1->layer
?width headLi1W
?length headLi1L
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "topHeadLi1%d" segment ) cv )
?alignHandle "lowerCenter"
?refObj rodGetObj( sprintf( nil "topHead%d" segment ) cv )
?refHandle "lowerCenter"
?ySep -max(rules->li1->minOLSlicon1,rules->li1->minOLSmcon)+headYadj
)
topHeadLicon1 = rodFillBBoxWithRects(
?cvId cv
?layer rules->licon1->layer
?fillBBox list(
rodAddToY(rodAddToX(topHeadLi1->lowerLeft headLicon1Xadj) headLicon1Yadj)
rodAddToY(rodAddToX(topHeadLi1->upperRight -headLicon1Xadj) -headLicon1Yadj)
)
?width rules->pres->contW
?length rules->pres->contL
?gap "minimum"
?spaceX rules->pres->contSP
?spaceY rules->pres->contSP
)
when( metCont
topHeadMet1 = rodCreateRect(
?cvId cv
?name sprintf( nil "topHeadMet1%d" segment )
?layer rules->met1->layer
?width headMet1W
?length headMet1L
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "topHeadMet1%d" segment ) cv )
?alignHandle "centerCenter"
?refObj rodGetObj( sprintf( nil "topHeadLi1%d" segment ) cv )
?refHandle "centerCenter"
)
topHeadMcon = rodFillBBoxWithRects(
?cvId cv
?layer rules->mcon->layer
?fillBBox list(
rodAddToY(rodAddToX(topHeadMet1->lowerLeft headMconXadj) headMconYadj)
rodAddToY(rodAddToX(topHeadMet1->upperRight -headMconXadj) -headMconYadj)
)
?width rules->mcon->minW
?length rules->mcon->minW
?gap "minimum"
?spaceX rules->mcon->minSP
?spaceY rules->mcon->minSP
)
); when metCont
else
botHeadLi1 = rodCreateRect(
?cvId cv
?name sprintf( nil "botHeadLi1%d" segment )
?layer rules->li1->layer
?width headLi1W
?length headLi1L
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "botHeadLi1%d" segment ) cv )
?alignHandle "upperCenter"
?refObj rodGetObj( sprintf( nil "botHead%d" segment ) cv )
?refHandle "upperCenter"
?ySep max(rules->li1->minOLSlicon1,rules->li1->minOLSmcon)-headYadj
)
botHeadLicon1 = rodFillBBoxWithRects(
?cvId cv
?layer rules->licon1->layer
?fillBBox list(
rodAddToY(rodAddToX(botHeadLi1->lowerLeft headLicon1Xadj) headLicon1Yadj)
rodAddToY(rodAddToX(botHeadLi1->upperRight -headLicon1Xadj) -headLicon1Yadj)
)
?width rules->pres->contW
?length rules->pres->contL
?gap "minimum"
?spaceX rules->pres->contSP
?spaceY rules->pres->contSP
)
when( metCont
botHeadMet1 = rodCreateRect(
?cvId cv
?name sprintf( nil "botHeadMet1%d" segment )
?layer rules->met1->layer
?width headMet1W
?length headMet1L
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "botHeadMet1%d" segment ) cv )
?alignHandle "centerCenter"
?refObj rodGetObj( sprintf( nil "botHeadLi1%d" segment ) cv )
?refHandle "centerCenter"
)
botHeadMcon = rodFillBBoxWithRects(
?cvId cv
?layer rules->mcon->layer
?fillBBox list(
rodAddToY(rodAddToX(botHeadMet1->lowerLeft headMconXadj) headMconYadj)
rodAddToY(rodAddToX(botHeadMet1->upperRight -headMconXadj) -headMconYadj)
)
?width rules->mcon->minW
?length rules->mcon->minW
?gap "minimum"
?spaceX rules->mcon->minSP
?spaceY rules->mcon->minSP
)
); when metCont
); end if semgments are odd
); end when last segment
); end if rType == "Serpentine"
); end for 1 to segments
; Time to connect the segments based on the rType
; no connections needed if there is only one segment
when( segments > 1
case( rType
("Series"
for( segment 1 segments-1
if( oddp(segment) then
rodCreateRect(
?cvId cv
?name sprintf( nil "connectLi1Top%d" segment )
?layer rules->li1->layer
?bBox list(
rodGetObj(sprintf(nil "topHeadLi1%d" segment) cv)->lowerLeft
rodGetObj( sprintf(nil "topHeadLi1%d" segment+1) cv)->upperRight
)
)
when( metCont
rodCreateRect(
?cvId cv
?name sprintf( nil "connectMet1Top%d" segment )
?layer rules->met1->layer
?bBox list(
rodGetObj(sprintf(nil "topHeadMet1%d" segment) cv)->lowerLeft
rodGetObj( sprintf(nil "topHeadMet1%d" segment+1) cv)->upperRight
)
)
); when metCont
else ; even segment
rodCreateRect(
?cvId cv
?name sprintf( nil "connectLi1Bot%d" segment )
?layer rules->li1->layer
?bBox list(
rodGetObj(sprintf(nil "botHeadLi1%d" segment) cv)->lowerLeft
rodGetObj( sprintf(nil "botHeadLi1%d" segment+1) cv)->upperRight
)
)
when( metCont
rodCreateRect(
?cvId cv
?name sprintf( nil "connectMet1Bot%d" segment )
?layer rules->met1->layer
?bBox list(
rodGetObj(sprintf(nil "botHeadMet1%d" segment) cv)->lowerLeft
rodGetObj( sprintf(nil "botHeadMet1%d" segment+1) cv)->upperRight
)
)
); when metCont
); end if segment is odd
); end for 1 to segments-1
); end case "Series"
("Parallel"
rodCreateRect(
?cvId cv
?name "connectLi1Bot1"
?layer rules->li1->layer
?bBox list(
rodGetObj("botHeadLi11" cv)->lowerLeft
rodGetObj( sprintf(nil "botHeadLi1%d" segments) cv)->upperRight
)
)
when( metCont
rodCreateRect(
?cvId cv
?name "connectMet1Bot1"
?layer rules->met1->layer
?bBox list(
rodGetObj("botHeadMet11" cv)->lowerLeft
rodGetObj( sprintf(nil "botHeadMet1%d" segments) cv)->upperRight
)
)
); when metCont
rodCreateRect(
?cvId cv
?name "connectLi1Top1"
?layer rules->li1->layer
?bBox list(
rodGetObj("topHeadLi11" cv)->lowerLeft
rodGetObj( sprintf(nil "topHeadLi1%d" segments) cv)->upperRight
)
)
when( metCont
rodCreateRect(
?cvId cv
?name "connectMet1Top1"
?layer rules->met1->layer
?bBox list(
rodGetObj("topHeadMet11" cv)->lowerLeft
rodGetObj( sprintf(nil "topHeadMet1%d" segments) cv)->upperRight
)
)
); when metCont
); end case "Parallel"
("Serpentine"
for( segment 1 segments-1
if( oddp(segment) then
rodCreateRect(
?cvId cv
?name sprintf( nil "connectPolyTop%d" segment )
?layer devInfo->resLay
?width 2*segmentW + segmentSP
?length segmentW
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "connectPolyTop%d" segment ) cv )
?alignHandle "upperRight"
?refObj rodGetObj( sprintf( nil "topHead%d" segment+1 ) cv )
?refHandle "upperRight"
)
rodCreateRect(
?cvId cv
?name sprintf( nil "connectResIdTop%d" segment )
?layer devInfo->mrk1Lay
?width 2*devInfo->mrk1OLres + rodGetObj( sprintf( nil "connectPolyTop%d" segment ) cv )->width
?length 2*devInfo->mrk1OLres + rodGetObj( sprintf( nil "connectPolyTop%d" segment ) cv )->length
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "connectResIdTop%d" segment ) cv )
?alignHandle "lowerLeft"
?refObj rodGetObj( sprintf( nil "connectPolyTop%d" segment ) cv )
?refHandle "lowerLeft"
?xSep -devInfo->mrk1OLres
?ySep -devInfo->mrk1OLres
)
rodCreateRect(
?cvId cv
?name sprintf( nil "connectResIdTopHead%d" segment )
?layer devInfo->mrk1Lay
?width 2*devInfo->mrk1OLres + rodGetObj( sprintf( nil "topHead%d" segment ) cv )->width
?length 2*devInfo->mrk1OLres + rodGetObj( sprintf( nil "topHead%d" segment ) cv )->length
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "connectResIdTopHead%d" segment ) cv )
?alignHandle "lowerLeft"
?refObj rodGetObj( sprintf( nil "topHead%d" segment ) cv )
?refHandle "lowerLeft"
?xSep -devInfo->mrk1OLres
?ySep -devInfo->mrk1OLres
)
rodCreateRect(
?cvId cv
?name sprintf( nil "connectResIdTopHead%d" segment+1 )
?layer devInfo->mrk1Lay
?width 2*devInfo->mrk1OLres + rodGetObj( sprintf( nil "topHead%d" segment+1 ) cv )->width
?length 2*devInfo->mrk1OLres + rodGetObj( sprintf( nil "topHead%d" segment+1 ) cv )->length
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "connectResIdTopHead%d" segment+1 ) cv )
?alignHandle "lowerLeft"
?refObj rodGetObj( sprintf( nil "topHead%d" segment+1 ) cv )
?refHandle "lowerLeft"
?xSep -devInfo->mrk1OLres
?ySep -devInfo->mrk1OLres
)
else ; even segment
rodCreateRect(
?cvId cv
?name sprintf( nil "connectPolyBot%d" segment )
?layer devInfo->resLay
?width 2*segmentW + segmentSP
?length segmentW
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "connectPolyBot%d" segment ) cv )
?alignHandle "lowerLeft"
?refObj rodGetObj( sprintf( nil "botHead%d" segment ) cv )
?refHandle "lowerLeft"
)
rodCreateRect(
?cvId cv
?name sprintf( nil "connectResIdBot%d" segment )
?layer devInfo->mrk1Lay
?width 2*devInfo->mrk1OLres + rodGetObj( sprintf( nil "connectPolyBot%d" segment ) cv )->width
?length 2*devInfo->mrk1OLres + rodGetObj( sprintf( nil "connectPolyBot%d" segment ) cv )->length
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "connectResIdBot%d" segment ) cv )
?alignHandle "lowerLeft"
?refObj rodGetObj( sprintf( nil "connectPolyBot%d" segment ) cv )
?refHandle "lowerLeft"
?xSep -devInfo->mrk1OLres
?ySep -devInfo->mrk1OLres
)
rodCreateRect(
?cvId cv
?name sprintf( nil "connectResIdBotHead%d" segment )
?layer devInfo->mrk1Lay
?width 2*devInfo->mrk1OLres + rodGetObj( sprintf( nil "botHead%d" segment ) cv )->width
?length 2*devInfo->mrk1OLres + rodGetObj( sprintf( nil "botHead%d" segment ) cv )->length
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "connectResIdBotHead%d" segment ) cv )
?alignHandle "lowerLeft"
?refObj rodGetObj( sprintf( nil "botHead%d" segment ) cv )
?refHandle "lowerLeft"
?xSep -devInfo->mrk1OLres
?ySep -devInfo->mrk1OLres
)
rodCreateRect(
?cvId cv
?name sprintf( nil "connectResIdBotHead%d" segment+1 )
?layer devInfo->mrk1Lay
?width 2*devInfo->mrk1OLres + rodGetObj( sprintf( nil "botHead%d" segment+1 ) cv )->width
?length 2*devInfo->mrk1OLres + rodGetObj( sprintf( nil "botHead%d" segment+1 ) cv )->length
)
rodAlign(
?alignObj rodGetObj( sprintf( nil "connectResIdBotHead%d" segment+1 ) cv )
?alignHandle "lowerLeft"
?refObj rodGetObj( sprintf( nil "botHead%d" segment+1 ) cv )
?refHandle "lowerLeft"
?xSep -devInfo->mrk1OLres
?ySep -devInfo->mrk1OLres
)
); end if segment is odd
); end for 1 to segments-1
); end case "Serpentine"
); end case
); end when segments > 1
; Make the pins
if( rType == "Parallel" && segments > 1 then
if( metCont then
rodCreateRect(
?cvId cv
?name "plusPin"
?layer list( rules->met1->pinlayer rules->met1->pinpurpose )
?bBox list( rodGetObj( "connectMet1Bot1" cv )->lowerLeft rodGetObj( "connectMet1Bot1" cv )->upperRight )
?netName "PLUS"
?termName "PLUS"
?termIOType "inputOutput"
?pin t
?pinLabel t
?pinLabelHeight 0.3
?pinLabelOrient "R90"
?pinLabelLayer list( rules->met1->layer "label")
?pinLabelFont "stick"
)
rodCreateRect(
?cvId cv
?name "minusPin"
?layer list( rules->met1->pinlayer rules->met1->pinpurpose )
?bBox list( rodGetObj( "connectMet1Top1" cv )->lowerLeft rodGetObj( "connectMet1Top1" cv )->upperRight )
?netName "MINUS"
?termName "MINUS"
?termIOType "inputOutput"
?pin t
?pinLabel t
?pinLabelHeight 0.3
?pinLabelOrient "R90"
?pinLabelLayer list( rules->met1->layer "label")
?pinLabelFont "stick"
)
else
rodCreateRect(
?cvId cv
?name "plusPin"
?layer list( rules->li1->pinlayer rules->li1->pinpurpose )
?bBox list( rodGetObj( "connectLi1Bot1" cv )->lowerLeft rodGetObj( "connectLi1Bot1" cv )->upperRight )
?netName "PLUS"
?termName "PLUS"
?termIOType "inputOutput"
?pin t
?pinLabel t
?pinLabelHeight 0.3
?pinLabelOrient "R90"
?pinLabelLayer list( rules->li1->layer "label")
?pinLabelFont "stick"
)
rodCreateRect(
?cvId cv
?name "minusPin"
?layer list( rules->li1->pinlayer rules->li1->pinpurpose )
?bBox list( rodGetObj( "connectLi1Top1" cv )->lowerLeft rodGetObj( "connectLi1Top1" cv )->upperRight )
?netName "MINUS"
?termName "MINUS"
?termIOType "inputOutput"
?pin t
?pinLabel t
?pinLabelHeight 0.3
?pinLabelOrient "R90"
?pinLabelLayer list( rules->li1->layer "label")
?pinLabelFont "stick"
)
); if metCont
else
if( metCont then
rodCreateRect(
?cvId cv
?name "plusPin"
?layer list( rules->met1->pinlayer rules->met1->pinpurpose )
?bBox list( rodGetObj( "botHeadMet11" cv )->lowerLeft rodGetObj( "botHeadMet11" cv )->upperRight )
?netName "PLUS"
?termName "PLUS"
?termIOType "inputOutput"
?pin t
?pinLabel t
?pinLabelHeight 0.3
?pinLabelOrient "R90"
?pinLabelLayer list( rules->met1->layer "label")
?pinLabelFont "stick"
)
rodCreateRect(
?cvId cv
?name "minusPin"
?layer list( rules->met1->pinlayer rules->met1->pinpurpose )
?bBox if( oddp(segments) then
list( rodGetObj( sprintf( nil "topHeadMet1%d" segments) cv )->lowerLeft
rodGetObj( sprintf( nil "topHeadMet1%d" segments) cv )->upperRight )
else
list( rodGetObj( sprintf( nil "botHeadMet1%d" segments) cv )->lowerLeft
rodGetObj( sprintf( nil "botHeadMet1%d" segments) cv )->upperRight )
)
?netName "MINUS"
?termName "MINUS"
?termIOType "inputOutput"
?pin t
?pinLabel t
?pinLabelHeight 0.3
?pinLabelOrient "R90"
?pinLabelLayer list( rules->met1->layer "label")
?pinLabelFont "stick"
)
else
rodCreateRect(
?cvId cv
?name "plusPin"
?layer list( rules->li1->pinlayer rules->li1->pinpurpose )
?bBox list( rodGetObj( "botHeadLi11" cv )->lowerLeft rodGetObj( "botHeadLi11" cv )->upperRight )
?netName "PLUS"
?termName "PLUS"
?termIOType "inputOutput"
?pin t
?pinLabel t
?pinLabelHeight 0.3
?pinLabelOrient "R90"
?pinLabelLayer list( rules->li1->layer "label")
?pinLabelFont "stick"
)
rodCreateRect(
?cvId cv
?name "minusPin"
?layer list( rules->li1->pinlayer rules->li1->pinpurpose )
?bBox if( oddp(segments) then
list( rodGetObj( sprintf( nil "topHeadLi1%d" segments) cv )->lowerLeft
rodGetObj( sprintf( nil "topHeadLi1%d" segments) cv )->upperRight )
else
list( rodGetObj( sprintf( nil "botHeadLi1%d" segments) cv )->lowerLeft
rodGetObj( sprintf( nil "botHeadLi1%d" segments) cv )->upperRight )
)
?netName "MINUS"
?termName "MINUS"
?termIOType "inputOutput"
?pin t
?pinLabel t
?pinLabelHeight 0.3
?pinLabelOrient "R90"
?pinLabelLayer list( rules->li1->layer "label")
?pinLabelFont "stick"
)
); if metCont
); end if rType = "Parallel"
; get the edges of the pres
allPresShapes = setof( shape cv->shapes shape->lpp == devInfo->resLay )
presTopEdge = topEdge( car(allPresShapes)->bBox )
presLftEdge = leftEdge( car(allPresShapes)->bBox )
presBotEdge = bottomEdge( car(allPresShapes)->bBox )
presRhtEdge = rightEdge( car(allPresShapes)->bBox )
foreach( presShape allPresShapes
presTopEdge = max(presTopEdge topEdge( presShape->bBox ))
presLftEdge = min(presLftEdge leftEdge( presShape->bBox ))
presBotEdge = min(presBotEdge bottomEdge( presShape->bBox ))
presRhtEdge = max(presRhtEdge rightEdge( presShape->bBox ))
); foreach presShape
resTotalW = presRhtEdge - presLftEdge
resTotalL = presTopEdge - presBotEdge
when( devInfo->imp1Lay
; need to insure the implant is > min width of implant
if( devInfo->imp1MinW > 2*devInfo->imp1OLres + resTotalW then
imp1W = devInfo->imp1MinW
imp1OLresW = 0.5*(devInfo->imp1MinW - resTotalW)
else
imp1W = 2*devInfo->imp1OLres + resTotalW
imp1OLresW = devInfo->imp1OLres
); end if imp1MinW > resTotalW + 2* imp1OLres
if( devInfo->imp1MinW > 2*devInfo->imp1OLres + resTotalL then
imp1L = devInfo->imp1MinW
imp1OLresL = 0.5*(devInfo->imp1MinW - resTotalL)
else
imp1L = 2*devInfo->imp1OLres + resTotalL
imp1OLresL = devInfo->imp1OLres
); end if imp1MinW > resTotalW + 2* imp1OLres
resImp1 = rodCreateRect(
?cvId cv
?name "resImp1"
?layer devInfo->imp1Lay
?width imp1W
?length imp1L
)
rodAlign(
?alignObj rodGetObj( "resImp1" cv )
?alignHandle "lowerLeft"
?refObj rodGetObj( "botHead1" cv )
?refHandle "lowerLeft"
?xSep -imp1OLresW
?ySep -imp1OLresL
)
; create body pin if no taps exist
unless( tapTop || tapLeft || tapBottom || tapRight
if( wellType == "Nwell" then
rodCreateRect(
?cvId cv
?name "wellPin"
?layer list( "nwell" "pin" )
?fromObj rodGetObj( "resImp1" cv )
?netName "B"
?termName "B"
?termIOType "inputOutput"
?pin t
?pinLabel t
?pinLabelHeight 0.3
?pinLabelLayer list( "nwell" "label")
?pinLabelFont "stick"
)
else
rodCreateRect(
?cvId cv
?name "wellPin"
?layer list( "pwell" "pin" )
?fromObj rodGetObj( "resImp1" cv )
?netName "B"
?termName "B"
?termIOType "inputOutput"
?pin t
?pinLabel t
?pinLabelHeight 0.3
?pinLabelLayer list( "pwell" "label")
?pinLabelFont "stick"
)
); if nwell
); unless any taps
); end when defInfo->imp1Lay
when( devInfo->imp2Lay
; need to insure the implant is > min width of implant
if( devInfo->imp2MinW > 2*devInfo->imp2OLres + resTotalW then
imp2W = devInfo->imp2MinW
imp2OLresW = 0.5*(devInfo->imp2MinW - resTotalW)
else
imp2W = 2*devInfo->imp2OLres + resTotalW
imp2OLresW = devInfo->imp2OLres
); end if imp2MinW > resTotalW + 2* imp2OLres
if( devInfo->imp2MinW > 2*devInfo->imp2OLres + resTotalL then
imp2L = devInfo->imp2MinW
imp2OLresL = 0.5*(devInfo->imp2MinW - resTotalL)
else
imp2L = 2*devInfo->imp2OLres + resTotalL
imp2OLresL = devInfo->imp2OLres
); end if imp2MinW > resTotalW + 2* imp2OLres
resImp2 = rodCreateRect(
?cvId cv
?name "resImp2"
?layer devInfo->imp2Lay
?width imp2W
?length imp2L
)
rodAlign(
?alignObj rodGetObj( "resImp2" cv )
?alignHandle "lowerLeft"
?refObj rodGetObj( "botHead1" cv )
?refHandle "lowerLeft"
?xSep -imp2OLresW
?ySep -imp2OLresL
)
); end when defInfo->imp2Lay
when( devInfo->imp3Lay
; need to insure the implant is > min width of implant
if( devInfo->imp3MinW > 2*devInfo->imp3OLres + resTotalW then
imp3W = devInfo->imp3MinW
imp3OLresW = 0.5*(imp3W - resTotalW)
else
imp3W = 2*devInfo->imp3OLres + resTotalW
imp3OLresW = devInfo->imp3OLres
); end if imp3MinW > resTotalW + 2* imp3OLres
if( devInfo->imp3MinW > 2*devInfo->imp3OLres + resTotalL then
imp3L = devInfo->imp3MinW
imp3OLresL = 0.5*(imp3L - resTotalL)
else
imp3L = 2*devInfo->imp3OLres + resTotalL
imp3OLresL = devInfo->imp3OLres
); end if imp3MinW > resTotalW + 2* imp3OLres
resImp3 = rodCreateRect(
?cvId cv
?name "resImp3"
?layer devInfo->imp3Lay
?width imp3W
?length imp3L
)
rodAlign(
?alignObj rodGetObj( "resImp3" cv )
?alignHandle "lowerLeft"
?refObj rodGetObj( "botHead1" cv )
?refHandle "lowerLeft"
?xSep -imp3OLresW
?ySep -imp3OLresL
)
); end when defInfo->imp3Lay
; Merge all the parts so it removes geometry lines
;leMergeShapes( cv~>shapes ) ; can't use this in pcells - breaks steaming
foreach( lpp cv~>lpps
lppShapes = lpp~>shapes
when( lppShapes && (car(lppShapes)->purpose == "drawing" || car(lppShapes)->purpose == "res" ||
car(lppShapes)->layerName == "areaid" )
dbLayerOr( cv car(lppShapes)->lpp lppShapes )
foreach(shape lppShapes dbDeleteObject(shape))
); end when lppShapes
); end foreach lpp
; create the taps
if( wellType == "Nwell" then
tapImp = rules->nsdm->layer
tapImpOLtap = rules->nsdm->minOLtap
taptbSPres = max( rules->poly->rpolyMinSPtap
devInfo->imp1OLres + rules->nsdm->minSPdiff
devInfo->imp2OLres + rules->licon1->taplicon1SPnpc - rules->tap->minOLSisoTapLicon1
imp3OLresL + devInfo->tapImpSPImp3 + rules->nsdm->minOLtap
)
taplrSPres = max( rules->poly->rpolyMinSPtap
devInfo->imp1OLres + rules->nsdm->minSPdiff
devInfo->imp2OLres + rules->licon1->taplicon1SPnpc - rules->tap->minOLSisoTapLicon1
imp3OLresW + devInfo->tapImpSPImp3 + rules->nsdm->minOLtap
)
else
tapImp = rules->psdm->layer
tapImpOLtap = rules->psdm->minOLtap
taptbSPres = max( rules->poly->rpolyMinSPtap
devInfo->imp2OLres + rules->licon1->taplicon1SPnpc - rules->tap->minOLSisoTapLicon1
)
taplrSPres = taptbSPres
); end if Nwell
; figure out the gap between psdm/nsdm to later adjust the res imp psdm to butt them
if( taptbSPres > devInfo->imp1OLres + tapImpOLtap then
resImp1Adjtb = taptbSPres - (devInfo->imp1OLres + tapImpOLtap)
else
resImp1Adjtb = 0.0
)
if( taplrSPres > devInfo->imp1OLres + tapImpOLtap then
resImp1Adjlr = taplrSPres - (devInfo->imp1OLres + tapImpOLtap)
else
resImp1Adjlr = 0.0
)
resImp1Shape = car( setof( shape cv~>shapes shape~>lpp == devInfo->imp1Lay ))
when( tapTop
resImp1Shape->bBox = list(
leftEdge(resImp1Shape):bottomEdge(resImp1Shape)
rightEdge(resImp1Shape):topEdge(resImp1Shape)+resImp1Adjtb
)
); end when tapTop
when( tapRight
resImp1Shape->bBox = list(
leftEdge(resImp1Shape):bottomEdge(resImp1Shape)
rightEdge(resImp1Shape)+resImp1Adjlr:topEdge(resImp1Shape)
)
); end when tapRight
when( tapBottom
resImp1Shape->bBox = list(
leftEdge(resImp1Shape):bottomEdge(resImp1Shape)-resImp1Adjtb
rightEdge(resImp1Shape):topEdge(resImp1Shape)
)
); end when tapBottom
when( tapLeft
resImp1Shape->bBox = list(
leftEdge(resImp1Shape)-resImp1Adjlr:bottomEdge(resImp1Shape)
rightEdge(resImp1Shape):topEdge(resImp1Shape)
)
); end when tapLeft
; best to go with max overlap contact so the corners will line up
tapOLcont = max(rules->tap->minOLLisoTapLicon1 rules->tap->minOLSisoTapLicon1)
tapMetOLcont = max(rules->li1->minOLLlicon1 rules->li1->minOLSlicon1)
tapW = max(rules->tap->minW 2*tapOLcont+rules->licon1->minW )
if( tapTop then tapRhtAdjT = tapLftAdjT = taptbSPres + tapW else tapRhtAdjT = tapLftAdjT = 0.0 )
if( tapLeft then tapTopAdjL = tapBotAdjL = taplrSPres + tapW else tapTopAdjL = tapBotAdjL = 0.0 )
if( tapBottom then tapRhtAdjB = tapLftAdjB = taptbSPres + tapW else tapRhtAdjB = tapLftAdjB = 0.0 )
if( tapRight then tapTopAdjR = tapBotAdjR = taplrSPres + tapW else tapTopAdjR = tapBotAdjR = 0.0 )
; make adjustments to top and bottom taps if their lengths are < tapW
when( tapW > presRhtEdge - presLftEdge
unless( tapLeft || tapRight
tapTopAdjL = tapBotAdjL = tapTopAdjR = tapBotAdjR = 0.5*(tapW-(presRhtEdge - presLftEdge))
)
); when
tapTopL = (presRhtEdge - presLftEdge) + tapTopAdjL + tapTopAdjR
tapLftL = (presTopEdge - presBotEdge) + tapLftAdjT + tapLftAdjB
tapBotL = (presRhtEdge - presLftEdge) + tapBotAdjL + tapBotAdjR
tapRhtL = (presTopEdge - presBotEdge) + tapRhtAdjT + tapRhtAdjB
tapEncPath = list( list( ?layer tapImp ?enclosure -tapImpOLtap ) )
tapSubRect = list( )
tapEncPathWithCnt = list(
?layer rules->li1->layer
?enclosure -(tapMetOLcont - tapOLcont)
)
tapSubRectWithCnt = list(
?layer rules->licon1->layer
?length rules->licon1->minW
?width rules->licon1->minW
?space rules->licon1->minSP
?endOffset -tapOLcont
?beginOffset -tapOLcont
)
; set well edges for later
; using tap OL for res OL since there is no rule and will work with taps added
nwellTop = presTopEdge + rules->nwell->minOLtap
nwellRht = presRhtEdge + rules->nwell->minOLtap
nwellBot = presBotEdge - rules->nwell->minOLtap
nwellLft = presLftEdge - rules->nwell->minOLtap
when( tapW > presRhtEdge - presLftEdge
unless( tapLeft || tapRight
nwellRht = nwellRht + 0.5*(tapW-(presRhtEdge - presLftEdge))
nwellLft = nwellLft - 0.5*(tapW-(presRhtEdge - presLftEdge))
)
); when
; create top tap
if( tapTop then
if( tapTopCnt then
tapTopEncPath = append1( tapEncPath tapEncPathWithCnt )
tapTopSubRect = append1( tapSubRect tapSubRectWithCnt )
else
tapTopEncPath = tapEncPath
tapTopSubRect = tapSubRect
); end when tapTopCnt
tapTopPath = rodCreatePath(
?cvId cv
?name "tapTopPath"
?layer rules->tap->layer
?width tapW
?pts list(
presLftEdge-tapTopAdjL : presTopEdge+taptbSPres+0.5*tapW
presRhtEdge+tapTopAdjR : presTopEdge+taptbSPres+0.5*tapW
)
?netName "B"
?termName "B"
?termIOType "inputOutput"
?pin t
?encSubPath tapTopEncPath
?subRect tapTopSubRect
); end rodCreatePath tapTopPath
; create pin
when( tapTopCnt
pinAdj = tapMetOLcont - tapOLcont
rodCreateRect(
?cvId cv
?name "tapTopPin"
?layer list( rules->li1->pinlayer rules->li1->pinpurpose )
?bBox list(
rodAddToY(rodAddToX(tapTopPath->lowerLeft -pinAdj) -pinAdj)
rodAddToY(rodAddToX(tapTopPath->upperRight pinAdj) pinAdj)
)
?netName "B"
?termName "B"
?termIOType "inputOutput"
?pin t
?pinLabel t
?pinLabelHeight tapTopPath->length
?pinLabelLayer list( rules->li1->layer "label")
?pinLabelFont "stick"
)
)
nwellTop = nwellTop + taptbSPres + tapW
); end if tapTop
; create right tap
if( tapRight then
if( tapRightCnt then
tapRhtEncPath = append1( tapEncPath tapEncPathWithCnt )
tapRhtSubRect = append1( tapSubRect tapSubRectWithCnt )
else
tapRhtEncPath = tapEncPath
tapRhtSubRect = tapSubRect
); end when tapRightCnt
tapRhtPath = rodCreatePath(
?cvId cv
?name "tapRhtPath"
?layer rules->tap->layer
?width tapW
?pts list(
presRhtEdge+taplrSPres+0.5*tapW : presBotEdge-tapRhtAdjB
presRhtEdge+taplrSPres+0.5*tapW : presTopEdge+tapRhtAdjT
)
?netName "B"
?termName "B"
?termIOType "inputOutput"
?pin t
?encSubPath tapRhtEncPath
?subRect tapRhtSubRect
); end rodCreatePath tapRhtPath
when( tapRightCnt
pinAdj = tapMetOLcont - tapOLcont
rodCreateRect(
?cvId cv
?name "tapRhtPin"
?layer list( rules->li1->pinlayer rules->li1->pinpurpose )
?bBox list(
rodAddToY(rodAddToX(tapRhtPath->lowerLeft -pinAdj) -pinAdj)
rodAddToY(rodAddToX(tapRhtPath->upperRight pinAdj) pinAdj)
)
?netName "B"
?termName "B"
?termIOType "inputOutput"
?pin t
?pinLabel t
?pinLabelHeight tapRhtPath->width
?pinLabelLayer list( rules->li1->layer "label")
?pinLabelFont "stick"
)
)
nwellRht = nwellRht + taplrSPres + tapW
); end if tapRight
; create bottom tap
if( tapBottom then
if( tapBottomCnt then
tapBotEncPath = append1( tapEncPath tapEncPathWithCnt )
tapBotSubRect = append1( tapSubRect tapSubRectWithCnt )
else
tapBotEncPath = tapEncPath
tapBotSubRect = tapSubRect
); end when tapBottomCnt
tapBotPath = rodCreatePath(
?cvId cv
?name "tapBotPath"
?layer rules->tap->layer
?width tapW
?pts list(
presLftEdge-tapBotAdjL : presBotEdge-taptbSPres-0.5*tapW
presRhtEdge+tapBotAdjR : presBotEdge-taptbSPres-0.5*tapW
)
?netName "B"
?termName "B"
?termIOType "inputOutput"
?pin t
?encSubPath tapBotEncPath
?subRect tapBotSubRect
); end rodCreatePath tapBotPath
when( tapBottomCnt
pinAdj = tapMetOLcont - tapOLcont
rodCreateRect(
?cvId cv
?name "tapBotPin"
?layer list( rules->li1->pinlayer rules->li1->pinpurpose )
?bBox list(
rodAddToY(rodAddToX(tapBotPath->lowerLeft -pinAdj) -pinAdj)
rodAddToY(rodAddToX(tapBotPath->upperRight pinAdj) pinAdj)
)
?netName "B"
?termName "B"
?termIOType "inputOutput"
?pin t
?pinLabel t
?pinLabelHeight tapBotPath->length
?pinLabelLayer list( rules->li1->layer "label")
?pinLabelFont "stick"
)
)
nwellBot = nwellBot - taptbSPres - tapW
); end if tapBottom
; create left tap
if( tapLeft then
if( tapLeftCnt then
tapLftEncPath = append1( tapEncPath tapEncPathWithCnt )
tapLftSubRect = append1( tapSubRect tapSubRectWithCnt )
else
tapLftEncPath = tapEncPath
tapLftSubRect = tapSubRect
); end when tapLeftCnt
tapLftPath = rodCreatePath(
?cvId cv
?name "tapLftPath"
?layer rules->tap->layer
?width tapW
?pts list(
presLftEdge-taplrSPres-0.5*tapW : presBotEdge-tapLftAdjB
presLftEdge-taplrSPres-0.5*tapW : presTopEdge+tapLftAdjT
)
?netName "B"
?termName "B"
?termIOType "inputOutput"
?pin t
?encSubPath tapLftEncPath
?subRect tapLftSubRect
); end rodCreatePath tapLftPath
when( tapLeftCnt
pinAdj = tapMetOLcont - tapOLcont
rodCreateRect(
?cvId cv
?name "tapLftPin"
?layer list( rules->li1->pinlayer rules->li1->pinpurpose )
?bBox list(
rodAddToY(rodAddToX(tapLftPath->lowerLeft -pinAdj) -pinAdj)
rodAddToY(rodAddToX(tapLftPath->upperRight pinAdj) pinAdj)
)
?netName "B"
?termName "B"
?termIOType "inputOutput"
?pin t
?pinLabel t
?pinLabelHeight tapLftPath->width
?pinLabelLayer list( rules->li1->layer "label")
?pinLabelFont "stick"
)
)
nwellLft = nwellLft - taplrSPres - tapW
); end if tapLeft
; create the nwell and hv imp if needed
when( wellType == "Nwell"
case( vType
( "1.8V"
nwell = rodCreateRect(
?cvId cv
?name "nwell"
?layer rules->nwell->layer
?bBox list( nwellLft:nwellBot nwellRht:nwellTop )
)
)
( "5V"
nwellTop = nwellTop - rules->nwell->minOLtap + rules->nwell->minOLhvtap
nwellRht = nwellRht - rules->nwell->minOLtap + rules->nwell->minOLhvtap
nwellBot = nwellBot + rules->nwell->minOLtap - rules->nwell->minOLhvtap
nwellLft = nwellLft + rules->nwell->minOLtap - rules->nwell->minOLhvtap
nwell = rodCreateRect(
?cvId cv
?name "nwell"
?layer rules->nwell->layer
?bBox list( nwellLft:nwellBot nwellRht:nwellTop )
)
temp = rules->hvi->minOLtap - rules->nwell->minOLhvtap
if( plusp(temp) then
hviBbox = list( nwellLft-temp:nwellBot-temp nwellRht+temp:nwellTop+temp )
else
hviBbox = list( nwellLft:nwellBot nwellRht:nwellTop )
)
rodCreateRect(
?cvId cv
?name "thkox"
?layer rules->thkox->layer
?bBox hviBbox
)
hvi = rodCreateRect(
?cvId cv
?name "hvi"
?layer rules->hvi->layer
?bBox hviBbox
)
)
( "12V"
nwellTop = nwellTop - rules->nwell->minOLtap + rules->nwell->minOLhvtap
nwellRht = nwellRht - rules->nwell->minOLtap + rules->nwell->minOLhvtap
nwellBot = nwellBot + rules->nwell->minOLtap - rules->nwell->minOLhvtap
nwellLft = nwellLft + rules->nwell->minOLtap - rules->nwell->minOLhvtap
nwell = rodCreateRect(
?cvId cv
?name "nwell"
?layer rules->nwell->layer
?bBox list( nwellLft:nwellBot nwellRht:nwellTop )
)
temp = rules->vhvi->minOLtap - rules->nwell->minOLhvtap
if( plusp(temp) then
vhviBbox = list( nwellLft-temp:nwellBot-temp nwellRht+temp:nwellTop+temp )
else
vhviBbox = list( nwellLft:nwellBot nwellRht:nwellTop )
)
rodCreateRect(
?cvId cv
?name "thkox"
?layer rules->thkox->layer
?bBox vhviBbox
)
vhvi = rodCreateRect(
?cvId cv
?name "vhvi"
?layer rules->vhvi->layer
?bBox vhviBbox
)
)
( "20V"
nwellTop = nwellTop - rules->nwell->minOLtap + rules->nwell->minOLhvtap
nwellRht = nwellRht - rules->nwell->minOLtap + rules->nwell->minOLhvtap
nwellBot = nwellBot + rules->nwell->minOLtap - rules->nwell->minOLhvtap
nwellLft = nwellLft + rules->nwell->minOLtap - rules->nwell->minOLhvtap
nwell = rodCreateRect(
?cvId cv
?name "nwell"
?layer rules->nwell->layer
?bBox list( nwellLft:nwellBot nwellRht:nwellTop )
)
temp = rules->uhvi->minOLtap - rules->nwell->minOLhvtap
if( plusp(temp) then
uhviBbox = list( nwellLft-temp:nwellBot-temp nwellRht+temp:nwellTop+temp )
else
uhviBbox = list( nwellLft:nwellBot nwellRht:nwellTop )
)
rodCreateRect(
?cvId cv
?name "thkox"
?layer rules->thkox->layer
?bBox uhviBbox
)
uhvi = rodCreateRect(
?cvId cv
?name "uhvi"
?layer rules->uhvi->layer
?bBox uhviBbox
)
)
); end case vType
); end when nwell
); let
); end pcDefinePCell
;===========================================================
;***** Define Symbol Pcell *****
;===========================================================
foreach( view list("symbol" "auCdl" "auLvs" "spectre")
pcDefinePCell( list( ddGetObj(libName) device->deviceName view "schematicSymbol" "w")
; formal parameters name value pairs
(
( rType "string" "Series" )
( res "string" sprintf(nil "%.3f" device->defRes ))
( segW "string" sprintf(nil "%.3f" device->defW ))
( segL "string" sprintf(nil "%.3f" device->defL ))
( segments "int" 1 )
( wellType "string" "Pwell" ) ;; values are "Pwell" or "Nwell"
( vType "string" "1.8V") ;; values are "1.8V", "5V", "12V", "20V"
)
let( (cv cellLabel instLabel labelR labelW labelL labelT labelB
netm netp netb plus minus bias termP termM termB paramLabel )
cv = pcCellView
dbReplaceProp(cv "instNamePrefix" "string" "RP")
; bounding box and main labels
;-----------------------------
dbCreateRect(cv list("instance" "drawing") list(-0.0625:-0.375 0.125:0.0))
cellLabel = dbCreateLabel( cv list("text" "drawing") -0.0625:0.015625 "[@cellName]"
"centerRight" "R0" "stick" 0.03125 )
cellLabel~>labelType = "NLPLabel"
instLabel = dbCreateLabel( cv list("annotate" "drawing7") -0.0625:-0.046875 "[@instanceName]"
"centerRight" "R0" "stick" 0.0625 )
instLabel~>labelType = "NLPLabel"
labelR = dbCreateLabel( cv list("annotate" "drawing") -0.0625:-0.140625 "[@res]"
"centerRight" "R0" "stick" 0.0625 )
labelR~>labelType = "NLPLabel"
if( rType == "Parallel" then
labelW = dbCreateLabel(cv list("annotate" "drawing") -0.0625:-0.234375
if( segments > 1 then "[@segments:W=%*][@segW:%]" else "[@segW:W=%]")
"lowerRight" "R0" "stick" 0.03125)
labelL = dbCreateLabel(cv list("annotate" "drawing") -0.0625:-0.296875
"[@segL:L=%]" "lowerRight" "R0" "stick" 0.03125)
else
labelW = dbCreateLabel(cv list("annotate" "drawing") -0.0625:-0.234375
"[@segW:W=%]" "lowerRight" "R0" "stick" 0.03125)
labelL = dbCreateLabel(cv list("annotate" "drawing") -0.0625:-0.296875
if( segments > 1 then "[@segments:L=%*][@segL:%]" else "[@segL:L=%]")
"lowerRight" "R0" "stick" 0.03125)
); if rType Parallel
labelW->labelType = "NLPLabel"
labelL->labelType = "NLPLabel"
labelT = dbCreateLabel(cv list("annotate" "drawing") -0.0625:-0.359375
"[@rType:%]" "lowerRight" "R0" "stick" 0.03125)
labelT->labelType = "NLPLabel"
; create nets and pins
;-----------------------------
netp = dbMakeNet(cv "PLUS")
dbCreateTerm(netp "PLUS" "inputOutput")
plus = dbCreateRect(cv list("pin" "drawing")
list(-0.01875:-0.01875 0.01875:0.01875) )
dbCreatePin(netp plus)
termP = dbCreateLabel( cv list("annotate" "drawing8") 0.0125:0 "cdsTerm(\"PLUS\")"
"upperLeft" "R90" "stick" 0.01875 )
termP~>labelType = "ILLabel"
termP->parent = plus
netm = dbMakeNet(cv "MINUS")
dbCreateTerm(netm "MINUS" "inputOutput")
minus = dbCreateRect(cv list("pin" "drawing")
list(-0.01875:-0.01875 0.01875:0.01875) )
dbMoveShape(minus cv list(0:-0.375 "R0"))
dbCreatePin(netm minus)
termM = dbCreateLabel( cv list("annotate" "drawing8") 0.0125:-0.375 "cdsTerm(\"MINUS\")"
"upperRight" "R90" "stick" 0.01875 )
termM~>labelType = "ILLabel"
termM->parent = minus
netb = dbMakeNet(cv "B")
dbCreateTerm(netb "B" "inputOutput")
;bias = dbCreateRect(cv list("pin" "drawing")
; list(-0.01875:-0.01875 0.01875:0.01875) )
if( wellType == "Pwell" then
bias = dbCreatePolygon(cv list("pin" "drawing")
list(0.01875:0.01875 -0.01875:0.0 0.01875:-0.01875) )
else
bias = dbCreatePolygon(cv list("pin" "drawing")
list(-0.01875:-0.01875 0.01875:0.0 -0.01875:0.01875) )
)
dbMoveShape(bias cv list(0.125:-0.1875 "R0"))
dbCreatePin(netb bias)
termB = dbCreateLabel( cv list("annotate" "drawing8") 0.125:-0.203125 "cdsTerm(\"B\")"
"upperLeft" "R0" "stick" 0.01875 )
termB~>labelType = "ILLabel"
termB->parent = bias
paramLabel = dbCreateLabel( cv list("annotate" "drawing") 0.140625:-0.250 "cdsParam(1)"
"upperRight" "R90" "stick" 0.03125 )
paramLabel~>labelType = "ILLabel"
paramLabel = dbCreateLabel( cv list("annotate" "drawing") 0.140625:-0.125 "cdsParam(2)"
"upperLeft" "R90" "stick" 0.03125 )
paramLabel~>labelType = "ILLabel"
paramLabel = dbCreateLabel( cv list("annotate" "drawing") 0.203125:-0.250 "cdsParam(3)"
"upperRight" "R90" "stick" 0.03125 )
paramLabel~>labelType = "ILLabel"
paramLabel = dbCreateLabel( cv list("annotate" "drawing") 0.203125:-0.125 "cdsParam(4)"
"upperLeft" "R90" "stick" 0.03125 )
paramLabel~>labelType = "ILLabel"
; main resistor drawing
;-----------------------------
dbCreateLine(cv list("device" "drawing") list(0.0:-0.375 0.0:-0.3 -0.0625:-0.28125
0.0625:-0.24375 -0.0625:-0.20625 0.0625:-0.16875 -0.0625:-0.13125 0.0625:-0.09375
0.0:-0.075 0.0:0.0 ) )
dbCreateLabel( cv list("device" "drawing") 0.06875:-0.06875
case( cv->cellName ("rpoly_hp" "H" ) ("rpoly_hp2K" "VH" ))
"lowerCenter" "R0" "stick" 0.03125 )
; bias label
if( wellType == "Pwell" then
labelB = dbCreateLabel(cv list("annotate" "drawing8") 0.0953125:-0.1875
"PW" "lowerCenter" "R90" "stick" 0.01875)
else
labelB = dbCreateLabel(cv list("annotate" "drawing8") 0.0953125:-0.1875
"[@vType:NW %]" "lowerCenter" "R90" "stick" 0.01875)
labelB->labelType = "NLPLabel"
); if wellType
); let
); pcDefinePCell symbols
); foreach view
;===========================================================
;***** CDF definition *****
;===========================================================
let( (cellName cellId cdf tfId)
cellName = device->deviceName
unless( cellId = ddGetObj( libName cellName )
error( "Could not get cell object Lib: %s, Cell:%s" libName cellName )
); unless
when( cdf = cdfGetBaseCellCDF( cellId )
cdfDeleteCDF( cdf )
); when
cdf = cdfCreateBaseCellCDF( cellId )
tfId = techGetTechFile(cellId)
cdfCreateParam( cdf
?name "model"
?prompt "Model Name"
?type "string"
?defValue sprintf( nil "%s" device->modelName )
?storeDefault "yes"
?parseAsCEL "yes"
?editable "nil"
?display "hiGetCurrentWindow()~>cellView~>cellViewType != \"maskLayout\""
)
cdfCreateParam( cdf
?name "lvsModel"
?prompt "LVS Model Name"
?type "string"
?defValue sprintf( nil "%s_pw" device->modelName )
?storeDefault "yes"
?parseAsCEL "yes"
?editable "nil"
?display "hiGetCurrentWindow()~>cellView~>cellViewType == \"maskLayout\""
)
cdfCreateParam( cdf
?name "rType"
?prompt "Type"
?type "cyclic"
?defValue "Series"
?storeDefault "yes"
?choices list("Series" "Parallel" "Serpentine")
?callback sprintf( nil "%s('rType)" device->paramCB )
)
cdfCreateParam( cdf
?name "rCalcMethod"
?prompt "Calculate By"
?type "cyclic"
?defValue "Total Resistance"
?storeDefault "yes"
?choices list("Total Resistance" "Segment Length")
)
cdfCreateParam( cdf
?name "res"
?prompt "Total Resistance"
?type "string"
?defValue sprintf( nil "%.3f" device->defRes )
?storeDefault "yes"
?parseAsCEL "no"
?parseAsNumber "yes"
?units "resistance"
?editable "cdfgData->rCalcMethod->value == \"Total Resistance\""
?callback sprintf( nil "%s('res)" device->paramCB )
)
cdfCreateParam( cdf
?name "segL"
?prompt "Segment Length"
?type "string"
?defValue sprintf( nil "%.3f" device->defL )
?storeDefault "yes"
?parseAsCEL "no"
?parseAsNumber "yes"
?editable "cdfgData->rCalcMethod->value == \"Segment Length\""
?callback sprintf( nil "%s('segL)" device->paramCB )
)
cdfCreateParam( cdf
?name "segW"
?prompt "Width"
?type "string"
?defValue sprintf( nil "%.3f" device->defW )
?storeDefault "yes"
?parseAsCEL "no"
?parseAsNumber "yes"
?callback sprintf( nil "%s('segW)" device->paramCB )
)
cdfCreateParam( cdf
?name "segments"
?prompt "Segments"
?type "int"
?defValue 1
?storeDefault "yes"
?parseAsCEL "no"
?callback sprintf( nil "%s('segments)" device->paramCB )
)
cdfCreateParam( cdf
?name "segmentSP"
?prompt "Segment Spacing"
?type "string"
?defValue sprintf( nil "%.3f" device->defSegSP )
?storeDefault "yes"
?parseAsCEL "no"
?parseAsNumber "yes"
?callback sprintf( nil "%s('segmentSP)" device->paramCB )
?editable "cdfgData->rType->value != \"Serpentine\""
?display "cdfgData->segments->value > 1"
)
cdfCreateParam( cdf
?name "contRows"
?prompt "Contact Rows"
?type "int"
?defValue 1
?storeDefault "yes"
?parseAsCEL "no"
?callback sprintf( nil "%s('contRows)" device->paramCB )
)
cdfCreateParam( cdf
?name "metCont"
?prompt "Metal1 Connections"
?defValue t
?storeDefault "yes"
?type "boolean"
?display "hiGetCurrentWindow()~>cellView~>cellViewType == \"maskLayout\""
)
cdfCreateParam( cdf
?name "wellType"
?prompt "Well Type"
?type "cyclic"
?defValue "Pwell"
?storeDefault "yes"
?choices list("Pwell" "Nwell")
?callback "{if( cdfgData->wellType->value == \"Pwell\" then
cdfgData->lvsModel->value = strcat(cdfgData->model->value \"_pw\")
else
cdfgData->lvsModel->value = strcat(cdfgData->model->value \"_nw\")
)}"
)
cdfCreateParam( cdf
?name "vType"
?prompt "Well Voltage Rating"
?type "cyclic"
?defValue "1.8V"
?storeDefault "yes"
?choices list("1.8V" "5V" "12V" "20V")
?display "cdfgData->wellType->value == \"Nwell\""
)
cdfCreateParam( cdf
?name "tapLeft"
?prompt "Left Tap"
?defValue t
?storeDefault "yes"
?type "boolean"
?display "hiGetCurrentWindow()~>cellView~>cellViewType == \"maskLayout\""
)
cdfCreateParam( cdf
?name "tapLeftCnt"
?prompt " Left Tap Contacts"
?defValue t
?storeDefault "yes"
?type "boolean"
?display "cdfgData->tapLeft->value && hiGetCurrentWindow()~>cellView~>cellViewType == \"maskLayout\""
)
cdfCreateParam( cdf
?name "tapRight"
?prompt "Right Tap"
?defValue nil
?storeDefault "yes"
?type "boolean"
?display "hiGetCurrentWindow()~>cellView~>cellViewType == \"maskLayout\""
)
cdfCreateParam( cdf
?name "tapRightCnt"
?prompt " Right Tap Contacts"
?defValue t
?storeDefault "yes"
?type "boolean"
?display "cdfgData->tapRight->value && hiGetCurrentWindow()~>cellView~>cellViewType == \"maskLayout\""
)
cdfCreateParam( cdf
?name "tapTop"
?prompt "Top Tap"
?defValue nil
?storeDefault "yes"
?type "boolean"
?display "hiGetCurrentWindow()~>cellView~>cellViewType == \"maskLayout\""
)
cdfCreateParam( cdf
?name "tapTopCnt"
?prompt " Top Tap Contacts"
?defValue t
?storeDefault "yes"
?type "boolean"
?display "cdfgData->tapTop->value && hiGetCurrentWindow()~>cellView~>cellViewType == \"maskLayout\""
)
cdfCreateParam( cdf
?name "tapBottom"
?prompt "Bottom Tap"
?defValue nil
?storeDefault "yes"
?type "boolean"
?display "hiGetCurrentWindow()~>cellView~>cellViewType == \"maskLayout\""
)
cdfCreateParam( cdf
?name "tapBottomCnt"
?prompt " Bottom Tap Contacts"
?defValue t
?storeDefault "yes"
?type "boolean"
?display "cdfgData->tapBottom->value && hiGetCurrentWindow()~>cellView~>cellViewType == \"maskLayout\""
)
cdfCreateParam( cdf
?name "segRes"
?prompt "Segment Resistance"
?type "string"
?defValue sprintf( nil "%.5f" device->defSegRes )
?storeDefault "yes"
?parseAsCEL "no"
?parseAsNumber "yes"
?editable "nil"
?display "cdfgData->rType->value != \"Serpentine\" && hiGetCurrentWindow()~>cellView~>cellViewType != \"maskLayout\""
)
cdfCreateParam( cdf
?name "serpL"
?prompt "Serpentine Length"
?type "string"
?defValue sprintf( nil "%.3f" device->defL )
?storeDefault "yes"
?parseAsCEL "no"
?parseAsNumber "yes"
?editable "nil"
?callback sprintf( nil "%s()" device->paramCB )
?display "cdfgData->rType->value == \"Serpentine\" && hiGetCurrentWindow()~>cellView~>cellViewType != \"maskLayout\""
)
cdfCreateParam( cdf
?name "headRes"
?prompt "Head Resistance"
?type "string"
?defValue sprintf( nil "%.5f" device->defHeadRes )
?storeDefault "yes"
?parseAsCEL "no"
?parseAsNumber "yes"
?editable "nil"
?display "hiGetCurrentWindow()~>cellView~>cellViewType != \"maskLayout\""
)
cdfCreateParam( cdf
?name "sheetRho"
?prompt "Sheet Rho"
?type "string"
?defValue sprintf( nil "%.3f" device->sheetRho )
?storeDefault "yes"
?parseAsCEL "no"
?parseAsNumber "yes"
?editable "nil"
?display "hiGetCurrentWindow()~>cellView~>cellViewType != \"maskLayout\""
)
; params for auCdl & auLvs netlisting
cdfCreateParam( cdf
?name "l"
?prompt "netlist length"
?type "string"
?defValue sprintf( nil "%.3f" device->defL )
?storeDefault "yes"
?parseAsCEL "no"
?parseAsNumber "yes"
?display "nil"
)
cdfCreateParam( cdf
?name "w"
?prompt "netlist width"
?type "string"
?defValue sprintf( nil "%.3f" device->defW )
?storeDefault "yes"
?parseAsCEL "no"
?parseAsNumber "yes"
?display "nil"
)
cdfCreateParam( cdf
?name "m"
?prompt "netlist m"
?type "int"
?defValue 1
?storeDefault "yes"
?parseAsCEL "no"
?display "nil"
)
cdfCreateParam( cdf
?name "r"
?prompt "netlist r"
?type "string"
?defValue sprintf( nil "%.3f" device->defRes )
?storeDefault "yes"
?parseAsCEL "no"
?parseAsNumber "yes"
?units "resistance"
?display "nil"
)
cdf->simInfo = list( nil)
cdf->simInfo->auCdl = '( nil
dollarEqualParams nil
dollarParams nil
otherParameters nil
netlistProcedure S130hrpolyCdlNLProc
instParameters (model w l m segments rType nf )
propMapping (nil model lvsModel )
componentName sprintf( nil "%s" device->deviceName )
termOrder (PLUS MINUS B)
namePrefix "R"
modelName lvsModel
)
cdf->simInfo->auLvs = '( nil
permuteRule "(p PLUS MINUS)"
)
cdf->simInfo->spectre = '( nil
netlistProcedure S130hrpolySpectreNLProc
namePrefix "R"
modelParamExprList nil
optParamExprList nil
opParamExprList nil
stringParameters nil
propMapping nil
componentName nil
instParameters nil
otherParameters nil
termOrder nil
termMapping nil
)
cdf->simInfo->spectreS = '( nil
netlistProcedure S130hrpolySpectreNLProc
namePrefix "R"
modelParamExprList nil
optParamExprList nil
opParamExprList nil
stringParameters nil
propMapping nil
componentName nil
instParameters nil
otherParameters nil
termOrder nil
termMapping nil
)
cdf->formInitProc = "S130disablePcellChange"
cdf->paramLabelSet = ""
cdf->opPointLabelSet = "v i pwr"
cdf->paramEvaluate = "t nil nil nil nil"
cdf->paramDisplayMode = "parameter"
cdf->instDisplayMode = "instName"
cdf->instNameType = "schematic"
cdfSaveCDF( cdf)
); let
); foreach device
); let
/*================================== EOF ===================================*/