• 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. Spectre Netlisting Multiple Instance Resistors

Stats

  • Locked Locked
  • Replies 4
  • Subscribers 143
  • Views 11948
  • 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

Spectre Netlisting Multiple Instance Resistors

Kevin Buck
Kevin Buck over 3 years ago

I've modified the PDK I'm using to enable instantiation of resistors with multiple parts. For example you can create a resistor of unit width 2um, unit length 10um and specify number of parts and whether they are configured in series or parallel. The way the CDF is configured (as well as the model) doesn't support the multiple part parameter and this creates a problem for both simulation and LVS verification. I found the following article to fix the LVS issue with auCdl netlist customization (https://support.cadence.com/apex/ArticleAttachmentPortal?id=a1O3w000009xxONEAY&pageName=ArticleContent) and I'm wondering if there is something similar I can do with the Spectre netlisting. I'd prefer to not mess with the models as it's not my area of expertise. I've also considered scaling the parameters that are passed to the model file (instParameters) but I don't see a way to do this that would satisfy both the resistance calculation and the statistical calculation, it would work fine for the parallel configuration but not series.

 ;;; Simulator Information
cdfId->simInfo = list( nil )
cdfId->simInfo->auCdl = '( nil
netlistProcedure ansCdlCompParamPrim
instParameters (W L SUB)
termOrder (PLUS MINUS)
propMapping (nil W w L l)
namePrefix "R"
componentName "RNPPO"
modelName "RNPPO"
)
cdfId->simInfo->spectre = '( nil
termMapping (nil PLUS \:1 MINUS \:2 B \:3)
termOrder (PLUS MINUS B)
instParameters (w l)
opParamExprList (("rh1" "OP(mappedRoot(\".rppoly_l_lf150.rHead_1\") \"res\")") ("rb" "OP(mappedRoot(\".rppoly_l_lf150.rBulk\") \"res\")") ("rh2" "OP(mappedRoot(\".rppoly_l_lf150.rHead_2\") \"res\")") ("i" "OP(mappedRoot(\".rppoly_l_lf150.rBulk\") \"i\")"))
otherParameters (model)
)
  • Cancel
