Altifigence Academy

15 / 37 · Concept

Nonblocking assignments and simultaneous state updates

Separate old and next values to interpret pipeline and counter RTL correctly.

Evaluate right-hand sides from the previous state

In a clocked sequential block, <= evaluates its right-hand expression and applies the result during the nonblockingNonblocking assignment An assignment written as <= in sequential RTL. It evaluates the right-hand side and schedules the update, allowing registers at the same edge to compute from the previous state. update phase. This lets multiple registersRegister A circuit that stores multiple bits of state. The synchronous registers in this course store their specified inputs at a clock edge. Learn more update on the same edge without new values cascading through them merely because of source-code order.

SystemVerilog
always_ff @(posedge clk) begin
  if (rst) begin
    a <= 8'd0;
    b <= 8'd0;
  end else begin
    a <= d;
    b <= a;
  end
end
ak+1=dk,bk+1=aka_{k+1}=d_k,\qquad b_{k+1}=a_k

Starting with a=b=0 and inputs 5, 9, 2, the post-edge pairs (a,b) are (5,0), (9,5), (2,9). Interpreting the second line as reading the updated a effectively removes a pipelinePipeline A structure that divides computation into register-separated stages and overlaps processing of multiple inputs. Data, valid and control signals must be aligned by stage. Learn more stage.

Each column below records a rising edgeRising edge The instant at which the clock changes from 0 to 1. Distinguish it from a level, which refers to the entire interval during which CLK=1. Learn more. Inputs are pre-edge; states labeled “after” are post-update. Alignment shows sample order, not physical propagation delayPropagation delay The time from an input change until the output settles to the correct value. Logical equivalence and timing behavior are separate properties. Learn more. Starting at a=b=0, a stores new d while b stores old a, so the two rows are offset by one stage.

a and b read the same previous state
View waveform data
Wave data: each character is one interval; a dot holds the previous state; p is a clock cycle.
SignalWaveBus values
edge234E0 → E1 → E2
d2345 → 9 → 2
a after2345 → 9 → 2
b after2340 → 5 → 9

Why switching to blocking can be dangerous

Replacing the code with a=d; b=a; lets b use the a already updated within that block. Scheduling with other sequential blocks can also create races. Use blocking for combinational computation and nonblocking for state storage as the default rule; make exceptions only when you can explain their event semantics.

Avoid multiple assignments to the same register

If several nonblocking assignments to q execute within one procedure, the last executed assignment can determine the result. Express priority with if / else if / else or an explicit next-state variable, instead of hiding it in independent if statements. Avoid driving a register from multiple blocks.

During RTL review, write one next-state equation per register. Two competing equations or a condition with no definition is a signal to revisit control priority.

Try it yourself

Starting with a=1 and b=4, execute a<=b; b<=a; in the same clocked block. What are the states after one and two edges?

Read the explanation

After one edge, (a,b)=(4,1); after two, (1,4). Both assignments read the same old state, so the values swap. With a=b; b=a;, execution order can make both become the old b; that is not equivalent.

Your choice applies to this browser. Change it any time using the footer.