A blocking assignment a = b updates the left side immediately, before the next statement runs. A nonblocking assignment a <= b evaluates the right side now, in the Active region, and commits the left side later, in the NBA region of the same slot.
That split models a flip-flop. Every clocked process samples pre-edge values and all updates commit together, so process execution order is irrelevant.
Aspect | Blocking | Nonblocking |
|---|---|---|
Left side updates | Immediately, in statement order | In the NBA region, after all sampling |
Across processes | Result can depend on process order | Order-independent, every reader sees pre-edge values |
Use for | Combinational blocks and testbench sequencing | Every clocked state element |
a is 0 and b is 1. At a clock edge one block runs a = b; b = a; and another runs a <= b; b <= a; on its own copy. What does each pair hold afterwards?Blocking: both 1, because b = a reads the a that the first line just overwrote. Nonblocking: a is 1 and b is 0, because both right sides were read before either update landed.
Two registers exchange on a clock edge with no temporary: both right-hand sides sample before either update lands. With blocking assignments the first line destroys the value the second line needs, and both end up holding the old b.
The same principle pipelines data. Three nonblocking stages form a real 3-stage shift register; with blocking assignments the input would ripple through all three stages in one cycle.
Watch a against b, then q1 through q3. The pair exchanges every edge while 1s fill the pipe one stage per edge.
Slot 0: a is 1 and b is 0 after the first exchange; q1 has the 1 while q2 and q3 are still 0.
Slot 1: a is 0 and b is 1; the 1 reaches q2 while q3 is still 0.
Slot 2: a is 1 and b is 0; the pipe reads 111 for the first time.
Slot 3: a is 0 and b is 1; the pipe holds 111.
Slot 4: a is 1 and b is 0; the pipe holds 111.
Slot 5: a is 0 and b is 1; the pipe holds 111.
The discipline follows from the semantics. Use nonblocking for every clocked element, blocking inside combinational blocks so intermediate values propagate in order, and never mix the two on the same variable.
Testbench sequencing defaults to blocking for its software-like order. Synchronous drives at a clock edge still use nonblocking, so the design samples old values exactly like a real upstream flop.
q1 <= d; q2 <= q1; q3 <= q2; with d held at 1. What do the stages read after the second edge?q1 and q2 read 1 while q3 still reads 0. Each stage sampled its pre-edge input, so the 1 advances one stage per edge.
data_in with = at one edge and <= at the next. What is wrong with this?Two disciplines share one variable. Later statements and the design can see different values depending on process order; one variable keeps one discipline.
The correct swap, its blocking collapse as a negative check, and the 3-stage pipe, all self-checked.
module swap2 (
input logic clk, rst,
output logic a, b
);
always_ff @(posedge clk) begin
if (rst) begin a <= 1'b0; b <= 1'b1; end
else begin
a <= b;
b <= a;
end
end
endmodule
module swap2_blocking (
input logic clk, rst,
output logic a, b
);
always @(posedge clk) begin
if (rst) begin a = 1'b0; b = 1'b1; end
else begin
a = b;
b = a;
end
end
endmodule
module shift3 (
input logic clk, rst,
output logic q1, q2, q3
);
always_ff @(posedge clk) begin
if (rst) begin q1 <= 1'b0; q2 <= 1'b0; q3 <= 1'b0; end
else begin
q1 <= 1'b1;
q2 <= q1;
q3 <= q2;
end
end
endmodule
PASS: nonblocking swap exchanges each edge and the pipe fills 111 while blocking collapsesRun with Verilator 5.048 (--binary --timing) on 2026-10-18; every bench printed the PASS line shown, with no warnings. Icarus 13 (-g2012) runs them too, with the same output.