• 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. align instances to pins in lower hierarchy based on con...

Stats

  • Locked Locked
  • Replies 8
  • Subscribers 144
  • Views 6541
  • 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

align instances to pins in lower hierarchy based on connectivity

JRP29
JRP29 over 1 year ago

Hi, 
I am looking for a quick way to align instances or pcells like NODE_BREAKER/ METAL_RESISTOR to pins in lower hierarchy in layout based on connectivity. 
For example, I have 100 pins say A2D<1:100> in a layout and in next hierarchy level those 100 pins are connecting to next level pins A2D_TOP<1:100> but with node_breaker/metal_resistor separating them. To align the top level pins to below level, first I need to align those 100 node_breaker/metal_resistor to the lower level pins. 
Manually doing this is time consuming. Is there a way to align instances to pins in lower level?

  • Cancel
Parents
  • AurelBuche
    AurelBuche over 1 year ago

    Hi, without more details it is quite hard to understand exactly what you want to do. (A screenshot is very welcome to illustrate what you mean)

    However, I modified a script I already developped to achieve the goal  I understood from your explanation.

    Here it is : 

    (defun ab_auto_place_instances ( @key  (cv         (geGetEditCellView))
                                           (cell_name  "rmx"              )
                                           (horiz_just 'left              )
                                           (vert_just  'bottom            )
                                     @rest _args )
      "Browse CV incomplete nets, align each instance matching CELL_NAME to the first found pin
    in the incomplete net. HORIZ_JUST can be 'left, 'center or 'right. VERT_JUST can be 'bottom, 'center or 'top. "
    ;; Define functions used to align the pins (let ((get_x (caseq (concat (lowerCase horiz_just)) (left (lambda (box) (leftEdge box))) (right (lambda (box) (rightEdge box))) (center (lambda (box) (xCoord (centerBox box)))) (t (error "?horiz_just should be 'left, 'center or 'right")) )) (get_y (caseq (concat (lowerCase vert_just)) (bottom (lambda (box) (bottomEdge box))) (top (lambda (box) (topEdge box))) (center (lambda (box) (yCoord (centerBox box)))) (t (error "?vert_just should be 'bottom, 'center or 'top")) )) ) ;; Browse incomplete nets (foreach incomplete_net (lceGetIncompleteNets cv) ;; Try to find instance matching CELL_NAME ;; 'source' prefixed variables describe objects related to the instance matching CELL_NAME ;; 'target' prefixed variables describe objects related to the destination pin used to align (letseq ((conns incomplete_net->instTerms) (source_conn (car (exists conn conns (equal cell_name conn->inst->cellName)))) ) (when source_conn (letseq (;; Find source pin box (source_inst source_conn->inst) (source_pin_shape (car source_conn->term->pins)->fig) (source_pin_box (dbTransformBBox source_pin_shape->bBox source_inst->transform)) ;; Find target pin box (target_conn (car (remove source_conn conns))) (target_inst target_conn->inst) (target_pin_shape (car target_conn->term->pins)->fig) (target_pin_box (dbTransformBBox target_pin_shape->bBox target_inst->transform)) ;; Find the offset vector between source and target (x (funcall get_x target_pin_box)-(funcall get_x source_pin_box)) (y (funcall get_y target_pin_box)-(funcall get_y source_pin_box)) ) ;; Align source_inst on target_inst (dbMoveFig source_inst cv (list x:y "R0" 1.)) ));letseq ;when ));letseq ;foreach ));let ;def

    It should work out-of-the-box using : 

    (ab_auto_place_instances ?cell_name "<resistor_cell_name>")

    Changing the horizontal and vertical justification might be required according to the positions of your target pins.

    Here is my example test case and the result : 

    Hope this helps, don't hesitate to ask if you have any question

    Cheers,

    Aurélien

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • JRP29
    JRP29 over 1 year ago in reply to AurelBuche

    Hi Aurelien,

    Thanks for the Reply. The scenario is same as explained by your script . Attached schematic representation for the same for illustration.
    I have to align 230 METAL_RESISTORS to the pins A2D_ADC1<1:230> inside a hierarchy in layout. 

    Your script is throwing error saying "undefined function - ccv" . The function 

     (lceGetIncompleteNets (ccv)) is not defined. can you provide a fix for this?



    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • AurelBuche
    AurelBuche over 1 year ago in reply to JRP29

    Oups, (ccv) is just an alias for (geGetEditCellView) I used it during my tests but it should not appear in my code (which I just edited)

    I replaced it with the variable cv and it should work

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • JRP29
    JRP29 over 1 year ago in reply to AurelBuche

    Thanks Aurel. Now it works properly. But it completes with below error after placing them. (Less worried as everything is placed in exact place) 
    *Error* dbTransformBBox: Invalid bBox - nil

    • Cancel
    • Vote Up +1 Vote Down
    • Cancel
Reply
  • JRP29
    JRP29 over 1 year ago in reply to AurelBuche

    Thanks Aurel. Now it works properly. But it completes with below error after placing them. (Less worried as everything is placed in exact place) 
    *Error* dbTransformBBox: Invalid bBox - nil

    • Cancel
    • Vote Up +1 Vote Down
    • Cancel
Children
  • AurelBuche
    AurelBuche over 1 year ago in reply to JRP29

    Hi,

    My code is just an example and worked in my simple test case. It's nice if it seems to work properly but actually it lacks many checks and assertions.

    I don't know the look of your incomplete nets but the first thing to do in the script would be to check that target_conn and target_inst variables are non-nil.

    The following version should work without error : 

    (defun ab_auto_place_instances ( @key  (cv         (geGetEditCellView))
                                           (cell_name  "rmx"              )
                                           (horiz_just 'left              )
                                           (vert_just  'bottom            )
                                     @rest _args )
      "Browse CV incomplete nets, align each instance matching CELL_NAME to the first found pin
    in the incomplete net.
    
    HORIZ_JUST can be 'left, 'center or 'right.
    VERT_JUST can be 'bottom, 'center or 'top.
    "
      ;; Define functions used to align the pins
      (let ((get_x (caseq (concat (lowerCase horiz_just))
                     (left   (lambda (box) (leftEdge   box)))
                     (right  (lambda (box) (rightEdge  box)))
                     (center (lambda (box) (xCoord (centerBox box))))
                     (t      (error "?horiz_just should be 'left, 'center or 'right"))
                     ))
            (get_y (caseq (concat (lowerCase vert_just))
                     (bottom (lambda (box) (bottomEdge box)))
                     (top    (lambda (box) (topEdge    box)))
                     (center (lambda (box) (yCoord (centerBox box))))
                     (t      (error "?vert_just should be 'bottom, 'center or 'top"))
                     ))
            )
      ;; Browse incomplete nets
      (foreach incomplete_net (lceGetIncompleteNets cv)
        ;; Try to find instance matching CELL_NAME
        ;; 'source' prefixed variables describe objects related to the instance matching CELL_NAME
        ;; 'target' prefixed variables describe objects related to the destination pin used to align
        (letseq ((conns       incomplete_net->instTerms)
                 (source_conn (car (exists conn conns (equal cell_name conn->inst->cellName))))
                 (source_inst source_conn->inst)
                 (target_conn (car (remove source_conn conns)))
                 (target_inst target_conn->inst)
                 )
          (when (and source_conn source_inst 
    target_conn target_inst
    ) (letseq (;; Find source pin box (source_pin_shape (car source_conn->term->pins)->fig) (source_pin_box (dbTransformBBox source_pin_shape->bBox source_inst->transform)) ;; Find target pin box (target_pin_shape (car target_conn->term->pins)->fig) (target_pin_box (dbTransformBBox target_pin_shape->bBox target_inst->transform)) ;; Find the offset vector between source and target (x (funcall get_x target_pin_box)-(funcall get_x source_pin_box)) (y (funcall get_y target_pin_box)-(funcall get_y source_pin_box)) ) ;; Align source_inst on target_inst (dbMoveFig source_inst cv (list x:y "R0" 1.)) ));letseq ;when ));letseq ;foreach ))
    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • JRP29
    JRP29 over 1 year ago in reply to AurelBuche

    Hi. Your code works properly. I  have one more requirement - Is there a way to align the instances to pins at same hierarchy and not to the pins at below hierarchy? Thanks in advance!

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Mavrick
    Mavrick over 1 year ago in reply to AurelBuche

    Hi,Aurel

    I just used your code ,but it doesn't seem to work.Does the pin layer need to be specified? i used "pin" layer for both pin and it's text .

    This is how i do with your code :

    i load the code file in CIW, and the return value is t,then i type in CIW:

    (ab_auto_place_instances ?cell_name "<>")
    ,in the <> i replace the cell name i need
    and the ciw window returns some code in the following format:(db:.......... db:.......... db:........ db:......)

    there is only one layout window i opened,but my pins stay still in layout   : (

    feels  

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • AurelBuche
    AurelBuche over 1 year ago in reply to JRP29

    Hi JRP29,

    The current solution I provided you with should work with both?

    If I understand correctly, you want to skip the pins that are not in current hierarchy level?

    To do so you might just add a filter on target_conn & target_inst to make sure target_conn is in current level
    (I haven't tried though)

    Also please note that using incomplete nets is a simple but limited solution (If a pin [that should also be connected] is closer than the one you target, you might not get the result you expect)

    Cheers

    Aurélien

    • 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