Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Need to know the list of layers used in Virtuoso layout design

3,866 views
Skip to first unread message

Vitalie

unread,
Dec 3, 2008, 5:12:02 AM12/3/08
to
Hi

How to find the list of used layers (not more not less) only these
that are in design?
I don't need the number of shapes, let see a more concret example:

suppose I have in layout
M1 (10:10 20:20)
M1 (30:25 40:50)
M2 (45:12 78:90)
...

POLY (...)
POLY (difertent coord)
XP (...)
XP (different coord)
....
etc. ....

then i need only a list of used layers:

M1, M2, POLY, XP (these layers are used in design)

I dig all documentation and I fond nothing :(

Thank You

Riad KACED

unread,
Dec 3, 2008, 4:42:08 PM12/3/08
to
Dear Vitalie,

Are you sure you have read all the docs ? Emmm, I'm having some
doubts ...
I'm pretty much sure you have missed that one:
Cadence® Design Framework II SKILL Functions Reference. The PDF is
available @:
$CDSHOME/doc/dkdfref/skdfref.pdf
Chapter 2 deals with the cds database access. If you scroll down to
the last section, i.e "Description of Database Objects", then you
would be able to read through the 'cellView' Database Object
Attributes. You would find 2 interesting attributes named after
layerPurposePairs and lpps. I shall leave you the pleasure to read
about them for now.

You could use cv~>? / cv~>?? to view the attributes/values of your
cellView.

Anyway, this is a bit of skill you could try:

; skill starts here
procedure( rkGetLppsInCurrentLayout(@optional
(cv geGetEditCellView()))
let( (cvLpps)
when(cv
cvLpps = foreach( mapcar (layer purpose)
cv~>lpps~>layerName cv~>lpps~>purpose
list(layer purpose)
)
printf("Layout %s:%s:%s does make use of the following Layers:
\n"
cv~>libName cv~>cellName cv~>viewName)
foreach(lpp cvLpps
printf(" %s.%s\n" car(lpp) cadr(lpp))
)
)
t
)
)
;skill ends here

That was my "not more not less" attempt to help you :-)
My "A bit more" advice is that printing out this information into the
CIW is a brilliant thing for people who consider the CIW as the 'most
important' window in Cadence. Unfortunately, this CIW is often ignored
and abandoned as a dead icon at the edge of one's desktop :-( So if
your skill is meant for those people who don't like the ciw, I would
highly recommend looking at the 'hiMakeLPChoiceList' function. It
makes a nice display and keeps everybody happy :-)
BTW, the aforementioned function is in the Custom Layout SKILL
Functions Reference manual (sklayoutref.pdf), just in case you dig all
documentation and don't find it ;-). No, just kidding, I'm not that
bad :-)

Have fun !
Riad.

sridh...@gmail.com

unread,
Dec 22, 2008, 12:40:21 AM12/22/08
to
Please can any one send me skill script for selecting the wanted
layers from the LSW window and deslect all just with the help of bind
key.
And one more script to convert a rectangle to a path.
Waiting for ur reply,

Andrew Beckett

unread,
Dec 31, 2008, 3:41:17 AM12/31/08
to
sridh...@gmail.com wrote, on 12/22/08 05:40:

Not quite sure what the first part is asking - select all is probably just the
control-A bindkey (if using the "standard" bindkeys) and deselect all is control-D.

The attached code is something I wrote to convert polygons to paths. It's not
perfect - after all, it's hard to know the direction from a rectangle (is it a
short fat path, or a long thin path).

/* abConvertPolygonToPath.ils

Author A.D.Beckett
Group Custom IC (UK), Cadence Design Systems Ltd.
Language SKILL
Date Aug 09, 2001
Modified
By

Code to attempt to convert polygons or rectangles to paths.

Usage:

abConvertPolygonToPath(obj) or
abConvertPolygonToPath(list_of_objs)

Typical usage:

abConvertPolygonToPath(geGetSelSet())

The code is SKILL++ code - ensure that the .ils suffix
is retained, to ensure it is interpreted correctly.

This employs a fairly brute force algorithm. It uses
rodCreatePath to create a path along the edge of one half
of the polygon, starting at successive points in the polygon.
For each path that was successfully created, it XORs the new
shape with the original shape, in order to find out whether the
path covers the original shape (and no more). If a matching
path is found, the search stops.
The algorithm is generally quite successful, and works in
most cases where there is a solution - even with 45 degree
paths. Non-45 degree paths are less likely to succeed.

By default, the working layers are "y1", "y2", "y3". If you
need to change these for whatever reason, this can be done
as follows:

abSetConvertPolygonWorkLayer("work1" '("annotate" "drawing1"))
abSetConvertPolygonWorkLayer("work2" '("annotate" "drawing2"))
abSetConvertPolygonWorkLayer("work3" '("annotate" "drawing3"))

In other words, use the layers you need as the second argument.

(Note to the interested. I don't use the create object from
object feature of rodCreatePath - partly because that isn't
available in 4.4.3, but also because it doesn't actually
save that much code. I'd need to tell it the start and end
handles to use - which would still need to be derived. Also,
the width would still need to be calculated in the same way
it's being done now).

***************************************************

SCCS Info: @(#) abConvertPolygonToPath.ils 05/25/05.10:05:56 1.4

*/

