Add parameters to vcd dumps
Writing parameters into VCD files makes the values available to waveform tools. This can be done easily enough by writing out a $dumpadd section at the beginning of the file that sets the parameter values. We don't need to track the values over change, because by definition they do not change. This changes the typical vcd output as well, so a few of the regression tests need to be adjusted to account for this. Also, while tracking this down, found and fixed the vvp/README.txt documention for the .param/x records.
This commit is contained in:
parent
e67a796a77
commit
a1485906ca
|
|
@ -1,5 +1,5 @@
|
|||
$date
|
||||
Tue Apr 21 18:40:22 2009
|
||||
Sun May 15 18:09:10 2022
|
||||
$end
|
||||
$version
|
||||
Icarus Verilog
|
||||
|
|
@ -17,6 +17,9 @@ $scope module top $end
|
|||
$var reg 8 # \array[2] [7:0] $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
$comment Show the parameter values. $end
|
||||
$dumpall
|
||||
$end
|
||||
#0
|
||||
$dumpvars
|
||||
bx #
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
$date
|
||||
Sun May 15 09:20:23 2022
|
||||
$end
|
||||
$version
|
||||
Icarus Verilog
|
||||
$end
|
||||
$timescale
|
||||
1s
|
||||
$end
|
||||
$scope module main $end
|
||||
$var wire 4 ! bat [3:0] $end
|
||||
$var parameter 4 " bar $end
|
||||
$var parameter 4 # foo $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
$comment Show the parameter values. $end
|
||||
$dumpall
|
||||
b101 #
|
||||
b111 "
|
||||
$end
|
||||
#0
|
||||
$dumpvars
|
||||
b1100 !
|
||||
$end
|
||||
#1
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
$date
|
||||
Wed Jun 4 10:37:42 2008
|
||||
Sun May 15 18:09:25 2022
|
||||
$end
|
||||
$version
|
||||
Icarus Verilog
|
||||
|
|
@ -11,6 +11,9 @@ $scope module top $end
|
|||
$var reg 8 ! \arr[4] [7:0] $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
$comment Show the parameter values. $end
|
||||
$dumpall
|
||||
$end
|
||||
#0
|
||||
$dumpvars
|
||||
b0 !
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
$date
|
||||
Tue Sep 15 16:56:35 2009
|
||||
Sun May 15 18:19:07 2022
|
||||
$end
|
||||
$version
|
||||
Icarus Verilog
|
||||
|
|
@ -16,6 +16,9 @@ $scope module top $end
|
|||
$var reg 4 " \array[1] [3:0] $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
$comment Show the parameter values. $end
|
||||
$dumpall
|
||||
$end
|
||||
#0
|
||||
$dumpvars
|
||||
bx "
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
$date
|
||||
Fri Oct 16 08:46:35 2009
|
||||
Sun May 15 15:15:18 2022
|
||||
$end
|
||||
$version
|
||||
Icarus Verilog
|
||||
|
|
@ -53,6 +53,9 @@ $upscope $end
|
|||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
$comment Show the parameter values. $end
|
||||
$dumpall
|
||||
$end
|
||||
#0
|
||||
$dumpvars
|
||||
x/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
//
|
||||
// This tests that the parameter and localparam show up in the vcd dump.
|
||||
//
|
||||
module main;
|
||||
parameter [3:0] foo = 4'd5;
|
||||
localparam [3:0] bar = 7;
|
||||
wire [3:0] bat = foo + bar;
|
||||
|
||||
initial begin
|
||||
$dumpfile("work/br_gh156.vcd");
|
||||
$dumpvars(0, main);
|
||||
#1 $finish;
|
||||
|
||||
end
|
||||
|
||||
endmodule // main
|
||||
|
|
@ -309,6 +309,7 @@ br_gh127e normal ivltests gold=br_gh127e.gold
|
|||
br_gh127f normal ivltests gold=br_gh127f.gold
|
||||
br_gh142 CE ivltests
|
||||
br_gh152 CE ivltests
|
||||
br_gh156 normal ivltests diff=work/br_gh156.vcd:gold/br_gh156.vcd.gold:2
|
||||
br_gh157 CE ivltests gold=br_gh157.gold
|
||||
br_gh162 normal ivltests
|
||||
br_gh163 CE ivltests
|
||||
|
|
|
|||
|
|
@ -37,6 +37,16 @@ static int dump_no_date = 0;
|
|||
|
||||
static struct t_vpi_time zero_delay = { vpiSimTime, 0, 0, 0.0 };
|
||||
|
||||
/*
|
||||
* The vcd_list is the list of all the objects that are tracked for
|
||||
* dumping. The vcd_checkpoint goes through the list to dump the current
|
||||
* values for everything. When the item has a value change, it is added to the
|
||||
* vcd_dmp_list for dumping in the current time step.
|
||||
*
|
||||
* The vcd_const_list is a list of all of the parameters that are being
|
||||
* dumped. This list is scanned less often, since parameters do not change
|
||||
* values.
|
||||
*/
|
||||
struct vcd_info {
|
||||
vpiHandle item;
|
||||
vpiHandle cb;
|
||||
|
|
@ -47,7 +57,7 @@ struct vcd_info {
|
|||
int scheduled;
|
||||
};
|
||||
|
||||
|
||||
static struct vcd_info *vcd_const_list = NULL;
|
||||
static struct vcd_info *vcd_list = NULL;
|
||||
static struct vcd_info *vcd_dmp_list = NULL;
|
||||
static PLI_UINT64 vcd_cur_time = 0;
|
||||
|
|
@ -158,6 +168,18 @@ __inline__ static int dump_header_pending(void)
|
|||
return dumpvars_status != 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function writes out all the traced parameters. They never change, so
|
||||
* this is the only way they get written.
|
||||
*/
|
||||
static void vcd_const_checkpoint(void)
|
||||
{
|
||||
struct vcd_info *cur;
|
||||
|
||||
for (cur = vcd_const_list ; cur ; cur = cur->next)
|
||||
show_this_item(cur);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function writes out all the traced variables, whether they
|
||||
* changed or not.
|
||||
|
|
@ -232,6 +254,11 @@ static PLI_INT32 variable_cb_1(p_cb_data cause)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called at the end of the timestep where the $dumpvars task is
|
||||
* called. This allows for values to settle for the timestep, so that the
|
||||
* checkpoint gets the current values.
|
||||
*/
|
||||
static PLI_INT32 dumpvars_cb(p_cb_data cause)
|
||||
{
|
||||
if (dumpvars_status != 1) return 0;
|
||||
|
|
@ -244,7 +271,13 @@ static PLI_INT32 dumpvars_cb(p_cb_data cause)
|
|||
fprintf(dump_file, "$enddefinitions $end\n");
|
||||
|
||||
if (!dump_is_off) {
|
||||
fprintf(dump_file, "$comment Show the parameter values. $end\n");
|
||||
fprintf(dump_file, "$dumpall\n");
|
||||
vcd_const_checkpoint();
|
||||
fprintf(dump_file, "$end\n");
|
||||
|
||||
fprintf(dump_file, "#%" PLI_UINT64_FMT "\n", dumpvars_time);
|
||||
|
||||
fprintf(dump_file, "$dumpvars\n");
|
||||
vcd_checkpoint();
|
||||
fprintf(dump_file, "$end\n");
|
||||
|
|
@ -275,6 +308,12 @@ static PLI_INT32 finish_cb(p_cb_data cause)
|
|||
free(cur);
|
||||
}
|
||||
vcd_list = 0;
|
||||
for (cur = vcd_const_list ; cur ; cur = next) {
|
||||
next = cur->next;
|
||||
free((char *)cur->ident);
|
||||
free(cur);
|
||||
}
|
||||
vcd_const_list = 0;
|
||||
vcd_names_delete(&vcd_tab);
|
||||
vcd_names_delete(&vcd_var);
|
||||
nexus_ident_delete();
|
||||
|
|
@ -601,10 +640,6 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
|||
|
||||
/* Generate the $var or $scope commands. */
|
||||
switch (item_type) {
|
||||
case vpiParameter:
|
||||
vpi_printf("VCD sorry: $dumpvars: can not dump parameters.\n");
|
||||
break;
|
||||
|
||||
case vpiNamedEvent:
|
||||
case vpiIntegerVar:
|
||||
case vpiBitVar:
|
||||
|
|
@ -618,7 +653,6 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
|||
case vpiTimeVar:
|
||||
case vpiNet:
|
||||
|
||||
|
||||
/* If we are skipping all signal or this is in an automatic
|
||||
* scope then just return. */
|
||||
if (skip || vpi_get(vpiAutomatic, item)) return;
|
||||
|
|
@ -684,6 +718,35 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
|||
fprintf(dump_file, " $end\n");
|
||||
break;
|
||||
|
||||
case vpiParameter:
|
||||
|
||||
/* If we are skipping all pamaeters then just return. */
|
||||
if (skip) return;
|
||||
|
||||
size = vpi_get(vpiSize, item);
|
||||
|
||||
/* Declare the parameter in the VCD file. */
|
||||
name = vpi_get_str(vpiName, item);
|
||||
prefix = is_escaped_id(name) ? "\\" : "";
|
||||
|
||||
ident = strdup(vcdid);
|
||||
gen_new_vcd_id();
|
||||
|
||||
/* Make an info item to go in the vcd_const_list. */
|
||||
info = malloc(sizeof(*info));
|
||||
info->item = item;
|
||||
info->ident = ident;
|
||||
info->scheduled = 0;
|
||||
info->dmp_next = 0;
|
||||
info->next = vcd_const_list;
|
||||
vcd_const_list = info;
|
||||
info->cb = NULL;
|
||||
|
||||
/* Generate the $var record. Now the parameter is declared. */
|
||||
fprintf(dump_file, "$var %s %u %s %s%s $end\n",
|
||||
type, size, ident, prefix, name);
|
||||
break;
|
||||
|
||||
case vpiModule:
|
||||
case vpiGenScope:
|
||||
case vpiFunction:
|
||||
|
|
@ -697,7 +760,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
|||
/* Value */
|
||||
vpiNamedEvent,
|
||||
vpiNet,
|
||||
/* vpiParameter, */
|
||||
vpiParameter,
|
||||
vpiReg,
|
||||
vpiVariables,
|
||||
/* Scope */
|
||||
|
|
|
|||
|
|
@ -133,10 +133,9 @@ objects.
|
|||
|
||||
The syntax of a parameter is:
|
||||
|
||||
<label> .param/str <name>, <value>;
|
||||
<label> .param/b <name>, <value> [<msb>,<lsb>];
|
||||
<label> .param/l <name>, <value> [<msb>,<lsb>];
|
||||
<label> .param/r <name>, <value>;
|
||||
<label> .param/str <name> <local-flag> <file-idx> <lineno>, <value>;
|
||||
<label> .param/l <name> <local-flag> <file-idx> <lineno>, <value>;
|
||||
<label> .param/r <name> <local-flag> <file-idx> <lineno>, <value>;
|
||||
|
||||
The <name> is a string that names the parameter. The name is placed in
|
||||
the current scope as a vpiParameter object. The .param suffix
|
||||
|
|
@ -144,7 +143,6 @@ specifies the parameter type.
|
|||
|
||||
.param/str -- The parameter has a string value
|
||||
.param/l -- The parameter has a logic vector value
|
||||
.param/b -- The parameter has a boolean vector value
|
||||
.param/r -- The parameter has a real value
|
||||
|
||||
The value, then, is appropriate for the data type. For example:
|
||||
|
|
|
|||
Loading…
Reference in New Issue