RTL Bench PRO

Clock Domain Crossing (CDC): Preventing Silicon Metastability

When digital data passes between asynchronous clock domains, standard static timing analysis (STA) cannot guarantee timing closure. Unsynchronized signals inevitably violate setup or hold windows, causing flip-flops to hover in metastable states. This guide breaks down CDC physics, synchronizer design, and automated structural verification.

1. The physics of metastability & MTBF

Every sequential flip-flop contains internal cross-coupled inverters. If data toggles inside the forbidden aperture window (defined by setup time Tsetup and hold time Thold), the internal latch cannot immediately resolve to a clean 0 or 1.

๐Ÿ’ก The Mean Time Between Failures (MTBF) Formula: The statistical likelihood of a synchronizer failure over time is defined by:
MTBF = exp(T_resolve / tau) / (T_0 * f_clk * f_data)
  • fclk (Receiver Clock Frequency): The sampling rate of the destination clock domain.
  • fdata (Asynchronous Data Transition Rate): How frequently the incoming signal changes state.
  • Tresolve (Settling Time): Time allowed for the flip-flop output to settle before downstream logic samples it.
  • τ & T0 (Silicon Process Constants): Intrinsic physical parameters of the chosen foundry library.

Because settling probability increases exponentially with available resolution time, inserting cascade flip-flops (the classic 2-FF or 3-FF synchronizer) extends MTBF from milliseconds into centuries.

2. Single-bit synchronization: The 2-FF synchronizer

For quasi-static control signals and pulses, a Two Flip-Flop (2-FF) Synchronizer provides adequate metastability protection:

// Asynchronous single-bit 2-FF synchronizer
module sync_2ff (
  input  wire clk_b,    // Destination clock domain
  input  wire rst_n,    // Active-low reset (destination domain)
  input  wire async_in, // Signal launched from clk_a
  output reg  sync_out
);
  reg meta_stage;

  always @(posedge clk_b or negedge rst_n) begin
    if (!rst_n) begin
      meta_stage <= 1'b0;
      sync_out   <= 1'b0;
    end else begin
      meta_stage <= async_in;   // Stage 1: Absorbs potential metastability
      sync_out   <= meta_stage;  // Stage 2: Clean, resolved synchronous output
    end
  end
endmodule
โš ๏ธ The No-Combinational Rule: Never place combinational logic (AND, OR, MUX) between the launch register and the first synchronizer flip-flop, or between synchronizer stages. Intermediate logic gates introduce glitches that drastically degrade MTBF.

3. Multi-bit bus crossings: Why 2-FF synchronizers fail

A common pitfall in digital logic design is placing a 2-FF synchronizer on each bit of a multi-bit data bus (e.g. data[31:0]).

Because physical wires have subtle routing skew differences, individual bits will not arrive at identical picoseconds. The destination domain may sample some bits in cycle N and others in cycle N+1. When transmitting from 0x00FF to 0x0100, intermediate corruption states like 0x0000 or 0x01FF will be captured.

Crossing Pattern Recommended Solution Engineering Trade-Off
Single-Bit Control Flag 2-Stage or 3-Stage DFF Synchronizer Adds 2 clock cycles of latency; zero area overhead.
Multi-Bit Quasi-Static Bus Source-Synchronous Handshake (REQ / ACK) Multi-cycle handshake latency; guarantees stable bus data.
Continuous Streaming Data Asynchronous Dual-Clock FIFO Requires dual-port SRAM and Gray-coded read/write pointers.

Gray-coded pointers in asynchronous FIFOs

In an asynchronous dual-clock FIFO, multi-bit pointers must cross between write and read domains to compute full and empty flags. By encoding pointer counters in Gray code (where only one bit changes per count), bus convergence hazards are eliminated:

// Binary to Gray code conversion
assign gray_ptr = bin_ptr ^ (bin_ptr >> 1);

// Gray code to Binary conversion (for 4-bit pointers)
assign bin_ptr[3] = gray_ptr[3];
assign bin_ptr[2] = gray_ptr[3] ^ gray_ptr[2];
assign bin_ptr[1] = gray_ptr[3] ^ gray_ptr[2] ^ gray_ptr[1];
assign bin_ptr[0] = gray_ptr[3] ^ gray_ptr[2] ^ gray_ptr[1] ^ gray_ptr[0];

4. Automated structural CDC verification in RTL Bench

Dynamic simulations rarely catch CDC bugs because ideal testbenches simulate with fixed zero-skew clock relationships. RTL Bench executes a static structural CDC audit directly on the elaborated gate netlist during synthesis:

  1. Clock Domain Extraction: The auditor identifies every D flip-flop cell in the netlist, parsing its clock pin (CLK, C) to group registers into distinct domain sets.
  2. Topological Back-Tracing: For every capturing flip-flop, the engine traverses input nets backward through combinational logic gates until it reaches driving source flip-flops.
  3. Domain Boundary Evaluation: If a launch flip-flop and capture flip-flop reside on different clock nets, the path is flagged as an inter-domain boundary.
  4. Synchronizer Pattern Matching: The engine checks whether the destination register feeds into a 2-stage back-to-back flip-flop chain without intervening combinational gates. Safe chains are marked as verified synchronizers; direct unbuffered crossings are reported as UNSYNCHRONIZED CDC HAZARDS.

Frequently asked questions

What is Clock Domain Crossing (CDC) and why is it dangerous in digital design?

A Clock Domain Crossing occurs when a signal launched by a flip-flop driven by one clock is sampled by a flip-flop driven by an asynchronous clock. Because the two clocks have independent phase and frequency relationships, the signal can violate setup or hold times, plunging the receiving flip-flop into a metastable state.

Why can't you synchronize a multi-bit bus with standard 2-FF synchronizers?

Different bits in a data bus experience different routing delays and cell propagation skews. If each bit passes through an independent 2-FF synchronizer, some bits will be captured one clock cycle earlier than others, creating corrupt intermediate data values. Multi-bit crossings require asynchronous FIFOs or Gray-coded pointer schemes.

Can static timing analysis (STA) catch CDC errors?

No. STA calculates propagation delays between synchronous registers governed by a common clock tree. On asynchronous boundaries, STA will report artificial setup and hold timing violations. Once synchronizers are verified, they must be set as set_false_path or set_clock_groups -asynchronous in your SDC constraints.

Next

Open CDC verification tool โ†’