Non-Blocking and Blocking Assignments
In Verilog procedural blocks (always), there are two assignment operators:
- Blocking assignment:
= - Non-blocking assignment:
<=
Using the right one is important for correct hardware behavior.
Blocking Assignment (=)
- Executes in order, line by line, inside the same
alwaysblock. - The left-hand side updates immediately for following statements in that block.
- Commonly used for combinational logic (
always @(*)).
always @(*) begin
y = a & b;
z = y | c; // uses updated y immediately
endNon-Blocking Assignment (<=)
- Schedules updates to happen at the end of the current time step.
- Right-hand sides are evaluated first, then all left-hand sides update together.
- Commonly used for sequential (clocked) logic (
always @(posedge clk)).
always @(posedge clk) begin
q1 <= d;
q2 <= q1; // q2 gets old q1 (register behavior)
endWhy This Matters
If you use blocking assignment in clocked logic, simulation can behave differently from intended register hardware.
always @(posedge clk) begin
q1 = d;
q2 = q1; // q2 now gets d immediately in simulation
endThis does not model two cascaded flip-flops correctly.
Rule of Thumb
- Use
=in combinationalalways @(*)blocks. - Use
<=in clockedalways @(posedge clk)/always @(negedge clk)blocks. - Avoid mixing
=and<=in the same block unless you have a very specific reason.
See also Always block.