Hi Wes,
I wrote some Schematic PCell code for this type of problem a while back, it may not be tested fully!! Here it is:
/*Description:
Sample PCell code for a schematic and a symbol PCell that is designed
to be a "wrapper" around an existing cell, in this case the resistor
from analogLib.
*/
let( (library cell pcellId)
library = "CIC_DEMO" ;; put your target library here
cell = "res" ;; put your new cellname here
;; create the schematic
pcellId = pcDefinePCell(
list(ddGetObj(library) cell "schematic" "schematic")
(
(connType "series")
(segNum 1)
)
let( (cv wrapLib wrapCell wrapView master
inst1 inst net in out step halfPin)
cv = pcCellView ;; global variable defined by the system
wrapLib = "analogLib" ;; put wrapped library here
wrapCell= "res" ;; put wrapped cellname here
wrapView= "symbol" ;; put wrapped viewname here
step = 0.5 ;; a stepping distance parameter
halfPin = 0.0625 ;; half a pin width/height
;; the master is the cell to be wrapped, it will be instantiated
;; in this schematic
master = dbOpenCellViewByType(wrapLib wrapCell wrapView "schematicSymbol")
;; create the input and output nets, terminals and pins
in = dbMakeNet(cv "in")
out = dbMakeNet(cv "out")
dbCreateTerm(in in~>name "inputOutput")
dbCreateTerm(out out~>name "inputOutput")
dbCreatePin(in
dbCreatePolygon(cv list("pin" "drawing")
list(-step:halfPin -step+halfPin:halfPin -step+(halfPin*2):0
-step+halfPin:-halfPin -step:-halfPin)))
dbCreatePin(out
dbCreatePolygon(cv list("pin" "drawing")
list(-step+(2*halfPin):halfPin-step
-step+halfPin:halfPin-step
-step:-step -step+halfPin:-step-halfPin
-step+(2*halfPin):-step-halfPin)))
;; create the first instance of the master and connect the
;; input pin to the PLUS terminal
inst1 = dbCreateInst( cv master "I1" 0:0 "R0" )
dbCreateConnByName(in inst1 "PLUS")
;; set inst to be the one we just created, this will get
;; overridden in the for loop (if it runs)
inst = inst1
;; for a parallel connection type we can connect MINUS to out
when(connType == "parallel"
dbCreateConnByName(out inst "MINUS")
)
;; iterate over the number of segments and create a new instance
;; of the master for each one. If the connection type is series
;; then connect each previous instances' MINUS to the next
;; instances' PLUS. If the connection type is parallel then
;; connect PLUS to 'in' and MINUS to 'out'. Step each instance
;; away from the last: series are stacked vertically, parallel
;; are spaced horizontally
for(conns 2 segNum
when(connType=="series"
net = dbMakeNet(cv sprintf(nil "net%d" conns-1))
dbCreateConnByName(net inst "MINUS")
)
inst = dbCreateInst(
cv master sprintf(nil "I%d" conns)
case(connType
("series" 0:(conns-1) * -step)
(t (conns-1)*step:0)
) "R0"
)
case(connType
("series"
dbCreateConnByName(net inst "PLUS")
)
("parallel"
dbCreateConnByName(in inst "PLUS")
dbCreateConnByName(out inst "MINUS")
)
)
); for
dbCreateConnByName(out inst "MINUS")
dbClose(master)
); let
); pcDefinePCell
;; save the schematic cellview
dbSave(pcellId)
dbClose(pcellId)
;; create the symbol
pcellId = pcDefinePCell(
list(ddGetObj(library) cell "symbol" "schematicSymbol")
(
(connType "series")
(segNum 1)
)
let( (cv inFig outFig in out halfPin resHt resWid lh label)
cv = pcCellView ;; global variable defined by the system
halfPin = 0.025 ;; half pin size in x or y dimension
resHt = 0.375 ;; resistor height
resWid = 0.25 ;; resistor width
lh = 0.0625 ;; label height
;; create the instance selection box
dbCreateRect(cv list("instance" "drawing")
list(-resWid/2.0:-resHt resWid/2.0:0))
;; create the resistor body and lines to the pins
dbCreateRect(cv list("device" "drawing")
list(-halfPin:-halfPin*10 halfPin:-halfPin*5))
dbCreateLine(cv list("device" "drawing") list(0:-halfPin 0:-halfPin*5))
dbCreateLine(cv list("device" "drawing")
list(0:-halfPin*10 0:halfPin-resHt))
;; create the pin figures, the nets and terminals
inFig = dbCreateRect(cv list("pin" "drawing")
list(-halfPin:-halfPin halfPin:halfPin))
outFig = dbCreateRect(cv list("pin" "drawing")
list(-halfPin:-resHt-halfPin halfPin:halfPin-resHt))
in = dbCreateNet(cv "in")
out = dbCreateNet(cv "out")
dbCreateTerm(in in~>name "inputOutput")
dbCreatePin(in inFig)
dbCreateTerm(out out~>name "inputOutput")
dbCreatePin(out outFig)
;; create a small label to denote the type and segments
if(connType=="series" then
dbCreateLabel(cv list("annotate" "drawing") -resWid/2.0:-lh
sprintf(nil "s%d" segNum) "upperLeft" "R0" "stick" lh/2.0)
else
dbCreateLabel(cv list("annotate" "drawing") -resWid/2.0:-lh
sprintf(nil "p%d" segNum) "upperLeft" "R0" "stick" lh/2.0)
)
;; create some analog-type information labels
label=dbCreateLabel(cv list("annotate" "drawing7") 0.5*resWid:-halfPin
"cdsName()" "centerRight" "R0" "stick" lh)
label~>labelType="ILLabel"
label=dbCreateLabel(cv list("annotate" "drawing") 0:-resHt*0.5
"cdsParam(1)" "centerLeft" "R0" "stick" lh)
label~>labelType="ILLabel"
label=dbCreateLabel(cv list("annotate" "drawing") 0:(-resHt*0.5)-(lh*2)
"cdsParam(2)" "centerLeft" "R0" "stick" lh)
label~>labelType="ILLabel"
); let
); pcDefinePCell
;; save the symbol cellview
dbSave(pcellId)
dbClose(pcellId)
;; create the cell CDF
let( (cellId cdfId)
;; need to get the cell dd object before creating the cell CDF
unless(cellId = ddGetObj( library cell )
error("Could not get cell %s." cell)
)
;; delete the CDF if it already exists and then re-create it
when(cdfId = cdfGetBaseCellCDF(cellId)
cdfDeleteCDF(cdfId)
)
when(cdfId = cdfCreateBaseCellCDF(cellId)
cdfCreateParam(cdfId
?name "connType"
?prompt "Connection Type"
?defValue "series"
?choices list("series" "parallel")
?type "cyclic"
?display "t"
)
cdfCreateParam(cdfId
?name "segNum"
?prompt "Number of Segments"
?defValue 1
?type "int"
?display "t"
)
;; create the simulation information properties
cdfId->simInfo = list(nil)
foreach((simulator value) '(UltraSim ams auCdl auLvs cdsSpice hspiceD
hspiceS spectre spectreS) '((nil) (nil) (nil) (nil) (nil) (nil) (nil)
(nil) (nil))
putprop(getq(cdfId simInfo) value simulator)
)
;; create the Interpreted Labels Information and Other Information
foreach((name value) '(formInitProc doneProc buttonFieldWidth
fieldHeight fieldWidth promptWidth paramLabelSet paramDisplayMode
instDisplayMode)
'("" "" 340 35 350 175 "-connType -segNum" "parameter" "instName")
putprop(cdfId value name)
)
cdfSaveCDF(cdfId)
)
)
); let
Apologies if anything is missing, I will try to upload the file too. I'm pretty sure that I borrowed some ideas from Andrew when I wrote this, but any mistakes are mine! Hope this helps.
Regards,
Lawrence.