• 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. My code (fill PP in fluid N-GR) works when pasted in the...

Stats

  • Replies 2
  • Subscribers 144
  • Views 642
  • Members are here 0

My code (fill PP in fluid N-GR) works when pasted in the CIW, but doesn't work when modified as a bindkey.

YC202502167727
YC202502167727 4 months ago

Hi,

I am trying to write a code that fills PP into existed N-Fluid GR.

My approach is quite intuitive, and it works successfully when I paste the code into the CIW.

1. flatten the GR

2. merge all the N-imps

3.Find the inner frame of N-imp.

4.hiUndo twice to restore the GR

5.use inner frame to create a new PP

Then I modified it in a text file and loaded it as a bindkey, but a problem occurred.

It seems that the "hiUndo" function can't be used.

Here's the explanation I found  from "dbUndoToHandle" function on the official website.

dbUndoToHandle ...... has the same limitations as hiUndo. For example, dbUndoToHandle cannot be called from within a SKILL procedure.

I'll paste my code in the text file below. I’d like to know if there’s a way  to restore the GR to its original state, or if there are alternative functions that can replace HiUndo.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

list("<Key>F6" "

a=geGetSelSet()
leFlattenInst(car(a) 31 t)

(let ((instances (geGetEditCellView()~>shapes)))
(foreach shape instances
(if (equal (shape~>layerName) \"NP\")
(progn
(geSelectObject shape)  ))))

leHiMerge()

(defun RemoveDuplicatesManually (lst)
(let ((result '()))
(foreach item lst
(if (not (memv item result))
(setq result (cons item result))))
(reverse result)))

(setq a (geGetEditCellView()~>shapes))

(setq xVals '())
(setq yVals '())

(foreach shape a
(if (equal (shape->layerName) \"NP\")
(foreach point (shape->points)
(setq xVals (cons (car point) xVals))
(setq yVals (cons (cadr point) yVals))  )))

(setq xVals (reverse xVals))
(setq yVals (reverse yVals))

(setq xVals (RemoveDuplicatesManually xVals))
(setq yVals (RemoveDuplicatesManually yVals))

(setq xVals (sort xVals (lambda (x y) (lessp x y))))
(setq yVals (sort yVals (lambda (x y) (lessp x y))))

(setq secondSmallestX (cadr xVals))
(setq secondLargestX (caddr xVals))

(setq secondSmallestY (cadr yVals))
(setq secondLargestY (caddr yVals))

hiUndo()
hiUndo()

dbCreateRect(geGetEditCellView() '(\"PP\" \"drawing\") list( (list secondSmallestX secondSmallestY) (list secondLargestX secondLargestY)))    ")

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

I have also saw an post titled 'Coordinates (bBoxes) of all the shapes (layers) in a layout view' that mentions using the abs function to avoid flatten.

However, due to insufficient reference material, I’m currently unable to write the code by using abs. function.

Could you provide any example by using abs function to find out the points of any shape within a fluid GR?

Any advise will be thankful and helpful.

Best Regards.

  • Sign in to reply
  • Cancel
  • YC202502167727
    YC202502167727 4 months ago

    Sorry for the typo mistake, it's the abe* function, not the abs function.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • henker
    henker 4 months ago


    The shown code is working according to the first sentence of the description only when certain constraints are met, i.e. no other NP shapes in the cellview (the code walks over all NP shapes, even those shapes that might be in the cellview before flattening), guardring must be rectangular, etc. It is not fully clear if that is intentional, prevented by design, or unwanted side effects.

    IF it is just filling the complete area that is fully enclosed by a certain layer of the currently selected guardring and assuming that the guardring is an instance of e.g. a techlib pcell, then it might be easier to use a graphical approach:
    1) temporarily copy the NP shape(s) from the master of the selected guardring to the current cellview with applying the instance transformation (much easier than searching a flattend pile of shapes)
    2) use dbLayerHoles to create PP shape(s) that are fully enclosed by the copied NP shapes
    3) remove the temporary NP

    Alternatively, you could also feed the above shapes from the guardring master to dbLayerHoles directly and apply the instance transformation on the result, so the third step could be omitted.

    However, if there is usage of NP inside the guardring (e.g. the guarded transistors), you would still need to apply further processing, as "NP over PP" is probably not allowed in DRC.


    abe functions would be preferable if you would like to work on the whole hierarchy, e.g when the ring shapes are in higher/deeper hierarchy and not only in the next hierarchy level; resp. work on the full cellview, not just on selected objects. Also the post processing to exclude the PP where NP exists could be done in the same run without extra effort.


    I'd also recommend to prevent usage of the undo functions. The only reliable undo in my opinion is dbSave+dbPurge, but I doubt it is of general applicability.
    It is usually much safer to track changes on the cellview and e.g. remove temporaries afterwards instead of creating a mess first and than rely on having it repaired somehow. If complicated, it is also no problem to create a scratchview (dbOpenCellViewByType and passing "s" as mode argument), do the operations there and just copy the final results.

    Regards,

    PS: The example from above as code:

    procedure( fillGR()
    	let( (cv tmpshp fig res)
    		cv = deGetCellView()
    		; 1) copy shapes from selected guardring instances to cellview
    		foreach( obj geGetSelectedSet()
    			when(obj~>objType=="inst" &&
    				obj~>libName=="<guardring libname>" &&
    				obj~>cellName=="<guardring cellname>"
    
    				foreach(shp obj~>master~>shapes
    					when(shp~>layerName=="NP"
    						fig = dbCopyFig(shp cv obj~>transform)
    						when(fig tmpshp = cons(fig tmpshp))
    					)
    				)
    			)
    		)
    
    		; 2) fill the holes inside the temporaries
    		res = dbLayerHoles(cv list("PP" "drawing") tmpshp)
    		
    		; may work on the created shapes, e.g. select them, put them into current figGroup, etc.
    		printf("created: %L\n" res~>??)
    
    		; 3) delete temporaries
    		foreach(e tmpshp dbDeleteObject(e))
    	); let
    )
    • Cancel
    • Vote Up 0 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