vhdl

Wait

Syntax#

  • wait [on SIGNAL1[, SIGNAL2[…]]] [until CONDITION] [for TIMEOUT];
  • wait; — Eternal wait
  • wait on s1, s2; — Wait until signals s1 or s2 (or both) change
  • wait until s1 = 15; — Wait until signal s1 changes and its new value is 15
  • wait until s1 = 15 for 10 ns; — Wait until signal s1 changes and its new value is 15 for at most 10 ns

Eternal wait

The simplest form of wait statement is simply:

wait;

Whenever a process executes this it is suspended forever. The simulation scheduler will never resume it again. Example:

signal end_of_simulation: boolean := false;
...
process
begin
  clock <= '0';
  wait for 500 ps;
  clock <= '1';
  wait for 500 ps;
  if end_of_simulation then
    wait;
  end if;
end process;

Sensitivity lists and wait statements

A process with a sensitivity list cannot also contain wait statements. It is equivalent to the same process, without a sensitivity list and with one more last statement which is:

wait on <sensitivity_list>;

Example:

  process(clock, reset)
  begin
    if reset = '1' then
      q <= '0';
    elsif rising_edge(clock) then
      q <= d;
    end if;
  end process;

is equivalent to:

  process
  begin
    if reset = '1' then
      q <= '0';
    elsif rising_edge(clock) then
      q <= d;
    end if;
    wait on clock, reset;
  end process;

VHDL2008 introduced the all keyword in sensitivity lists. It is equivalent to all signals that are read somewhere in the process. It is especially handy to avoid incomplete sensitivity lists when designing combinatorial processes for synthesis. Example of incomplete sensitivity list:

  process(a, b)
  begin
    if ci = '0' then
      s  <= a xor b;
      co <= a and b;
    else
      s  <= a xnor b;
      co <= a or b;
    end if;
  end process;

the ci signal is not part of the sensitivity list and this is very likely a coding error that will lead to simulation mismatches before and after synthesis. The correct code is:

  process(a, b, ci)
  begin
    if ci = '0' then
      s  <= a xor b;
      co <= a and b;
    else
      s  <= a xnor b;
      co <= a or b;
    end if;
  end process;

In VHDL2008 the all keyword simplifies this and reduces the risk:

  process(all)
  begin
    if ci = '0' then
      s  <= a xor b;
      co <= a and b;
    else
      s  <= a xnor b;
      co <= a or b;
    end if;
  end process;

Wait until condition

It is possible to omit the on <sensitivity_list> and the for <timeout> clauses, like in:

    wait until CONDITION;

which is equivalent to:

    wait on LIST until CONDITION;

where LIST is the list of all signals that appear in CONDITION. It is also equivalent to:

    loop
      wait on LIST;
      exit when CONDITION;
    end loop;

An important consequence is that if the CONDITION contains no signals, then:

    wait until CONDITION;

is equivalent to:

    wait;

A classical example of this is the famous:

    wait until now = 1 sec;

that does not do what one could think: as now is a function, not a signal, executing this statement suspends the process forever.

Wait for a specific duration

using only the for <timeout> clause, it is possible to get an unconditional wait that lasts for a specific duration. This is not synthesizable (no real hardware can perform this behaviour so simply), but is frequently used for scheduling events and generating clocks within a testbench.

This example generates a 100 MHz, 50% duty cycle clock in the simulation testbench for driving the unit under test:

constant period : time := 10 ns;
...
process
begin
   loop
      clk <= '0';
      wait for period/2;
      clk <= '1';
      wait for period/2;
   end loop;
end process;

This example demonstrates how one might use a literal duration wait to sequence the testbench stimulus/analysis process:

process
begin
   rst <= '1';
   wait for 50 ns;
   wait until rising_edge(clk); --deassert reset synchronously
   rst <= '0';
   uut_input <= test_constant;
   wait for 100 us; --allow time for the uut to process the input
   if uut_output /= expected_output_constant then
      assert false report "failed test" severity error;
   else
      assert false report "passed first stage" severity note;
      uut_process_stage_2 <= '1';
   end if;
   ...
   wait;
end process;

This modified text is an extract of the original Stack Overflow Documentation created by the contributors and released under CC BY-SA 3.0 This website is not affiliated with Stack Overflow