From 6564f5521934ba6d5a0f166e71b6d86011a23fcb Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sat, 21 May 2022 10:13:27 -0700 Subject: [PATCH] Fix vcd dump of real value parameters Parameters with real values are possible in Verilog, but not in the VCD format, so lie a little and call them "real" objects. Otherwise, we can treat them like constants and it works out, at least for gtkwave. --- ivtest/gold/br_gh156.vcd.gold | 14 +++++++++----- ivtest/ivltests/br_gh156.v | 2 ++ vpi/sys_fst.c | 12 +++++++++++- vpi/sys_vcd.c | 13 ++++++++++++- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/ivtest/gold/br_gh156.vcd.gold b/ivtest/gold/br_gh156.vcd.gold index ccac9620e..328241847 100644 --- a/ivtest/gold/br_gh156.vcd.gold +++ b/ivtest/gold/br_gh156.vcd.gold @@ -1,5 +1,5 @@ $date - Sun May 15 09:20:23 2022 + Sat May 21 10:00:47 2022 $end $version Icarus Verilog @@ -9,17 +9,21 @@ $timescale $end $scope module main $end $var wire 4 ! bat [3:0] $end -$var parameter 4 " bar $end -$var parameter 4 # foo $end +$var real 1 " PI $end +$var parameter 4 # bar $end +$var parameter 4 $ foo $end +$var real 1 % tau $end $upscope $end $enddefinitions $end $comment Show the parameter values. $end $dumpall -b101 # -b111 " +b101 $ +b111 # +r3.14 " $end #0 $dumpvars +r6.28 % b1100 ! $end #1 diff --git a/ivtest/ivltests/br_gh156.v b/ivtest/ivltests/br_gh156.v index 296711232..e31febf92 100644 --- a/ivtest/ivltests/br_gh156.v +++ b/ivtest/ivltests/br_gh156.v @@ -5,7 +5,9 @@ module main; parameter [3:0] foo = 4'd5; localparam [3:0] bar = 7; + parameter real PI = 3.14; wire [3:0] bat = foo + bar; + wire real tau = 2.0 * PI; initial begin $dumpfile("work/br_gh156.vcd"); diff --git a/vpi/sys_fst.c b/vpi/sys_fst.c index ea471a5c4..f01771629 100644 --- a/vpi/sys_fst.c +++ b/vpi/sys_fst.c @@ -74,6 +74,10 @@ static void show_this_item(struct vcd_info*info) value.format = vpiRealVal; vpi_get_value(info->item, &value); fstWriterEmitValueChange(dump_file, info->ident, &value.value.real); + } else if (type == vpiParameter && vpi_get(vpiConstType, info->item) == vpiRealConst) { + value.format = vpiRealVal; + vpi_get_value(info->item, &value); + fstWriterEmitValueChange(dump_file, info->ident, &value.value.real); } else { value.format = vpiBinStrVal; vpi_get_value(info->item, &value); @@ -483,7 +487,13 @@ static void scan_item(unsigned depth, vpiHandle item, int skip) case vpiNamedEvent: type = FST_VT_VCD_EVENT; break; case vpiIntVar: case vpiIntegerVar: type = FST_VT_VCD_INTEGER; break; - case vpiParameter: type = FST_VT_VCD_PARAMETER; break; + /* FST (gtkwave) assumes PARAMETER are bit, so handle other cases */ + case vpiParameter: + switch (vpi_get(vpiConstType, item)) { + case vpiRealConst: type = FST_VT_VCD_REAL; break; + default: type = FST_VT_VCD_PARAMETER; break; + } + break; /* Icarus converts realtime to real. */ case vpiRealVar: type = FST_VT_VCD_REAL; break; case vpiMemoryWord: diff --git a/vpi/sys_vcd.c b/vpi/sys_vcd.c index 0a72e9ea0..13eea5e5d 100644 --- a/vpi/sys_vcd.c +++ b/vpi/sys_vcd.c @@ -115,6 +115,11 @@ static void show_this_item(struct vcd_info*info) fprintf(dump_file, "r%.16g %s\n", value.value.real, info->ident); } else if (type == vpiNamedEvent) { fprintf(dump_file, "1%s\n", info->ident); + } else if (type == vpiParameter && vpi_get(vpiConstType, info->item) == vpiRealConst) { + + value.format = vpiRealVal; + vpi_get_value(info->item, &value); + fprintf(dump_file, "r%.16g %s\n", value.value.real, info->ident); } else if (vpi_get(vpiSize, info->item) == 1) { value.format = vpiBinStrVal; vpi_get_value(info->item, &value); @@ -533,7 +538,13 @@ static void scan_item(unsigned depth, vpiHandle item, int skip) case vpiNamedEvent: type = "event"; break; case vpiIntVar: case vpiIntegerVar: type = "integer"; break; - case vpiParameter: type = "parameter"; break; + /* VCD doesn't support real parameters, so lie. */ + case vpiParameter: + switch (vpi_get(vpiConstType, item)) { + case vpiRealConst: type = "real"; break; + default: type = "parameter"; break; + } + break; /* Icarus converts realtime to real. */ case vpiRealVar: type = "real"; break; case vpiMemoryWord: