What to do get rid of this error in Ubuntu? - tcl

set tracefile [open out.tr w]
$ns trace-all $namfile
When I am running the above TCL code this is showing in terminal. I have just started learning TCL so don't know what to do anything this error.
can't read "namfile": no such variable
while executing
"$ns trace-all $namfile"

The error message is pretty clear: the variable called namfile is not set at the point when the code $ns trace-all $namfile is run. I can't tell why from the snippet you provided; maybe it's because you should have used $tracefile instead, or maybe you should set namfile to something and haven't done so? Or even possibly something more complicated. (I also don't know whether you're supposed to give a channel or a filename to the trace-all method; you should look that up.)

Related

Get attributes of an Agent in NS2

I actually need to know the attributes of my UDP Agent in my TCL script (to print some values and use it for statistics) and this is my first time with this script language. I tried to use the command info but I failed to use it.
This is my code :
#Setup a UDP connection
set udp [new Agent/UDP]
puts [$udp info class] # Work and print "Agent/UDP"
puts [info class variables Agent/UDP] #Fail with the error "Agent/UDP does not refer to an object"
I tried with :
puts [info class variables udp] #Fail (same error)
puts [info class variables $udp] #Error : _o87 does not refer to an object
No more result.
Can you tell me what I did wrong and how to get the attributes of my Agent/UDP object.
The problem is that there are multiple object systems about. Agent/UDP is an OTcl class, whereas info class operates on TclOO classes. TclOO (the standard object system from Tcl 8.6 onwards) is quite a lot newer than OTcl and has more features (it is faster too) but the syntax is a bit different in the detail so we don't expect ns-2 to ever be ported over. (There is a twisted heritage from OTcl to TclOO via XOTcl… but the syntax isn't one of the things that made the transition, as that was drawn more from another object system, [incr Tcl]. Tcl's been “blessed” with a plague of object systems.)
Documentation for OTcl isn't the easiest to find, but this page is helpful, as is the equivalent for instances. In particular, it tells us that we can do introspection via the info instproc (i.e., method):
set udp [new Agent/UDP]
puts [$udp info vars]
puts [$udp info commands]

Redirect the stdout when loading package in Tcl

I would like to redirect the stdout to null when loading package in Windows Tcl. (Redirect the wording of "Quality Windows Audio/Video Experience (qWAVE) support is available." to null)
Is their any way to solve this or any idea for this ?? Thank you so much.
C:\Users\Tester>tclsh
% set ixchariot_installation_dir "C:/Program Files x86)/Ixia/IxChariot"
C:/Program Files (x86)/Ixia/IxChariot
% cd $ixchariot_installation_dir
% load ChariotExt
Quality Windows Audio/Video Experience (qWAVE) support is available.
If the library is using Tcl channels to write its message, and you're using Tcl 8.6, it's pretty easy. You just push a transform on the stdout channel that swallows all bytes.
# Most of this is boiler-plate stuff...
namespace eval swallow {
proc initialize {handle mode} {
return {initialize clear finalize write flush}
}
proc clear {handle} {}
proc finalize {handle} {}
proc flush {handle} {}
# The important one; do nothing to throw away bytes
proc write {handle buffer} {}
# Export as an ensemble
namespace export *
namespace ensemble create
}
# Start dropping output
chan push stdout swallow
load ChariotExt
# Stop dropping output
chan pop stdout
That only works if the library is using Tcl channels to write it's message. If it is using a direct write (the more likely case) it won't. You can instead try a full redirect, but these are not easily undone.
close stdout
open NUL
load ChariotExt
I know that'd work on POSIX systems (except with /dev/null instead of NUL). Not sure on Windows. And it can't be easily undone; the old standard output stream is gone.
And in any case, it's possible that the library is using a direct write to the console; those aren't blockable, and you might just have to live with that irritating message.

Behavioral simulation in TCL Batch Mode

