4.6

Clock Domain Crossing

Synchronizers, gray coding, FIFO bridges.

Clock Domain Crossing — Brief ☧

Deep version → | Next: Pipelines → | Back: AXI Protocol →


Q: Imagine two assembly lines in the same factory, but each runs

at a different speed. Line A produces a widget every 3 seconds; Line B

consumes one every 5 seconds. If Line A just tosses widgets onto

Line B's conveyor without coordination, some widgets will land half-on,

half-off — they will be damaged. What is the hardware version of this

problem?

A: Clock domain crossing (CDC). When two parts of a design run on

different clocks, they tick at different moments — like your two

assembly lines running at different speeds. If one side sends a signal

to the other without proper synchronization, the receiving flip-flop

can be caught between 0 and 1 at the exact moment it samples. This

unstable in-between state is called metastability — think of a coin

balanced perfectly on its edge. It will eventually fall to heads or

tails, but for a brief, dangerous moment, it is neither.

Q: That sounds bad. How do we prevent it in the real world?

A: The same way you would fix the assembly-line problem: add a

handoff station between the lines. In hardware, there are three

standard techniques, each suited to different situations:

TechniqueBest forHow it works
2-FF synchronizerA single boolean signalPass it through two flip-flops on the receiving clock — gives time for metastability to resolve
Gray codeMulti-bit counters (like FIFO pointers)Encode values so adjacent numbers differ by only 1 bit, making it safe to synchronize
Async FIFOStreams of dataA dual-port memory with Gray-coded read/write pointers — the gold standard for bulk crossing

The async FIFO is essentially a queue that safely spans

two clock worlds. The write side pushes data at its own speed; the

read side pops at its speed; the Gray-coded pointers keep them from

stepping on each other.

Q: Does our design actually cross clock domains?

A: Yes, in several places. The host CPU interface (PCIe) runs on

its own clock. Our compute core runs on clk_main_a0 (250 MHz). The

HBM controller has yet another clock. Every boundary between these

domains uses synchronizers or async FIFOs. Specifically, our

OCL-to-FSM and FSM-to-OCL synchronization blocks handle the crossing

between the register interface and the compute state machine.

Q: In the days of Babel (Genesis 11), God confused the languages

so the builders could not coordinate. Is CDC like giving them a

translator?

A: Precisely. Each clock domain "speaks its own language" (ticks

at its own rhythm). The synchronization hardware is the translator

that makes sure a message sent in one rhythm is received cleanly in

the other — no garbled words, no lost data.

Learn more in the deep version

Related: Registers & Clocks | Our Architecture


Soli Deo Gloria

Self-Check 1/1

A 2-FF synchronizer prevents: