• 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. Finding all paths in a cell and increase width

Stats

  • Locked Locked
  • Replies 6
  • Subscribers 144
  • Views 16876
  • 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

Finding all paths in a cell and increase width

Lynks
Lynks over 11 years ago

I never used SKILL before but I decided to put one together to migrate a cell library. 

The final piece I am missing is finding all paths on a particular metal layer (e.g. M1) whose width is less than 0.1 um. Once found, I'd like to set the width of all those paths to be 0.1 um. I tried searching a bit but the solutions I found were assuming the paths are selected already. In my case, I am iterating through all the cells in my library and opening the layout view. By the way, when I mention 'paths', they show up as 'path segments' in Layout XL (created by using the wire command Ctrl+Shift+W). I am not sure what the difference is between these two.

Any help on the above (assuming I already have the appropriate cv opened through dbOpenCellViewByType()) would be great.

Aside from that, this forum provided nice solutions for changing metal layers and replacing vias with new ones, and I was able to use them in my migration script. 

  • Cancel
  • Andrew Beckett
    Andrew Beckett over 11 years ago

    thinPaths=setof(shape cv~>shapes member(shape~>objType '("path" "pathSeg")) && shape~>width<0.1)
    thinPaths~>width=0.1

    This will find all the shapes which are either path or pathSeg (the path segments you mention, which are the more modern way of handling connectivity) which are narrower than 0.1um. Then having found that list, it will set the width to 0.1um.

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Lynks
    Lynks over 11 years ago

     Thank you for your fast and helpful reply, Andrew. This solution works. The only small change I made was to constrain it to the M1 layer so I added the condition:

     thinPaths=setof(shape cv~>shapes member(shape~>objType '("path" "pathSeg")) && shape~>width<0.1 && shape~>layerName=="M1")

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • tweeks
    tweeks over 11 years ago

    Another example of the map(filter(...)) pattern!  :)

    One of SKILL's more clever innovations is the inclusion of tradtional logical/set-theoretic operations implemented as variable-binding macros:

    • Quantifiers: forall, exists
    • Filter: setof
    • Map: [foreach] mapcar
    • Reduce: [foreach] mapcan

    (Well, mapcan really only covers the special case of reduce where the operator is append, but it is one of the most common use cases.)

    These macros really add a lot to the expressiveness of SKILL, and since they bind a local variable for you automatically, they often save you from using let/prog to declare one yourself.  E.g., Andrew's code above could also be written:

    foreach(thinPath setof(shape cv->shapes member(shape->objType '("path" "pathSeg")) && shape->width<0.1)
        thinPath->width = 0.1
    )
    

    Which automatically scopes "thinPath" within the foreach(mapc...), at the cost of an additional level of nesting.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 11 years ago

    I could also have used the implicit foreach mapcar of the ~> operator (rather than adding an explicit foreach like you did) by doing:

    setof(shape cv~>shapes member(shape~>objType '("path" "pathSeg")) && shape~>width<0.1 && shape~>layerName=="M1")~>width=0.1

    but for the purposes of explaining it (particular to those who are less familiar with a more functional style of programming), I intentionally broke it into two steps.

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • tweeks
    tweeks over 11 years ago

    Andrew Beckett said:
    for the purposes of explaining it (particular to those who are less familiar with a more functional style of programming), I intentionally broke it into two steps.

    Yeah, I regularly do the same for my co-workers.

    Andrew Beckett said:

    I could also have used the implicit foreach mapcar of the ~> operator (rather than adding an explicit foreach like you did) by doing:

    setof(shape cv~>shapes member(shape~>objType '("path" "pathSeg")) && shape~>width<0.1 && shape~>layerName=="M1")~>width=0.1

    For years I always wrote my code this way because it was shorter. :)  It's great for one-liners, but it doesn't scale well.  Sometimes I'd end up with code like this:

    foreach(
        foreach(
            foreach(...
               ...
            )
        )~>stuff
    )
    

    The infix ~> is just sort of awkwardly hanging there in the middle of all this prefix nesting.

    Two years ago I switched to using Lisp style so I could take advantage of Emacs' Lisp mode (since I was too lazy to write one for infix SKILL), so now I write

     
    (foreach ...
      (getSGq (foreach ...
                (foreach ...
                   ...))
              stuff))
                
    

    Which I think more clearly reflects the nesting, since it's consistently prefix.

    Using Lisp style also avoids wasting vertical space. I like the way the Emacs Lisp Reference Manual said it:

    Don't make a habit of putting close-parentheses on lines by themselves; Lisp programmers find this disconcerting.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 11 years ago

    tweeks said:
    Two years ago I switched to using Lisp style so I could take advantage of Emacs' Lisp mode (since I was too lazy to write one for infix SKILL)

     

    I too tend to write in Lisp style (and have done so for 20 years or so), for a few reasons. One was that I used to write a lot of C code, and SKILL was different enough from C that I kept making mistakes. Secondly I was somewhat familiar with Lisp and writing in Lisp syntax tended to encourage me to think in terms of Lisp ways of doing things. Thirdly "vi" has a lisp mode (I'm a vi rather than emacs user). Fourthly I'm a bit perverse...

    That said, I do tend to revert to C style when I am trying to illustrate examples or ideas, because I know the majority of the SKILL user-base uses C style and I don't want them to be put off by the "Lots of Irritating and Superflous Parentheses"...

    tweeks said:
    Don't make a habit of putting close-parentheses on lines by themselves; Lisp programmers find this disconcerting.

    That said, I do tend to shy away from excessive numbers of close parentheses on the same line - I'm not rigid on this, but I try to consider readability over compactness...

    Regards,

    Andrew.

     

    • 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