Previous

Wait Statements

A wait statement suspends a process until a positive-going edge or negative-going edge is detected on a signal. The syntax follows.

wait until signal = value ;
   
wait until signal'event and signal = value ;
   
wait until not signal'stable 
              and signal = value ;

Signal is the name of a single-bit signal - a signal of an enumerated type encoded with one bit (see the “Enumeration Encoding” section of the “Data Types” chapter). Value must be one of the literals of the enumerated type. If the signal type is BIT, the awaited value is either '1' for a positive-going edge or '0' for a negative-going edge.


NOTE

The three forms of the wait statement, a subset of IEEE VHDL, are specific to the current implementation of Foundation Express.


Inferring Synchronous Logic

A wait statement implies synchronous logic, where signal is usually a clock signal. The next section describes how Foundation Express infers and implements this logic.

The example below shows three equivalent wait statements (all positive-edge triggered).

wait until CLK = '1';
wait until rising_edge;
wait until not CLK'stable and CLK = '1';

When a circuit is synthesized, the hardware in the three forms of wait statements does not differ.

The following example shows a wait statement used to suspend a process until the next positive edge (a 0-to-1 transition) on signal CLK.

signal CLK: BIT;
...
process
begin
     wait until rising_edge; 
          -- Wait for positive transition (edge)
     ...
end process;

NOTE

IEEE VHDL specifies that a process containing a wait statement must not have a sensitivity list. See the “Process Statements” section of the “Concurrent Statements” chapter for more information.


The example below shows how a wait statement is used to describe a circuit where a value is incremented on each positive clock edge.

process
begin
y <= 0;
wait until rising_edge;
while (y < MAX) loop
wait until rising_edge;
x <= y ;
y <= y + 1;
end loop;
end process;

The following example shows how multiple wait statements describe a multicycle circuit. The circuit provides an average value of its input A over four clock cycles.

process
   begin
     wait until rising_edge; 
     AVE <= A;
     wait until rising_edge; 
     AVE <= AVE + A;
     wait until rising_edge; 
     AVE <= AVE + A;
     wait until rising_edge; 
     AVE <= (AVE + A)/4;
end process;

The example below shows two equivalent descriptions. The first description uses implicit state logic, and the second uses explicit state logic.

-- Implicit State Logic
process 
begin
     wait until rising_edge;
     if (CONDITION) then 
          X <= A;
     else 
          wait until rising_edge;
     end if;
end process;
   
-- Explicit State Logic
...
type STATE_TYPE is (SO, S1);
variable STATE : STATE_TYPE;
...
process 
begin
     wait until rising_edge;
     case STATE is
          when S0 =>
               if (CONDITION) then
                     X <= A;
                     STATE := S0;  -- Set STATE here to avoid an
                                                   -- extra feedback loop in the 
                                                   -- synthesized logic.
               else 
                     STATE := S1;
               end if;
       when S1 =>
            STATE := S0;
     end case;
end process;

NOTE

Wait statements can be used anywhere in a process except in for...loop statements or subprograms. However, if any path through the logic contains one or more wait statements, all paths must contain at least one wait statement.


The following example shows how a circuit with synchronous reset can be described with wait statements in an infinite loop. The reset signal must be checked immediately after each wait statement. The assignment statements in this example (X <= A; and Y <= B;) represent the sequential statements used to implement your circuit.

process 
begin
     RESET_LOOP: loop
          wait until rising_edge;
          next RESET_LOOP when (RESET = '1');
          X <= A; 
          wait until rising_edge;
          next RESET_LOOP when (RESET = '1');
          Y <= B;
     end loop RESET_LOOP;
end process;

The example below shows two invalid uses of wait statements that are specific to Foundation Express.

...
type COLOR is (RED, GREEN, BLUE);
attribute ENUM_ENCODING : STRING;
attribute ENUM_ENCODING of COLOR : type is -100 010 001";
signal CLK : COLOR;
...
process
     begin
          wait until CLK'event and CLK = RED; 
                -- Illegal: clock type is not encoded with one bit 
          ...
     end;
process
     begin 
          if (X = Y) then
                wait until rising_edge; 
                ...
          end if;
                -- Illegal: not all paths contain wait statements
          ...
     end;

Combinatorial vs. Sequential Processes

If a process has no wait statements, the process is synthesized with combinatorial logic. Computations performed by the process react immediately to changes in input signals.

If a process uses one or more wait statements, it is synthesized with sequential logic. The process computations are performed only once for each specified clock edge (positive or negative edge). The results of these computations are saved until the next edge by storing them in flip-flops.

The following values are stored in flip-flops.


NOTE

Like the wait statement, some uses of the if statement can also imply synchronous logic, causing Foundation Express to infer registers or latches. These methods are described in the “Register and Three-State Inference” chapter.


The following example uses a wait statement to store values across clock cycles. The example code compares the parity of a data value with a stored value. The stored value (called CORRECT_PARITY) is set from the NEW_CORRECT_PARITY signal if the SET_PARITY signal is TRUE.

The resulting circuit is shown in the figure following the example.

signal CLOCK: BIT;
signal SET_PARITY, PARITY_OK: Boolean;
signal NEW_CORRECT_PARITY: BIT;
signal DATA: BIT_VECTOR(0 to 3);
...
process
     variable CORRECT_PARITY, TEMP: BIT;
begin
     wait until rising_edge;
   
     -- Set new correct parity value if requested
     if (SET_PARITY) then
          CORRECT_PARITY := NEW_CORRECT_PARITY;
     end if;
   
       -- Compute parity of DATA
     TEMP := '0';
     for I in DATA'range loop
          TEMP := TEMP xor DATA(I);
     end loop;
   
       -- Compare computed parity with the correct value
     PARITY_OK <= (TEMP = CORRECT_PARITY);
end process;

Figure 6.12 Circuit for Parity Tester Using the wait Statement

Note that two flip-flops are in the synthesized schematic for the example of a parity tester using the wait statement. The first (input) flip-flop holds the value of CORRECT_PARITY. A flip-flop is needed here because CORRECT_PARITY is read (when it is compared to TEMP) before it is set (if SET_PARITY is FALSE). The second (output) flip-flop stores the value of PARITY_OK between clock cycles. The variable TEMP is not given a flip-flop because it is always set before it is read.

Next