Below is the code that I am running. My question is why doesn't the 3rd wait until
trigger in modelsim? The console output is simply GOT HERE
. It never gets to the line GOT HERE 2
. I would think that having the same wait until <SIGNAL> = 1
twice in a row would be fine because the condition is true both times. I didn't add 'event in there, so I wouldn't think the simulator would need to see the edge. Can anyone explain this behavior?
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity example_wait_failure is
end example_wait_failure;
architecture behave of example_wait_failure is
signal r_CLK_TB : std_logic := '0';
begin
r_CLK_TB <= '1' after 20 ns, '0' after 40 ns, '1' after 60 ns;
p_TEST : process
begin
wait until r_CLK_TB = '1';
report "GOT HERE" severity note;
wait until r_CLK_TB = '1';
wait until r_CLK_TB = '1';
report "GOT HERE 2 " severity note;
end process p_TEST;
end behave;
The behaviour is in the details of the wait statement (the details of wait that
Jim Lewis refers to). The reason is that the wait
statements has three
parts:
wait
[on sensitivity_list]
[until condition]
[for time_expression]; -- Only for timeout, and not relevant here
The wait
in the relevant code only has an until
part, so the
sensitivity_list is created according to VHDL standard: "If no sensitivity
clause appears, the sensitivity set is constructed according to the following
(recursive) rule: ...". The generated sensitivity_list will in this case
contain r_CLK_TB
.
The VHDL standard has an example that matches the code precisely, and this states that:
wait until r_CLK_TB = '1';
is identical to:
loop
wait on r_CLK_TB;
exit when r_CLK_TB = '1';
end loop;
So even though the wait
does not explicitly contain a wait until
r_CLK_TB'event
(as written in comment), the execution results in waiting until
an event on r_CLK_TB
in order to pass the first wait
in wait on r_CLK_TB
.
Is that intuitive... judge for yourself ;-)
So maybe the original code should be changes so:
wait until r_CLK_TB = '1';
is replaced with:
if r_CLK_TB /= '1' then
wait until r_CLK_TB = '1';
end if;
In this case both "GOT HERE" and "GOT HERE 2" are shown at 20 ns, since the condition of all three constructions will be TRUE here.