Redirect the stdout when loading package in Tcl - 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.

Related

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.

d programming language : standard input problem or misunderstanding?

Here is a simple program that reads lines from stdin and outputs them to stdout.
module test;
import std.stdio;
void main(string[] args)
{
foreach (int i, string line; lines(stdin)) {
writeln(line ~ " (test)");
}
}
I'm using the Windows DMD compiler v2.052.
If I do : type file.txt | test.exe
The program appends the word "test" to each line of file.txt and outputs them to the console.
However I keep getting an error at the end:
std.stdio.StdioException#std\stdio.d(2138): Bad file descriptor
Maybe I'm missing something?
It drives me crazy! :)
This is a longstanding bug: http://d.puremagic.com/issues/show_bug.cgi?id=3425
What you're trying to do definitely works on non-Windows operating systems and should work on Windows, too. I think it's a bug in the Digital Mars implementation of the C I/O functions, which are being wrapped by std.stdio. I've tried to fix this bug before, but never even succeeded in identifying its root cause.
I'm not familiar with the type command, maybe it isn't sending EOF when the file is done. In Linux you just do: ./test < file.txt
This is input redirection. Unlike piping, which turns the program output into standard input, this turns the file into standard input of the program. There is also output redirection which takes the output of the program and stores it in a file.
./test > output.txt

Implementation of breadth-first search in tcl

I am trying to implement breadth-first search algorithm but I am unable to implement , and I am new user of TCL can any one help me to implement this algorithm in tcl.
I think we need a bit more detail before we can help.
So, are we are talking about a graph, if so what type? The simplest would be a undirected graph with no edge weights but is this the case?
Do you have a data structure for the graph, if so what is it?
Finally why are you re-inventing the wheel? Tcllib has the struct::graph package which implements breadth first search, see the walk command. Can you use this or the algorithms in the struct::graph::op package to do what you want.
If you are searching for files instead of generic objects, look up the command for_recursive_glob in the Tclx package. Here is a quick example:
package require Tclx
for_recursive_glob fileName {/path/to/dir1 /to/dir2} {*.txt *.doc} { puts $fileName }
The document said for_recursive_glob use breadth-first algorithm. If you want to exit prematurely (i.e. found what you were looking for), use the 'break' command to exit the for loop:
package require Tclx
for_recursive_glob fileName {/path/to/dir1 /to/dir2} {*.txt *.doc} {
puts $fileName
if {[string match *myfile*]} { break }
}