From a1485906ca05a708f8920977a4a7f3565c96e2b1 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 15 May 2022 18:47:18 -0700 Subject: [PATCH 1/2] 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. --- ivtest/gold/array_dump.vcd.gold | 5 ++- ivtest/gold/br_gh156.vcd.gold | 25 +++++++++++ ivtest/gold/dump_memword.vcd | 5 ++- ivtest/gold/pr2859628.vcd.gold | 5 ++- ivtest/gold/vcd-dup.vcd.gold | 5 ++- ivtest/ivltests/br_gh156.v | 17 ++++++++ ivtest/regress-vlg.list | 1 + vpi/sys_vcd.c | 77 ++++++++++++++++++++++++++++++--- vvp/README.txt | 8 ++-- 9 files changed, 132 insertions(+), 16 deletions(-) create mode 100644 ivtest/gold/br_gh156.vcd.gold create mode 100644 ivtest/ivltests/br_gh156.v diff --git a/ivtest/gold/array_dump.vcd.gold b/ivtest/gold/array_dump.vcd.gold index da8c9312d..4c78ece41 100644 --- a/ivtest/gold/array_dump.vcd.gold +++ b/ivtest/gold/array_dump.vcd.gold @@ -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 # diff --git a/ivtest/gold/br_gh156.vcd.gold b/ivtest/gold/br_gh156.vcd.gold new file mode 100644 index 000000000..ccac9620e --- /dev/null +++ b/ivtest/gold/br_gh156.vcd.gold @@ -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 diff --git a/ivtest/gold/dump_memword.vcd b/ivtest/gold/dump_memword.vcd index 03de017d5..501fd5231 100644 --- a/ivtest/gold/dump_memword.vcd +++ b/ivtest/gold/dump_memword.vcd @@ -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 ! diff --git a/ivtest/gold/pr2859628.vcd.gold b/ivtest/gold/pr2859628.vcd.gold index 36c6406bb..1fbe9ed1e 100644 --- a/ivtest/gold/pr2859628.vcd.gold +++ b/ivtest/gold/pr2859628.vcd.gold @@ -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 " diff --git a/ivtest/gold/vcd-dup.vcd.gold b/ivtest/gold/vcd-dup.vcd.gold index 2439e1a37..3e0235580 100644 --- a/ivtest/gold/vcd-dup.vcd.gold +++ b/ivtest/gold/vcd-dup.vcd.gold @@ -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/ diff --git a/ivtest/ivltests/br_gh156.v b/ivtest/ivltests/br_gh156.v new file mode 100644 index 000000000..296711232 --- /dev/null +++ b/ivtest/ivltests/br_gh156.v @@ -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 diff --git a/ivtest/regress-vlg.list b/ivtest/regress-vlg.list index 7c019c309..2f4ce90ad 100644 --- a/ivtest/regress-vlg.list +++ b/ivtest/regress-vlg.list @@ -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 diff --git a/vpi/sys_vcd.c b/vpi/sys_vcd.c index 1229304d3..a2ad3b076 100644 --- a/vpi/sys_vcd.c +++ b/vpi/sys_vcd.c @@ -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 */ diff --git a/vvp/README.txt b/vvp/README.txt index db3ee0cbd..26938b188 100644 --- a/vvp/README.txt +++ b/vvp/README.txt @@ -133,10 +133,9 @@ objects. The syntax of a parameter is: -