ncsim stop in Tcl proc problem?

Discussion in 'Cadence' started by Davy, Sep 25, 2006.

  1. Davy

    Davy Guest

    Hi all,

    I want to write a proc to encapsulate a stop command (Cadence NCsim).
    The tcl list below. But it seems the input(phy_state, stop_name) cannot
    be access/read in the stop -exec {}, why? Is it related to scope?
    Thanks!

    Code:
    #----- tcl start -----
    proc phy_state_trans {phy_state stop_name} {
    # below three puts work OK
    puts "phy_state is $phy_state\n"
    puts "stop_name is $stop_name\n"
    puts "!!! enter proc\n"
    run 1us
    stop -name $stop_name -silent -cont -cond { #$DLR_ref.PCLK == 1'b1
    } -exec {
    # Tcl run here and report error $stop_name cannot be read
    puts "!!! stop_name is $stop_name"
    force dlr_pkg.dlr_INST.PHY_STATE = $phy_state
    }
    puts "OK_3 state is $phy_state\n"
    run 1us
    stop -delete "$stop_name"
    force dlr_pkg.dlr_INST.PHY_STATE = $PHY_STATE_L0
    run 1us
    }

    phy_state_trans PHY_STATE_L1 Trans_Stop
    #----- tcl end -----


    Best regards,
    Davy
     
    Davy, Sep 25, 2006
    #1
  2. I want to write a proc to encapsulate a stop command (Cadence NCsim).
    I think 'stop' command it's not something like pure catch {}, and
    probably commands from '-exec' are not executed in the 'phy_state_trans'
    scope. Try to prepare your command line for -exec switch by using 'list'
    command or set 'stop_name' variable as global.
     
    Bogdan Slusarczyk, Sep 25, 2006
    #2
  3. Davy

    dbwalker0min Guest

    You could also use "subst" to build the -exec command. For example:

    set cmd [subst {
    puts "!!! stop_name is $stop_name"
    force dlr_pkg.dlr_INST.PHY_STATE = $phy_state
    }]
    ....
    Then do

    stop ... -exec $cmd

    David Walker
     
    dbwalker0min, Sep 25, 2006
    #3
  4. Davy

    Davy Guest

    [snip]

    Hi,

    I think use 'list' or 'subst' will crack the encapsulation of the
    'proc'. Because I want to encapsulate the parameter of '-exec' switch
    in the 'proc' scope.

    And I want to use global or upvar, do you think where shall I put the
    global or upvar?

    Thanks!
    Davy
     
    Davy, Sep 26, 2006
    #4
  5. I think use 'list' or 'subst' will crack the encapsulation of the
    I don't understand where is problem to use subst or list command to
    prepare substituted commands for -exec switch. What do you mean that
    list or subst will crack 'proc' encapsulation?
    I didn't notice that stop_name is proc argument, sorry....
     
    Bogdan Slusarczyk, Sep 26, 2006
    #5
  6. Davy

    Davy Guest

    [snip]
    Hi Bogdan,

    Because I want to encapsulate all the command argument to proc. If I
    use 'list' or 'subst', maybe I have to write -exec argument outside
    proc.

    And I have tried global inside proc, but it seems not work. And I tried
    upvar 0,1,2, it also seems not work. Mmm, shall I change my idea to put
    -exec argument outside proc?

    Thanks!
    Davy
     
    Davy, Sep 27, 2006
    #6
  7. Because I want to encapsulate all the command argument to proc. If I
    I'm sorry, it's still unclear for me. You don't need write -exec
    arguments outside of 'proc phy_state_trans', unless you have 'stop'
    command in mind. Can't you do something like this?:

    proc phy_state_trans {phy_state stop_name} {
    # below three puts work OK
    puts "phy_state is $phy_state\n"
    puts "stop_name is $stop_name\n"
    puts "!!! enter proc\n"
    run 1us

    set cmd [subst {
    puts "!!! stop_name is $stop_name"
    force dlr_pkg.dlr_INST.PHY_STATE = $phy_state
    }]

    stop -name $stop_name -silent -cont -cond { #$DLR_ref.PCLK == 1'b1
    } -exec $cmd
    puts "OK_3 state is $phy_state\n"
    run 1us
    stop -delete "$stop_name"
    force dlr_pkg.dlr_INST.PHY_STATE = $PHY_STATE_L0
    run 1us
    }
     
    Bogdan Slusarczyk, Sep 27, 2006
    #7
  8. Davy

    Davy Guest

    [snip]

    Hi Bogdan,

    Oh, I understand. I will try it soon and give out the result.
    Thanks a lot!

    Best regards,
    Davy
     
    Davy, Sep 27, 2006
    #8
  9. Davy

    Bryan Oakley Guest

    Let me preface this by saying I know absolutely nothing about ncsim. I
    do know a fair bit about tcl though, so bear with me.

    Using subst in the above manner could cause failures in all sorts of
    ways if $stop_name or $phy_state has special characters in it. For
    example, consider the case where $stop_name contains something like ";

    Now, maybe in the above case that will never happen, but it's not wise
    to believe that the above is good practice. Eventually it will bite you.

    Here's a safe way to build up a command. It takes advantage of the fact
    that tcl commands are lists of words, and tcl scripts are simply
    commands separated by semicolons and/or newlines. By using [list ...] to
    build up each individual command, word boundaries are preserved no
    matter what the content of the variables.

    set cmds {}
    lappend cmds [list puts "!!! stop_name is $stop_name"]
    lappend cmds [list force dlr_pkg.dlr_INST.PHY_STATE = $phy_state]

    stop ... -exec [join $cmds ";\n"]
     
    Bryan Oakley, Sep 27, 2006
    #9
  10. Davy

    Davy Guest

    Hi Bryan,

    I have tried your code, and it works OK, thanks a lot!

    Because I want to write a if command in -exec argument like:
    stop ... -exec {
    if {...} {
    [join $cmds ";\n"]
    }
    }

    So I tried change your code to
    stop ... -exec { [join $cmds ";\n"] }
    ,but it cannot find $cmds, why?

    Best regards,
    Davy
     
    Davy, Sep 28, 2006
    #10
  11. Davy

    Bryan Oakley Guest

    Because everthing beginning with "if ..." is inside a pair of curly
    braces, and curly braces inhibit substitution.

    If you are doing more than just a line or two of code you should write a
    proc and pass in your arguments unless there's some restriction imposed
    by ncsim.

    stop ... -exec [mySpecialCommand $stop_name $phy_state]
    ...
    proc mySpecialCommand {stop_name phy_state} {
    if {...} {
    puts "!!! stop_name is $stop_name"
    force dlr_pkg.dlr_INST.PHY_STATE = $phy_state
    }
    }

    At least, that's how I do it in pure tcl. I don't know exactly what
    -exec does in your environment (for example, it may run the code in a
    special process, interpreter, thread or namespace) so I'm not 100%
    certain it will work. It can be made to work -- tcl is remarkably
    flexible -- but without knowing more about ncsim it's hard for me to say
    for certain.
     
    Bryan Oakley, Sep 28, 2006
    #11
  12. Davy

    slebetman Guest

    Because you quoted the code in -exec with braces {}. Remenber that Tcl
    is a string substitution language and the rules say that no
    substitutions occur in braces {}. Which is why we've gone to all the
    trouble with manual script composition in the first place. What you
    want is probably something like this:

    set finalcmds "if {...} {[join $cmds \n]}"
    stop ... -exec $finalcmds

    or even better:

    set finalcmds [list if {...} [join $cmds \n]]

    But by now your code looks very convoluted due to having to manually
    compose nested commands using the list commands. Perhaps you should
    simply use [list ..] as your quoting mechanism instead of {...} and
    leave the formatting of your original code intact. To me it's more
    readable:

    stop {...} -exec [join [list \
    [list if {...} \
    [join [list \
    [list puts "!!! stop_name is $stop_name"] \
    [list force dlr_pkg.dlr_INST.PHY_STATE = $phy_state] \
    ] \n]
    ] \
    ] \n]

    On second thought, that looks quite unreadable as well. Perhaps we
    should have given you the usual advise we give to people who have the
    same problem supplying parameters to -command in Tk: make -exec run
    another proc.

    proc stopHandler {name state} {
    if {...} {
    puts "!!! stop_name is $name"
    force dlr_pkg.dlr_INST.PHY_STATE = $state
    }
    }


    proc phy_state_trans {phy_state stop_name} {

    # ...some code here

    stop ... -exec [list stopHandler $stop_name $phy_state]

    # ...some code here
    }
     
    slebetman, Sep 28, 2006
    #12
  13. Didn't we just go through this with $base?

    (By the way, no need for *both* ; and \n. Either would suffice.)
     
    Donald Arseneau, Sep 28, 2006
    #13
  14. Davy

    Davy Guest

    [snip]

    Hi Bryan,

    Thanks a lot!
    Though it doesn't work yet (I think ncsim may not use the pure Tcl you
    mentioned), I learned a lot of Tcl techniques from your post.
    And I will try to read the artical on your website to learn Tcl/Tk
    these days.

    Best regards,
    Davy
     
    Davy, Sep 28, 2006
    #14
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.