;*;PUBLIC abConvertPolygonToPath
;*;PUBLIC abSetConvertPolygonWorkLayer

/***************************************************************
* *
* (abConvertPolygonToPath (obj)) *
* *
* The generic function which errors if any invalid arguments *
* are given. *
* *
***************************************************************/

(defgeneric abConvertPolygonToPath (obj)
(error "abConvertPolygonToPath passed incorrect args %L\n" obj)
)


/****************************************************************
* *
* (abConvertPolygonToPath ((obj dbobject))) *
* *
* The method which handles converting database objects to paths *
* *
****************************************************************/

(defmethod abConvertPolygonToPath ((obj dbobject))
(let ((cellView (getSGq obj cellView))
(origLayer (getSGq obj lpp))
(nPoints (getSGq obj nPoints))
(work1 (abGetConvertPolygonWorkLayer "work1"))
(work2 (abGetConvertPolygonWorkLayer "work2"))
(work3 (abGetConvertPolygonWorkLayer "work3"))
(pointstried 0) newPoints
width pt1 pt2 halfpoints found newShape
hidewoport
pointList xorResults
)
;-----------------------------------------------------------------
; Decide if this is a shape we can do anything with
;-----------------------------------------------------------------
(cond
;----------------------------------------------------------------
; Polygons - just get the point list
;----------------------------------------------------------------
((and (equal (getSGq obj objType) "polygon")
(evenp nPoints))
(setq pointList (getSGq obj points))
)
;----------------------------------------------------------------
; Rectangles - build the point list. Try to be vaguely
; smart by ordering the point list so that the algorithm
; below will choose the minimum width as the path width
;----------------------------------------------------------------
((equal (getSGq obj objType) "rect")
(let (ll ur w1 w2)
(setq ll (lowerLeft (getSGq obj bBox)))
(setq ur (upperRight (getSGq obj bBox)))
(setq w1 (difference (xCoord ur) (xCoord ll)))
(setq w2 (difference (yCoord ur) (yCoord ll)))
(setq pointList
(if (greaterp w1 w2)
(list
ll (list (xCoord ll) (yCoord ur))
ur (list (xCoord ur) (yCoord ll)))
(list
ll (list (xCoord ur) (yCoord ll))
ur (list (xCoord ll) (yCoord ur)))
))
(setq nPoints 4)
)
)
)
;-----------------------------------------------------------------
; If a point list was found above, try to find a path
; which fits the polygon
;-----------------------------------------------------------------
(when pointList
(setq halfpoints (rightshift nPoints 1))
;-----------------------------------------------------------
; Set up a port for hiding warnings. Unfortunately
; the rodCreatePath function creates two sets of warnings,
; and so getWarn can't swallow them
;-----------------------------------------------------------
(setq hidewoport (outfile "/dev/null"))
;-----------------------------------------------------------
; Move the original object onto a work layer
;-----------------------------------------------------------
(setSGq obj work1 lpp)
(foreach map subList pointList
(unless (or found (geqp pointstried halfpoints))
;------------------------------------------
; Get the guessed width - the length
; of the first segment of the subList
;------------------------------------------
(setq pt1 (car subList))
(setq pt2 (cadr subList))
(setq width
(sqrt
(plus
(expt
(difference (xCoord pt2) (xCoord pt1)) 2)
(expt
(difference (yCoord pt2) (yCoord pt1)) 2)
)))
;------------------------------------------
; Build the new point list - this is
; the first "halfpoints" number of points
; in the rest of the subList
;------------------------------------------
(setq newPoints nil)
(for point 1 halfpoints
(setq subList (cdr subList))
(setq newPoints
(cons (car subList) newPoints))
)
;------------------------------------------
; Try creating the path with both left and right
; justification (if necessary). Note that
; the errset is there to trap errors thrown
; if the point list was invalid.
;------------------------------------------
(forall just '("left" "right")
(progn
;---------------------------------
; Invoke wrapper around rodCreatePath
;---------------------------------
(setq newShape
(abConvertPolygonToPathCreatePath
hidewoport cellView work2 width
newPoints just
))
(getWarn)
;---------------------------------
; If a shape was created, Xor the
; original shape with the new shapes.
;---------------------------------
(when newShape
(setq xorResults
(leLayerXor
cellView
work1 work2 work3)
)
;---------------------------
; If there was anything output
; by the Xor, then the path isn't
; the same as the polygon, so
; delete this attempt
;---------------------------
(if xorResults
(progn
(foreach shape xorResults
(dbDeleteObject
shape
)
)
(dbDeleteObject
(getSGq newShape dbId))
)
;-----------------------
; Otherwise we've found a
; matching path
;-----------------------
(setq found t)
)
)
(null found)
)
)
;------------------------------------------
; Increment the number of points tried. There's
; no need to go past half way around the
; polygon
;------------------------------------------
(postincrement pointstried)
)
)
;-----------------------------------------------------------
; Close the port for hiding warnings
;-----------------------------------------------------------
(when hidewoport (close hidewoport))
)
;-----------------------------------------------------------------
; Cleanup. If it was found, delete the original object
; and move the new path onto the right layer. Otherwise make
; sure that the original shape is back on the right layer
;-----------------------------------------------------------------
(if found
(progn
(setSGq (getSGq newShape dbId) origLayer lpp)
(dbDeleteObject obj)
(getSGq newShape dbId)
)
(progn
(setSGq obj origLayer lpp)
nil
)
)
)
)

