VUnit/vunit

Avalon Sink Stream VC hangs simulators

albydnc opened this issue · 3 comments

I am trying to use the avalon stream sink VC from VUnit. When I try to run my code, the simulators hang without even starting to write any output and I have to force kill them. So far I've tried with GHDL and Modelsim, both with the same result.

Here is my entity:

library ieee;
context ieee.ieee_std_context;
use ieee.math_real.all;

library vunit_lib;
context vunit_lib.vunit_context;
context vunit_lib.vc_context;

entity dma_sim_file is
  generic
  (
    constant FILE_NAME : string := "dma_0"
  );
  port
  (
    eof : in boolean := false;
    snk_clk   : out std_logic;
    snk_rst   : in std_logic;
    snk_ready : out std_logic;
    snk_valid : in std_logic;
    snk_sop   : in std_logic;
    snk_eop   : in std_logic;
    snk_data  : in std_logic_vector(255 downto 0)
  );
end entity dma_sim_file;

architecture sim of dma_sim_file is
  constant CLOCK_PERIOD : time      := 4 ns;
  signal clk            : std_logic := '1';
  -- avalon stream BFM
  constant avalon_sink_stream : avalon_sink_t :=
  new_avalon_sink(data_length => 256, ready_high_probability => 1.0);
  constant slave_stream : stream_slave_t := as_stream(avalon_sink_stream);

begin
  snk_clk <= clk;

  clk_gen : process
  begin
    clk <= not clk after CLOCK_PERIOD/2;
  end process;

  avalon_sink_vc : entity vunit_lib.avalon_sink
    generic
    map (
    sink => avalon_sink_stream)
    port map
    (
      clk   => clk,
      valid => snk_valid,
      ready => snk_ready,
      sop   => snk_sop,
      eop   => snk_eop,
      data  => snk_data
    );

  main : process
    variable data : std_logic_vector(255 downto 0);
  begin
    while not eof loop
      pop_stream(net, slave_stream, data);
      report "AVALON RX: " & to_hstring(data);
    end loop;
  end process;

end architecture;

and here the tb:

library ieee;
context ieee.ieee_std_context;
use ieee.math_real.all;

library vunit_lib;
context vunit_lib.vunit_context;
context vunit_lib.com_context;

entity file_tb is
  generic
  (
    runner_cfg : string
  );
end entity file_tb;

architecture sim of file_tb is

  constant CLOCK_PERIOD : time     := 4 ns;
  signal eof            : boolean  := false;
  signal snk_clk        : std_logic;
  signal snk_rst        : std_logic := '1';
  signal snk_ready      : std_logic;
  signal snk_valid      : std_logic := '0';
  signal snk_sop        : std_logic := '0';
  signal snk_eop        : std_logic := '0';
  signal snk_data       : std_logic_vector(255 downto 0);
begin

  DUT : entity work.dma_sim_file(sim)
    port map
    (
      eof       => eof,
      snk_clk   => snk_clk,
      snk_rst   => snk_rst,
      snk_ready => snk_ready,
      snk_valid => snk_valid,
      snk_sop   => snk_sop,
      snk_eop   => snk_eop,
      snk_data  => snk_data
    );

SEQUENCER_PROC : process
begin
  ---------------- VUNIT SETUP ---------------
  test_runner_setup(runner, runner_cfg);
  eof <= false;
  wait until rising_edge(snk_clk);
  snk_rst <= '0';
  -- TEST : normal behaviour
  if run("dataflow_all") then
    wait until rising_edge(snk_clk);
    for i in 0 to 10 loop
      report "Sending message " & natural'image(i);
      snk_sop   <= '1';
      snk_eop   <= '0';
      snk_valid <= '1';
      snk_data  <= 256x"BCABCABCABCABCABCABCAB";
      wait for CLOCK_PERIOD;
      snk_sop <= '0';
      snk_eop <= '0';
      wait for 2 * CLOCK_PERIOD;
      snk_sop <= '0';
      snk_eop <= '1';
    end loop;
  end if;
  eof <= true;
  wait for 0 ns;
  test_runner_cleanup(runner);
end process;

end architecture;
g0t00 commented

I might be wrong, but

  clk_gen : process
  begin
    clk <= not clk after CLOCK_PERIOD/2;
  end process;

isn't this missing a sensitivity list and now doing a infinite loop?
Try:

  clk_gen : process (all)
  begin
    clk <= not clk after CLOCK_PERIOD/2;
  end process;

Just to check: it doesn't hang when running without VUnit?

I might be wrong, but

  clk_gen : process
  begin
    clk <= not clk after CLOCK_PERIOD/2;
  end process;

isn't this missing a sensitivity list and now doing a infinite loop? Try:

  clk_gen : process (all)
  begin
    clk <= not clk after CLOCK_PERIOD/2;
  end process;

This was indeed the issue, now it works. Thanks for spotting it!