I am trying to write a tcl script for some simulations in isim. the script would run two nested loops and generate a file in each iteration. when running the simulation with this scrips the simulator generates the error:
TCL batch file "D:...subbyte.tcl" encountered an error in line 2. Simulator is exiting.
but all the output files are generated and saved. I am totally confused with it.
Thanks for any help in advance!
run 100 ns
for {set i 0} { $i<1} {incr i} {
for {set j 0} { $j<256} {incr j} {
saif open -scope uut -file "saifsubbyte $i$j .saif" -allnets
run 1 ns
saif close
run 19 ns
}
}
Related
I tried to write an automatic script for modelsim, where I would go through each possible malfunction in the circuit one by one, and then analyze it. For one malfunction, I did everything, and it works, however when I tried to make a loop where I did the same with everyone one by one, I had several problems at once.
Can do files be called from tcl scripts? Since the actions for one malfunction are performed using the do file, and the loop for iterating over them is already a Tcl script.
When trying to run the whole thing, modelsim gave an execution result of 0 and that's all, despite the fact that it did not swear at syntax errors.
Here is the do file for one fault (fault.do):
vmap work work
vcom -reportprogress 300 -work work {sheme.vhd}
vcom -reportprogress 300 -work work {testbench.vhd}
vsim -wav simwave.wlf work.device_tb
env sim:/device_tb/uut
view signals
.signals.tree write signalfile.txt
add wave sim:/device_tb/uut/*
add list sim:/device_tb/uut/*
run 5000 ns
quit -sim
quietly WaveActivateNextPane {} 0
dataset open ./simwave.wlf simwave
add wave simwave:/device_tb/uut/*
add list simwave:/device_tb/uut/*
vsim work.device_tb
env sim:/device_tb/uut
view signals
quietly WaveActivateNextPane
add wave sim:/device_tb/uut/*
add list sim:/device_tb/uut/*
source forc.tcl
tosignal 1
quietly WaveActivateNextPane
compare start simwave sim
compare options -track
compare add -wave -recursive -tolL {0 ns} -tolT {0 ns} simwave:/device_tb/uut sim:/device_tb/uut
compare add -list -recursive -tolL {0 ns} -tolT {0 ns} simwave:/device_tb/uut sim:/device_tb/uut
compare run
view wave
view list
compare info -write C:/Modeltech_5.7f/examples/dip/compare.txt
source analys.tcl
comp 2
And here are my attempts to make a loop for all such faults:
set fp [open "signalfile.txt" r]
set cnts 0
set cntoth 0
while { [gets $fp data] >= 0 } {
if {[string match $data s?] == 1} {
incr cnts } else {
incr cntoth }
}
for {set i 0} {$i < $cnts} {incr i} {
set var $env($i)
source fault.do
exec $var }
set fn [open "errors.txt" r]
set er 0
while { [gets $fn data] >= 0 } {
incr er }
set per [expr $er/[expr $cntoth + $cnts]]
puts $per
Can anyone suggest how best to implement this? I'll be very thankful)
I have a code as you can see below.
I execute this using hv (Altair hyperview) to load and take pictures of FE results.
This is the results log I see on my linux terminal:
*Ready
Loading Report...
Applying Report...
Ready
Ready
Capturing...
Ready*
It's stuck at "Ready" and unless I press Ctrl+c or enter it doesn't exit back to terminal. How can I make the code to exit to terminal after the proc is over?
So I just found out that the commands are running as a subprocess thats why I am not able to kill it with exit command.
proc BatchMain { } {
set inputdeck [lindex $::argv 6]
set resultfile [lindex $::argv 7]
puts $inputdeck
puts $resultfile
set t [::post::GetT]
hwi GetSessionHandle sess$t
sess$t GetProjectHandle proj$t
hwi OpenStack
sess$t LoadReport Batch_Process.tpl
sess$t ApplyReport Batch_Process replace true false 2 $inputdeck $resultfile
set numpages [proj$t GetNumberOfPages];
for {set i 1} {$i <= $numpages} {incr i} {
proj$t SetActivePage $i
proj$t GetPageHandle pg$t $i
pg$t Draw
pg$t ReleaseHandle
sess$t CaptureScreen png image_$i.png
}
hwi CloseStack
proj$t ReleaseHandle
sess$t Close
}
BatchMain
The canonical way of stopping a Tcl program is to call the exit command. You could put this inside your BatchMain, or as its own call:
# ... procedure definition as in the question ...
BatchMain
exit
The exit command takes an optional exit code argument, with the usual definitions of what an exit code means, and where 0 is the default value. Under normal circumstances, exit has no Tcl result at all as it never finishes executing from the perspective of the script.
In some circumstances, Tcl will call exit for you. The most notable of these is when execution falls off the end of a classic tclsh script.
I was wondering how you would find the name of the test you're running in tcl from the test itself? I couldn't find this on google.
I'm calling another proc and passing the name of the test that is calling it, as an argument. So I would like to know which tcl command can do that for me.
This isn't an encouraged use caseā¦ but you can use info frame 1 to get the information if you use it directly inside the test.
proc example {contextTest} {
puts "Called from $contextTest"
return ok
}
tcltest::test foo-1.1 {testing the foo} {
example [lindex [dict get [info frame 1] cmd] 1]
} ok
This assumes that you're using Tcl 8.5 or later, but Tcl 8.5 is the oldest currently-supported Tcl version so that's a reasonable restriction.
I read your comments ("source ... instade of my test name") as follows: You seem to source the Tcl script file containing the tests (and Donal's instrumented tcltest), rather than batch-running the script from the command line: tclsh /path/to/your/file.tcl In this setting, there will be an extra ("eval") stack frame which distorts introspection.
To turn Donal's instrumentation more robust, I suggest actually walking the Tcl stack and watching out for a valid tcltest frame. This could look as follows:
package req tcltest
proc example {} {
for {set i 1} {$i<=[info frame]} {incr i} {
set frameInfo [info frame $i]
set frameType [dict get $frameInfo type]
set cmd [dict get $frameInfo cmd]
if {$frameType eq "source" && [lindex $cmd 0] eq "tcltest::test"} {
puts "Called from [lindex $cmd 1]"
return ok
}
}
return notok
}
tcltest::test foo-1.1 {testing the foo} {
example
} ok
This will return "Called from foo-1.1" both, when called as:
$ tclsh test.tcl
Called from foo-1.1
and
$ tclsh
% source test.tcl
Called from foo-1.1
% exit
The Tcl version used (8.5, 8.6) is not relevant. However, your are advised to upgrade to 8.6, 8.5 has reached its end of life.
I try to implement a simple scenario for LEACH protocol but I get this error:
Creating Sensors ...
invalid command name "Agent/LeachAgent"
while executing
"Agent/LeachAgent create _o2340 "
invoked from within
"catch "$className create $o $args" msg"
invoked from within
"if [catch "$className create $o $args" msg] {
if [string match "__FAILED_SHADOW_OBJECT_" $msg] {
delete $o
return ""
}
global errorInfo
error "class $..."
(procedure "new" line 3)
invoked from within
"new Agent/LeachAgent"
("for" body line 3)
invoked from within
"for {set i 1} {$i <= $val(nsn)} {incr i} {
set agent($i) [new Agent/LeachAgent]
$ns attach-agent $node_($i) $agent($i)
$agent($i) set packetSize_..."
(file "newleach3.tcl" line 187)
I use ubuntu 16.04 and ns-allinone-2.35 . when I ran my tcl file for the first time, i did not get this error.
Change your script to use Agent/RCAgent/LeachAgent as class name:
set agent($i) [new Agent/RCAgent/LeachAgent]
From what I can see, there is no Agent/LeachAgent in ns-allinone-2.35.
I was not successful in writing a correct code for attaching Leach protocol in my scenario, but I found that mannasim has a Mannasim Script Generator (MSG). It is a front-end for TCL simulation scripts easy creation.
Can anyone tell me how should I fix this problem? I have a problem in attaching more than one applications to one agent. (I am running ns2.35 on Ubuntu12.10)
There are two nodes(Source and Destination) in my environment and here are some features:
I attached a loss-monitor agent on Destination node.
I attached an udp agent on Source node.
I attached 9 applications on the udp agent by following declaration:
set nExpGen 9
for {set i 1} {$i <= $nExpGen} {incr i} {
set eee($i) [new Application/Traffic/Exponential]
$eee($i) attach-agent $udp
$ns connect $eee($i) $lmt
#nExpGen= number of exponential generators
#eee = exponential application
#lmt = loss-monitor agent
I got errors "cant read agent address: no such variable.." when running my tcl file ( see [error message])
Did I use the wrong way to attach these applications to the agent? How can I fix that?
Thank you all in advance.
[error messages]
can't read "agent_addr_": no such variable
while executing
"subst $[subst $var]"
(procedure "_o40" line 5)
(Object next line 5)
invoked from within
"_o40 next agent_addr_"
("eval" body line 1)
invoked from within
"eval $self next $args"
(procedure "_o40" line 11)
(Application/Traffic set line 11)
invoked from within
"$dst set agent_addr_"
(procedure "_o3" line 2)
(Simulator simplex-connect line 2)
invoked from within
"$self simplex-connect $dst $src"
(procedure "_o3" line 10)
(Simulator connect line 10)
invoked from within
"$ns connect $eee($i) $lmt"
("for" body line 4)
invoked from within
"for {set i 1} {$i <= $nExpGen} {incr i} {
set eee($i) [new Application/Traffic/Exponential]
$eee($i) attach-agent $udp
$ns con..."
(file "myTest3.tcl" line 47)
I got the solution:
The following statement build connections between two "Agents" (here $A and $B).
$ns connect $A $B
So, for this question, I shall connect my UDP agent and LossMonitor agent (outside my for loop).
$ns connect $udp $lmt
Connecting an "application" to an "agent" causes compiling error.