• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC SKILL
  3. modified Pcell has no parameter

Stats

  • Replies 5
  • Subscribers 148
  • Views 1623
  • Members are here 0

modified Pcell has no parameter

XZ202601196340
XZ202601196340 27 days ago

hello everyone.
Thanks for reading this and i really appreciate any help.

i am trying to modify a Pcell from a PDK. I followed this (SKILL: How to recreate/modify an existing PCell and also generate SKILL code for a schematic, layout PCell from an existing schematic) post and did the following steps:

my goal is to remove some metal from the layout of the Pcell and here is what i did:

1. open the Pcell layout and do cvID=geGetEditRep() 

2. Use the dbDumpPcell(cvID "pcell_src.il" "proc_src.il") procedure to dump the existing PCell.

3. Make the desired changes in the output files generated, and name them pcell_mod.il and proc_mod.il.

4. Backup/delete the existing PCell layout cellview.
5. load("pcell_mod.il")

6. Open the newly generated layout cellview. it is asking to update connectivity and there is no schematic in the cell, only spectre, aucdl and symbol so i didnt update anything.
7. Get the cellview ID. cvId=geGetEditRep()

8. dbDefineProc(cvId "proc_mod.il"); changes the layout cellview to be a parametrized cell.

9. when trying to save the updated layout pcell, i chose to save it as transistor but the hierarchy pcell generator says There is no parameter in this cell, continue to compile? i knew something was wrong but i chose yes regardless

and now the shapes in the layout cell do not have ROD associated with them and whenever i try to create an instance of this pcell, it does not scale with my parameter (e.g. i put in width/length and the generated layout does not change)

i m wondering what could go wrong. i also tried not modifying the pcell_src and proc_src and just load them but still, it is not scaling based on my parameter. i m using IC23.


any help is appreciated.


  • Cancel
  • Sign in to reply
