• 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. Skill Code for Automatic Pin Placement

Stats

  • Locked Locked
  • Replies 2
  • Subscribers 144
  • Views 15763
  • 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

Skill Code for Automatic Pin Placement

imaneet
imaneet over 11 years ago

Can some help creating a skill code for automatic pin placement on devices/blocks?

In my case, i have a logic block which is already been done (pins are placed) but on the next heirarchy, the pins labels have changed. the skill routine should just place the new pins to the logic block instead of doing it manually again.

  • Cancel
  • W Relyveld
    W Relyveld over 11 years ago

    Hello,

    I am doing this and have inserted the function below. But it is not directly usable: it is part of a collection of functions I use and needs a global parameter wrtop and another function to notify results (wrWindowName). You could modify the procedure to accept parameters or first define the global parameter, see below.

    After the pins are copied, the pin labels can be added with procedure wrAddLabels. It is also pasted below. I also requires some wrtop.xx values which are process dependent. I always try to create process independent procedures. I probably miss several things but if you want to invest some time I think you can get it working. Use what you need.

     

    Greetings, William 

          setplist( 'wrtop nil)

          wrtop.Cell = geGetEditCellView( wrtop.Window)

          wrtop.LibName = wrtop.Cell->libName

          wrtop.DbType = dbGetDatabaseType()

          wrtop.CellName = wrtop.Cell->cellName

          wrtop.ViewName = wrtop.Cell->viewName

          wrtop.CellViewType = wrtop.Cell->cellViewType

          wrtop.CellViewMode = wrtop.Cell->mode  wrtop.StepMin = 0.01

    ;; process dependent: select pin/text  

    wrtop.LabelPinType  = "pin"


    ;; The function: 

    procedure( wrCopyPins( )

      

      let( ( wr instances)

        

        wr = ncons( nil)

        wr->Text = ""

        

        wr->Replaced = 0

        

        unless( rexMatchp( "layout" wrtop.ViewName)

          wr->Text = strcat( "skip non-layout view " wrtop.ViewName)

          wr->Error = t

        )

        

        when( ! wr->Error && wrtop.CellViewMode == "r"

          wr->Text = "error: cell must be editable"

          wr->Error = t

        )

        

        unless( wr->Error

          wr->SchCell = wrOpenCellViewByType( wrtop.LibName wrtop.CellName "schematic")

          unless( wr->SchCell

            wr->Text = "warning: schematic view not found"

            printf( wr->Text)

          )

        )

        

        unless( wr->Error

          instances = geGetSelectedSet( )

          instancepointer = car( instances)

        )

        

        when( ! wr->Error && ! instancepointer

          wr->Text = "error: nothing selected, please select a single instance"

          wr->Error = t

        )

        

        when( ! wr->Error && length( instances) > 1

          wr->Text = "error: selection contains more than one instance, please select a single instance"

          wr->Error = t

        )

        

        when( ! wr->Error && instancepointer->objType != "inst"

          wr->Text = strcat( "error: " pcExprToString( instancepointer->objType) " selected, please select a single instance")

          wr->Error = t

        )

        

        unless( wr->Error || ! wr->SchCell

          ;; get the schematic instance to be able to search the net names to which the instance terminals connect 

          rexCompile( "|")

          wr->InstName = rexReplace( instancepointer->name "" 1)

          wr->SchInst = dbFindAnyInstByName( wr->SchCell wr->InstName)

        )

        

        when( ! wr->Error && ! wr->SchInst

          printf( "%s: warning: did not find schematic instance %s\nwill not translate pins names." getCallingFunction( 0) instancepointer->name)

          wr->Text = "warning: pins not translated. "

        )

        

        when( ! wr->Error && wr->SchInst

          wr->TerminalNames = wr->SchCell~>terminals~>name

          when( ! wr->Error && ! wr->TerminalNames

            wr->Text = "no terminals found"

            wr->Error = t

          )

        )

        

        when( ! wr->Error && wr->SchInst

          ;; The schematic terminal names can contain <x:0> while the layout terminals are <y> type. Change both to <>.

          rexCompile( "<[0-9:]+>")

          wr->TerminalNamesFiltered = list( nil)

          foreach( term wr->TerminalNames

            wr->TerminalNamesFiltered = append1( wr->TerminalNamesFiltered rexReplace( term "<>" 1))

          )

        )

        unless( wr->Error

        

          when( wr->SchInst

            rexCompile( "<[0-9:]+>")

            wr->ConList = mapcar( lambda( ( name) rexReplace( name "" 1)) wr->SchInst->conns~>name)

            wr->NetList = mapcar( lambda( ( name) rexReplace( name "" 1)) wr->SchInst->conns~>net~>name)

            wr->TranslateList = mapcar( lambda( ( con net) if( con != net list( con net))) wr->ConList wr->NetList)

            wr->TranslateList = setof( list wr->TranslateList list)

          )

          geDeselectAll( )

          wr->BboxV = wrGetBBView( )

          wr->trans = geGetInstTransform( instancepointer)

          foreach( net instancepointer~>master~>nets

            wr->NewNetName = net~>name

            rexCompile( "<[0-9]+>")

            wr->OldNetNameBase = rexReplace( net~>name "" 1)

            rexCompile( ":$")

            wr->OldNetNameBase = rexReplace( wr->OldNetNameBase "" 1)

            wr->NewNetNameBase = cadr( assoc( wr->OldNetNameBase wr->TranslateList))

            if( wr->NewNetNameBase

            then

              rexCompile( wr->OldNetNameBase)

              wr->NewNetName = rexReplace( net~>name wr->NewNetNameBase 1)

            else

              wr->NewNetName = net~>name

              wr->NewNetNameBase = wr->OldNetNameBase

            )

            when( ! wr->SchInst || member( wr->NewNetNameBase wr->TerminalNamesFiltered) || member( strcat( wr->NewNetNameBase "<>") wr->TerminalNamesFiltered)

              ;; copy pins if it is also a pin at the current level

              wr->NewNet = dbFindNetByName( wrtop.Cell wr->NewNetName)

              unless( wr->NewNet wr->NewNet = dbCreateNet( wrtop.Cell wr->NewNetName))

              wr->term = net~>term

              wr->NewTerm = dbFindTermByName( wrtop.Cell wr->NewNetName)

              unless( wr->NewTerm

                wr->IOType = wr->term->direction

                unless( wr->IOType wr->IOType = "input")

                wr->NewTerm = dbCreateTerm( wr->NewNet wr->NewNetName wr->IOType)

              )

              wr->Rect = nil

              foreach( pin wr->term~>pins

                when( pin->fig->bBox

                  wr->Bbox = dbTransformBBox( pin->fig->bBox wr->trans)

                  when( 

                       leftEdge(  wr->Bbox) > leftEdge( wr->BboxV) && 

                       rightEdge( wr->Bbox) < rightEdge( wr->BboxV) && 

                       bottomEdge( wr->Bbox) > bottomEdge( wr->BboxV) && 

                       topEdge( wr->Bbox) < topEdge( wr->BboxV)

                       when( net->name != wr->NewNetName printf( "%s: connecting %s to %s\n" getCallingFunction( 0) net->name wr->NewNetName))

                     wr->RodName = sprintf( nil "pin_%s" wr->NewNetName)

                     ; wr->lpp = pin->fig->lpp

                     wr->lpp = list( car( pin->fig->lpp) "pin")

                     wr->Rod = rodGetObj( wr->RodName wrtop.Cell)

                     cond( 

                       ( ! wr->Rod

                         ;; Create a rod object for the rect

                         wr->Rod = rodCreateRect( ?name wr->RodName ?layer wr->lpp ?bBox wr->Bbox ?cvId wrtop.Cell)

                         wr->Rect = wr->Rod->dbId

                       )

                       ( wr->Rod->dbId->bBox != wr->Bbox

                         wr->Rect = dbCreateRect( wrtop.Cell wr->lpp wr->Bbox)

                       )

                     )

                     when( wr->Rect

                       leAttachFig( wr->Rect instancepointer)

                       wr->newpin = dbCreatePin( wr->NewNet wr->Rect)

                       wr->newpin~>accessDir = pin~>accessDir

                       geSelectObject( wr->Rect)

                       wr->Replaced = wr->Replaced + 1

                    )

                  )

                )

              )

            )

          )

        ) ;; unless

        unless( wr->Error

          if( wr->Replaced == 0

          then

            wr->Text = "no pins copied"

          else

            wr->Text = strcat( wr->Text pcExprToString( wr->Replaced) " pins copied")

            wrtop.stick = t

          )

        ) ;; unless

        

        stringp( wr->Text) && wrWindowName( sprintf( nil "%s%s%s: %s: %s" wrtop.MacroTxt wrtop.WriteModeTxt wrtop.DecodeBindKeysText getCallingFunction( 0) wr->Text))

        ! wr->Error

      )

    )

    procedure( wrAddLabels( )

      

      let( ( wr instances)

        

        wr = ncons( nil)

        

        wr->Replaced = 0

        

        unless( rexMatchp( "layout" wrtop.ViewName)

          wr->Text = strcat( "skip non-layout view " wrtop.ViewName)

          wr->Error = t

        )

        

        when( ! wr->Error && wrtop.CellViewMode == "r"

          wr->Text = "error: cell must be editable"

          wr->Error = t

        )

        

        if( wrtop.Window

        then

          instances = geGetSelectedSet( )

          wr->BboxV = wrGetBBView( )

        else

          instances = wrtop.Cell~>instances

          wr->BboxV = wrtop.Cell->bBox

        )

        

        unless( instances

          geAddSelectBox( wrtop.Window t hiGetViewBBox( ))

          instances = geGetSelectedSet( )

          geDeselectAll( )

        )

        sel = setof( shape instances shape~>objType == "rect" && ( shape~>purpose == "pin" || shape~>purpose == "lvstext"))

        

        when( ! wr->Error && ! sel

          wr->Text = "no pins found"

           wr->Error = t

        )

        

        unless( wr->Error

          wr->BboxVx1 = leftEdge( wr->BboxV)

          wr->BboxVy1 = bottomEdge( wr->BboxV)

          wr->BboxVx2 = rightEdge( wr->BboxV)

          wr->BboxVy2 = topEdge( wr->BboxV)

          foreach( pin sel

            when( wr->Term = pin->net->term

              wr->PinName = pin->net->name

              wr->Bbox = pin->bBox

              wr->x1 = leftEdge( wr->Bbox)

              wr->y1 = bottomEdge( wr->Bbox)

              wr->x2 = rightEdge( wr->Bbox)

              wr->y2 = topEdge( wr->Bbox)

              wr->PointX = (wr->x1 + wr->x2)/2

              wr->PointY = (wr->y1 + wr->y2)/2

              wr->Point = list( wr->PointX wr->PointY)

              wr->Height = wr->y2 - wr->y1

              wr->Width  = wr->x2 - wr->x1

     

              if( min( abs( wr->PointY - wr->BboxVy1) abs( wr->PointY - wr->BboxVy2)) < min( abs( wr->PointX - wr->BboxVx1) abs( wr->PointX - wr->BboxVx2)) + 0.001

              then

                wr->LabelOrient = "R90"

                wr->LabelHeight = wr->Height / 2

              else

                wr->LabelOrient = "R0"

                wr->LabelHeight = wr->Width / 2

              )

              cond(

               ( wr->LabelHeight < 0.2

                wr->LabelHeight = 0.2

                )

               ( wr->LabelHeight > 22.0

                wr->LabelHeight = 22.0

                )

              )

              ;; BB: changed layer name reference for abcd3

              if( wrtop.Process == "abcd3" 

              then

                wr->layerName = "text"

              else

                wr->layerName = pin->layerName

              )

              

              unless( pin->children

                wr->Label = dbCreateTextDisplay( wr->Term wr->Term list( wr->layerName wrtop.LabelPinType) list( "font" "justify" "height" "orient" "drafting" "overbar" "origin" "visible") wr->Point "centerCenter" wr->LabelOrient "stick" wr->LabelHeight t nil t nil t "name" nil)

                wr->Label->parent = pin

                wr->Replaced = wr->Replaced + 1

                

                wr->RodName = sprintf( nil "pin_%s" wr->PinName)

                unless( rodGetObj( wr->RodName wrtop.Cell)

                  ;; Asign a rod name to the rect

                  rodNameShape( ?name wr->RodName ?shapeId pin ?permitRename t)

                )

              )

            )

          ); foreach pin

          

          unless( wr->Error

            if( wr->Replaced == 0

            then

              wr->Text = "no corrections required"

            else

              wr->Text = strcat( pcExprToString( wr->Replaced) " labels created")

              

              when( integerp( wrtop.Applied)

                wrtop.Applied = wrtop.Applied + 1

              )

            )

          )

        )

        

        unless( stringp( wr->Text) wr->Text = "unknown error")

        unless( rexMatchp( wrtop.CellName wr->Text) wr->Text = sprintf( nil "%s, %s" wrtop.CellName wr->Text))

        wrWindowName( sprintf( nil "%s%s%s: %s: %s" wrtop.MacroTxt wrtop.WriteModeTxt wrtop.DecodeBindKeysText getCallingFunction( 0) wr->Text))

        ! wr->Error

      )

    )

    procedure( wrGetBBView( )

      

      let( ( wrPointList)

        wrPointList = list( 

          geWindowToEditPoint( wrtop.Window car( hiGetViewBBox( hiGetCurrentWindow( ))))

          geWindowToEditPoint( wrtop.Window cadr( hiGetViewBBox( hiGetCurrentWindow( )))))

      list( 

        min( caar( wrPointList) caadr( wrPointList)) : min( cadar( wrPointList) cadadr( wrPointList))

        max( caar( wrPointList) caadr( wrPointList)) : max( cadar( wrPointList) cadadr( wrPointList)))

      )

    )

    procedure( wrWindowName( text "t")

     

      let( ( wr)

        

        wr = ncons( nil)

        

        if( wrtop.stick

        then

          wrtop.stick = nil

        else

          foreach( window hiGetWindowList( )

            

            if( boundp( 'geIsGraphicalWindow)

            then

              geIsGraphicalWindow( window)

              hiChangeBannerLabel( window text 0)

            else

              wr->ViewName = geGetWindowRep( window)->viewName

              getWarn( )

              unless( wr->ViewName

                wr->ViewName = "empty"

              )

              when( rexMatchp( "schematic" wr->ViewName) || rexMatchp( "layout" wr->ViewName) || rexMatchp( "symbol" wr->ViewName) || rexMatchp( "extracted" wr->ViewName)

                hiChangeBannerLabel( window text 0)

              )

            )

          )

          when( wrtop.LogFile

            fprintf( wrtop.LogFile "%s - %s\n" getCurrentTime( ) text)

            printf( "%s\n" text)

            sh( sprintf( nil "echo \"%s\"\n" text))

            when( rexMatchp( "error" text)

              sh( sprintf( nil "zsh -c \". ~/.zshrc; Background=on; FlowE '%s'\"" text))

            )

          )

        )

      )

    )


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

    Thanks, I like the line that says "Greetings William". Just to do test cases i would just say "hello" to be sure it's working.

    I will use whatever i can, thanks for the help.

    • 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