3.5.4 · D1HDL & Digital Design Flow

Foundations — Blocking vs non-blocking assignments

2,347 words11 min readBack to topic

Before you can understand why one operator makes a chain of logic and the other makes a row of memory cells, you must own every small piece the parent note quietly assumed. We build each from nothing, and every piece leans only on the pieces above it.


1. A signal, and its "value over time"

The picture you must hold in your head is not a number — it is a line drawn left-to-right over time, like a heartbeat monitor. This is called a waveform.

Figure — Blocking vs non-blocking assignments
Figure 1 — A signal is a value over time. The horizontal axis is time flowing left-to-right; the vertical axis is the bit value (0 or 1). The blue trace is one wire; the yellow arrows mark where its value stays and where it jumps.


2. The clock, and the "edge"

The moment the clock jumps from 0 up to 1 is called the positive edge. Verilog gives you a built-in keyword for it:

That rising instant is the "tick" — the heartbeat of the chip.

Figure — Blocking vs non-blocking assignments
Figure 2 — The clock and its positive edges. The yellow trace is clk oscillating over time. Each red dashed vertical line marks a posedge — the exact instant clk goes from 0 up to 1, and the only moment sequential hardware may update.

For completeness, the clock has other moments too:

  • negedge — the fall from 1 to 0 (some flip-flops trigger on this instead).
  • The flat stretches between edges — nothing sequential happens here; only combinational wires ripple.

We link this idea deeper in Combinational vs Sequential logic.


3. Two kinds of hardware: gates vs flip-flops

Figure — Blocking vs non-blocking assignments
Figure 3 — Combinational (left) vs sequential (right). Left: an AND gate — inputs a, b (green) ripple straight through to output y (yellow), no clock, no memory. Right: a D flip-flop — input D (green) is only copied to output Q (yellow) at the red clock edge, so it remembers between ticks.


4. The always block — a rule that watches signals

Two shapes you will see everywhere:

Written as Watches Meaning
always @(*) every input read inside the block combinational — recompute whenever any input changes
always @(posedge clk) only the clock's rising edge sequential — update only on the tick

5. reg vs wire — where a value is allowed to live


6. The two operators, finally

Now every piece is in place, we can name the two operators — but only to say what symbol means what. The behaviour is the parent note's job.

Here is the smallest possible pair that shows the difference. Assume a=1, b=2 just before the edge:

// Blocking: ordered, immediate
always @(posedge clk) begin
    a = b;   // a becomes 2 right now
    b = a;   // a is ALREADY 2, so b = 2  -> both end up 2, NO swap
end
// Non-blocking: sample-all-then-update-all
always @(posedge clk) begin
    a <= b;  // right side sampled: new_a = old b = 2
    b <= a;  // right side sampled: new_b = old a = 1
end          // now both apply together -> a=2, b=1  -> SWAPPED

The only textual change is = vs <=, yet the first collapses both to 2 and the second genuinely swaps. That single behavioural gap is the entire parent topic.

The subtle danger of getting this wrong is a race condition (Race conditions in RTL simulation) or a simulation–synthesis mismatch (Synthesis vs Simulation mismatch) — the chip you build behaves differently from the code you simulated.


Prerequisite map

Signal value over time

Waveform timeline

Clock and posedge

Combinational logic

Sequential logic and flip-flops

always block and sensitivity list

reg vs wire

Blocking = vs Non-blocking <=

Everything flows downhill into the operator choice — which is exactly the parent topic.


Equipment checklist

A signal in hardware is best pictured as
a value drawn along a time axis (a waveform), not a single stored number.
What is a positive clock edge?
the instant the clock signal jumps from 0 up to 1 — the only moment sequential logic may update.
What Verilog keyword names the rising edge?
posedge (its partner negedge names the falling edge).
Combinational logic depends on
only the current inputs — it ripples to a new output with no memory and no clock.
Sequential logic depends on
the input as it was just before the clock edge — it remembers between ticks.
always @(*) describes what kind of hardware?
combinational — it recomputes whenever any input read inside changes.
What does the * in always @(*) mean?
an automatic sensitivity list — the tool watches every signal read inside the block, so the list can never be incomplete.
What bug comes from an incomplete sensitivity list in a combinational block?
the block misses input changes and holds an old value, forcing synthesis to infer an unwanted latch.
always @(posedge clk) describes what kind of hardware?
sequential — it updates only on the clock's rising edge.
Why must every left-hand side inside an always block be a reg?
only a reg can hold a value while the block decides what to assign; a wire must be continuously driven.
Blocking = in plain words
do it now — finish updating the left side before the next line runs.
Non-blocking <= in plain words
note the right side now, but delay changing the left side to the NBA region (one delta later, same simulated time).
What is a delta cycle?
a zero-time ordering step within one simulation time — blocking updates land in the Active region, non-blocking updates in the later NBA region, both at the same time value.
What two failures come from choosing the wrong operator?
race conditions in simulation and simulation–synthesis mismatch.

Connections