/***************************************************************
* *
* (abConvertPolygonToPath ((obj list))) *
* *
* A method which handles a list of objects being passed to the *
* function. This does a mapcar on the entries in the list *
* *
***************************************************************/

(defmethod abConvertPolygonToPath ((obj list))
(mapcar abConvertPolygonToPath obj)
)

/*****************************************************************************
* *
* (abConvertPolygonToPathCreatePath woport cellView layer width points just) *
* *
* Function to wrap up creating the path (or at least trying) in order *
* to trap any errors or warnings. Note that this is defined as *
* a SKILL (i.e. dynamically scoped) function in order to allow *
* woport to be safely overridden *
* *
*****************************************************************************/

(inSkill
(defun abConvertPolygonToPathCreatePath
(woport cellView layer width points just)
(let (newShape)
(errset
(setq newShape
(rodCreatePath
?cvId cellView
?layer layer
?width width
?pts points
?justification just
)
)
) ; errset
newShape
) ; let
) ; defun
) ; inSkill

/***************************************************************
* *
* A lexically scoped bit of code to provide a means of hiding *
* a "global" variable. This is to allow the user to override *
* the working layers used. *
* *
***************************************************************/
(let (workLayers)
(setq abGetConvertPolygonWorkLayer
(lambda (layerName) (arrayref workLayers layerName))
)
(setq abSetConvertPolygonWorkLayer
(lambda (layerName actualLayer)
(setarray workLayers layerName actualLayer))
)
;----------------------------------------------------------------------
; Initialise the workLayers table with the default working
; layers
;----------------------------------------------------------------------
(setq workLayers (makeTable 'abConvertPolygonWorkLayers nil))
(abSetConvertPolygonWorkLayer "work1" '("y1" "drawing"))
(abSetConvertPolygonWorkLayer "work2" '("y2" "drawing"))
(abSetConvertPolygonWorkLayer "work3" '("y3" "drawing"))
)

--
Andrew Beckett
Senior Solution Architect - Cadence Design Systems Ltd (UK)

Murat Tepegoz

unread,
Jan 3, 2009, 11:42:40 AM1/3/09
to
Hi,
If you just want the names of the layers, you may find a very simple
solution: convert the layout into gds file. The gds conversion log
file gives the layer list used in the layout.
An important point, however, is that, during conversion you simply
provide a stream layer table list. Just make sure that, that layer
list contains every layer in the layout. Normaly, that list will
contain every layer in the technology anyways, but just make sure of
it.

GDS conversion is done by File->Export->Stream in icfb.

Regards

Riad KACED

unread,
Jan 5, 2009, 2:55:28 PM1/5/09
to
Dear Vitalie,

As far as I understand, what you want there is the list of layers that
are used in the current hierarchy level, i.e ignoring the lower levels
of hierarchy. Assuming my understanding, I would propose the
following:
The cv~>shapes~>lpps would give you the list of all the layers that
are contributed from the shapes (rect, polygon, path ... etc) of the
TOP LEVEL layout. This, however, would ignore all the layers that are
in the TOP LEVEL but not originated from shapes, i.e layers from
Pcells, Digital coerlibs and other standard cells (IOs, memories ...
etc). It is easy to find the Pcells and add the contribution of their
layers. A Pcell has the special property called a superMaster. I don't
see however anyway, rather than hard coding, to distinguish standard
cells from other cells in lower levels down the hierarchy.

More details for your problem are very likely to help us understanding
your needs.

Riad.

> Thank You, Riad
> You write the skill well, it show all the layers:purpose from the
> design, but I only need the LIST OF USED layers in a design not the
> all layers and purposes from the design (is the M1 used? is the M2
> used? is the POLY used? such way not all of them)

> How to list all shapes from the hierarchical cell view I know, but how
> to get the above faster (I can write a complex procedure but it take a
> lot of time to execute)
> That will be very simple and can be used with the dbProduceOverlap(cv
> cv-bBox dbGetMaxHierDepth()) in combination with foreach, I'm sure you
> know the process.
> Also can be used dbGetOverlaps(cv cv->bBox t dbGetMaxHierDepth()) with
> foreach.
> The same do dbGetTrueOverlaps(...)

> Best regards,
> Vitalie

Vitalie

unread,
Mar 4, 2009, 1:53:46 PM3/4/09
to
0 new messages