Search code examples
vhdl

Stop VHDL simulation with wait statements


When testing a simple counter implementation, the VHDL simulation is not exiting the simulation. My intention is to stop both concurrent processes using the shared variable changed by the main process. But the main process is not stopping the clock process.

My counter implementation is:

entity dff is
port(
    direction, reset, clk, load : in std_logic;
    din : in std_logic_vector(3 downto 0);
    dout : out std_logic_vector(3 downto 0));
end dff;

architecture behav of dff is
    signal temp : std_logic_vector(3 downto 0);
begin
    process(clk, reset)
begin
     if (reset='1') then
         temp <= "0000";
         elsif rising_edge(clk) then
            if (load='1') then
                temp <= din;
            else
                if (direction='0') then
                    temp <= std_logic_vector(unsigned(temp) + 1);
                else
                    temp <= std_logic_vector(unsigned(temp) - 1);
                end if;
            end if;
        end if;
        dout <= temp;
    end process;
end behav;

And my testbench:

architecture behav of test_tb is
    component dff port(
        direction, reset, clk, load : in std_logic;
        din : in std_logic_vector(3 downto 0);
        dout : out std_logic_vector(3 downto 0));
    end component;
    signal direction, reset, clk, load : std_logic := '1';
    signal din, dout : std_logic_vector(3 downto 0) := x"7";
    shared variable simend : boolean := false;
begin

    clkk : process
    begin
        if simend=false then
            clk <= not clk after 50 ns;
        else
            wait;
        end if;
    end process clkk;

    uut : dff port map(
        direction, reset, clk, load, din, dout);

    stim : process
    begin
        reset <= '0';
        wait for 1 us;
        load <= '0';
        wait for 2 us;
        direction <= '0';
        wait for 2 us;
        load <= '1';
        wait for 1 us;
        reset <= '1';
        wait for 0.5 us;

        simend := true;
        wait;
    end process stim;
end behav;

Solution

  • I would code your clock generator more like this:

    clkk : process
    begin
        while simend=false loop
            clk <= not clk;
            wait for 50 ns;
        end loop;
        wait;
    end process clkk;
    

    It is possible to execute your clkk process without ever executing a wait statement. (The line clk <= not clk after 50 ns does not wait or block - <= is a non-blocking assignment.) Therefore, you have an infinite loop that will never stop. You can see this by running this example on EDA Playground where the simulation time never advances and, because the maximum runtime on EDA Playground is 1 minute, times out after 1 minute.

    Also, I would recommend not using a shared variable for simend. Instead, why not use a signal? You code would not even be compiable in VHDL-2000 onwards, because after VHDL-2000, shared variables had to be protected types. You can see that a warning is produced on EDA Playground unless you set the option to compile VHDL-93. Compiling for VHDL-93, would prevent you using the stop (or finish) procedures.