Clock Domain Crossing (CDC)
The art of safely transferring data between asynchronous clock domains. Essential for multi-clock SoC designs.
1. What is CDC & Why Do We Need It?
What is CDC?
Clock Domain Crossing (CDC) occurs whenever a signal is launched by a Flip-Flop in one clock domain (Source) and sampled by a Flip-Flop in a different clock domain (Destination). If the clocks are asynchronous (no fixed phase relationship), the setup and hold times relative to the destination clock generally cannot be guaranteed.
Why is it Critical?
Modern SoCs have dozens of clocks (CPU at 3GHz, DDR at 1.6GHz, USB at 480MHz, UART at 1MHz). Different modules MUST communicate. Without proper synchronization, you risk:
- Metastability: The destination flop output settles at an unknown voltage (neither 0 nor 1), potentially propagating errors.
- Data Incoherence: Sampling multi-bit buses at different times (Skew), receiving invalid values.
- Data Loss: Fast pulses missed by slow clocks.
2. Metastability & The 2-FF Synchronizer
Metastability happens when data changes inside the setup/hold window of a Flip-Flop. The output may oscillate or hover at VDD/2 for an indefinite time.
module synchronizer_2ff (
input wire clk_dest, // Destination Clock
input wire rst_n,
input wire d_async, // Asynchronous Input
output reg d_sync // Synchronized Output
);
reg q1;
// Standard 2-stage shift register
// Place these FFs close together during P&R (set_false_path)
always @(posedge clk_dest or negedge rst_n) begin
if (!rst_n) begin
q1 <= 1'b0;
d_sync <= 1'b0;
end else begin
q1 <= d_async; // Stage 1: May become Metastable
d_sync <= q1; // Stage 2: Likely Stable (filtered)
end
end
endmodule
Why 2 Flip-Flops? The first flop (q1) allows the metastability to resolve. By the time the second flop samples (one clock cycle later), the probability of q1 still being metastable is near zero (measured by MTBF - Mean Time Between Failures). For very high speeds, 3-FF synchronizers are used.
3. Pulse Stretchers (Fast-to-Slow)
If a pulse in the Fast Domain is narrower than the period of the Slow Domain, the slow clock might miss it entirely (sampling between pulses).
How to Implement:
Use a "Toggle" mechanism. Toggle a signal on every pulse in the source. Synchronize the toggle to the destination. Perform an XOR with the previous value (edge detection) to recreate the pulse.
4. Multi-Bit Synchronization (The Danger Zone)
Why? Clock Skew. If bits D[0] and D[1] transition from `00` to `11` simultaneously, delay variations might cause D[0] to arrive in cycle N and D[1] in cycle N+1. The destination would see `01` or `10` momentarily. This is catastrophic for pointers.
Solution A: Mux-Recirculation (Handshake)
Keep the Data Bus stable. Send a `Valid` signal. Synchronize only the `Valid` signal (using 2-FF). Once the destination sees `synchronized_valid`, it is safe to sample the Data Bus.
Solution B: Gray Codes (For Counters/Pointers)
Gray codes ensure that only **one bit changes** at a time when incrementing (e.g., `00` -> `01` -> `11` -> `10`). Even if skew exists, the sampled value will either be the *Old Count* or the *New Count*. Both are valid states. This is the heart of Async FIFO design.