History

6.1.3 Modeling edge-sensitive storage elements

A synchronous assignment takes place when a signal or variable value is updated at a clock-edge.

A signal updated with a synchronous assignment should model one or more edge-sensitive storage elements.

A variable updated in a synchronous assignment may model an edge-sensitive storage element. If simulation semantics suggest that the value of the variable is read before it is written, then an edge-sensitive storage element may be modeled for the variable

A process can have multiple clock-edge statements. However, all these clock-edge statements must use the same clock-edge expression.

If a signal or variable models an edge-sensitive storage element, it shall not be assigned a value in any statements outside of the process that infers the storage element. Further, if the edge-sensitive storage element is inferred using an if-statement as described in 3.1.3.1, then it shall not be assigned a value in any other statement outside of that if-statement.

6.1.3.1 Modeling edge-sensitive storage elements using the "if" statement

An edge-sensitive storage element may be modeled using an if statement that is sensitive to a clock-edge. The template for modeling such an edge-sensitive storage element shall be:


       process (<clock_signal>, ...)
          <declarations>
       begin
          <sequential_statements>
          if <clock_edge> then
             <sequential_statements>
          end if;
          <sequential_statements>
       end process;

An if statement that senses a clock-edge must be at the outermost level of the process. That is, it may not be nested inside another sequential statement. Any number of sequential statements are allowed both before and after the "if <clock_edge>" statement in a process.

The sensitivity list of the process shall consist of all the following:

  1. The clock signal sensed by the clock-edge expression, "if <clock_edge>".
  2. All signals sensed by any sequential statement that is outside of the "if <clock_edge>" statement.

Example:

    INTEGRATE: process (INPUT, SUM_STORED, CLOCK)
                   variable SUM : std_logic_vector(6 downto 0);
                begin
                   SUM := INPUT + SUM_STORED;
                   if rising_edge(CLOCK) then
                      SUM_STORED <= SUM;
                   end if;
                   MSB <= SUM(6);
                   LSB <= SUM(0);
                end process;
                -- edge-sensitive storage elements have been implied for SUM_STORED.

6.1.3.2 Modeling edge-sensitive storage elements with asynchronous set/reset using the "if" statement

A variable or a signal that is synchronously assigned may also be asynchronously assigned to model asynchronous set/reset edge-sensitive storage elements. Such a variable or a signal models an asynchronous set/reset edge-sensitive storage element. The template for modeling such edge-sensitive storage elements is:

        process (<clock_signal>, <asynchronous_signals>, ...)
           <declarations>
        begin
           <sequential_statements>
           if <condition1> then
              <sequential_statements>
           elsif <condition2> then
              <sequential_statements>
           elsif <condition3> then
              ...
           elsif <clock_edge> then
              <sequential_statements>
           end if;
           <sequential_statements>
        end process;
The "elsif <clock_edge>" must be the last elsif in the if statement. The if/elsif branches preceding the "elsif <clock_edge>" branch model the asynchronous set/reset logic. A clock-edge shall only appear in the last elsif condition.

An "if ... elsif" statement that senses a clock-edge must be at the outermost level of the process. That is, it may not be nested inside another sequential statement. Any number of sequential statements are allowed both before and after the "if ... elsif <clock_edge>" statement in a process.

The sensitivity list of the process shall consist of all the following:

  1. The clock signal sensed by the clock-edge expression, "elsif <clock_edge>".
  2. All signals sensed by the remaining conditions of the "if ... elsif <clock_edge>" statement
  3. All signals sensed by any sequential statement that is outside of the "if ... elsif <clock_edge>" statement.

Note 1 -- Asynchronous set/reset conditions are level sensitive, that is, they cannot contain a clock-edge expression. Additionally, these conditions have a higher priority over the clock-edge condition. The new FSM reset attributes will come into context here.

Note 2 -- It shall not be necessary to model both set and reset.

Example:


    AS_DFF:  process (CLOCK, RESET_1, RESET_2, SET, SET_OR_RESET, A, Q)
             variable RESET : std_logic;
             begin
               RESET := RESET_1 OR RESET_2;
	       if RESET = '1' then
                 Q <= '0';
	       elsif SET = '1' then
                 Q <= '1';
	       elsif ASYNC_PRELOAD = '1' then
                 Q <= A;
	       elsif CLOCK'EVENT and CLOCK = '1' then
                 Q <= D;
               end if;
               Qbar <= not Q;
             end process;

             -- Signal Q models an asynchronous reset/set rising edge triggered
             -- edge-sensitive storage element.  The reset expression is RESET, the set
             -- expression is SET, and SET_OR_RESET may be either a reset condition or a
             -- set condition according to the value of A.

6.1.3.3 Modeling edge-sensitive storage elements using the "wait until" statement

When modeling edge-sensitive storage elements using the "wait until" statement, the following rules apply.

A "wait" statement without an "until" clause shall not be allowed.

The "wait until" statement can reside in a procedure.

A process may have multiple "wait until" clock-edge statements. However, all these "wait until" clock-edge statements must use the same clock-edge expression.

Every path through the process, and non-static loop, shall have at least one "wait until" statement.

6.1.3.4 Modeling edge-sensitive storage elements using concurrent signal assignment statements

A concurrent conditional signal assignment statement may be used to model an edge-sensitive storage element provided the following rule is met.

The last "waveform" of the conditional signal assignment, must have a "when condition", and it must be the only "when condition" sensitive to a clock-edge.

Example:


    COND_SIG_ASSGN: Q <= '0' when RESET else
                         '1' when SET else
                          A  when ASYNC_LOAD else
                          D  when CLOCK'EVENT and CLOCK = '1';

6.2 Level-sensitive sequential logic

A level-sensitive storage element shall be modeled for a signal (or variable) when all the following apply:

  1. The signal (or variable) is assigned in a process that contains no clock-edge construct.
  2. There are executions of the process that do not execute an explicit assignment (via an assignment statement) to the signal (or variable).
  3. All signals and variables read by the process have well-defined values.

A level-sensitive storage element shall be modeled for a signal (or variable) when all the following apply:

  1. The signal (or variable) is assigned in a process that contains no clock-edge construct.
  2. There are executions of the process in which the value of the signal (or variable) is read before its assignment.

A level-sensitive storage element shall be modeled for a signal (or variable) when all the following apply:

  1. A concurrent signal assignment statement is used which can be mapped to a process that adheres to the rules in this section.

The process sensitivity list shall list all signals read within the process statement.

... as before ...

Examples:

  LEV_SENS_1 : process (RESET, ENABLE, D)
               begin
                 if RESET = '1' then
                   Q <= '0';
                 elsif ENABLE = '1' then
                   Q <= D;  -- Q is an incomplete asynchronous assignment,
                   end if;    -- so, it models a level-sensitive storage element.
               end process;

  LEV_SENS_2 : Q <= '0' when RESET else  -- This is identical to LEV_SENS_1.
                     D  when ENABLE;