How do I run the tcl proc function with verilog? - tcl

currently I've got some bunch of tcl files. in the tcl files, especially in the one tcl, I found the below a proc function in the tcl.
proc ahb_write {addr data {str s}} {
set ahbm top.cpu_subsys
...
if {$::verbose > 0} {
}
silent {
...........
...........
delay 1
So I want to invoke and run this ahb_write proc function when I run the simulation.
Is there any possible way to run the proc function when I run the simulation with verilog?

You would need the SystemVerilog DPI to do this in any simulator. In Modelsim, you would call the function mti_fli::mti_com("command") An alternative that would probably work in any simulator is to to have a command executed upon hitting a breakpoint.

I have done this before where I wanted to use a verilog task that would inject bit errors on a memory. In NCSim, I had to first individually deposit the values for the parameters of the task and then call the task itself.
deposit tinst.u_buffer.u_fifo.u_sram_0.injectSA.addr 1
deposit tinst.u_buffer.u_fifo.u_sram_0.injectSA.bitn 2
deposit tinst.u_buffer.u_fifo.u_sram_0.injectSA.typen 1
task tinst.u_buffer.u_fifo.u_sram_0.injectSA
run 0.1
I don't know for sure if the 'run 0.1' was necessary or not, but I know this at least worked in my example.
The verilog task was defined in the RAM model like this:
task injectSA;
input [numWordAddr-1:0] addr;
input integer bitn;
input typen;
...

Related

How to write the equivalent tcl script for "wait until (SomeSignal)" in ModelSim

I am writing tcl scripts as a wrapper for my VHDL simulation and I am trying to implement the equivalent of the following VHDL pseudo code snippet:
Data <= SomeData;
wait until (strobe = '1');
Data <= NewData;
I tried to do that by creating a loop in tcl that checks the value of the strobe signal for some amount of time but it is extremely inefficient. As far as I see "when" clause is not going to help as well. Are there any suggestions?
proc wait_until {sig val} {
for {set i 0} {$i < 50} {incr i} {
set dummy [examine -radix unsigned $sig]
if {$dummy eq $val} {
break
}
run 10 ns
}
}
you run it:
wait_until strobe 1
Short answer: vwait does "wait until variable is written to (by some event callback)", and that's when you reevaluate the expression to see if it has changed, going back to waiting if it hasn't. The variable name given to vwait must be a global variable (or the qualified name of a namespace variable); it cannot be a local variable.
Longer answer: You can use a variable trace to determine whether to reevaluate the expression, and then write (an arbitrary value) to some sort of trigger variable that vwait notices. The trigger variable has to be global, but the trace can be on a local variable if needed. (You formally take a performance hit for that, but it doesn't matter if that's what you need.)
However, in all cases you'll need some sort of event (or rather a callback in response to an event) somewhere that causes the variable in the expression to change.

TCL API coverage : check if a TCL command have been called and tested exaustively in a test suite

Supposing I have a TCL API like :
namespaceXY::apiXY <value> -opt1 <value1> -opt2 <value2> -opt3 <value3>
This API is used (or maybe not) in a test suite (i.e thousands of tests).
How I can check if my API have been called + tested exhaustively (all options have been called/tested).
Many thanks
You can set an execution trace on the command. That way the signature of your command won't change. So you still get the same results if any code does info args namespaceXY::apiXY. Also error messages are not affected.
proc cmdtracer {cmd op} {
global cmdtracer
dict incr cmdtracer $cmd
}
trace add execution namespaceXY::apiXY enter cmdtracer
In the end you'll have a cmdtracer dict that contains the counts of each way the command was called. You will have to figure out yourself how to check if all options have been tested. There is not enough information in your question to provide suggestions for that part.
See #SchelteBron's answer for covering commands.
Exhaustively testing all options is going to be tricky, since they could potentially all interact in complex ways and some may be mutually-exclusive (think about the standard Tcl lsearch command for example). However, auditing that all options are at least called in your own commands can be done by additional audit-only probes. Checking all the sensible combinations of them is a manual task; you probably need a coverage tool for that.
Auditing Options in C Commands
Assuming that you're dealing with the case where you've got a C command that uses Tcl_GetIndexFromObj() to parse the option name (this is common and recommended) and where you don't mind having a threading hazard (also pretty common) the idea is simple. Make an integer variable (probably with file scope) in your C code, bind it to a Tcl variable with Tcl_LinkVar(), then use the resulting index from your (successful) Tcl_GetIndexFromObj() call to set a bit in that integer variable that says that the option was parsed.
#ifdef AUDIT_OPTIONS
static int foobar_optionTracker;
#endif
// in the implementation function, called FoobarImpl here for sake of argument
int index;
if (Tcl_GetIndexFromObj(interp, objPtr, optionNameTable, "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
#ifdef AUDIT_OPTIONS
foobar_optionTracker |= 1 << index;
// Theoretically should call Tcl_UpdateLinkedVar() here, but for audit-only its not important
#endif
switch (index) {
// ...
}
// In your command registration function
Tcl_CreateObjCommand(interp, "foobar", FoobarImpl, NULL, NULL);
#ifdef AUDIT_OPTIONS
Tcl_LinkVar(interp, "optionTracker(foobar)", (void*) &foobar_optionTracker, TCL_LINK_INT);
#endif
With that in place, you can just read the array element optionTracker(foobar) from your Tcl test control code to see what options have been parsed (assuming you're happy with a bit-mask) in the foobar command since the last time the mask was reset. You reset the mask by just writing 0 to it.
Note that there's also Tcl_GetIndexFromObjStruct() in the C API, but auditing coverage of that is not significantly different from above.
Auditing Options in Tcl Commands
The equivalent of Tcl_GetIndexFromObj() in pure Tcl code is tcl::prefix match, but that doesn't return an index. Instead it returns the full option name that you can use with switch. Auditing that is most easily done with a full array. (This is morally the same as what the version for the C code does, but adapted to work with the optimal tools in a particular language.)
proc foobar {mandatoryArgument1 mandatoryArgument2 args} {
# Parse other things here, set up the TABLE of option descriptors, etc.
foreach option $args {
set option [tcl::prefix match $TABLE $option]
if {$::DoAudit} {
set ::foobarAudit($option) 1
}
switch -- $option {
# etc...
}
}
You can use things like array size foobarAudit to count the number of options actually used, or parray foobarAudit to print out what was actually used.

Chisel randomly initialize register value when simulating with verilator

I'm using Chisel and blackbox to run my chisel logic against a verilog register file.
The registerfile does not have reset signal so I expect the register to be randomly initialized.
I passed the --x-initial unique to verilator,
Basically this is how I launch the test:
private val backendName = "verilator"
"NOCDMA" should s" do blkwrite and blkread correctly (with $backendName)" in {
Driver.execute(Array("--fint-write-vcd","--backend-name",s"$backendName",
"--more-vcs-flags","--trace-depth 1 --x-initial unique"),
()=>new DMANetworkWithMem(memAddrWidth,memDataWidth)(nocDataWidth)(nNodesX,nNodesY)){
c => new DMANetworkRWTest(c)
}
}
But The data I read from the register file is all zero before I wrote anything to it.
The read data is correct after I wrote to it.
So, is there anything inside chisel that I need to tune or I did not do everything properly ?
Any suggestions?
I'm not certain, but I found the following issue on Verilator with a similar issue: https://github.com/verilator/verilator/issues/1399.
From skimming the above issue, I think you also need to pass +verilator+seed+<value> and +verilator+rand+reset+<value> at runtime. I am not an expert in the iotesters, but I believe you can add these runtime values through the iotesters argument: --more-vcs-c-flags.
Side note, I would also set --x-assign unique in Verilator if there are cases in the Verilog where runtime would otherwise inject an X (eg. out-of-bounds index).
I hope this helps!

How to check for functions dependency in powershell scripts. Avoid running the same function multiple times

In my PowerShell script - one function's output is another function's input. For Eg: Function CreateReport($x) cannot run until unless the Function ParseXml($x) runs. What if a user directly runs the 2nd function before running the 1st. How can I check if 1st function is already run to continue with 2nd, i.e, first run the 1st function (generate the txt file) then run the 2nd? if first func is already run do not re-run it.
For Eg: Suppose I have a TestFunc.ps1 file having 2 functions as below
$X = "C:\XmlPath\file1.xml"
Function ParseXml($X)
{
#Read xml and output contents in a txt file
}
#This function should execute only after the function Parsexml($X) and if Pasrsexml() has run before and generated the output, it shouldnot be allowed to re-run here
Function CreateReport($T)
{
#from the txtfile Create csv
}
According to this and your other question How to alias a parameterized function as a flag in powershell script? you are trying to implement a so called build script. Instead of inventing a wheel (implementing task dependencies, watching tasks to be run once, etc.) take a look at some already implemented tools like psake or Invoke-Build. They are designed for PowerShell and they do exactly what you want (run specified task sets, maintain task dependencies, run tasks once, etc.). These tools require a little bit of learning, of course, but in a long run they are worth to be learned.
If ParseXml function output a file, you can, in the CreateReport function, test for the existence of this file with Test-Path cmdlet:
if exists continue with CreateReport function else call the ParseXml function before continue.
Use a flag. Set the flag in ParseXml function and check it in the CreateReport function. If the flag isn't set, print an error and exit, othervise run the reporting code. Remember to clear the flag when the process is complete.
You can use a flag variable. For more persistent flags, consider using flag files or setting the flag in a database.

Adding help to the user defined functions in TCL

how can i add some kind of help to the user defined functions in TCL
Supposing if i have a function called runtest {ip_address test_time},
How to describe what the test or procedure is about in the TCL_shell?
How can i specify the information to the user, if he types in function_name --help in the TCL shell the user should be able to know what the function does and what exactly are the parameters.
how can i do this?
While it is true that it is not part of the language, it is fairly easy to implement something that adds this functionality to pre-existing functions. The only caveat being that the function then cannot take the string --help as a valid argument since that argument will trigger the feature.
Here's one simple implementation:
# Lets call the feature "document". As in, add documentation:
proc document {procname text} {
rename $procname __$procname
proc $procname args [string map [list %TEXT% $text %PROC% $procname] {
if {$args == "--help"} {
puts {%TEXT%}
} else {
set script [linsert $args 0 __%PROC%]
return [uplevel 1 $script]
}
}]
}
What this does is to override the function (by renaming and then declaring another function of the same name) and see if the function is called with the argument --help. If it is it prints the documentation otherwise it executes the original function. Just be careful not to call this twice on the same function (it can be modified for it to work though).
So you can do things like:
proc foo {} {puts 2}
document foo {Prints the number 2.}
Now if you call:
foo --help
and it would output:
Prints the number 2.
You don't have to touch the existing procedures:
proc help {procname} {
puts $::helptext($procname)
}
proc addhelp {procname text} {
set ::helptext($procname) $text
}
addhelp foo "this is the help text for procedure foo"
help foo
Without redefining the proc command, you cannot. Ie, that functionality is not built into the language, but would be possible to add if you so wished.
I will note that adding the capability yourself, while possible, is probably beyond the difficulty where it's worth doing, especially for someone that isn't intimately familiar with the language. That being said, you can check the tclers wiki for a preexisting implementation.
I tend to prefer to put help in a separate file (e.g., as HTML) which lets me browse it in another window. There are so many ways you can do that while still keeping the docs with the code, such as through doxygen.
There are also a number of ways of doing interactive documentation, several of which are described in the Tcler's Wiki; it would seem to me that some of the techniques mentioned on that page (together with #slebetman's answer) would give you what you wanted. (I think it would be easier to have a separate help command as that would avoid having the help syntax interfere with the command, but that's your call.)