Why CDC Matters
Clock Domain Crossing (CDC) occurs when a signal travels from one clock domain to another asynchronous clock domain. Without proper handling, it leads to metastability, data corruption, or functional failures — problems that are invisible in RTL simulation but catastrophic in silicon.
Metastability
Flip-flop setup/hold violations when sampling an asynchronous signal. Output is undefined for an unpredictable duration.
Data Corruption
Multi-bit signals where each bit is sampled at a different transition — producing an invalid intermediate value.
Reduced MTBF
Mean Time Between Failures degrades sharply in SoCs with many CDC crossings handled improperly.
Simulation Blindspot
RTL simulation uses ideal timing — CDC failures are invisible until the chip is fabricated and tested at speed.
1. Single-Bit Synchronizer
The two-FF synchronizer is the fundamental CDC building block. Two flip-flops clocked by the destination clock are chained in series. The first stage absorbs metastability; the second provides a stable output.
module two_ff_sync ( input wire clk_dest, input wire rst_dest_n, input wire async_in, output reg sync_out ); reg sync_ff1; always @(posedge clk_dest or negedge rst_dest_n) begin if (!rst_dest_n) {sync_out, sync_ff1} <= 2'b00; else {sync_out, sync_ff1} <= {sync_ff1, async_in}; end endmodule
2. Multi-Bit Data Transfer
Passing multiple bits across a clock boundary is fundamentally harder. You cannot synchronize each bit independently — they may be sampled at different transitions, producing an invalid combined value.
Gray Code Synchronization
Convert binary to Gray code before crossing. Since only one bit changes per increment, any sampling error reads the old value or the new — never a corrupted intermediate. Essential for async FIFO pointers.
Handshake Protocol (REQ/ACK)
Source asserts REQ, waits for ACK from the destination domain before changing data. Guarantees correctness but limits bandwidth to one transfer per 4+ cycles. Best for infrequent, critical transfers.
Asynchronous FIFO
Separate write and read clock domains with Gray-coded pointers synchronized across the boundary. Full/empty flags with high-bandwidth data transfer — the standard solution for high-throughput CDC.
Best Practices
- ✓Use 2-FF or 3-FF synchronizers for every single-bit CDC signal
- ✓Convert bus signals to Gray code before crossing clock domains
- ✓Use Async FIFO for high-bandwidth multi-bit transfers
- ✓Run static CDC checks (SpyGlass CDC, Questa CDC) before tapeout
- ✓Never pass multi-bit signals directly across asynchronous domains
- ✓Constrain CDC paths in SDC: set_false_path or set_max_delay -datapath_only
- ✓Zero tolerance — review and resolve every CDCcheck violation
Interactive CDC Simulator
Real-time 2-FF synchronizer, Gray code, and Async FIFO simulator — coming soon.