Guest
Hi,
I am trying to semi automate the transitions from poly to metal and
metal to metal while using Virtuoso. Below is code I whipped up.
While the path command is up and the user has laid the first wire,
lets say Metal1, and wishes to transition to Metal2, the user would
press the alt "2"
keys and would transition to Metal2 with a via below. The line
le0PathForm->changePathLayer->value = '(12584937 102 26 "metal2
(drawing)"); simply changes the Path form to Metal2. The issue with
this code is the number "12584937" in the example is "techLPld"(i
think from the error i get) and needs to change each transition(be
unique). Any ideas how I would do this?
form->changePathLayer->value =
*Error* lefSetEnv: Invalid techLPId object - nil
The other way I have tried to do this is with code from Cadence(after
the first example below), which works on one of our PDKs fine but not
on the nine other PDKs we use. This is due to how the tech file
needs to be set. Our DA team is always slammed so.....
Any help or ideas would be greatly appreciated.
Thanks!
Eric
;=====================================================================
;Transition code is used with the path command. The code allows
transition
;from one metal layer(or poly) to the next without touching the path
;command form. Poly is the "0" key, 1 is M1 and so on.
;====================================================================
procedure(m3trans()
le0PathForm->changePathLayer->value = '(12584943 102 26
"metal3 (drawing)");
)
procedure(m2trans()
le0PathForm->changePathLayer->value = '(12584937 102 26
"metal2 (drawing)");
)
procedure(m1trans()
le0PathForm->changePathLayer->value = '(12584935 102 26
"metal1 (drawing)");
)
procedure(m0trans()
le0PathForm->changePathLayer->value = '(12584931 102 26 "poly
(drawing)");
)
hiSetBindKeys( "Layout" list(
list("Alt<Key>0" "m0trans()");
list("Alt<Key>1" "m1trans()");
list("Alt<Key>2" "m2trans()");
list("Alt<Key>3" "m3trans()");
))
-----------------------------
end of first code
-------------------------
Code from Cadence, but needs tech file to be formatted for code to
work properly.
;********************************************************************
;* DISCLAIMER: The following code is provided for Cadence customers *
;* to use at their own risk. The code may require modification to *
;* satisfy the requirements of any user. The code and any *
;* modifications to the code may not be compatible with current or *
;* future versions of Cadence products. *
;* THE CODE IS PROVIDED "AS IS" AND WITH NO WARRANTIES, INCLUDING *
;* WITHOUT LIMITATION ANY EXPRESS WARRANTIES OR IMPLIED WARRANTIES *
;* OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. *
;********************************************************************
;; the CCSlayerUp() and CCSlayerDown() commands are intended
;; to be assigned to bindkeys and should supply the arguments
;; "topLayer"/"bottomLayer" and "silent" to be passed to the
;; CCSchangePathLayer() command
;; The example below assumes a 3-layer metal process with
;; the "poly1" layer being the bottom-most interconnect and
;; the "M3" layer being the top-most metal layer.
hiSetBindKeys("Layout"
list(
list("Ctrl<Btn2Down>" nil "CCSlayerUp(\"M3\")")
list("Ctrl<Btn3Down>" nil "CCSlayerDown(\"poly1\")")
)
)
;/***************************************************************
;* *
;* CCSlayerUp([t_topLayer | nil] [g_silent]) *
;* This procedure calls the CCSchangePathLayer function if the *
;* current command is the Path command. The "topLayer" and *
;* "silent" arguments are passed through without being checked *
;* *
;***************************************************************/
procedure(CCSlayerUp(@optional topLayer silent)
let( ((wid hiGetCurrentWindow()))
when(wid && hiGetCurrentCmd(wid)=="Path"
CCSchangePathLayer("up" topLayer silent)
); when
); let
); procedure CCSlayerUp
;/***************************************************************
;* *
;* CCSlayerDown([t_bottomLayer | nil] [g_silent]) *
;* This procedure calls the CCSchangePathLayer function if the *
;* current command is the Path command. The "bottomLayer" and *
;* "silent" arguments are passed through without being checked *
;* *
;***************************************************************/
procedure(CCSlayerDown(@optional bottomLayer silent)
let( ((wid hiGetCurrentWindow()))
when(wid && hiGetCurrentCmd(wid)=="Path"
CCSchangePathLayer("down" bottomLayer silent)
); when
); let
); procedure CCSlayerDown
;/***************************************************************
;* *
;* CCSchangePathLayer( *
;* [t_direction] *
;* [t_limit | nil] *
;* [g_silent] *
;* ) *
;* This procedure is designed to be called during the Create *
;* Path enterfunction. The direction argument controls whether *
;* the layer is changed up or down, "up" or "down" are valid *
;* values. The limit argument specifies the top layer name as *
;* a limit in the up direction or the bottom layer name as the *
;* limit in the down direction, this information is needed to *
;* cope with the top or bottom layer conditions when the Change *
;* To Layer field typically contains only 2 entries. The silent *
;* argument controls whether information messages are output to *
;* the CIW while changing the path layer, 't' turns them off. *
;* *
;***************************************************************/
procedure(CCSchangePathLayer(@optional (direction "down")
limit silent "tgg")
let( (form pathLayers)
when(and( form = hiGetCurrentForm()
form->changePathLayer)
pathLayers = form->changePathLayer->choices
cond(
;; if the change layer direction is 'down' and as long as
;; there are at least three choices, choose the second
;; layer which should be one layer down from current
(and(direction=="down" length(pathLayers)>=3)
form->changePathLayer->value = cadr(pathLayers)
;; unless the silent flag is 't' print a message
unless(silent
printf("changed layer %s to %s\n"
direction cadddr(cadr(pathLayers)))
); unless
)
;; if the change layer direction is 'up' and as long as
;; there are at least three choices, then select the third
;; choice which should be one layer up from current
(and(direction=="up" length(pathLayers)>=3)
form->changePathLayer->value = caddr(pathLayers)
;; unless the silent flag is 't' print a message
unless(silent
printf("changed layer %s to %s\n"
direction cadddr(caddr(pathLayers)))
); unless
)
;; if there are two choices and we are changing up choose
;; the second layer which should be one layer up from current
(and(direction=="up" length(pathLayers)==2)
if(!equal(limit
car(parseString(cadddr(form->changePathLayer->value))))
then
form->changePathLayer->value = cadr(pathLayers)
;; unless the silent flag is 't' print a message
unless(silent
printf("changed layer %s to %s\n"
direction cadddr(cadr(pathLayers)))
); unless
else
;; unless the silent flag is 't' print a message
unless(silent
printf("could not change layer %s from %s\n"
direction cadddr(form->changePathLayer->value))
); unless
); if
)
;; if there are two choices and we are changing down choose
;; the second layer which should be one layer down from
current
(and(direction=="down" length(pathLayers)==2)
if(!equal(limit
car(parseString(cadddr(form->changePathLayer->value))))
then
form->changePathLayer->value = cadr(pathLayers)
;; unless the silent flag is 't' print a message
unless(silent
printf("changed layer %s to %s\n"
direction cadddr(cadr(pathLayers)))
); unless
else
;; unless the silent flag is 't' print a message
unless(silent
printf("could not change layer %s from %s\n"
direction cadddr(form->changePathLayer->value))
); unless
); if
)
;; for any other condition don't do anything
(t
;; unless the silent flag is 't' print a message
unless(silent
printf("could not change layer %s from %s\n" direction
cadddr(form->changePathLayer->value))
); unless
nil
)
); cond
); when
); let
); procedure CCSchangePathLayer
I am trying to semi automate the transitions from poly to metal and
metal to metal while using Virtuoso. Below is code I whipped up.
While the path command is up and the user has laid the first wire,
lets say Metal1, and wishes to transition to Metal2, the user would
press the alt "2"
keys and would transition to Metal2 with a via below. The line
le0PathForm->changePathLayer->value = '(12584937 102 26 "metal2
(drawing)"); simply changes the Path form to Metal2. The issue with
this code is the number "12584937" in the example is "techLPld"(i
think from the error i get) and needs to change each transition(be
unique). Any ideas how I would do this?
form->changePathLayer->value =
*Error* lefSetEnv: Invalid techLPId object - nil
The other way I have tried to do this is with code from Cadence(after
the first example below), which works on one of our PDKs fine but not
on the nine other PDKs we use. This is due to how the tech file
needs to be set. Our DA team is always slammed so.....
Any help or ideas would be greatly appreciated.
Thanks!
Eric
;=====================================================================
;Transition code is used with the path command. The code allows
transition
;from one metal layer(or poly) to the next without touching the path
;command form. Poly is the "0" key, 1 is M1 and so on.
;====================================================================
procedure(m3trans()
le0PathForm->changePathLayer->value = '(12584943 102 26
"metal3 (drawing)");
)
procedure(m2trans()
le0PathForm->changePathLayer->value = '(12584937 102 26
"metal2 (drawing)");
)
procedure(m1trans()
le0PathForm->changePathLayer->value = '(12584935 102 26
"metal1 (drawing)");
)
procedure(m0trans()
le0PathForm->changePathLayer->value = '(12584931 102 26 "poly
(drawing)");
)
hiSetBindKeys( "Layout" list(
list("Alt<Key>0" "m0trans()");
list("Alt<Key>1" "m1trans()");
list("Alt<Key>2" "m2trans()");
list("Alt<Key>3" "m3trans()");
))
-----------------------------
end of first code
-------------------------
Code from Cadence, but needs tech file to be formatted for code to
work properly.
;********************************************************************
;* DISCLAIMER: The following code is provided for Cadence customers *
;* to use at their own risk. The code may require modification to *
;* satisfy the requirements of any user. The code and any *
;* modifications to the code may not be compatible with current or *
;* future versions of Cadence products. *
;* THE CODE IS PROVIDED "AS IS" AND WITH NO WARRANTIES, INCLUDING *
;* WITHOUT LIMITATION ANY EXPRESS WARRANTIES OR IMPLIED WARRANTIES *
;* OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. *
;********************************************************************
;; the CCSlayerUp() and CCSlayerDown() commands are intended
;; to be assigned to bindkeys and should supply the arguments
;; "topLayer"/"bottomLayer" and "silent" to be passed to the
;; CCSchangePathLayer() command
;; The example below assumes a 3-layer metal process with
;; the "poly1" layer being the bottom-most interconnect and
;; the "M3" layer being the top-most metal layer.
hiSetBindKeys("Layout"
list(
list("Ctrl<Btn2Down>" nil "CCSlayerUp(\"M3\")")
list("Ctrl<Btn3Down>" nil "CCSlayerDown(\"poly1\")")
)
)
;/***************************************************************
;* *
;* CCSlayerUp([t_topLayer | nil] [g_silent]) *
;* This procedure calls the CCSchangePathLayer function if the *
;* current command is the Path command. The "topLayer" and *
;* "silent" arguments are passed through without being checked *
;* *
;***************************************************************/
procedure(CCSlayerUp(@optional topLayer silent)
let( ((wid hiGetCurrentWindow()))
when(wid && hiGetCurrentCmd(wid)=="Path"
CCSchangePathLayer("up" topLayer silent)
); when
); let
); procedure CCSlayerUp
;/***************************************************************
;* *
;* CCSlayerDown([t_bottomLayer | nil] [g_silent]) *
;* This procedure calls the CCSchangePathLayer function if the *
;* current command is the Path command. The "bottomLayer" and *
;* "silent" arguments are passed through without being checked *
;* *
;***************************************************************/
procedure(CCSlayerDown(@optional bottomLayer silent)
let( ((wid hiGetCurrentWindow()))
when(wid && hiGetCurrentCmd(wid)=="Path"
CCSchangePathLayer("down" bottomLayer silent)
); when
); let
); procedure CCSlayerDown
;/***************************************************************
;* *
;* CCSchangePathLayer( *
;* [t_direction] *
;* [t_limit | nil] *
;* [g_silent] *
;* ) *
;* This procedure is designed to be called during the Create *
;* Path enterfunction. The direction argument controls whether *
;* the layer is changed up or down, "up" or "down" are valid *
;* values. The limit argument specifies the top layer name as *
;* a limit in the up direction or the bottom layer name as the *
;* limit in the down direction, this information is needed to *
;* cope with the top or bottom layer conditions when the Change *
;* To Layer field typically contains only 2 entries. The silent *
;* argument controls whether information messages are output to *
;* the CIW while changing the path layer, 't' turns them off. *
;* *
;***************************************************************/
procedure(CCSchangePathLayer(@optional (direction "down")
limit silent "tgg")
let( (form pathLayers)
when(and( form = hiGetCurrentForm()
form->changePathLayer)
pathLayers = form->changePathLayer->choices
cond(
;; if the change layer direction is 'down' and as long as
;; there are at least three choices, choose the second
;; layer which should be one layer down from current
(and(direction=="down" length(pathLayers)>=3)
form->changePathLayer->value = cadr(pathLayers)
;; unless the silent flag is 't' print a message
unless(silent
printf("changed layer %s to %s\n"
direction cadddr(cadr(pathLayers)))
); unless
)
;; if the change layer direction is 'up' and as long as
;; there are at least three choices, then select the third
;; choice which should be one layer up from current
(and(direction=="up" length(pathLayers)>=3)
form->changePathLayer->value = caddr(pathLayers)
;; unless the silent flag is 't' print a message
unless(silent
printf("changed layer %s to %s\n"
direction cadddr(caddr(pathLayers)))
); unless
)
;; if there are two choices and we are changing up choose
;; the second layer which should be one layer up from current
(and(direction=="up" length(pathLayers)==2)
if(!equal(limit
car(parseString(cadddr(form->changePathLayer->value))))
then
form->changePathLayer->value = cadr(pathLayers)
;; unless the silent flag is 't' print a message
unless(silent
printf("changed layer %s to %s\n"
direction cadddr(cadr(pathLayers)))
); unless
else
;; unless the silent flag is 't' print a message
unless(silent
printf("could not change layer %s from %s\n"
direction cadddr(form->changePathLayer->value))
); unless
); if
)
;; if there are two choices and we are changing down choose
;; the second layer which should be one layer down from
current
(and(direction=="down" length(pathLayers)==2)
if(!equal(limit
car(parseString(cadddr(form->changePathLayer->value))))
then
form->changePathLayer->value = cadr(pathLayers)
;; unless the silent flag is 't' print a message
unless(silent
printf("changed layer %s to %s\n"
direction cadddr(cadr(pathLayers)))
); unless
else
;; unless the silent flag is 't' print a message
unless(silent
printf("could not change layer %s from %s\n"
direction cadddr(form->changePathLayer->value))
); unless
); if
)
;; for any other condition don't do anything
(t
;; unless the silent flag is 't' print a message
unless(silent
printf("could not change layer %s from %s\n" direction
cadddr(form->changePathLayer->value))
); unless
nil
)
); cond
); when
); let
); procedure CCSchangePathLayer