If you have been following our CDC (Clock Domain Crossing) series, you know the golden rule of single-bit transfers: Always use a 2-Flop Synchronizer.
So, you design your RTL. You have two independent control bits—let's call them enable and mode—crossing from a 100MHz domain to a 500MHz domain. Like a good design engineer, you place a 2-flop synchronizer on each signal. The metastability resolves, the linting tools pass, and you tape out.
But when the silicon comes back, your destination state machine occasionally jumps into an illegal state and freezes. What went wrong?
Welcome to the hidden trap of CDC: Reconvergent Logic.
The +/- 1 Clock Cycle Uncertainty
To understand why your design crashed, we have to look at how synchronizers actually behave in the physical world.
When a signal goes metastable in the first stage of a 2-flop synchronizer, it will eventually settle to a 1 or a 0. But which one it settles to during that specific clock cycle is entirely random.
If it settles to the new value, the destination domain sees the signal change this cycle.
If it settles to the old value, the destination domain won't see the signal change until the next cycle.
This introduces a fundamental hardware rule: Every synchronizer has a built-in temporal uncertainty of +/- 1 clock cycle.
The Reconvergence Disaster
Now, let's look back at your enable and mode signals. Let's assume the source domain asserts both of them at the exact same time.
Because of microscopic routing delays and the +/- 1 cycle uncertainty of synchronizers, these two signals might not exit their respective 2-flop synchronizers in the destination domain simultaneously.
Cycle 1:
enablesynchronizer resolves to1.modesynchronizer resolves to0(it needs one more cycle).Cycle 2:
enableis still1.modesynchronizer finally resolves to1.
For exactly one clock cycle, your destination domain saw enable = 1 and mode = 0. If your downstream logic combines these two signals (i.e., the logic reconverges), that temporary mismatch can trigger a fatal false state in your state machine.
Key Takeaway: You successfully prevented metastability, but you destroyed the logical relationship between your signals.
How to Fix Reconvergent CDC Paths
The rule for fixing this is simple: Never synchronize related control signals separately if they will be evaluated together in the destination domain.
Here is how experienced design engineers handle this:
1. Consolidate Before Crossing
Instead of sending enable and mode as separate signals, combine them into a single validation signal in the source domain.
For example, create a new signal: valid_operation = enable & mode; in the source clock domain. Then, pass only that single valid_operation bit through a 2-flop synchronizer.
2. Use a Multi-Bit CDC Technique
If you truly need both distinct bits in the destination domain, you can no longer treat them as independent control signals. You must treat them as a multi-bit bus. As we covered in a previous post, this means you must use a Gray Code encoding scheme or a Request/Acknowledge Handshake to ensure both bits are stable before the destination domain is allowed to read them.
Wrapping Up
CDC bugs are notoriously difficult to catch because they rarely show up in standard RTL simulations. A standard simulator doesn't model the microscopic silicon delays that cause the +/- 1 cycle uncertainty.
When designing your architecture, always trace your synchronized signals. If two signals cross domains separately and then meet at an AND gate, a MUX, or a State Machine evaluation down the line, you have a reconvergence bug waiting to happen.
No comments:
Post a Comment