Metal change, Transition code for Virtuoso.

Discussion in 'Cadence' started by eric.d.fitzsimmons, Jan 14, 2009.

  1. 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
     
    eric.d.fitzsimmons, Jan 14, 2009
    #1
  2. Eric,

    Perhaps you can explain why the Cadence code doesn't work - it wasn't obvious to
    me what it would need from the tech file that was particularly special?

    Anyway, I think what you want (for your code) is:

    car(
    hiMakeLPChoiceList(
    techGetTechFile(geGetEditCellView())
    list(list("metal2" "drawing"))
    )
    )

    So you could write a general function:

    procedure(ABlayerChange(layer)
    le0PathForm->changePathLayer->value =
    car(
    hiMakeLPChoiceList(
    techGetTechFile(geGetEditCellView())
    list(list(layer "drawing"))
    )
    )
    )

    and then m1trans() would become:

    procedure(m1trans()
    ABlayerChange("metal1")
    )

    hiMakeLPChoiceList() would normally be used to construct the choices for a
    layer-cyclic field, but in this case I'm using it to just find a list of choices
    for a list of a single layer...

    Regards,

    Andrew.
     
    Andrew Beckett, Jan 14, 2009
    #2
  3. Thank you for your reply. I will try your suggestions as soon as I
    can.

    Andrew you wrote,



    ;; if there are two choices and we are changing up choose
    ;; the second layer which should be one layer up from current
    I have not investigated this entirely, but between the two of us maybe
    we can get the answer.

    In the PDK that the cadence code works on the "change to layer" Create
    Path form has only three layers to choose from
    unless you are on the top or bottom layer, then there are two. For
    instance, if you are on the "poly" layer the "change to layer" has
    poly and metal1 only. If you are on Metal1 there will be Metal1, 2,
    and Metal3 as selections. This is the behavour I see with the PDK
    that the code works on.

    The PDKs that the code doesn't work on has layers in the "change to
    layer" such as RX and so forth. One PDK had all metals and poly as a
    selection. So, transitioning would sometimes give an unexpected
    layer such as RX. It seems the Create Path command uses the tech file
    to get the list, is that correct? And if that is true, I suspect
    that one of our PDKs has a tech file that is compatible and the rest
    do not.

    I am new to Cadence and Skill as an Intel refuge so I may need more
    help to implement your suggestions. I do have some programming
    background and am finishing a Cadence class on Skill.

    Thank you for your input. It is beyond appreciated.
    Eric
     
    eric.d.fitzsimmons, Jan 14, 2009
    #3
  4. I presume "RX" is showing up in the list of layers on the form?

    As far as I recall, the layers is determined by the symbolic contacts in the
    tech file - it uses the layers in the symbolic contacts to figure out which
    layers it knows how to traverse between.

    Can you pick "RX" from the form? Or is it just that you don't want to ever
    choose that layer when you go up or down?

    Regards,

    Andrew.
     
    Andrew Beckett, Jan 15, 2009
    #4
  5. Yes you can pick the RX from the form and it isn't an appropriate
    metal layer, it appears our symbolic contacts are
    not formatted properly.

    At any rate I was able to drop your code in and it worked perfect, so
    I consider the issue resolved. If I get time, I will come back and
    take another look at why our tech file doesn't work with the cadence
    code.

    For a summary, I wanted code to be able to transition from a metal
    layer to the next metal layer up or down without going to the Create
    Path form to increase productivity as my team hand routes all
    signals.

    Thank you,
    Eric

    procedure(ABlayerChange(layer)
    le0PathForm->changePathLayer->value =
    car(
    hiMakeLPChoiceList(
    techGetTechFile(geGetEditCellView())
    list(list(layer "drawing"))
    )
    )
    )

    procedure(m3trans()
    ABlayerChange("metal3")
    )

    procedure(m2trans()
    ABlayerChange("metal2")
    )

    procedure(m1trans()
    ABlayerChange("metal1")
    )

    procedure(m0trans()
    ABlayerChange("poly")
    )

    hiSetBindKeys( "Layout" list(
    list("Alt<Key>0" "m0trans()");
    list("Alt<Key>1" "m1trans()");
    list("Alt<Key>2" "m2trans()");
    list("Alt<Key>3" "m3trans()");
    ))
     
    eric.d.fitzsimmons, Jan 15, 2009
    #5
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.