5
\$\begingroup\$

Say I have a state machine in verilog implemented with enums instead of parameters. I'd like to simulate this design in Icarus Verilog (iverilog) and look at the results in GtkWave. Is there any way I can get Icarus to dump out the enumeration text values and have them displayed in GktWave? For example, instead of 0, 1, 2 , I want to see "STATE0", "STATE1", "STATE2", etc?

In states.v:

module states ();

typedef enum logic [1:0] {
    STATE0,
    STATE1,
    STATE2
} state_t;


state_t state;

initial begin
    state = STATE0;
    #10;
    state = STATE1;
    #10;
    state = STATE2;
    #10;
end

`ifdef __ICARUS__
initial begin
    $dumpfile("states.fst");
    $dumpvars(0, states);
end
`endif

endmodule

Commands:

iverilog -g2012 states.sv
vvp a.out -fst
gtkwave states.fst

Then, after I've added the bus state to the waveform view, I'd expect Right-Mouse -> Data Format -> Enum to change the numbers to the state text values. But it just seems to change the values to a binary representation.

Tools:

  • Icarus Verilog version 11.0 (devel) (s20150603-612-ga9388a89)
  • GTKWave Analyzer v3.3.107 (w)1999-2020 BSI

Thanks!

\$\endgroup\$

2 Answers 2

5
\$\begingroup\$

This is a workaround: I have used a Translate Filter file

Steps:

  1. Create a file with the extension gtkw. This file contains how you want the state variable to be displayed on the waveform. For your example it would be:
00 STATE0
01 STATE1
10 STATE2

Because you have used logic type which is 2 bits wide and have not encoded the state variables, SystemVerilog assigns the state variables the default values in ascending order. In this case the default binary values would be from 00 to 10 since you have 3 State variables.

  1. Open the waveform and dump the signal. Do Right-Mouse -> Data Format -> Translate Filter File -> Enable and Select. The Select Signal Filter Dialog Box opens. Then left click on Add Filter to List button. Select the gtkw extension file that you created. This file will then be displayed in the Select Signal Filter dialog box. Select your file in the Select Filter Dialog Box, make sure it is highlighted, then left click on the OK button. The binary signals in the waveform should be replaced with the enum values.
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I was hoping to avoid this! Thanks for your answer. \$\endgroup\$
    – Marty
    Nov 14, 2020 at 14:13
3
+450
\$\begingroup\$

The *.vcd (fst/lxt/lxt2) file does not contain enum definition. But this is not the worst news.

The iverilog.exe translates the *.sv to the special file (a.out in your example). Then this file is playing on vvp.exe virtual machine.

Let's modify you example:

module states();
    typedef enum logic[1:0] {STATE0, STATE1, STATE2} state0_t;
    typedef enum logic[1:0] {STATE3, STATE4, STATE5} state1_t;  
    state0_t state0;
    state1_t state1;    
    initial begin
        state0 <= STATE0;
        state1 <= STATE3;
        #10;
        state0 <= STATE1;
        state1 <= STATE4;
        #10;
        state0 <= STATE2;
        state1 <= STATE5;
        #10;
    end
    initial begin
        $dumpfile("states.fst");
        $dumpvars(0, states);
    end
endmodule

Then let's get the a.out file and try to read them:

#! c:/iverilog-x64/bin/vvp
:ivl_version "10.1 (stable)" "(v10_1_1)";
:ivl_delay_selection "TYPICAL";
:vpi_time_precision - 9;
:vpi_module "system";
:vpi_module "vhdl_sys";
:vpi_module "v2005_math";
:vpi_module "va_math";
:vpi_module "v2009";
S_000000000069e5b0 .scope module, "states" "states" 2 3;
 .timescale -9 -9;
enum0000000000699650 .enum4 (2)
   "STATE0" 2'b00,
   "STATE1" 2'b01,
   "STATE2" 2'b10
;
enum000000000075cf80 .enum4 (2)
   "STATE3" 2'b00,
   "STATE4" 2'b01,
   "STATE5" 2'b10
;
v000000000069e980_0 .var "state0", 1 0;
v000000000069eb40_0 .var "state1", 1 0;
   .scope S_000000000069e5b0;
T_0 ;
   %pushi/vec4 0, 0, 2;
   %assign/vec4 v000000000069e980_0, 0;
   %pushi/vec4 0, 0, 2;
   %assign/vec4 v000000000069eb40_0, 0;
   %delay 10, 0;
   %pushi/vec4 1, 0, 2;
   %assign/vec4 v000000000069e980_0, 0;
   %pushi/vec4 1, 0, 2;
   %assign/vec4 v000000000069eb40_0, 0;
   %delay 10, 0;
   %pushi/vec4 2, 0, 2;
   %assign/vec4 v000000000069e980_0, 0;
   %pushi/vec4 2, 0, 2;
   %assign/vec4 v000000000069eb40_0, 0;
   %delay 10, 0;
   %end;
   .thread T_0;
   .scope S_000000000069e5b0;
T_1 ;
    %vpi_call/w 2 24 "$dumpfile", "states.fst" {0 0 0};
    %vpi_call/w 2 25 "$dumpvars", 32'sb00000000000000000000000000000000, S_000000000069e5b0 {0 0 0};
    %end;
    .thread T_1;
# The file index is used to find the file name in the following table.
:file_names 3;
    "N/A";
    "<interactive>";
    "main.sv";

Each vector (state0 or state1) has an ID (69e980_0 or 69eb40_0). You can see that the vector assignment happens only by value.

state0 <= STATE1;

    %pushi/vec4 1, 0, 2;
    %assign/vec4 v000000000069e980_0, 0;

state0 <= STATE2;

    %pushi/vec4 2, 0, 2;
    %assign/vec4 v000000000069e980_0, 0;

Also you can see that the enum's ID (699650 or 75cf80) does't used anywhere.

So the conclusion is that the vvp virtual machine doesn't know anything about the binding between an enum and a vector's value and the vvp can't provide this data to the GTKWave.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Sad times! Thanks for the detail. \$\endgroup\$
    – Marty
    Nov 14, 2020 at 14:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.