RTL Best Practices

Clock Domain Crossing

Safe data transfer between asynchronous clock domains — synchronizers, Gray code, and async FIFOs for robust VLSI/ASIC designs.

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.

SystemVerilog — Two-FF Synchronizer
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

🔬

Interactive CDC Simulator

Real-time 2-FF synchronizer, Gray code, and Async FIFO simulator — coming soon.