0
0
VerilogDebug / FixIntermediate · 4 min read

How to Handle Clock Domain Crossing in Verilog: Fix and Best Practices

To handle clock domain crossing in Verilog, use synchronizer flip-flops to safely transfer signals between different clock domains and avoid metastability. This typically involves passing signals through two or more flip-flops clocked by the destination clock domain.
🔍

Why This Happens

When signals move from one clock domain to another with a different clock, timing mismatches can cause metastability. This means the receiving flip-flop may not settle to a stable 0 or 1 in time, causing unpredictable behavior.

Here is an example of broken code that directly assigns a signal from one clock domain to another without synchronization:

verilog
module broken_cdc(
    input wire clk_a,
    input wire clk_b,
    input wire signal_a,
    output reg signal_b
);

    // Direct assignment without synchronization
    always @(posedge clk_b) begin
        signal_b <= signal_a; // Unsafe crossing
    end

endmodule
Output
Metastability may cause signal_b to glitch or behave unpredictably.
🔧

The Fix

The correct way is to use a two-stage synchronizer in the destination clock domain. This reduces metastability risk by giving the signal time to settle before use.

Here is the fixed code using two flip-flops to synchronize the signal from clk_a to clk_b domain:

verilog
module fixed_cdc(
    input wire clk_a,
    input wire clk_b,
    input wire signal_a,
    output reg signal_b
);

    reg sync_ff1, sync_ff2;

    // Synchronize signal_a into clk_b domain
    always @(posedge clk_b) begin
        sync_ff1 <= signal_a;
        sync_ff2 <= sync_ff1;
        signal_b <= sync_ff2;
    end

endmodule
Output
signal_b safely follows signal_a with reduced metastability risk.
🛡️

Prevention

To avoid clock domain crossing issues in the future, follow these best practices:

  • Always use at least two flip-flops for synchronizing single-bit signals crossing clock domains.
  • For multi-bit buses, use handshake protocols or FIFOs designed for CDC.
  • Use static timing analysis tools and CDC checkers to detect unsafe crossings.
  • Keep clock domains clearly separated and document their interactions.
⚠️

Related Errors

Other common errors related to clock domain crossing include:

  • Data corruption: When multi-bit signals cross without synchronization, bits can arrive at different times causing invalid data.
  • Glitches: Unsynchronized signals can cause short pulses that trigger unintended logic.
  • Timing violations: Setup and hold time violations occur if signals are sampled too close to clock edges.

Quick fixes involve adding synchronizers, using handshake signals, or employing asynchronous FIFOs.

Key Takeaways

Always synchronize signals crossing clock domains using at least two flip-flops.
Avoid direct assignments of signals between different clock domains to prevent metastability.
Use handshake or FIFO methods for multi-bit or complex data transfers across clock domains.
Employ CDC verification tools to catch unsafe crossings early in design.
Clearly separate and document clock domains to reduce design errors.