Blocking vs Nonblocking in Verilog: Key Differences and Usage
blocking assignments use the = operator and execute statements sequentially, pausing the next until the current finishes. Nonblocking assignments use <= and schedule updates to happen simultaneously at the end of the time step, allowing parallel execution.Quick Comparison
This table summarizes the main differences between blocking and nonblocking assignments in Verilog.
| Aspect | Blocking (=) | Nonblocking (<=) |
|---|---|---|
| Execution Order | Sequential, one after another | Parallel, all updates happen together |
| Use Case | Combinational logic modeling | Sequential logic (flip-flops) modeling |
| Timing | Right side evaluated and assigned immediately | Right side evaluated immediately, assigned later |
| Effect on Simulation | Can cause race conditions if misused | Avoids race conditions in sequential logic |
| Typical in Always Block | always @(*) for combinational | always @(posedge clk) for sequential |
| Assignment Behavior | Blocks next statement until done | Does not block next statement |
Key Differences
Blocking assignments use the = operator and execute statements in the order they appear. Each assignment completes before the next one starts, similar to how you do tasks one by one in real life. This makes blocking assignments suitable for modeling combinational logic where outputs depend immediately on inputs.
Nonblocking assignments use the <= operator and schedule the assignment to happen at the end of the current time step. This means all right-hand sides are evaluated first, then all left-hand sides updated together. This behavior models how flip-flops update simultaneously on a clock edge, preventing race conditions and ensuring correct sequential logic simulation.
Using blocking assignments in sequential logic can cause unexpected results because statements execute one after another, potentially reading stale or intermediate values. Nonblocking assignments avoid this by updating all variables in parallel after evaluation, matching hardware behavior more closely.
Code Comparison
Here is an example showing how blocking assignments handle a simple sequential logic task of updating two registers.
module blocking_example(input clk, input rst, output reg [3:0] a, output reg [3:0] b); always @(posedge clk or posedge rst) begin if (rst) begin a = 0; b = 0; end else begin a = b + 1; b = a + 1; end end endmodule
Nonblocking Equivalent
The same logic rewritten with nonblocking assignments updates both registers simultaneously, avoiding the problem.
module nonblocking_example(input clk, input rst, output reg [3:0] a, output reg [3:0] b); always @(posedge clk or posedge rst) begin if (rst) begin a <= 0; b <= 0; end else begin a <= b + 1; b <= a + 1; end end endmodule
When to Use Which
Choose blocking assignments when modeling combinational logic where operations must happen step-by-step and outputs depend immediately on inputs. Use nonblocking assignments for sequential logic inside clocked always blocks to correctly model flip-flop behavior and avoid race conditions. Mixing them incorrectly can cause simulation mismatches and hardware bugs.