I have a behavioral simulation, which stores all needed information after simulation in a .txt file. I need to run this simulation about 8000 + times with different parameters, which are generated in MATLAB. I would like to run a TCL script with different parameters. What I have so far:
From MATLAB I call Vivado in batch mode with following parameters:
system('C:/Xilinx/Vivado/2015.4/bin/vivado -mode batch -nojournal -nolog -notrace -source E:/Projects/Vivado/Test_Files/VivTCLstim.txt -tclargs 256 32 15 25790');
The TCL script looks as follows:
open_project E:/Projects/Vivado/THD/THD_VHDL.xpr
set_property top tb_THD [get_filesets sim_1]
set_property top_lib xil_defaultlib [get_filesets sim_1]
set_property generic N=[lindex $argv 0] [get_filesets sim_1]
set_property generic DWIDTH=[lindex $argv 1] [get_filesets sim_1]
set_property generic ITER =[lindex $argv 2] [get_filesets sim_1]
launch_simulation
run [lindex $argv 3] ns
close_sim
However, it seems that Vivado does not change the values. It always runs simulation for 1000 ns (default set up) and uses generic parameters which are set by default in .vhd file. I’ve also tried to set generic parameters through GUI as shown here http://www.xilinx.com/support/answers/64118.html (this is where I got the TCL commands from), but the simulation parameters don’t change. What can be the cause? And is my script and the way to do the simulation in the batch mode right or not?
You don't need to run the simulation through Vivado. Vivado has command line tools for each step in a simulation:
VHDL source file compilation => xvhcomp
elaboration => xelab and
simulation run => xsim
The first step can be skipped, because xelab can also trigger the compile steps. You just need to provide a *.prj file containing all needed VHDL source file.
vhdl mylib my/source/file1.vhdl
vhdl mylib my/source/file2.vhdl
vhdl test my/source/testbench.vhdl
You can provide top-level generics to the simulation and of cause, you can provide your own Tcl file for xsim in batch mode. I wrote a Python wrapper around these tools to control all steps in the simulation run, and it works fine :).

Access higher level from script called by fileevent

