Reputation: 78
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;
Upvotes: 2
Views: 8884
Reputation: 13977
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.
Upvotes: 1
Reputation: 3983
I agree with @scary_jeff, std.env.stop is a great answer here. If I am just calling it in one place, my preference is to leave off the package reference and just call it:
std.env.stop;
In the event you are stuck with an older simulator, you can use
report "Just Kidding. Test Done." severity failure ;
OTOH if you need to coordinate ending a simulation between multiple processes and add a watch dog timer to your simulation run, you might consider the procedure Osvvm.TbUtilPkg.WaitForBarrier. It is used as shown below. The first call to WaitForBarrier(TestDone, 5 ms) will wake up in 5 ms in the event that TestDone does not happen before then and stop the simulation at that time.
signal TestDone : integer_barrier := 1 ;
ControlProc : process
begin
-- initialize test
SetAlertLogName("Uart1_Rx") ;
. . .
WaitForBarrier(TestDone, 5 ms) ; -- control process uses timeout
AlertIf(now >= 5 ms, "Test finished due to Time Out") ;
ReportAlerts ;
std.env.stop ;
end process ControlProc ;
CpuProc : process
begin
InitDut(. . . )_;
Toggle(CpuReady) ;
-- run numerous Cpu test transactions
. . .
WaitForBarrier(TestDone) ;
wait ;
end process CpuProc ;
UartTxProc : process
Begin
WaitForToggle(CpuReady) ;
-- run numerous Uart Transmit test transactions
. . .
WaitForBarrier(TestDone) ;
wait ;
end process UartTxProc ;
. . .
You can find the OSVVM library at both osvvm.org and on github. There is also a complete user guide in for this package in the download.
Upvotes: 1
Reputation: 4374
An alternative way to end the simulation if you have a VHDL2008-compliant simulator is to:
use std.env.stop;
you can then end the simulation by calling stop
:
stop;
This seems to me to be more elegant than waiting for a lack of clock transitions to cause the simulator iteration limit to be reached.
Upvotes: 5