ncsim stop in Tcl proc problem?

D

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
 
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!
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.

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
 
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

Bogdan Slusarczyk wrote:
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!

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.


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
 
Bogdan Slusarczyk wrote:
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!

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.
[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

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
 
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.
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?

And I want to use global or upvar, do you think where shall I put the
global or upvar?
I didn't notice that stop_name is proc argument, sorry....
 
Bogdan Slusarczyk wrote:
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.

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?
[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
And I want to use global or upvar, do you think where shall I put the
global or upvar?

I didn't notice that stop_name is proc argument, sorry....
 
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.
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 wrote:
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.

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?:
[snip]

Hi Bogdan,

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

Best regards,
Davy

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 wrote:
set cmd [subst {
puts "!!! stop_name is $stop_name"
force dlr_pkg.dlr_INST.PHY_STATE = $phy_state
}]
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 wrote:
Bogdan Slusarczyk wrote:
set cmd [subst {
puts "!!! stop_name is $stop_name"
force dlr_pkg.dlr_INST.PHY_STATE = $phy_state
}]

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"]
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 wrote:
Bryan Oakley wrote:

Bogdan Slusarczyk wrote:

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

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"]

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?
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
http://www.tclscripting.com
 
Davy wrote:
Bryan Oakley wrote:
snip
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
snip
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"]
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?
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
}
 
"Davy" <zhushenli@gmail.com> writes:

stop ... -exec { [join $cmds ";\n"] }
,but it cannot find $cmds, why?
Didn't we just go through this with $base?

(By the way, no need for *both* ; and \n. Either would suffice.)



--
Donald Arseneau asnd@triumf.ca
 
Bryan Oakley wrote:
Davy wrote:
Bryan Oakley wrote:

Bogdan Slusarczyk wrote:

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

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"]

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?

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
}
}

[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

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
http://www.tclscripting.com
 

Welcome to EDABoard.com

Sponsor

Back
Top