blob: fa62c7d84375da3bfb86827b6d018ead7acc0f0b [file] [log] [blame]
/*==============================================================================
File: S130padPcell.il
Purpose: Pcell code for layout and/or symbols, and cdf setup for the pads
for Skywater S130 Pcell
Created: June 21, 2020 Madek Graham
Description: Pcell code to create pad devices
Devices/views: pad_bond / symbol auCdl auLvs layout
pad_probe / symbol auCdl auLvs layout
pad_microprobe / symbol auCdl auLvs layout
------------------------------------------------------------
Modifications:
- Nov 2, 2020 MSG
Added marker layers for I/O, Power, or Ground pad type, as well as new CDF
parameter to flag the pad type.
==============================================================================*/
/*==============================================================================
This file only needs to be loaded once to create the pcells and cdf information
for the dioDevices set within the S130techData.il file
==============================================================================*/
let( ( libName )
libName = "S130"
foreach( device padDevices
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))) )
( w "float" device->defW )
( l "float" device->defL )
( metalOL "float" max(designRules->pad->minBotMetOL designRules->pad->minTopMetOL) )
( padType "string" "I/O" )
)
let(( cv adj45 pt0x pt1x pt2x pt3x pt0y pt1y pt2y pt3y )
cv = pcCellView
dbReplaceProp(cv "instNamePrefix" "string" "PAD")
; figure out the points since all pads need 45 degree corners
; origin will always be the center of the pad
; create the pad
if( devInfo->minLbevel then
adj45 = ceiling(sqrt(0.5*expt(rules->pad->minLbevel 2))/grid)*grid
else
adj45 = ceiling(min(w l)*0.1/grid)*grid
)
pt0x = pt0y = 0.0
pt1x = adj45
pt2x = w - adj45
pt3x = w
pt1y = adj45
pt2y = l - adj45
pt3y = l
rodCreatePolygon(
?cvId cv
?name "pad"
?layer devInfo->padLay->layer
?pts list( pt1x:pt0y pt2x:pt0y pt3x:pt1y pt3x:pt2y pt2x:pt3y
pt1x:pt3y pt0x:pt2y pt0x:pt1y )
)
; create pad type marking layer
rodCreatePolygon(
?cvId cv
?name "padType"
?layer case( padType
("I/O" list( "areaid" "pad_io" ) )
("Power" list( "areaid" "pad_pwr" ) )
("Ground" list( "areaid" "pad_gnd" ) )
)
?fromObj rodGetObj("pad" cv)
)
; create length LVS marking layer
rodCreateRect(
?cvId cv
?name "lvsLengthMrk"
?layer list("areaid" "padLength")
?width w
?length grid
?origin list(0.0 round(0.5*l/grid)*grid)
)
; create marking layer if any
when( devInfo->mrkLay
rodCreatePolygon(
?cvId cv
?name "mrkLay"
?layer devInfo->mrkLay
?pts list( pt1x:pt0y pt2x:pt0y pt3x:pt1y pt3x:pt2y pt2x:pt3y
pt1x:pt3y pt0x:pt2y pt0x:pt1y )
)
); when mrkLay
; create identifier label if any
when( devInfo->label
dbCreateLabel( cv list(devInfo->padLay->layer "label") rodGetObj("pad" cv)->centerCenter devInfo->label
"centerCenter" "R0" "stick" min(0.5 min(w l)*0.01) )
); when label
/*
; create the module cut layer
modcutOL = rules->pad->minModcutOL
pt0x = pt0y = -modcutOL
pt1x = round((adj45 - 0.5*modcutOL)/grid)*grid
pt2x = ceiling((w - adj45 + 0.5*modcutOL)/grid)*grid
pt3x = w + modcutOL
pt1y = round((adj45 - 0.5*modcutOL)/grid)*grid
pt2y = ceiling((l - adj45 + 0.5*modcutOL)/grid)*grid
pt3y = l + modcutOL
rodCreatePolygon(
?cvId cv
?name "modCut"
?layer list("areaid" "moduleCut")
?pts list( pt1x:pt0y pt2x:pt0y pt3x:pt1y pt3x:pt2y pt2x:pt3y
pt1x:pt3y pt0x:pt2y pt0x:pt1y )
)
*/
; create the top metal
adj45 = round((adj45 - 0.5*metalOL)/grid)*grid
pt0x = pt0y = -metalOL
pt1x = adj45
pt2x = w - adj45
pt3x = w + metalOL
pt1y = adj45
pt2y = l - adj45
pt3y = l + metalOL
rodCreatePolygon(
?cvId cv
?name "topMet"
?layer devInfo->topMetLay->layer
?pts list( pt1x:pt0y pt2x:pt0y pt3x:pt1y pt3x:pt2y pt2x:pt3y
pt1x:pt3y pt0x:pt2y pt0x:pt1y )
)
; create the bottom metal
dbLayerAndNot( cv devInfo->botMetLay->layer list( rodGetObj("topMet" cv)->dbId )
list( rodGetObj("pad" cv)->dbId ))
; create the vias
; create a keepout to ensure proper metal overlap for bot metal
rodCreatePolygon(
?cvId cv
?name "keepOut"
?layer list( "text" "drawing" )
?fromObj rodGetObj("pad" cv)
?size devInfo->botMetLay->minOLSviaU
)
rodFillWithRects(
?shapeId rodGetObj("topMet" cv)->dbId
?keepOut list( rodGetObj("keepOut" cv)->dbId->points )
?fillShapeLPP list(devInfo->viaLay->layer devInfo->viaLay->purpose)
?fillShapeWidth devInfo->viaLay->minW
?fillShapeLength devInfo->viaLay->minW
?justification "centerCenter"
?spaceX devInfo->viaLay->minSP
?spaceY devInfo->viaLay->minSP
?enclosureX max(
devInfo->botMetLay->minOLSviaU
devInfo->topMetLay->minOLSviaL
)
?enclosureY max(
devInfo->botMetLay->minOLSviaU
devInfo->topMetLay->minOLSviaL
)
?grid grid
)
dbDeleteObject(rodGetObj("keepOut" cv)->dbId)
; create the pins
rodCreatePolygon(
?cvId cv
?name "padPin"
?layer list( devInfo->topMetLay->pinlayer devInfo->topMetLay->pinpurpose )
?pts rodGetObj("pad" cv)->dbId->points
?netName "PAD"
?termName "PAD"
?termIOType "inputOutput"
?pin t
?pinLabel t
?pinLabelHeight 0.1*min(w l)
?pinLabelLayer list( devInfo->topMetLay->layer "label")
?pinLabelFont "stick"
?pinLabelJust "centerCenter"
)
); let
); pcDefinePCell layout
printf(" ...layout view created\n")
;===========================================================
;***** Define Symbol Pcell *****
;===========================================================
foreach( view list("symbol" "auCdl" "auLvs")
let( (cv instLabel labelT labelM netp pad termP sizeFactor)
when( cv = dbOpenCellViewByType( ddGetObj(libName) device->deviceName view "schematicSymbol" "w" )
case( device->deviceName
("pad_bond"
dbReplaceProp(cv "instNamePrefix" "string" "PAD")
sizeFactor = 0.0
)
("pad_probe"
dbReplaceProp(cv "instNamePrefix" "string" "PROBE")
sizeFactor = 0.0625
)
("pad_microprobe"
dbReplaceProp(cv "instNamePrefix" "string" "MPROBE")
sizeFactor = 0.125
)
); end case
; only need this for auCdl and auLvs, not for simulation
dbReplaceProp(cv "nlIgnore" "string" "ams hspiceD spectre spectreS verilog vhdl")
; pad drawing and main labels
;-----------------------------
dbCreateRect(cv list("instance" "drawing") list(-0.375+sizeFactor:-0.5+sizeFactor
0.375-sizeFactor:0.375-sizeFactor))
dbCreateRect(cv list("device" "drawing") list(-0.375+sizeFactor:-0.375+sizeFactor
0.375-sizeFactor:0.375-sizeFactor))
dbCreateRect(cv list("device" "drawing2") list(-0.25+sizeFactor:-0.25+sizeFactor
0.25-sizeFactor:0.25-sizeFactor))
dbCreateLine(cv list("device" "drawing2") list(-0.25+sizeFactor:-0.25+sizeFactor
0.25-sizeFactor:0.25-sizeFactor))
dbCreateLine(cv list("device" "drawing2") list(-0.25+sizeFactor:0.25-sizeFactor
0.25-sizeFactor:-0.25+sizeFactor))
dbCreateLine(cv list("device" "drawing") list(0:-0.375+sizeFactor 0:-0.5+sizeFactor))
instLabel = dbCreateLabel( cv list("annotate" "drawing7") 0:0.40625-sizeFactor
"[@instanceName]" "lowerCenter" "R0" "stick" 0.0625 )
instLabel~>labelType = "NLPLabel"
labelT = dbCreateLabel(cv list("text" "drawing") 0:0.3125-sizeFactor
"[@lvsModel:%]" "centerCenter" "R0" "stick" 0.05625-0.2*sizeFactor)
labelT->labelType = "NLPLabel"
labelM = dbCreateLabel(cv list("annotate" "drawing") 0:-0.3125+sizeFactor
"[@m:M=%]" "centerCenter" "R0" "stick" 0.03125)
labelM->labelType = "NLPLabel"
; create net and pin
;-----------------------------
netp = dbMakeNet(cv "PAD")
dbCreateTerm(netp "PAD" "inputOutput")
pad = dbCreateRect(cv list("pin" "drawing")
list(-0.01875:-0.01875 0.01875:0.01875) )
dbMoveShape(pad cv list(0:-0.5+sizeFactor "R0"))
dbCreatePin(netp pad)
termP = dbCreateLabel( cv list("annotate" "drawing8") 0.0125+sizeFactor:-0.48125+sizeFactor
"cdsTerm(\"PAD\")" "lowerLeft" "R0" "stick" 0.01875 )
termP~>labelType = "ILLabel"
termP->parent = pad
dbSave(cv)
dbClose(cv)
); when cv
); let
printf(" ...%s view created\n" view )
); 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 device->modelName
?storeDefault "yes"
?parseAsCEL "yes"
?editable "nil"
?display "nil"
)
cdfCreateParam( cdf
?name "lvsModel"
?prompt "LVS Model Name"
?type "string"
?defValue device->lvsModel
?storeDefault "yes"
?parseAsCEL "yes"
?editable "nil"
?display "hiGetCurrentWindow()~>cellView~>cellViewType == \"maskLayout\""
)
when( device->label == "e-test"
cdfCreateParam( cdf
?name "padSize"
?prompt "Size"
?type "radio"
?defValue sprintf(nil "%g" device->minW)
?storeDefault "yes"
?choices list(sprintf(nil "%g" device->minW) sprintf(nil "%g" device->maxW))
?callback "cdfgData->w->value = cdfgData->l->value = cdfParseFloatString(cdfgData->padSize->value)"
)
); when etest pad
cdfCreateParam( cdf
?name "w"
?prompt "Width (um)"
?type "float"
?defValue device->defW
?storeDefault "yes"
?callback strcat(device->paramCB "('w)")
?editable "if( cdfgData->padSize then nil else t)"
)
cdfCreateParam( cdf
?name "l"
?prompt "Length (um)"
?type "float"
?defValue device->defL
?storeDefault "yes"
?callback strcat(device->paramCB "('l)")
?editable "if( cdfgData->padSize then nil else t)"
)
cdfCreateParam( cdf
?name "m"
?prompt "Multiples"
?type "int"
?defValue 1
?storeDefault "yes"
?callback strcat(device->paramCB "('m)")
?display "hiGetCurrentWindow()~>cellView~>cellViewType != \"maskLayout\""
)
cdfCreateParam( cdf
?name "metalOL"
?prompt "Metal Overlap Pad"
?type "float"
?defValue device->minTopMetOL
?storeDefault "yes"
?callback strcat(device->paramCB "('metalOL)")
?display "hiGetCurrentWindow()~>cellView~>cellViewType == \"maskLayout\""
)
cdfCreateParam( cdf
?name "padType"
?prompt "Type"
?type "radio"
?defValue "I/O"
?storeDefault "yes"
?choices list("I/O" "Power" "Ground")
)
cdfCreateParam( cdf
?name "minW"
?prompt "minimum width"
?type "float"
?defValue device->minW
?storeDefault "yes"
?parseAsCEL "no"
?display "nil"
)
cdfCreateParam( cdf
?name "maxW"
?prompt "maximum width"
?type "float"
?defValue device->maxW
?storeDefault "yes"
?parseAsCEL "no"
?display "nil"
)
cdfCreateParam( cdf
?name "minTopMetOL"
?prompt "minimum Top Metal overlap"
?type "float"
?defValue device->minTopMetOL
?storeDefault "yes"
?parseAsCEL "no"
?display "nil"
)
cdf->simInfo = list( nil)
cdf->simInfo->auCdl = '( nil
dollarEqualParams nil
dollarParams nil
otherParameters nil
netlistProcedure ansCdlSubcktCallExtended
instParameters (model m w l)
propMapping (nil model lvsModel)
componentName nil
termOrder (PAD)
namePrefix "X"
)
cdf->simInfo->auLvs = '( nil
dollarEqualParams nil
dollarParams nil
otherParameters nil
netlistProcedure ansLvsCompParamPrim
instParameters (model m w l )
propMapping (nil model lvsModel)
termOrder (PAD)
namePrefix "X"
)
;;; Properties
cdf->formInitProc = "S130disablePcellChange"
cdf->doneProc = ""
cdf->buttonFieldWidth = 250
cdf->fieldHeight = 35
cdf->fieldWidth = 250
cdf->promptWidth = 120
cdf->modelLabelSet = ""
cdf->opPointLabelSet = ""
cdf->paramLabelSet = ""
cdf->instDisplayMode = "instName"
cdf->instNameType = "schematic"
cdf->termDisplayMode = "netName"
cdf->netNameType = "schematic"
cdfSaveCDF(cdf)
); let
); foreach device
); let
/*================================== EOF ===================================*/