Hello,
I wrote a hierarchical, SKILL based pCell. The hierarchical pCell includes a child cell, with few parameters, and a parent cell.
I bounded the child pCell numerical parameters fields using the field's CallBack option. This works OK and when the child pCell is instantiated, it's fields are bounded accordingly within a specific range.
Yet, when using the parent cell, the child pCell fields are losing their boundaries and accept any value.
Below please find a sample code to demonstrate the issue. If the child cell is called, it's fields are bounded properly, but under the parent cell, they lose their boundaries.
The fields to be bound to specific ranges are: w and l.
l is bounded within a range of 10 to 100, if not within this range make default: 25, 2 Digits after decimal point.
?callback "cdfgData->l->value=sprintf(nil \"%.2fu\" atof(cdfgData->l->value)) if(atof(cdfgData->l->value) < 10 || atof(cdfgData->l->value) > 100 then cdfgData->l->value = \"25.0u\")"
w is bounded within a range of 0.095 to 1 , If not within this range make default 0.25, 2 digits after decimal point.
?callback "cdfgData->w->value=sprintf(nil \"%.2fu\" atof(cdfgData->w->value)) if(atof(cdfgData->w->value) < 0.095 || atof(cdfgData->w->value) > 1 then cdfgData->w->value = \"0.25u\")"
Here is the complete sample code that is based on Cadence Hierarchical pCell sample:
***************************************************************
SCLAIMER: The following code is provided for Cadence customers *
* to use at their own risk. The code may require modification to *
* satisfy the requirements of any user. The code and any *
* modifications to the code may not be compatible with current or *
* future versions of Cadence products. *
* THE CODE IS PROVIDED "AS IS" AND WITH NO WARRANTIES, INCLUDING *
* WITHOUT LIMITATION ANY EXPRESS WARRANTIES OR IMPLIED WARRANTIES *
* OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. *
********************************************************************/
/***************************************************************
* *
* Child pcell *
* *
***************************************************************/
pcDefinePCell(
;--------------------------------------------------------------------
; Identify target cellView
;--------------------------------------------------------------------
list(ddGetObj("DannyR_Tests") "childCell" "layout")
;--------------------------------------------------------------------
; Define the formal parameter names
;--------------------------------------------------------------------
(
(l 1.0)
(w 1.0)
(metal1Layer "MET1")
(metal1Purpose "drawing")
(metal2Layer "MET2")
(metal2Purpose "drawing")
(overlap 0.1)
)
;--------------------------------------------------------------------
; The code itself
;--------------------------------------------------------------------
let((r1 r2)
r1=rodCreateRect(
?layer list(metal1Layer metal1Purpose)
?width w
?length l
)
r2=rodCreateRect(
?layer list(metal2Layer metal2Purpose)
?width w+overlap*2.0
?length l+overlap*2.0
)
rodAlign(
?alignObj r1
?alignHandle 'centerCenter
?refObj r2
?refHandle 'centerCenter
)
) ; let
; Creating teh CDF parameters
let( (cellId cdfId)
when(cellId = ddGetObj("DannyR_Tests" "childCell")
;; if the cell CDF already exists, delete it
when( cdfId = cdfGetBaseCellCDF(cellId)
cdfDeleteCDF(cdfId)
)
;; create the base cell CDF
cdfId = cdfCreateBaseCellCDF(cellId)
;; create the parameters
cdfCreateParam( cdfId
?name "w"
?prompt "w"
?defValue "0.25u"
?type "string"
?display "t"
?callback "cdfgData->w->value=sprintf(nil \"%.2fu\" atof(cdfgData->w->value)) if(atof(cdfgData->w->value) < 0.095 || atof(cdfgData->w->value) > 1 then cdfgData->w->value = \"0.25u\")"
)
cdfCreateParam( cdfId
?name "l"
?prompt "l"
?defValue "25.0u"
?type "string"
?display "t"
?callback "cdfgData->l->value=sprintf(nil \"%.2fu\" atof(cdfgData->l->value)) if(atof(cdfgData->l->value) < 10 || atof(cdfgData->l->value) > 100 then cdfgData->l->value = \"25.0u\")"
)
)
)
) ; end of pcDefinePCell
/***************************************************************
* *
* The parent cellView *
* *
***************************************************************/
pcDefinePCell(
;--------------------------------------------------------------------
; Identify target cellView
;--------------------------------------------------------------------
list(ddGetObj("DannyR_Tests") "parentCell" "layout")
;--------------------------------------------------------------------
; Define the formal parameter names
;--------------------------------------------------------------------
(
(l 25.0)
(w 0.25.0)
(numX 2)
(numY 2)
(metal1Layer "MET1")
(metal1Purpose "drawing")
(metal2Layer "MET2")
(metal2Purpose "drawing")
(overlap 0.1)
)
;--------------------------------------------------------------------
; The code itself
;--------------------------------------------------------------------
let((dummy bBox width height mosaic master childParamList)
;----------------------------------------------------------------
; Work out the parameter list to pass to the child pcell
;----------------------------------------------------------------
childParamList=
list(
list("l" "float" l)
list("w" "float" w)
list("metal1Layer" "string" metal1Layer)
list("metal1Purpose" "string" metal1Purpose)
list("metal2Layer" "string" metal2Layer)
list("metal2Purpose" "string" metal2Purpose)
list("overlap" "float" overlap)
)
;----------------------------------------------------------------
; Create a dummy instance first, so that we can measure it
;----------------------------------------------------------------
master=dbOpenCellViewByType("DannyR_Tests" "childCell" "layout")
dummy=dbCreateParamInst(
pcCellView
master
"" 0:0 "R0"
1
childParamList
) ; create the dummy instance
;----------------------------------------------------------------
; Figure out the bBox
; probably would be more complex than this in reality; he we're
; just looking at the bBox directly.
;----------------------------------------------------------------
bBox=dummy~>master~>bBox
width=xCoord(upperRight(bBox))-xCoord(lowerLeft(bBox))
height=yCoord(upperRight(bBox))-yCoord(lowerLeft(bBox))
;----------------------------------------------------------------
; Now delete the dummy instance
;----------------------------------------------------------------
dbDeleteObject(dummy)
;----------------------------------------------------------------
; Now create the parameterized cell
;----------------------------------------------------------------
mosaic=dbCreateSimpleMosaic(
pcCellView
master
"" 0:0 "R0"
; note rows then columns
numY numX
height width
)
;----------------------------------------------------------------
; Then update the parameters
; NOTE: dbReplacePropList doesn't re-trigger the pcell evaluation
; (it should - PCR 715526 is for a function to do this cleanly).
; As a workaround, I use dbReplaceProp with one of the
; parameters in the list in order to trigger an eval.
; Also note, you need to replace the parameters on the first
; instance in the mosaic, since it is a simple mosaic of just
; one instance type. This will be better when a function (something
; like) dbCreateSimpleParamMosaic gets created
;----------------------------------------------------------------
dbReplacePropList(
car(mosaic~>instanceList)
childParamList
)
dbReplaceProp(
car(mosaic~>instanceList)
car(car(childParamList))
cadr(car(childParamList))
caddr(car(childParamList))
)
;----------------------------------------------------------------
; Now close the master that was used to create the dummy and
; the mosaic
;----------------------------------------------------------------
dbClose(master)
) ; let
) ; end of pcDefinePCell
Any tip would be greatly appreciated.
Thanks,
Danny