EC-21.5 Crossing Clock Domains, and Getting Reset Right
The standard treatment of clock domain crossing and reset: metastability, synchronisers, multi-bit crossings, reset release and automatic checking, September 2026
What this is and why it exists
These are the two failures that survive every simulation and appear months later in the field.
They arrive at a rate of once a week, on one unit in fifty, and they are gone by the time anybody looks. Neither is difficult once seen clearly. Both are catastrophic when handled by instinct.
A two-flip-flop synchroniser and a reset asserted asynchronously but released synchronously are small pieces of code. A hardware engineer is expected to be able to write both from memory.
The vocabulary
- Clock domain — a group of registers driven by one clock.
- Crossing — a signal that leaves one domain and arrives in another.
- Metastability — a flip-flop settling to neither logic level for an unbounded time.
- Synchroniser — two or more registers in series, letting metastability decay.
- Gray code — an encoding in which consecutive values differ by one bit.
- Handshake — a protocol where one side holds data until the other confirms.
- Asynchronous first-in-first-out memory — a buffer written in one domain and read in another.
- Recovery and removal — the setup and hold equivalents for reset release.
The mental model
Start with the flip-flop. If its input changes exactly when it is clocked, both setup and hold are violated, and the output can sit between the two logic levels. It will settle eventually, to a value that is not predictable. How long it takes is statistical, not deterministic, which is precisely why simulation never shows it.
The two-flip-flop synchroniser gives the first register time to settle before anything reads it. The improvement is quantified as a mean time between failures, computed from the clock rate and the rate at which the input changes. Where that figure is not long enough, a third stage is added.
Now the mistake that matters. A multi-bit value cannot be synchronised bit by bit. Each synchroniser settles at its own moment, so a counter crossed that way can be read as a value it never held. Crossing from three to four, one bit may update before the other, and the reader sees one or two. This is the most common serious error in multi-clock design.
There are three standard answers. A handshake passes one control bit and holds the data still until it is confirmed. A Gray code ensures only one bit changes at a time, so any sampling error yields an adjacent value. An asynchronous buffer built for the purpose handles streams. Each has its own throughput and latency cost.
Reset is the second half. Asserting it immediately is what you want, because a system in trouble should stop at once. Releasing it at an arbitrary moment can violate the recovery requirement, leaving one part of the design out of reset a cycle before another. The standard shape asserts asynchronously and releases in step with each clock.
Finally, checking. On a design with several clocks, the number of crossings exceeds what anyone can enumerate by hand. Tools exist that find every crossing and verify a recognised structure protects it. Using one is not optional at that scale.
What you should now be able to explain or do
- Explain metastability in terms of setup and hold on one flip-flop.
- Say why the improvement from a synchroniser is a statistical figure.
- Explain why a multi-bit value must not be crossed bit by bit.
- Choose between a handshake, a Gray code and a buffer for a given crossing.
- Write a reset that asserts asynchronously and releases synchronously.
- Say why crossings need automatic checking on a multi-clock design.
Check yourself
Why does simulation never show a metastability failure?
Because a simulator resolves each flip-flop to a defined value. The unbounded settling time is a physical, statistical effect the model does not represent.
What goes wrong when a counter is crossed bit by bit?
Each bit's synchroniser settles independently. The reader can sample a mixture of old and new bits, giving a value the counter never actually held.
What does a Gray code buy at a crossing?
Only one bit changes between consecutive values. Any sampling error therefore yields either the old value or the new one, never a spurious third.
Why release a reset synchronously?
Because an arbitrary release can violate recovery timing. Different registers would leave reset on different cycles, starting the design in an inconsistent state.
Go deeper
We haven't checked most of these for screen reader use yet.
Back to Crossing Clock Domains, and Getting Reset Right: work through the checklist