• 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. Is there a procedure to copy pins from instance inside layout...

Stats

  • Locked Locked
  • Replies 4
  • Subscribers 144
  • Views 11305
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Is there a procedure to copy pins from instance inside layout pcell to the pcell?

Sheppie
Sheppie over 3 years ago

Hi,

I'm creating a layout pcell in which i instantiate a few transistors, amongst other things. Of those transistors, I'd like to (I mean: I have to) add pins to the pcell which are at the exact location of the gate of those transistors. Is a build-in SKILL procedure available that simply takes the terminal information from an instance and creates copies of it in the current level? Or do I have to build those pins myself, using dbCreateNet/dbCreatePin/dbCreateRect/dbCreateLabel/...?

To illustrate it a bit more. Imagine creating a pcell which instantiates just one transistor. The pcell must have pins, and all pins should be identical to the pins in the transistor it instantiates. So the pcell should have a source pin on top of the source pin of the transistor, the same for gate/drain/back-gate. This means same layer, same name, same geometry, everythign the same, just "one level up". It is easy to get the information from the pins in the instantiated transistor. However, I couldn't find an easy solution for copying/creating those pins at the pcell level.

Thanks in advance.

With kind regards,

Sjoerd

  • Cancel
Parents
  • Andrew Beckett
    Andrew Beckett over 3 years ago

    Hi Sjoerd,

    There's not really a simple built-in function to do this - you'd have to do it yourself, unfortunately. That said (and I'm sure you know I'm going to say this), this is staggeringly easy to do with PCell Designer:

    The "copy terminals" command does exactly this. The PCell above is instantiating a transistor and then propagating the terminals upwards. 

    Of course, I'd be happy to talk to you about potentially using PCell Designer ;-)

    Regards,

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Reply
  • Andrew Beckett
    Andrew Beckett over 3 years ago

    Hi Sjoerd,

    There's not really a simple built-in function to do this - you'd have to do it yourself, unfortunately. That said (and I'm sure you know I'm going to say this), this is staggeringly easy to do with PCell Designer:

    The "copy terminals" command does exactly this. The PCell above is instantiating a transistor and then propagating the terminals upwards. 

    Of course, I'd be happy to talk to you about potentially using PCell Designer ;-)

    Regards,

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Children
  • Sheppie
    Sheppie over 3 years ago in reply to Andrew Beckett

    Hi Andrew,

    That was the expected answer. I'd love to use the PCell Designer, however, for some reason my CAD department decided not to allow this tool to be used (in a DM I can give you the reason though). I'm compiling a list of things why I should be allowed to use this tool, and this has already made it to this list. So for now, I'll go ahead and write my own procedure to copy terminals...

    Thanks for your time.

    With kind regards,

    Sjoerd

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Kevin Buck
    Kevin Buck over 3 years ago in reply to Sheppie

    If you haven't already written it I did this recently:

    oldLayView = dbOpenCellViewByType(oldLibName cellName "layout" "" "r")

    ;Iterate over the shapes of the old layout to copy the pins and pin labels to the new layout, also rename the power/ground pins
    foreach(shape oldLayView~>shapes

    ;Find and copy all MET1 pin objects
    if(shape~>lpp == list("MET1" "pin") then
    newLayFig = dbCopyFig(shape newLayView)

    ;Re-name the supply labels
    if(newLayFig~>objType == "label" then
    if(newLayFig~>theLabel == "vdd!" then
    newLayFig~>theLabel = "vdd018"
    )
    if(newLayFig~>theLabel == "gnd!" then
    newLayFig~>theLabel = "vss018"
    )
    ;For the shapes create terminals and pins with the updated names
    ;for power/ground and make a copy of the input and output pins
    else
    case(shape~>pin~>net~>name
    ("vdd!"
    layNetVDD = dbCreateNet(newLayView "vdd018")
    dbCreateTerm(layNetVDD "vdd018" "input")
    newLayFig~>pin~>net~>name = "vdd018"
    layPinVDD = dbCreatePin(layNetVDD newLayFig)
    )
    ("gnd!"
    layNetVSS = dbCreateNet(newLayView "vss018")
    newLayFig~>pin~>net~>name = "vss018"
    dbCreateTerm(layNetVSS "vss018" "input")
    layPinVSS = dbCreatePin(layNetVSS newLayFig)
    )
    (t
    layNetIO = dbCreateNet(newLayView shape~>pin~>net~>name)
    dbCreateTerm(layNetIO shape~>pin~>net~>name shape~>pin~>term~>direction)
    layPinIO = dbCreatePin(layNetIO newLayFig)
    )
    )
    )
    )
    )

    I was doing something rather specific here so you'd need to modify it to suit you but this should work for you. You can change the if statement to a case statement assuming you have more than one layer that has desired pins on it.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Sheppie
    Sheppie over 3 years ago in reply to Kevin Buck

    Hi Kevin,

    Thank you for your response and suggestion.

    I already started coding, and my case is a bit different. The main transistor instantiated by my pcell has two gate pins on each gate; the transistor may have more then one finger. See the image below for a two-finger example.

    In the example, you'll see two gate fingers (filled green, wide rectangles in "portrait") and each finger has 2 pins: 1 at the top (above the diffusion area, pink-ish in color, dashed) and 1 at the bottom (below the diffusion). When I do the following (after setting variable "o" to the id of this instance) (searching for gate terminals):

    terminals = setof( terminal o~>master~>terminals pcreMatchp( "^G" terminal~>name ) )

    The variable "terminals get this value:

    (db:0x5f03cb9b db:0x5f03cb9c)

    As you can see, two terminals for the gate.

    Retrieving more information:

    terminals~>??
    ((db:0x5f03cb9b cellView db:0x5f03c51a objType "term"
        prop nil direction "input" groupMembers
        nil name "G" net db:0x5f03cb1b
        numBits 1 pins
        (db:0x5f03cc1e db:0x5f03cc1d) routeMethod
        "symbolic" connRoutes nil textDisplays nil
        assocTextDisplays nil pinCount 2 markers
        nil mustJoinTerms
        (db:0x5f03cb9c) position nil
        physOnly nil pinConnectMethod "default" isInterface
        t
        )
        (db:0x5f03cb9c cellView db:0x5f03c51a objType "term"
        prop nil direction "input" groupMembers
        nil name "G_1" net db:0x5f03cb1c
        numBits 1 pins
        (db:0x5f03cc20 db:0x5f03cc1f) routeMethod
        "symbolic" connRoutes nil textDisplays nil
        assocTextDisplays nil pinCount 2 markers
        nil mustJoinTerms
        (db:0x5f03cb9b) position nil
        physOnly nil pinConnectMethod "default" isInterface
        t
        )
    )

    As you can see, two terminals with each its own name, and each with two pins. The "mustJoinTerms" parameter has a value as well. This tells LayoutXL that both terminals must be shorted (which is obvious of course).

    Digging a bit deeper, this is some more information:

    terminals~>net~>??
    ((db:0x5f03cb1b cellView db:0x5f03c51a objType "net"
        prop nil allInstTerms nil connStatus
        nil criticality 0 figs nil
        routePattern "steiner" groupMembers nil instTerms
        nil name "G" numBits 1
        parent nil pins
        (db:0x5f03cc1e db:0x5f03cc1d) shieldNet1
        nil shieldNet2 nil signals
        (db:0x5f03cb1b)
        sigNames
        ("G") subnet nil subnets
        nil term db:0x5f03cb9b terms
        (db:0x5f03cb9b)
        textDisplays nil assocTextDisplays nil instTermCount
        0 markers nil routes nil
        source "netlist" sigType "signal" aliases
        ("G") isGlobal nil memInstTerms nil
        memNets
        ((db:0x5f03cb1b 0)) memTerms
        ((db:0x5f03cb9b 0))
        )
        (db:0x5f03cb1c cellView db:0x5f03c51a objType "net"
        prop nil allInstTerms nil connStatus
        nil criticality 0 figs nil
        routePattern "steiner" groupMembers nil instTerms
        nil name "G_1" numBits 1
        parent nil pins
        (db:0x5f03cc20 db:0x5f03cc1f) shieldNet1
        nil shieldNet2 nil signals
        (db:0x5f03cb1c)
        sigNames
        ("G_1") subnet nil subnets
        nil term db:0x5f03cb9c terms
        (db:0x5f03cb9c)
        textDisplays nil assocTextDisplays nil instTermCount
        0 markers nil routes nil
        source "netlist" sigType "signal" aliases
        ("G_1") isGlobal nil memInstTerms nil
        memNets
        ((db:0x5f03cb1c 0)) memTerms
        ((db:0x5f03cb9c 0))
        )
    )

    terminals~>pins~>??
    (((db:0x5f03cc1e cellView db:0x5f03c51a objType "pin"
            prop nil accessDir nil fig
            db:0x5f03c6a7 groupMembers nil name "G_B"
            net db:0x5f03cb1b term db:0x5f03cb9b connRoutes
            nil textDisplays nil assocTextDisplays nil
            markers nil figs
            (db:0x5f03c6a7) status
            nil type nil
        )
        (db:0x5f03cc1d cellView db:0x5f03c51a objType "pin"
            prop nil accessDir nil fig
            db:0x5f03c6a8 groupMembers nil name "G_T"
            net db:0x5f03cb1b term db:0x5f03cb9b connRoutes
            nil textDisplays nil assocTextDisplays nil
            markers nil figs
            (db:0x5f03c6a8) status
            nil type nil
        )
        )
        ((db:0x5f03cc20 cellView db:0x5f03c51a objType "pin"
            prop nil accessDir nil fig
            db:0x5f03c6b5 groupMembers nil name "G_1_B"
            net db:0x5f03cb1c term db:0x5f03cb9c connRoutes
            nil textDisplays nil assocTextDisplays nil
            markers nil figs
            (db:0x5f03c6b5) status
            nil type nil
        )
        (db:0x5f03cc1f cellView db:0x5f03c51a objType "pin"
            prop nil accessDir nil fig
            db:0x5f03c6b6 groupMembers nil name "G_1_T"
            net db:0x5f03cb1c term db:0x5f03cb9c connRoutes
            nil textDisplays nil assocTextDisplays nil
            markers nil figs
            (db:0x5f03c6b6) status
            nil type nil
        )
        )
    )

    terminals~>pins~>figs~>??
    ((((db:0x5f03c6a7 cellView db:0x5f03c51a objType "rect"
            prop nil bBox
            ((0.0 -0.1)
                (1.0 0.0)
            ) children
            nil groupMembers nil isAnyInst nil
            isShape t matchPoints nil net
            db:0x5f03cb1b parent nil pin db:0x5f03cc1e
            purpose "drawing" textDisplays nil assocTextDisplays
            nil markers nil figGroup nil
            isUnshielded nil shieldedNet1 nil shieldedNet2
            nil layerName "PO" layerNum 17
            lpp
            ("PO" "drawing") connRoutes nil routeStatus
            "normal"
            )
        )
        ((db:0x5f03c6a8 cellView db:0x5f03c51a objType "rect"
            prop nil bBox
            ((0.0 1.0)
                (1.0 1.1)
            ) children
            nil groupMembers nil isAnyInst nil
            isShape t matchPoints nil net
            db:0x5f03cb1b parent nil pin db:0x5f03cc1d
            purpose "drawing" textDisplays nil assocTextDisplays
            nil markers nil figGroup nil
            isUnshielded nil shieldedNet1 nil shieldedNet2
            nil layerName "PO" layerNum 17
            lpp
            ("PO" "drawing") connRoutes nil routeStatus
            "normal"
            )
        )
        )
        (((db:0x5f03c6b5 cellView db:0x5f03c51a objType "rect"
            prop nil bBox
            ((1.18 -0.1)
                (2.18 0.0)
            ) children
            nil groupMembers nil isAnyInst nil
            isShape t matchPoints nil net
            db:0x5f03cb1c parent nil pin db:0x5f03cc20
            purpose "drawing" textDisplays nil assocTextDisplays
            nil markers nil figGroup nil
            isUnshielded nil shieldedNet1 nil shieldedNet2
            nil layerName "PO" layerNum 17
            lpp
            ("PO" "drawing") connRoutes nil routeStatus
            "normal"
            )
        )
        ((db:0x5f03c6b6 cellView db:0x5f03c51a objType "rect"
            prop nil bBox
            ((1.18 1.0)
                (2.18 1.1)
            ) children
            nil groupMembers nil isAnyInst nil
            isShape t matchPoints nil net
            db:0x5f03cb1c parent nil pin db:0x5f03cc1f
            purpose "drawing" textDisplays nil assocTextDisplays
            nil markers nil figGroup nil
            isUnshielded nil shieldedNet1 nil shieldedNet2
            nil layerName "PO" layerNum 17
            lpp
            ("PO" "drawing") connRoutes nil routeStatus
            "normal"
            )
        )
        )

    This is what I have to replicate. In my code, I (try to) do it like this:

            terminalList = setof( terminal instId~>master~>terminals pcreMatchp( "^G" terminal~>name ) )

            foreach( terminal terminalList
                netId = dbCreateNet( cvId terminal~>net~>name )
                termId = dbCreateTerm( netId terminal~>net~>name "inputOutput" )

                foreach( pin terminal~>pins
                    instTermPinFig = car( pin~>figs )
                    pinFigId = dbCreateRect( cvId instTermPinFig~>lpp instTermPinFig~>bBox )
                    pinPinId = dbCreatePin( netId pinFigId pin~>name)
                    pinLabelId = dbCreateTextDisplay( pinFigId->net
                                    pinFigId
                                    list( car( instTermPinFig~>lpp ) "pin" )
                                    t
                                    centerBox( pinFigId~>bBox )
                                    "centerCenter"
                                    "R0"
                                    "roman"
                                    0.1
                                    nil nil t nil t
                                    "name" )
                ) ;;; end of foreach pin
             ) ;;; end of foreach terminal

    This may not be the most efficient way of doing it, but so far LayoutXL accepts this. Still, have to do some more testing LVS for instance) but so far so good.

    I still have to find a solution for the mustJoinTerms parameter. This is not working:

             when( mustJoinTermsList
                 foreach( terminal mustJoinTermsList
                     terminal~>mustJoinTerms = remove( terminal mustJoinTermsList )
                 ) ;;; end of foreach mustJoinTerms
             ) ;;; end of when

    The error it generates:

    *Error* setSGq: (DB-370034): dbSetq: Cannot set attribute - mustJoinTerms

    No clue how to do this yet.

    And Andrew, yes, you are right of course Wink, I shouldn't put those ;;; end of something comments in the code, I just set-up my editor to add this automatically....

    Once again, thank you for your contribution.

    With kind regards,

    Sjoerd

    • Cancel
    • Vote Up 0 Vote Down
    • 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.

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

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