ghdl icon indicating copy to clipboard operation
ghdl copied to clipboard

gtkwave does not run for the expected time within a testbench

Open seanybaggins opened this issue 4 years ago • 8 comments

When I run python run.py -g I am expecting to see the output of my unit test displayed within gtkwave.

Test Bench

LIBRARY vunit_lib;
CONTEXT vunit_lib.vunit_context;

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

LIBRARY src;
USE src.mux_2i_1o;

ENTITY tb_mux_2i_1o IS
  GENERIC (runner_cfg : STRING);
END ENTITY;

ARCHITECTURE tb OF tb_mux_2i_1o IS
  SIGNAL button : std_logic := 'X';
  SIGNAL input_1 : std_logic := '0';
  SIGNAL input_2 : std_logic := '1';
  SIGNAL output : std_logic;
BEGIN
  mux : ENTITY mux_2i_1o PORT MAP (
    button => button,
    input_1 => input_1,
    input_2 => input_2,
    output => output
    );

  main : PROCESS
  BEGIN
    test_runner_setup(runner, runner_cfg);

    WHILE test_suite LOOP

      IF run("button press to switch inputs") THEN
        button <= '0';
        check(output = input_1);
        wait for 20 ns;
        button <= '1';
        wait for 20 ns;
        check(output = input_2, "Input did not change when button was pressed");
      END IF;

    END LOOP;

    test_runner_cleanup(runner); -- Simulation ends here
    WAIT;
  END PROCESS;
END ARCHITECTURE;

As you can see, there are two 20ns waits within the test bench. Which means I am expecting the gtkwave gui to show me a sim for a total of 40ns. But when I run python run.py -g I get the following output.

image

Steps to reproduce on Linux desktop environment

cd $HOME
git clone https://github.com/seanybaggins/ben_eaters_8_bit_computer.git
cd ben_eaters_8_bit_computer

docker run --volume="$HOME/.Xauthority:/root/.Xauthority:rw" --volume="$HOME/ben_eaters_8_bit_computer/:$HOME/ben_eaters_8_bit_computer" -w="$HOME/ben_eaters_8_bit_computer"  --env="DISPLAY" --net=host ghdl/ext python run.py -g

docker start -a <default name>

seanybaggins avatar Apr 03 '20 01:04 seanybaggins

I can reproduce. If you add a wait; statement in the end of your main process (after the last check), 40ns of waveform are shown. However, I don't know if this is because of GHDL, VUnit and/or GtkWave. It would be useful to reproduce it without VUnit.

eine avatar Apr 03 '20 04:04 eine

That's because there are no new signal events after 20ns.

You'd like to see a waveform until 40 ns, but if the simulation goes until time'last (which is not unusual), you will have a very very long waveform).

I agree that the output could be improved, but I haven't yet found the best one.

tgingold avatar Apr 03 '20 05:04 tgingold

Fair enough. I guess we can add some note to the docs (in https://ghdl.readthedocs.io/en/latest/using/Simulation.html#cmdoption-ghdl-wave?) so that users are aware. Remembering to end all the sims with some signal event is straightforward.

eine avatar Apr 03 '20 13:04 eine

@eine putting the wait statement just after the check manage to solve my issue. Thank you. Should the ticket remain open until a comment is put into documentation?

seanybaggins avatar Apr 03 '20 18:04 seanybaggins

I'm glad it worked! Yes, I think we can keep this open until we update the docs.

eine avatar Apr 03 '20 19:04 eine

Hang on. While adding these wait statements do improve the output of the timing diagram, it also causes the unit tests to fail.

Steps to reproduce

cd $HOME
git clone https://github.com/seanybaggins/ben_eaters_8_bit_computer.git
cd ben_eaters_8_bit_computer
git checkout 95c213e668d550416d6683aa18043910816a9b83

docker run --volume="$HOME/.Xauthority:/root/.Xauthority:rw" --volume="$HOME/ben_eaters_8_bit_computer/:$HOME/ben_eaters_8_bit_computer" -w="$HOME/ben_eaters_8_bit_computer"  --env="DISPLAY" --net=host ghdl/ext python run.py

docker start -a <default name>

seanybaggins avatar Apr 03 '20 20:04 seanybaggins

That makes sense, because the simulation does not reach test_runner_cleanup(runner);. It is related to how VUnit decides whether a test failed. Hence, it is a false negative.

Instead of adding a wait, you can create any dummy signal and do assign it. See, for example, the usage of start, done and saved in https://github.com/VUnit/vunit/blob/master/examples/vhdl/array_axis_vcs/src/test/tb_axis_loop.vhd#L60-L66 So, you would create signal done, assign it to 0 and set it to 1 when you want to have a last event triggered before closing the sim.

eine avatar Apr 03 '20 20:04 eine

@eine thank you. That was extremely well explained. I now have reliable unit tests and can debug them in gtkwave.

seanybaggins avatar Apr 03 '20 22:04 seanybaggins