Visual walkthrough — Sequential logic and always blocks
This is the derivation behind the parent note's central rule from Sequential logic and always blocks. If a word here is unfamiliar, it is defined the moment it appears.
Step 1 — WHAT is a flip-flop, drawn as a box?
WHAT. Before anything moves in time, we need the one building block: a flip-flop. Picture a small box with three ports:
- an input wire on the left, labelled
D(the value we want it to remember), - an output wire on the right, labelled
Q(the value it currently shows the world), - a triangle notch on the bottom edge — the clock input.
WHY a triangle notch? That notch is the universal symbol for "this port only cares about the moment the clock rises, not its steady level." The flip-flop ignores D at every other instant.
PICTURE. The box below. The rule it obeys is written beside it: at the tick, Q copies whatever D was — and between ticks, Q is frozen (the padlock).

Step 2 — WHAT is a "clock edge"? Draw the tick.
WHAT. The clock is one wire that marches forever. A rising edge (posedge) is the instant it climbs from to — an event, not a duration.
WHY only the edge, not the whole "1"? If the flip-flop copied D for the entire time the clock was high, Q would keep changing as D wobbled — no clean memory. By acting only at the razor-thin moment, every flop takes exactly one snapshot per cycle. That is what keeps millions of gates in step.
PICTURE. The square wave below; the burnt-orange arrows mark the only instants the flip-flop wakes up.

Step 3 — Chain three flops. WHAT do we WANT to happen?
WHAT. Now wire three flip-flops in a line: the Q of flop 1 feeds the D of flop 2, and Q of flop 2 feeds D of flop 3. Call the outputs . We want a value to march one box to the right on every tick — a shift register.
WHY chain them? A single flop remembers one bit for one tick. Chaining lets a bit travel through time and space — the basis of serial-to-parallel conversion, delay lines, and pipelines.
PICTURE. Three boxes, one shared clock rail underneath. The desired motion is the plum arrow: data flows rightward, one stage per tick.

Step 4 — Non-blocking <=: read ALL old values, THEN update together
WHAT. The non-blocking operator <= splits every tick into two phases:
- Evaluate phase: read all right-hand sides using the values present before the tick.
- Update phase: assign all left-hand sides at once.
WHY two phases? Because real flops physically do this — they all sample at the same instant using pre-edge inputs. The two-phase rule is not a software quirk; it is a faithful copy of the hardware.
PICTURE. Watch one tick. Top row = old values frozen and read (teal). Bottom row = the simultaneous update (orange). Nothing in the bottom row can "see" a bottom-row value.

Step 5 — Trace it numerically. WATCH the bit walk.
WHAT. Let the incoming bit be for exactly one tick, then forever. Start all outputs at . Tick by tick:
| tick | |||
|---|---|---|---|
| start | 0 | 0 | 0 |
| 1 | 1 | 0 | 0 |
| 2 | 0 | 1 | 0 |
| 3 | 0 | 0 | 1 |
| 4 | 0 | 0 | 0 |
WHY this proves it. The single 1 appears in , then moves to , then , exactly one box per tick, and finally leaves. That marching-diagonal is the signature of a working shift register — and it only happens because each stage read its neighbour's old value.
PICTURE. The diagonal of orange cells sliding down-right is the bit walking through time.

Step 6 — The degenerate case: blocking = collapses the chain
WHAT. Swap <= for the blocking operator =. Now assignments run immediately, top to bottom, like ordinary software — line 2 sees the value line 1 just wrote.
WHY it breaks. Line 1 does q2 = q1, so q2 instantly becomes q1. Line 2 then does q3 = q2 — but q2 is already the new value, equal to q1. So q3 grabs q1 too. Stages 2 and 3 merge into one; the middle box vanishes.
PICTURE. The same tick as Step 4, but arrows show the value racing straight through both boxes in one tick (the "short-circuit" in plum). The bit skips a stage.

Step 7 — Edge case: order of <= lines does NOT matter
WHAT. With non-blocking, you can reorder the two lines and get the identical result:
q3 <= q2; // written first
q2 <= q1; // written secondWHY. Both right-hand sides are read in the evaluate phase before any update. Reading q2 then q1, or q1 then q2, reads the same frozen old values either way. Order of the update phase is irrelevant because updates are simultaneous.
PICTURE. Two code orderings pointing to one identical output column — proof that <= describes parallel hardware, where "line order" is a fiction.

The one-picture summary
Everything above in a single frame: the two-phase <= (read-all-old, then update-all) makes the bit walk one box per tick; the immediate = makes it skip stages in one tick.
Recall Feynman retelling — explain the walkthrough to a friend
Imagine three kids in a row, each holding a whiteboard, and a teacher who rings a bell. Each kid's job: "when the bell rings, copy what the kid to my left was holding." The trick is when they look. With the good rule (<=), the teacher says "everyone freeze, read your neighbour's board as it was before the bell, and only now flip your own." So a number written by the first kid moves one seat right at every bell — it walks down the row. With the bad rule (=), the kids update one at a time in order: the first kid flips, then the second peeks at the already-flipped first kid, then the third peeks at the already-flipped second — so a number teleports all the way down in a single bell. The whole design flow rests on this: clocked logic uses "freeze-read-then-flip together" (<=), and that is why a shift register shifts instead of collapsing.