Registers put time in a box
A clock is just a wire that rhythmically toggles high and low. We use it to coordinate the chaos. When the clock ticks—usually on the moment it flips from low to high (the rising edge)—a register grabs whatever value is currently sitting on its input wires and holds onto it. It will keep outputting that exact bit pattern until the next clock tick tells it to grab something new.
Everyone grabs at the same time
Here's a crucial mindset shift: in a clocked block, every register looks at its inputs and decides what to do at the exact same instant. The updates only become visible after the clock edge has passed. This is how hardware avoids becoming accidental, line-by-line sequential software.
Worked example
A two-register bucket brigade
Imagine a clock edge where we say first <= input and second <= first. Before the tick, let's say input = 9, first = 5, and second = 2. When the clock ticks, everyone reaches to their left simultaneously. After the tick, first becomes 9. But second grabbed the old first, so it becomes 5. It doesn't get the newly written 9, because the 9 wasn't there when the grabbing happened.
Reset gives us a clean slate
When you power on a chip, the registers wake up holding garbage. A reset signal forces validity flags, state machines, and counters into a clean, known starting position so the system doesn't immediately crash.
Enable signals let us hit pause
A register doesn't actually have to grab new data on every single clock tick. We can wire up a "clock enable" signal that tells the register, "Hey, go ahead and grab new data" or "Hold onto what you've got for now." We'll use this later to handle backpressure and freeze the pipeline when things get jammed up.
Check your understanding
If we have a clocked update b <= a, what value does b actually get when the clock ticks?
Section summary
- Registers lock in values and hold them steady between clock ticks.
- Clocked updates all sample the old state together at the exact same moment.
- Reset clears out the garbage state so we can start clean.
Repository layer · second pass
How do registers turn a function into behavior over time?
A register samples its next value at a clock edge and holds the result between edges. Nonblocking assignments make all clocked state read old values and update together. This differs from a software sequence in which each assignment is immediately visible to the next line.
Reset establishes a known protocol state, but reset strategy has timing and fanout costs. Trace state cycle by cycle using “before edge” and “after edge” columns rather than vague words like next.
Reasoning chain
- 1
List current state before the edge.
- 2
Evaluate enable/reset conditions.
- 3
Compute every next-state expression from old state.
- 4
Apply updates simultaneously.
- 5
Observe outputs during the following cycle.
Worked trace
Swap with nonblocking updates
- Before edge: a=3,b=8.
- Clocked logic requests a≤b and b≤a.
- Both right sides read old state.
- After edge: a=8,b=3.
Result. The values swap; they do not both become 8.
Executable lens · Python
Make the hidden state visible
state={"a":3,"b":8}
next_state={"a":state["b"], "b":state["a"]}
state=next_state
assert state=={"a":8,"b":3}Retype this example, predict each intermediate value, and then change one input that touches a boundary.
Misconception clinic
Tempting mistakes
- Using newly assigned state on a later nonblocking line.
- Assuming reset is free or instantaneous everywhere.
Retrieval and transfer
Close the book first
- Trace a three-register pipeline for five cycles.
- Compare synchronous and asynchronous reset.
- State what remains stable between edges.