Parents
  • Andrew Beckett
    Andrew Beckett over 3 years ago

    Hi Kevin,

    The best way to achieve this is to have a Schematic PCell which takes care of producing the series or parallel connected structure and that then means that everything will behave, albeit with an extra level of hierarchy (of course, PCell Designer would help with that Slight smile ). It would also be possible to write a custom netlist procedure for the spectre netlister to write multiple instances into the netlist (as the approach for the CDL netlister you link to proposes), but there's a downside with that since annotation and probing of currents etc becomes problematic because there's nothing for the tools to know that there is a one to many mapping from the schematic device to what ends up in the netlist (and hence the simulation results). Given a choice, I'd definitely go for the Schematic PCell approach.

    There are a few netlist procedure examples (for example here - one I picked somewhat at random), but I don't think there are any articles that show doing this to create multiple instances (although it wouldn't be hard using the documented nl functions), even though I don't think it's the best approach.

    Regards,

    Andrew

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

    I found an easy way to fix this but I'm having an LVS issue with the linked procedure due to the way the instance creation handles the instance term order. This doesn't seem to be controlled by the port order property in the symbol or the term order specified in the in the base CDF. However it creates an issue because the default ordering is the alphanumeric sorting default first sorted by pin type. It's easy enough to modify the script to get the right terminal but I'd rather force the instance to have the terminal order I want as it seems a little dangerous to leave that to chance. To be specific what I'm referring to is this property:

    schView = dbOpenCellViewByType("kbu_edatrial" "lvs_check" "schematic" "" "r")
    inst=nth(1 schView~>instances)             ;This is an instance of the customized resistor


    If I request inst~>instTerms~>name it shows the default alphanumeric ordering (B MINUS PLUS) and inst is what gets passed to the function ansCdlGetSegmentConnections. Is there a way to control this instance order? If I open the properties in the schematic it shows the order I want in the system menu (PLUS MINUS B). The pin order in the symbol shows MINUS PLUS B so that doesn't seem to control the ordering on instances.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Reply
  • Kevin Buck
    Kevin Buck over 3 years ago in reply to Andrew Beckett

    I found an easy way to fix this but I'm having an LVS issue with the linked procedure due to the way the instance creation handles the instance term order. This doesn't seem to be controlled by the port order property in the symbol or the term order specified in the in the base CDF. However it creates an issue because the default ordering is the alphanumeric sorting default first sorted by pin type. It's easy enough to modify the script to get the right terminal but I'd rather force the instance to have the terminal order I want as it seems a little dangerous to leave that to chance. To be specific what I'm referring to is this property:

    schView = dbOpenCellViewByType("kbu_edatrial" "lvs_check" "schematic" "" "r")
    inst=nth(1 schView~>instances)             ;This is an instance of the customized resistor


    If I request inst~>instTerms~>name it shows the default alphanumeric ordering (B MINUS PLUS) and inst is what gets passed to the function ansCdlGetSegmentConnections. Is there a way to control this instance order? If I open the properties in the schematic it shows the order I want in the system menu (PLUS MINUS B). The pin order in the symbol shows MINUS PLUS B so that doesn't seem to control the ordering on instances.

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

    Sorry I should have specified the pin types to make this more clear:

    So B gets placed first because it is type 'input' and then MINUS and PLUS follow with the alphanumeric sorting.

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

    I found a SKILL function that makes it easy to build the netlist the way I want without caring what the instance terms look like. Maybe this would be an improvement to the existing solution?

    procedure(ansCdlGetSegmentConnections( inst connectionPairs iterSeg iterMult
    numSegments multiplicityFactor
    segmentConnType netCount )

    let( ( pairList )
    ;For series connections the procedure varies depending on which segment
    ;is being processed. In all cases the bulk connection remains the same.
    if( "series" == segmentConnType
    then
    cond(
    ;For the first segment the plus connection remains the same as in the schematic and
    ;the minus connection gets a new net name sNet with the netCount appended to it.
    ( (1 == iterSeg )
    pairList = list(
    car(setof(x connectionPairs car(x)=="PLUS"))
    list( caar(setof(x connectionPairs car(x)=="MINUS")) sprintf( nil "%s_sNet_%d" inst~>name netCount) )
    list( caar(setof(x connectionPairs car(x)=="B")) cadar(setof(x connectionPairs car(x)=="B")) )
    )
    )
    ;For the last segment the minus connection remains the same as in the schematic
    ;and the plus connection gets connected to the previously processed segment.
    ( ( iterSeg == numSegments )
    pairList = list(
    list( caar(setof(x connectionPairs car(x)=="PLUS")) sprintf( nil "%s_sNet_%d" inst~>name netCount-1) )
    car(setof(x connectionPairs car(x)=="MINUS"))
    list( caar(setof(x connectionPairs car(x)=="B")) cadar(setof(x connectionPairs car(x)=="B")) )
    )
    )
    ;For intermediate segments the plus connection gets connected to the previously processed
    ;segment and the minus connection gets a new net name with the netCount appended to it.
    (t
    pairList = list(
    list( caar(setof(x connectionPairs car(x)=="PLUS")) sprintf( nil "%s_sNet_%d" inst~>name netCount-1) )
    list( caar(setof(x connectionPairs car(x)=="MINUS")) sprintf( nil "%s_sNet_%d" inst~>name netCount) )
    list( caar(setof(x connectionPairs car(x)=="B")) cadar(setof(x connectionPairs car(x)=="B")) )
    )
    )
    )
    ;For parallel connections the terminals are identical to the schematic for all parts
    else
    pairList = list(
    list( caar(setof(x connectionPairs car(x)=="PLUS")) cadar(setof(x connectionPairs car(x)=="PLUS")) )
    list( caar(setof(x connectionPairs car(x)=="MINUS")) cadar(setof(x connectionPairs car(x)=="MINUS")) )
    list( caar(setof(x connectionPairs car(x)=="B")) cadar(setof(x connectionPairs car(x)=="B")) )
    )
    )
    ;Return the list of connections for this segment
    pairList
    )
    )
    • 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