Module 89 min

Blocking vs Non-blocking

The single most important rule in Verilog

Why this matters

More beginner designs break from this one topic than any other. The rule is short. Learn it once, apply it always, and you will sidestep bugs that take seniors hours to find.

The two assignments

SymbolNamePicture
=BlockingA to-do list done in order - finish one, then the next
<=Non-blockingEveryone reads the old values, then all update together

Why it matters - a tiny shift register

Suppose you want b to take a's value, and c to take b's old value, all on one clock edge - a chain that shifts data along. Watch what each assignment does.

verilog
// CORRECT - non-blocking. All read old values, then update.
always @(posedge clk) begin
  b <= a;
  c <= b;   // c gets the OLD b, so data shifts a -> b -> c
end
verilog
// WRONG for this - blocking. Runs top to bottom in order.
always @(posedge clk) begin
  b = a;
  c = b;   // c gets the NEW b (= a), so b and c both become a
end        // the shift is broken

With non-blocking (<=), the hardware matches your intent: at the clock edge, b grabs a and c grabs the previous b, both at once. With blocking (=) the simulator runs line by line, so c sees the already-updated b. That is not how the flip-flops will behave on the chip, so simulation and silicon disagree.

The rule, in two lines

  1. Clocked block - always @(posedge clk): use non-blocking <=
  2. Combinational block - always @(*): use blocking =
Watch out

Never mix = and <= in the same always block. And never assign the same signal from two different always blocks - the tool will not know which one wins, and you will get x or unpredictable hardware.

Pro tip

If you remember nothing else from this whole path, remember: <= for clocked, = for combinational. Write it on a sticky note. This rule alone separates working RTL from broken RTL.