Parents
  • Andrew Beckett
    Andrew Beckett 27 days ago

    The instructions are a bit unclear in that article, to be honest. Some suggestions based on the experiments I just performed:

    6. When you try to open it, it prompts for the schematic source (because layout is Layout XL in IC23.1). Simply uncheck the schematic source - that would be OK.

    9. Rather than pressing the save button on the layout editor, I suggest you use:
        dbSave(cvId)
        (i.e the same variable you used the geGetEditRep/geGetEditCellView for). 

    That worked for me. I think it's confusing it with the graphical PCell system (because of opening up the Pcell in edit mode). Personally I would have changed:

    1. Open the Pcell in readonly mode and then do cvID=geGetEditCellView()
    2-5. As before
    6. cvId=dbOpenCellViewByType("libName" "cellName" "viewName" "" "a") ; rather than opening in a layout editor
    7. skip this
    8. As before call the dbDefineProc
    9. dbSave(cvId)

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
Reply
  • Andrew Beckett
    Andrew Beckett 27 days ago

    The instructions are a bit unclear in that article, to be honest. Some suggestions based on the experiments I just performed:

    6. When you try to open it, it prompts for the schematic source (because layout is Layout XL in IC23.1). Simply uncheck the schematic source - that would be OK.

    9. Rather than pressing the save button on the layout editor, I suggest you use:
        dbSave(cvId)
        (i.e the same variable you used the geGetEditRep/geGetEditCellView for). 

    That worked for me. I think it's confusing it with the graphical PCell system (because of opening up the Pcell in edit mode). Personally I would have changed:

    1. Open the Pcell in readonly mode and then do cvID=geGetEditCellView()
    2-5. As before
    6. cvId=dbOpenCellViewByType("libName" "cellName" "viewName" "" "a") ; rather than opening in a layout editor
    7. skip this
    8. As before call the dbDefineProc
    9. dbSave(cvId)

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
Children
  • XZ202601196340
    XZ202601196340 27 days ago in reply to Andrew Beckett

    Hi Andrew,
    Thank you so much for the reply. it is almost perfect now but there is still a little problem:

    I followed the steps you suggested and did a quick test. I didn't modify the "pcell_src.il" and "proc_src.il" and just loaded them as it is and i was expecting the pcell will be the same as before.
    However, although the pcell is now scalable(e.g. changing the number of fingers in the parameter will make the layout change. Thank you very much!), the ROD is still missing for the shapes when I inspect the shape properties (ROD tab is greyed out).

    and i also dumped pcell_src.il again after the pcell is generated and compared the original pcell_src.il with the newly dumped one to see if there is any difference: 

    In the section of "FIGGROUPS AND GROUPS", the newly dumped pcell_src.il only has dbCreateGroup(dbD_xxxxxxxx "rodMasters"
    list("set" "unordered" "uniqueName"
    "deleteNever")) but NO dbAddObjectToGroup(dbD_xxxxxx dbD_xxxxx) following it, whereas the original pcell_src.il has a bunch of dbAddObjectToGroup(dbD_xxxxxx dbD_xxxxx).

    is this why the ROD tab is all greyed out for the newly generated pcell? i dont know if this will be an issue...? can it be solved?

    Thank you so much.


    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • XZ202601196340
    XZ202601196340 27 days ago in reply to Andrew Beckett

    upon further inspection of the newly dumped pcell_src.il, it seems like all the SHAPES/NETS/TERMINALS/PINS got reassigned to a different dbD value (e.g. dbD_0x000000002f54aa23 = dbCreateRect() to dbD_0x000000002f54ae1f = dbCreateRect() and the order of the SHAPES are shuffled as well) and the dbAddObjectToGroup cannot find the original dbD value so i guess all of those dbAddObjectToGroup lines got removed?

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Andrew Beckett
    Andrew Beckett 27 days ago in reply to XZ202601196340

    OK, a bit of background as to how PCells work. The PCell consists of a superMaster which defines a hierarchical property called parameters under which each of the PCell parameters live; then it uses dbDefineProc() to associate some code (in your case proc_mod.il) with the PCell. 

    By convention, the superMaster also contains the objects which would get created if the PCell was evaluated with its default parameters; this is what you see in the pcell_src.il file when dumped. However, this is only a convention and in practice never matters because this superMaster layout is never used by anything. When you instantiate the PCell, a new in-memory subMaster is created for unique variant of PCell parameter combinations, and then the pcGenCell function within the proc_mod.il would be called to generate that variant. This happens even if the parameters are the default - i.e. it doesn't re-use the data in the superMaster because that's only a convention and not guaranteed to be correct.

    What this means is that really only editing the proc_src.il/proc_mod.il matters. That is the code that's going to create the actual objects in the subMaster, including all the ROD objects. If you didn't edit the pcell_src.il/pcell_mod.il whatsoever, then the PCell would still function correctly.

    Now, the data that ends up dumped into pcell_src.il is a dump of the database objects in the superMaster cellView, similar to what is produced by dbWriteSkill. This is not guaranteed to be complete, and in fact it will not preserve ROD objects. That's why you don't see the ROD objects in the superMaster when you open that. If instead you instantiated an instance of the PCell and then did a descend read into that instance, you would be able to see the ROD objects in the edit properties form - and that's what normally matters. Note too that the dbIds used in the dump will be different each time - but that doesn't matter (so don't worry about that - you mentioned this in your last post).

    Now, you might think that the solution is to just create the parameters hierarchical property and its members and then load the proc_mod.il file and call pcGenCell. However, this typically won't work because functions like rodGetObj() have a special case scenario when being called from within a PCell - they automatically know the cellView being operated on. This is fine when the variants are evaluated, but not if you manually call pcGenCell to generate the default layout - it would need somehow to know what the current cellView is. pcDefinePCell takes care of this, but to do it manually requires a couple of private SKILL functions which I can't mention here (since they are private, undocumented, and liable to change - however unlikely after all these years).

    So, if you really want the superMaster to contain the objects for the default parameter values (including ROD objects), I'd suggest a slightly different strategy - and maybe something slightly simpler than the flow suggested in that article:

    1. Open the PCell you are trying to replace in readonly mode
    2. dbDumpPcDefinePcell(geGetEditCellView() "./pcell_code.il")
    3. Then edit this pcell_code.il file. You'll see at the top it has information about the lib/cell/view of the PCell and the formal parameters, and then a dump of the pcGenCell function:
      ("gpdk045" "nmos1v" "layout")
      (
        (fingers float 1.000000e+00)
        (connectGates string "None")
        (connectSD string "None")
        (switchSD boolean nil)
        (diffCont boolean  t)
        (dfm string "Minimum")
        (mtlCvg string "")
        (sdMtlWidth float 6.000000e-08)
        (leftAbut int 0)
        (rightAbut int 0)
        (tap string "None")
        (topTap boolean nil)
        (bottomTap boolean nil)
        (leftTap boolean  t)
        (rightTap boolean nil)
        (tapExtension string "")
        (tapCntRows int 1)
        (fw float 1.200000e-07)
        (l float 4.500000e-08)
      )
      procedure( pcGenCell(pcCellView "d")
          prog( (_pcParameters l fingers connectGates connectSD
      	switchSD diffCont dfm mtlCvg sdMtlWidth
      	leftAbut rightAbut tap topTap bottomTap
      	leftTap rightTap tapExtension tapCntRows fw
          )
      	if( !pcCellView
      	    return()
      	)
      	(_pcParameters = (pcCellView~>parameters))
      	(l = (_pcParameters~>l))
      	if( !l
      	    then
      	    (l = 0.0)
      	)
      	if( !floatp(l)
      	    then
      	    (l = 0.0)
      	)
      	(fingers = (_pcParameters~>fingers))
      	if( !fingers
      	    then
      	    (fingers = 1.0)
      	)
      	if( !floatp(fingers)
      	    then
      	    (fingers = 1.0)
      	)
    4. Change the first line to be in this format:
      pcDefinePCell(list(ddGetObj("gpdk045") "nmos1v" "layout")
    5. Scroll down to the bottom of the formal parameter list, just above the procedure line above and add /* before the procedure line (this will start commenting out the procedure definition)
    6. Then scroll down to the end of where it's retrieving the PCell parameters - in my case that's for fw, the last parameter in the prog:
      	if( !floatp(fw)
      	    then
      	    (fw = 0.0)
      	)
      	let((cv tfId mfgGrid grid grid2
      		gteLabelId gteNetId gteTermId gtePinId gteWeakName
      		gteMustName gteUniqueTermNum gteX gteY gteWidth
    7. Insert a */ (close comment) just after that final if (in my case there's a let that follows, which you may or may not have depending on what was in the original PCell code).
    8. Now scroll down to the very end of the code, where you'll see this:
      	return(t)
          )
      )
    9. Comment out the return line and the close parenthesis that follows it, leaving the final close parenthesis (that should match the open parenthesis for the pcDefinePCell you inserted whereas it originally matched the open parenthesis for the procedure definition. The return was the return from the prog that's been commented out, and the commented-out close parenthesis is for the now commented-out prog.
    10. Make the other changes to the code that you want (as you did before - changing layers etc)
    11. Define the PCell by using load("./pcell_code.il") - this does everything - creates the PCell, with the parameters, and the superMaster default layout, plus the variant handling.

    It's a slightly more involved process (because you have to transform the dumped code into the correct syntax to recreate the PCell), but you only have to make the changes to the layers in one place, plus the ROD objects will be created both in the subMaster variants (which is what matters) but also the superMaster (for consistency and visual inspection).

    I hope this lengthy explanation helps!

    Regards,

    Andrew

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
  • XZ202601196340
    XZ202601196340 24 days ago in reply to Andrew Beckett

    Thanks Andrew. I tried this and it works beautifully. Thumbsup

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2026 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information