I'm trying to draw on a canvas that is in the top level of my Tcl/Tk script, but from inside a call by fileevent like this:
canvas .myCanvas {}
proc plot_Data { myC inp } { $myC create rectangle {} }
fileevent $inp readable [list plot_Data .myCanvas $inp ]
pack .myCanvas
I have found out that the script called by fileevent (plot_Data) lives in a different space.
The script for a file event is executed at global level (outside the context of any Tcl procedure) in the interpreter in which the fileevent command was invoked.
I cannot make the two meet. I have definitely narrowed it down to this: plot_Data just can't access .myCanvas . Question: How can the fileevent script plot on the canvas?
The goal of this is live plotting, by the way. $inp is a pipe to a C-program that reads data from a measurement device. It is imho rightly configured with fconfigure $inp -blocking 0 -buffering none.
Callback scripts (except for traces, which you aren't using) are always called from the context of the global namespace. They cannot see any stack frames above them. This is because they are called at times that aren't closely controlled; there's no telling what the actual stack would be, so it is forced into a known state.
However, canvases (and other widgets) have names in the global namespace as well. Your callbacks most certainly can access them, provided the widget has not been destroyed, and might indeed be working. You just happen to have given it an empty list of coordinates to create, which is not usually legal to use with a canvas item.
Since you are using non-blocking I/O, you need to be aware that gets may return the empty string when reading an incomplete line. Use fblocked to determine if a partial read happened; if it does, the data is in a buffer on the Tcl side waiting for the rest of the line to turn up, and it is usually best to just go to sleep and wait for the next fileevent to fire.
A problem that might bite you overall is if the C program is in fully buffered mode; this is true by default when writing output from C to a pipe. Setting the buffering on the Tcl side won't affect it; you need to use setvbuf on the C side, or insert regular fflush calls, or use Expect (which pretends to be an interactive destination, though at quite a lot of cost of complexity of interaction) or even unbuffer (if you can find a copy).

How to wait for Modelsim Simulations to complete before proceeding in TCL script

I am trying to execute a regression test in Modelsim. I call a TCL script which compiles my source files and launches vsim. I launch a .do file and it runs a series of testbenches which all output result files. What I am adding is an automated checker that verifies the result files match known good runs. The problem is that after launching modelsim the TCL script doesn't wait for the completion of simulation before executing the checker "results_pass.py".
set nice_pid [open "|$modelsim_dir/vsim.exe -do do_files/vsim.do -novopt -gui"]
cd ../../Scripts
set script_name "results_pass.py"
set tb_name "rcp"
call_python $script_name $tb_name
vwait forever
For those wondering why I am calling a Python script. Mostly because I know very little TCL but don't have the time to go and change the legacy TCL script into Python.
Anyway, I am confident there is something I can stick between lines 1 and 2 that will wait for some indication from modelsim that it has completed executing my .do file. Any advice is appreciated.
Have you tried VUnit?https://github.com/LarsAsplund/vunit
It is an open source VHDL test framework that already does what you want.
It can run tests in parallel as well as with different generics values.
A test bench can have multiple tests which can be run in independent simulations as well as in the same simulation.
It can emit a test report that is understood by Jenkins containing test output, runtime and status.
It comes with a VHDL library of convenience functions such as check_equal.
It has complete VHDL dependency scanning so that files can just be added and VUnit will know what to incrementally compile to speedup the edit/compile/run cycle.
Can run user defined post simulation checks to verify for instance an output file against golden data.
In addition to running in batch it can launch the test in a GUI with a single flag.
It supports Modelsim and GHDL with Aldec and NVC coming soon.
I have personally used it to manage 200+ test cases.
Disclaimer I am one of the main authors.
It was created to avoid each VHDL team in the world to re-inventong the wheel with inhouse scripts of varying quality.
Answering my own question I wound up getting this to work before receiving responses. The other suggested solutions may be better.
First I modified my .do file adding line three below.
project open my_project.mpf
do do_files/regression.do
file delete -force "lock.txt"
Then I modified my TCL script as follows.
set nice_pid [open "|$modelsim_dir/vsim.exe -do do_files/vsim.do -novopt -gui"]
,# Create a "lock file" that is cleared at the completion of the .do file.
set lock_file "lock.txt"
set lock_PID [open $lock_file w]
close $lock_PID
while {[file exists $lock_file]}
{after 1000}
cd ../../Scripts
set script_name "results_pass.py"
set tb_name "my_tb"
call_python $script_name $tb_name
vwait forever
This way the calling process waits for Modelsim to complete before proceeding.
For anyone looking to use this here is call_python proc which I found here
;#----------------------------------------------------------------------------;
;# Procedure to call python scripts. Include ".py" extention.
;#----------------------------------------------------------------------------;
proc call_python {script_name tb_name} {
set output [exec python $script_name $tb_name]
print $output
}
$tb_name is just an argument for my python script.
TCL is actually returning a channel from the open call, not a pid. There are a couple of things you can do:
Use exec command instead of opening a pipe because you clearly don't want asynchronous I/O.
Use the close command to close the pipe which I believe waits for the process to close via the wait() system call.
You should open the subprocess with read-write and set a fileevent to listen for readable events from the subprocess pipe. When the subprocess exits it closes its stdout and you will receive a readable event with [eof] being true when reading from this pipe.
If you are not too familiar with tcl and the asynchronous channel handling I've done a quick example that uses two tcl scripts, the client driving the server process. When the server gets "quit" on stdin it will exit. The client process sees that the channel gets closed and cleans up then exits. The key commands are fconfigure to set the channel to non-blocking and fileeventto set a procedure to be called whenever something readable happens on the pipe.
server.tcl
proc main {} {
while {[gets stdin line] != -1} {
if {[string match "quit" [string trim $line]]} {
break
}
puts "ECHO $line"
}
return 0
}
main
client.tcl
proc Read {chan} {
set len [gets $chan line]
if {[eof $chan]} {
puts stderr "eof received"
set ::forever quit
fileevent $pipe readable {}
}
puts stderr "RECV: $len '$line'"
}
proc main {} {
set pipe [open |[list tclsh server.tcl] r+]
fconfigure $pipe -blocking 0 -buffering line -translation auto
fileevent $pipe readable [list Read $pipe]
after 500 [list puts $pipe begin]
after 1000 [list puts $pipe quit]
after 2000 [list set ::forever timeout]
vwait ::forever
puts "exit with status '$::forever'"
return 0
}
main
expected output
c:\src>tclsh client.tcl
RECV: 10 'ECHO begin'
eof received
exit quit
I managed this problem of automating Modelsim from Python by defining a dummy sentinal proc in Tcl. vsim is run with pipes for the I/O channels. The sentinel command is sent after every command I want to run. Then I wait to see the "sentinel" text appear in the output stream which guarantees that the previous command completed.
# Define a dummy sentinel proc
self.p.stdin.write('proc sentinel {} {}\n')
self.p.stdin.write(cmd + '\n')
self.p.stdin.write('sentinel\n')
self.p.stdin.flush()
while True:
if self.process_done(): break # The process died
out.append(get_output(self.outq))
if '> sentinel' in out[-1]: break # Stop when we see the prompt with the sentinel
You can see the full automation code here. A similar approach can be used when controlling Modelsim from a separate Tcl interpreter.