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.
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:
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.
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:
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.
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.
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';
A level-sensitive storage element shall be modeled for a signal (or variable) when all the following apply:
A level-sensitive storage element shall be modeled for a signal (or variable) when all the following apply:
A level-sensitive storage element shall be modeled for a signal (or variable) when all the following apply:
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;