• 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. Looking for SKILL or Bindkey to change wire width based...

Stats

  • Replies 7
  • Subscribers 144
  • Views 2340
  • Members are here 0

Looking for SKILL or Bindkey to change wire width based on list of width while doing wire command

Finn Huckle
Finn Huckle 4 months ago

Hi Cadence Forum,
I am using virtuoso and familiar with the command Ctrl+Shift+Mouse Scroll Up/Down to change the wire width by increment.
Is there a SKILL, Bindkey or GUI way so that the wire width will change based on a list of widths instead of an increment?

  • Sign in to reply
  • Cancel
Parents
  • Andrew Beckett
    Andrew Beckett 3 months ago

    I tried writing something that did this, but not happy with it for two reasons:

    1. The scroll wheel is a bit sensitive to cycling through two many widths in one step
    2. I've not got the window refreshing properly and so I don't see the change until I release all the keys on the keyboard (maybe if I can fix that, then point 1 might not be a problem)

    I'll continue tinkering a bit more (likely to be next week though).

    Andrew

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
  • henker
    henker 3 months ago in reply to Andrew Beckett

    I had a small x11 utility, that moves the mouse a bit using XWarpPointer, that I called with system() in order to trigger the canvas refresh for a  more exotic trials; Maybe the problem of yours here is similar, at least it sounds familiar. Although this is a quite ugly way, it did what I wanted back then. 'xdotool mousemove' should probably do the same if available. 

    On second thought, here it could prob. also work to assign the new width from a list and than call "weScaleMagnifierOrIncreaseWidth() weScaleMagnifierOrDecreaseWidth()", which should not touch the new width but do the missing refresh.

    Regards,

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
  • Andrew Beckett
    Andrew Beckett 3 months ago in reply to henker
    henker said:

    On second thought, here it could prob. also work to assign the new width from a list and than call "weScaleMagnifierOrIncreaseWidth() weScaleMagnifierOrDecreaseWidth()", which should not touch the new width but do the missing refresh.

    I'd been trying various hiFlush/hiUpdate/hiSynchronize/hiRedraw approaches and nothing helped, and had just come to the same conclusion that calling the existing bindkey function to take advantage of that would be a good idea - when I saw your post. That also has the benefit of showing the width next to the wire being drawn.

    The code works quite well - comments in the code and example of how to register the list of widths at the top.

    /* CCFcycleWireWidths.ils
    
    Author     A.D.Beckett
    Group      Custom IC (UK), Cadence Design Systems Ltd.
    Language   SKILL
    Date       May 08, 2025 
    Modified   
    By         
    
    Uses SKILL++ lexical scoping to take advantage of local functions
    and private data, so keep the .ils suffix on this file.
    
    Example:
    
    CCFregisterWireWidths(list(0.14 0.2 0.3 0.5 0.7 0.9))
    
    hiSetBindKeys("Layout" list(
        list("Ctrl Shift<Btn4Down>" "" "CCFincreaseWireWidth()")
        list("Ctrl Shift<Btn5Down>" "" "CCFdecreaseWireWidth()")
      )
    )
    
    Note that this is a proof of concept. You could extend this to
    allow per-layer and per-technology widths (although figuring out
    the current layer in the middle of create wire might be hard).
    
    ***************************************************
    
    SCCS Info: @(#) CCFcycleWireWidths.ils 05/08/25.21:23:17 1.1
    
    */
    
    let((wireWidths)
      /***************************************************************
      *                                                              *
      *             CCFregisterWireWidths(listOfWidths)              *
      *                                                              *
      *      Global function to register a list of wire widths       *
      *                                                              *
      ***************************************************************/
      globalProc(CCFregisterWireWidths(listOfWidths)
        wireWidths=listOfWidths
      )
      /***************************************************************
      *                                                              *
      *                changeWireWidth(win increase)                 *
      *                                                              *
      *  Local (internal) function to change the wire width through  *
      *  the registered list, either increase (t) or decrease (nil)  *
      *                                                              *
      ***************************************************************/
      procedure(changeWireWidth(win increase)
        letseq((
          (cvId geGetEditCellView(win))
          (techId techGetTechFile(cvId))
          (wireForm leGetTechFormList(techId)->wireForm)
          (wireWidth wireForm->wireWidth->value)
          remainingWidths
          )
          if(increase then
            remainingWidths=exists(width wireWidths width>wireWidth)
          else
            remainingWidths=exists(width reverse(wireWidths) width<wireWidth)
          )
          when(remainingWidths
            wireForm->wireWidth->value=car(remainingWidths)
          )
          ;----------------------------------------------------------------
          ; force an update. By increasing then decreasing, it leaves
          ; it at the level set by the code above
          ;----------------------------------------------------------------
          weScaleMagnifierOrIncreaseWidth()
          weScaleMagnifierOrDecreaseWidth()
        )
      )
      /***************************************************************
      *                                                              *
      *  CCFincreaseWireWidth(@optional (win hiGetCurrentWindow()))  *
      *                                                              *
      *  Increase the wire width to the next in the list of widths   *
      *                                                              *
      ***************************************************************/
      globalProc(CCFincreaseWireWidth(@optional (win hiGetCurrentWindow()))
        if(hiGetCurrentCmd(win)=="Wire" then
          changeWireWidth(win t)
        else
          weScaleMagnifierOrIncreaseWidth()
        )
      )
      /****************************************************************
      *                                                               *
      *  CCFdecreaseWireWidth(@optional (win hiGetCurrentWindow()))   *
      *                                                               *
      * Decrease the wire width to the previous in the list of widths *
      *                                                               *
      ****************************************************************/
      globalProc(CCFdecreaseWireWidth(@optional (win hiGetCurrentWindow()))
        if(hiGetCurrentCmd(win)=="Wire" then
          changeWireWidth(win nil)
        else
          weScaleMagnifierOrDecreaseWidth()
        )
      )
    )
              

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
  • Finn Huckle
    Finn Huckle 3 months ago in reply to Andrew Beckett

    Hi Andrew Beckett ,
    Thank you for the response.
    The SKILL script you created is now working.
    But we encountered some minor hiccups:
    1. Code works for leHiCreateWire() but doesn't work on leHiCreateBus() is it possible to make it work for both?
    2. We set the max wire width as 4.5 (This is the max for the technology we are using) but SKILL script stops at 4.49 (see screenshot)
        Is it possible to fix it?

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
  • Andrew Beckett
    Andrew Beckett 3 months ago in reply to Finn Huckle

    I updated the code to address both of these. I plan to add support next week (when I have a moment) for per-layer width lists (since I think that would be useful too - just didn't have time to do that...)

    /* CCFcycleWireWidths.ils
    
    Author     A.D.Beckett
    Group      Custom IC (UK), Cadence Design Systems Ltd.
    Language   SKILL
    Date       May 08, 2025 
    Modified   A.D.Beckett
    By         May 09, 2025 
    
    Uses SKILL++ lexical scoping to take advantage of local functions
    and private data, so keep the .ils suffix on this file.
    
    Example:
    
    CCFregisterWireWidths(list(0.14 0.2 0.3 0.5 0.7 0.9))
    
    hiSetBindKeys("Layout" list(
        list("Ctrl Shift<Btn4Down>" "" "CCFincreaseWireWidth()")
        list("Ctrl Shift<Btn5Down>" "" "CCFdecreaseWireWidth()")
      )
    )
    
    Note that this is a proof of concept. You could extend this to
    allow per-layer and per-technology widths.
    
    ***************************************************
    
    SCCS Info: @(#) CCFcycleWireWidths.ils 05/09/25.08:51:40 1.2
    
    */
    
    let((wireWidths)
      /***************************************************************
      *                                                              *
      *             CCFregisterWireWidths(listOfWidths)              *
      *                                                              *
      *      Global function to register a list of wire widths       *
      *                                                              *
      ***************************************************************/
      globalProc(CCFregisterWireWidths(listOfWidths)
        wireWidths=listOfWidths
      )
      /***************************************************************
      *                                                              *
      *                changeWireWidth(win increase)                 *
      *                                                              *
      *  Local (internal) function to change the wire width through  *
      *  the registered list, either increase (t) or decrease (nil)  *
      *                                                              *
      ***************************************************************/
      procedure(changeWireWidth(win increase @optional (formName 'wireForm)
                  (widthField 'wireWidth))
        letseq((
          (cvId geGetEditCellView(win))
          (techId techGetTechFile(cvId))
          (wireForm get(leGetTechFormList(techId) formName))
          (wireWidth get(wireForm widthField)->value)
          (isString stringp(wireWidth))
          (wireWidthNum if(isString atof(wireWidth) wireWidth))
          remainingWidths
          )
          if(increase then
            remainingWidths=exists(width wireWidths width>wireWidthNum)
          else
            remainingWidths=exists(width reverse(wireWidths) width<wireWidthNum)
          )
          when(remainingWidths
            get(wireForm widthField)->value=
              if(isString lsprintf("%g" car(remainingWidths)) car(remainingWidths))
          )
          ;----------------------------------------------------------------
          ; force an update. By increasing then decreasing, it leaves
          ; it at the level set by the code above. Ordering is to ensure 
          ; that if the min or max width then you don't end up one step
          ; before that limit
          ;----------------------------------------------------------------
          if(increase then
            weScaleMagnifierOrDecreaseWidth()
            weScaleMagnifierOrIncreaseWidth()
          else
            weScaleMagnifierOrIncreaseWidth()
            weScaleMagnifierOrDecreaseWidth()
          )
        )
      )
      /***************************************************************
      *                                                              *
      *  CCFincreaseWireWidth(@optional (win hiGetCurrentWindow()))  *
      *                                                              *
      *  Increase the wire width to the next in the list of widths   *
      *                                                              *
      ***************************************************************/
      globalProc(CCFincreaseWireWidth(@optional (win hiGetCurrentWindow()))
        let(((viewType deGetViewType(win)))
          case(hiGetCurrentCmd(win)
            ("Wire" changeWireWidth(win t))
            ("Bus" 
              changeWireWidth(
                win t if(viewType=="maskLayout" 'busForm 'busBetterTierForm)
                'busWireWidth
              )
            )
            (t weScaleMagnifierOrIncreaseWidth())
          )
        )
      )
      /****************************************************************
      *                                                               *
      *  CCFdecreaseWireWidth(@optional (win hiGetCurrentWindow()))   *
      *                                                               *
      * Decrease the wire width to the previous in the list of widths *
      *                                                               *
      ****************************************************************/
      globalProc(CCFdecreaseWireWidth(@optional (win hiGetCurrentWindow()))
        let(((viewType deGetViewType(win)))
          case(hiGetCurrentCmd(win)
            ("Wire" changeWireWidth(win nil))
            ("Bus" 
              changeWireWidth(
                win nil if(viewType=="maskLayout" 'busForm 'busBetterTierForm)
                'busWireWidth
              )
            )
            (t weScaleMagnifierOrDecreaseWidth())
          )
        )
      )
    )
    

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
Reply
  • Andrew Beckett
    Andrew Beckett 3 months ago in reply to Finn Huckle

    I updated the code to address both of these. I plan to add support next week (when I have a moment) for per-layer width lists (since I think that would be useful too - just didn't have time to do that...)

    /* CCFcycleWireWidths.ils
    
    Author     A.D.Beckett
    Group      Custom IC (UK), Cadence Design Systems Ltd.
    Language   SKILL
    Date       May 08, 2025 
    Modified   A.D.Beckett
    By         May 09, 2025 
    
    Uses SKILL++ lexical scoping to take advantage of local functions
    and private data, so keep the .ils suffix on this file.
    
    Example:
    
    CCFregisterWireWidths(list(0.14 0.2 0.3 0.5 0.7 0.9))
    
    hiSetBindKeys("Layout" list(
        list("Ctrl Shift<Btn4Down>" "" "CCFincreaseWireWidth()")
        list("Ctrl Shift<Btn5Down>" "" "CCFdecreaseWireWidth()")
      )
    )
    
    Note that this is a proof of concept. You could extend this to
    allow per-layer and per-technology widths.
    
    ***************************************************
    
    SCCS Info: @(#) CCFcycleWireWidths.ils 05/09/25.08:51:40 1.2
    
    */
    
    let((wireWidths)
      /***************************************************************
      *                                                              *
      *             CCFregisterWireWidths(listOfWidths)              *
      *                                                              *
      *      Global function to register a list of wire widths       *
      *                                                              *
      ***************************************************************/
      globalProc(CCFregisterWireWidths(listOfWidths)
        wireWidths=listOfWidths
      )
      /***************************************************************
      *                                                              *
      *                changeWireWidth(win increase)                 *
      *                                                              *
      *  Local (internal) function to change the wire width through  *
      *  the registered list, either increase (t) or decrease (nil)  *
      *                                                              *
      ***************************************************************/
      procedure(changeWireWidth(win increase @optional (formName 'wireForm)
                  (widthField 'wireWidth))
        letseq((
          (cvId geGetEditCellView(win))
          (techId techGetTechFile(cvId))
          (wireForm get(leGetTechFormList(techId) formName))
          (wireWidth get(wireForm widthField)->value)
          (isString stringp(wireWidth))
          (wireWidthNum if(isString atof(wireWidth) wireWidth))
          remainingWidths
          )
          if(increase then
            remainingWidths=exists(width wireWidths width>wireWidthNum)
          else
            remainingWidths=exists(width reverse(wireWidths) width<wireWidthNum)
          )
          when(remainingWidths
            get(wireForm widthField)->value=
              if(isString lsprintf("%g" car(remainingWidths)) car(remainingWidths))
          )
          ;----------------------------------------------------------------
          ; force an update. By increasing then decreasing, it leaves
          ; it at the level set by the code above. Ordering is to ensure 
          ; that if the min or max width then you don't end up one step
          ; before that limit
          ;----------------------------------------------------------------
          if(increase then
            weScaleMagnifierOrDecreaseWidth()
            weScaleMagnifierOrIncreaseWidth()
          else
            weScaleMagnifierOrIncreaseWidth()
            weScaleMagnifierOrDecreaseWidth()
          )
        )
      )
      /***************************************************************
      *                                                              *
      *  CCFincreaseWireWidth(@optional (win hiGetCurrentWindow()))  *
      *                                                              *
      *  Increase the wire width to the next in the list of widths   *
      *                                                              *
      ***************************************************************/
      globalProc(CCFincreaseWireWidth(@optional (win hiGetCurrentWindow()))
        let(((viewType deGetViewType(win)))
          case(hiGetCurrentCmd(win)
            ("Wire" changeWireWidth(win t))
            ("Bus" 
              changeWireWidth(
                win t if(viewType=="maskLayout" 'busForm 'busBetterTierForm)
                'busWireWidth
              )
            )
            (t weScaleMagnifierOrIncreaseWidth())
          )
        )
      )
      /****************************************************************
      *                                                               *
      *  CCFdecreaseWireWidth(@optional (win hiGetCurrentWindow()))   *
      *                                                               *
      * Decrease the wire width to the previous in the list of widths *
      *                                                               *
      ****************************************************************/
      globalProc(CCFdecreaseWireWidth(@optional (win hiGetCurrentWindow()))
        let(((viewType deGetViewType(win)))
          case(hiGetCurrentCmd(win)
            ("Wire" changeWireWidth(win nil))
            ("Bus" 
              changeWireWidth(
                win nil if(viewType=="maskLayout" 'busForm 'busBetterTierForm)
                'busWireWidth
              )
            )
            (t weScaleMagnifierOrDecreaseWidth())
          )
        )
      )
    )
    

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
Children
  • Finn Huckle
    Finn Huckle 3 months ago in reply to Andrew Beckett

    Hi Andrew,

    Your new code works!
    Yeah, a per layer feature would be great.

    We are trying to use a grid/track workflow, and this type of SKILL made the implementation easier.

    Thanks always for the help.

    • Cancel
    • Vote Up +1 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.

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

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