i'd like some advice for creating my first simple pCell from skill. I have no skill experience so i'm looking for a good place to start.
My ultimate aim (for now) is to create a rectangular via array with X and Y stretch handles. For example you have M1->M4(the top & bottom layers would be parameters) that you can stretch in X or Y and it fills with the max vias allowed by spacing rules. However to begin with i'd be happy to create a parameterised rectangle of M1 that i can stretch in one direction & take it from there.
Pointers to on-line tutorials and very simple examples would be great, right now i am blindly searching around source-link.
Here is a simple example on SourceLink that has a stretch handle, I'm also posting the code here, but I recommend viewing the full solution for a little more detail and description. If I get time later I can look at creating a better example. Look at the rodFillBBoxWithRects() function or the subRectArray argument to the rodCreateRect() function.
/* CCSencapRodPcell.ilGroup Custom IC, Cadence Design SystemsLanguage SKILLRevision No. 1.1Date Created Aug 06, 2008Last ModifiedTested in IC5141Lint score 94 (best is 100)Description:A simple example of an encapsulated PCell with a stretch handle andCDF for one of the parameters. CDF is created for the two parametersand the stretchable parameter is either hidden, or visible but noteditable on the Edit Instance Properties form.NOTE: The Lint score is not 100 because SKILL Lint does not recognisepcCellView as a legal parameter, but instead thinks it is a global.***************************************************SCCS Info: @(#) CCSencapRodPcell.il 08/11/08.11:19:22 1.1********************************************************************* DISCLAIMER: 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. **********************************************************************/;; This is the function that does all the work in creating the;; PCell shapes, labels etc. This routine can be tested outside;; of the pcDefinePCell statement, and it goes through SKILL Lint;; with better results too.procedure(CCScreateBoxAndLabels(cv w l "dnn") let( (rectRodObj) ;; create a rectangle on metal1 with x & y dimensions set by w & l rectRodObj = rodCreateRect( ?name "myRect" ?cvId cv ?layer list("metal1" "drawing") ?width w ?length l ?origin list(0 0) ) ;; create labels to show the w and l parameters dbCreateLabel(cv list("text" "drawing") list(0 0) sprintf(nil "%2.8f" w) "lowerLeft" "R0" "stick" 0.05) dbCreateLabel(cv list("text" "drawing") list(0 0.2) sprintf(nil "%2.8f" l) "lowerLeft" "R0" "stick" 0.05) ;; create a stretch handle for the width, in the X dimension, it ;; will display as "width = <value>" and change by 0.1 increments rodAssignHandleToParameter( ?parameter "w" ?rodObj rectRodObj ?handleName "centerRight" ?stretchDir "X" ?displayName "width" ?displayExpression "w" ?updateIncrement 0.1 ); rodAssignHandleToParameter ); let); procedure CCScreateBoxAndLabels;; Create the PCell, the "drawing routine" is encapsulated in the;; CCScreateBoxAndLabels function which does all the workpcDefinePCell( list(ddGetObj("test") "encapRodPcell" "layout") ( (w 1.0) (l 0.6) ) let( ((cv pcCellView)) CCScreateBoxAndLabels(cv w l) ); let);; Create the CDF for the 'l' and 'w' parameters, the width (w);; parameter is either hidden or displayed but not editable.let( (cellId cdfId) when(cellId = ddGetObj("test" "encapRodPcell") ;; 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 "l" ?prompt "Length" ?defValue 0.6 ?type "float" ?display "t" ) cdfCreateParam( cdfId ?name "w" ?prompt "Width" ?defValue 1.0 ?type "float" ;; comment out the next line and uncomment the lines below ;; it if the parameter is to be visible but not editable ?display "nil"; ?display "t"; ?editable "nil" ) cdfSaveCDF(cdfId) ); when); let for CDF creation
In reply to skillUser:
thanks as usual for your input. I just tried to load this skill into my icfb but it returned:
*WARNING* Invalid libId - nil
*Error* eval: unbound variable - cv
I guess cv is cell view and maybe i need to pass some sort of variable or define cv before i load the skill.
In reply to stuso:
You will need to create a library named "test" so that when the code is loaded the libraryId is found and then used to create the "encapRodPcell" cellview in that library. The library should have technology information in it, for example, the "metal1" "drawing" layer is used in this example. There is a sample techfile in <cds_install_dir>/tools/dfII/samples/techfile/mpu.tf which contains this layer if you don't have a ready example to play with.
Hopefully this will help you get started.
How are you getting on with your PCell development? Hope it is going well, let us (the community) know if we can help.
Hi Lawrence, thanks for asking.
i had a quick try & the cell had no stretch handles for me.
I need to spend a bit of time looking into this, its a side project for me just now but i'll definately be back to bug you over the next few weeks when i get round to it.
I forgot to mention that the stretch handle visibility can be controlled by the user from the Options->Display "Stretch Handles" toggle, which may be off by default.
Yes, that works now, thanks
Hi Lawrence, i've been using your example (thanks for that) and i've had managed to make some good progress (for a beginner). I now can generate a pCell with say M1,VIA1,M2,VIA2 & M3 which has X&Y stretch handles. I've used M1 as my main ROD rectangle with the other 4 layers as subrectangles.
It works nicely in the sense that I can place & stretch it around, it looks like all the layers are in place and the correct size. I have a couple of immediate issues & a more generic question.
1) How do i set a miimum value for parameters, currently i can stretch the pCell to 0um then i can't recover it, i have to select it (by area for example) then delete it.
2) It fails to run PVS DRC with message:
*WARNING* Pcell evaluation for stu_test_skill/GGL_pCell_M1viaM3/layout has the following error(s):*WARNING* ("eval" 0 t nil ("*Error* eval: undefined function" GGLcreateViaM1M3))*WARNING* Error kept in "errorDesc" property of the label "pcellEvalFailed" on layer/purpose "marker/error" in the submaster.FATAL (449): Pcell evaluation failed. This could happen as a result of either a syntax error or the use of an unsupported PIPO function in Pcell SKILL code. Only db*() and rod*() functions can be used in Pcell SKILL code. To continue, either use the 'Ignore Pcell evaluation failure' option in Stream In/Out Options or fix the Pcell SKILL code.pvsvirt: PROBLEM happened while processing strmout.
3) This is the more generic Question. Once i have a nice clean pcell code how should i store & implement the Skill for the design team. For example i could just load the code from the project .cdsinit, would that be wise? I noticed that when i start a new session i have to reload the skill function else i get the pCell evaluation failed message in the layout view.
Thanks for you help
Here is my code, all feedback is very welcome:
procedure(GGLcreateViaM1M3(cv w l "dnn") let( (rectRodObj) ;; create a rectangle on metal1 with x & y dimensions set by w & l rectRodObj = rodCreateRect( ?name "gglVIA1m1m3" ?cvId cv ?layer list("M1" "drawing") ?width w ?length l ?origin list(0 0) ?subRectArray list( list( ?layer list("M2" "drawing") ?width w ?length l ) list( ?layer list("M3" "drawing") ?width w ?length l ) list( ?layer list("VIA1" "drawing") ?width 0.07 ?length 0.07 ?lowerLeftOffsetX 0.05 ?lowerLeftOffsetY 0.05 ?upperRightOffsetX -0.05 ?upperRightOffsetY -0.05 ?spaceX 0.075 ?spaceY 0.075 ) list( ?layer list("VIA2" "drawing") ?width 0.07 ?length 0.07 ?lowerLeftOffsetX 0.05 ?lowerLeftOffsetY 0.05 ?upperRightOffsetX -0.05 ?upperRightOffsetY -0.05 ?spaceX 0.075 ?spaceY 0.075 ) ) );; create a stretch handle for the width & length rodAssignHandleToParameter( ?parameter "w" ?rodObj rectRodObj ?handleName "centerRight" ?stretchDir "X" ?updateIncrement 0.005 ); rodAssignHandleToParameter rodAssignHandleToParameter( ?parameter "l" ?rodObj rectRodObj ?handleName "upperCenter" ?stretchDir "Y" ?updateIncrement 0.005 ); rodAssignHandleToParameter ); let); procedure ;; Create the PCell, the "drawing routine" is encapsulated in the;; GGLcreateViaM1M3 function which does all the workpcDefinePCell( list(ddGetObj("stu_test_skill") "GGL_pCell_M1viaM3" "layout") ( (w 0.33) (l 0.33) ) let( ((cv pcCellView)) GGLcreateViaM1M3(cv w l) ); let);; Create the CDF for the 'l' and 'w' parameterslet( (cellId cdfId) when(cellId = ddGetObj("stu_test_skill" "GGL_pCell_M1viaM3") ;; 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 "l" ?prompt "Length" ?defValue 0.33 ?type "float" ?display "t" ) cdfCreateParam( cdfId ?name "w" ?prompt "Width" ?defValue 0.33 ?type "float" ?display "t" ) cdfSaveCDF(cdfId) ); when); let for CDF creation
In addition to what Andrew has said, you can also use a CDF callback for a parameter as a validation check, this is a good use of a CDF callback - please also bear in mind the advice in the following solution (written by Andrew): The Dangers of CDF Callbacks
If you use CDF for a parameter, you can use this to set the Display of the parameter which can appear differently to the parameter name, and you can use the CDF to control whether a parameter is displayed or not. You can create the CDF through SKILL also, so this can be in the file that is loaded by the libInit.il (or in that file directly) alongside the PCell code itself. Depending on the amount and complexity of your code, you may wish to have multiple files to house the SKILL in, e.g. you've got multiple PCells and want one SKILL code file per cell. You might then just load all of the SKILL from the libInit.il, as in this example:
let( ((libName "pcells") path skillPath ilFiles)
;; you might have the code in a subdirectory, if so, add this to the path
path = ddGetObjReadPath(ddGetObj(libName))
skillPath = getSkillPath()
ilFiles = setof(files getDirFiles(path) rexMatchp("\\.il$" files))
unless(file == "libInit.il"
printf("Library %s libInit.il loading %s\n" libName file)
); unless the file is this file
An easy way to write the SKILL to create the CDF is to create the CDF using the form-driven interface and then use cdfDump() to write this to a file as SKILL code.
Oops, I forgot to say that the CDF callback can be used to provide feedback to the user, as well as changing the value, e.g. to clamp it at the minimum or maximum value so that the CDF callback enforces a valid range, as well as perhaps printing a message in the CIW or popping up a dialog box (although the latter tends to annoy users since you have to dismiss it).
I am new in pcell creation.I need help.I wnt code which creates pcell which takes more then 3 layers as its parameters.Also the layer purpose pair i would like to have as "fill".Can anyone help me out.
I am new to skill.I am trying to use your program to draw metal rectangle and labels.What command should I give in CIW window .I tried CCScreateBoxAndLabels( 1 0.6 1) its complaning about dnn being database object ?? I scanned through the sklanguser manual but could not get the answere.
In reply to NewStudent:
The precise error message would have been:
CCScreateBoxAndLabels( 1 0.6 1)
*Error* CCScreateBoxAndLabels: argument #1 should be a database object (type template = "dnn") - 1
The "dnn" is the argument to the function definition which adds type-checking. It is checking that the first argument is a database object, and the next two are numbers.
I'm not sure why you passed 1 as the first argument, that makes no sense. It is expecting a cellView id, as returned by geGetEditCellView() (if you have a layout window open), or from dbOpenCellViewByType("mylib" "mycell" "layout" "maskLayout" "a")
So for example:
cv=geGetEditCellView()CCScreateBoxAndLabels(cv 0.6 1)
In reply to Andrew Beckett:
Thanks Andrew. I started with top-down approach with skill rather then bottom-up.I thought it was easier way for me to learn skill coding.
What I mean by that is :I have written skill code that can generate array and labels from already layed out cell.
I had few questions regarding this :
Is there any way I can generate skill code from layout I have? I had this question because I wanted generic way for generating text from lower level layout cells on top level cells.
Eg : If I have x cell which has 10 - y cells arrayed.I want labels from y cells to be replicated at x level with _1,_2,_3 .
I know and I already did skill code for this but I need a standard way ( single code) that can do it for any cell array I want .This without hardcoding the labels and pins in my skill script.
For this reason wanted to check if there is some way I can generate skill code from layout of lower level.This way I can make my standard skill code point to skill code generated from layout to pass on the pins labels etc.
I am really struggling over making standard code for all the array combinations without having hard coded labels or pins.Please suggest me if you have any other better way or idea regarding this.