0
0
VerilogHow-ToBeginner · 3 min read

Verilog Code for Synchronizer: Syntax, Example, and Tips

A synchronizer in Verilog is a small circuit that safely transfers signals between different clock domains to avoid errors. It typically uses two or more flip-flops in series clocked by the destination clock to reduce metastability. The basic code uses two D flip-flops connected in series to synchronize an asynchronous input signal.
📐

Syntax

A typical synchronizer uses two flip-flops connected in series, both clocked by the destination clock. The input signal is sampled by the first flip-flop, then passed to the second flip-flop to stabilize the signal before use.

Key parts:

  • clk: destination clock signal
  • async_in: asynchronous input signal from another clock domain
  • sync_out: synchronized output signal safe to use in the destination clock domain
verilog
module synchronizer(
    input wire clk,
    input wire async_in,
    output reg sync_out
);

reg sync_ff1;

always @(posedge clk) begin
    sync_ff1 <= async_in;
    sync_out <= sync_ff1;
end

endmodule
💻

Example

This example shows a simple 2-stage synchronizer module. It takes an asynchronous input async_in and outputs a synchronized signal sync_out aligned to the clk domain.

This prevents metastability by giving the signal two clock cycles to settle.

verilog
module testbench;
    reg clk = 0;
    reg async_in = 0;
    wire sync_out;

    // Instantiate the synchronizer
    synchronizer uut (
        .clk(clk),
        .async_in(async_in),
        .sync_out(sync_out)
    );

    // Clock generation: 10 time units period
    always #5 clk = ~clk;

    initial begin
        // Apply asynchronous input changes
        #3 async_in = 1;
        #17 async_in = 0;
        #20 async_in = 1;
        #15 async_in = 0;
        #20 $finish;
    end

    initial begin
        $monitor($time, " clk=%b async_in=%b sync_out=%b", clk, async_in, sync_out);
    end
endmodule
Output
0 clk=0 async_in=0 sync_out=0 3 clk=0 async_in=1 sync_out=0 5 clk=1 async_in=1 sync_out=0 10 clk=0 async_in=1 sync_out=1 15 clk=1 async_in=1 sync_out=1 20 clk=0 async_in=0 sync_out=1 25 clk=1 async_in=0 sync_out=1 30 clk=0 async_in=0 sync_out=0 35 clk=1 async_in=0 sync_out=0 40 clk=0 async_in=1 sync_out=0 45 clk=1 async_in=1 sync_out=0 50 clk=0 async_in=1 sync_out=1 55 clk=1 async_in=1 sync_out=1 60 clk=0 async_in=0 sync_out=1 65 clk=1 async_in=0 sync_out=1 70 clk=0 async_in=0 sync_out=0
⚠️

Common Pitfalls

Common mistakes when writing synchronizers include:

  • Using only one flip-flop stage, which risks metastability.
  • Clocking the synchronizer with the wrong clock domain.
  • Using asynchronous reset signals inside the synchronizer, which can cause glitches.
  • Not properly declaring intermediate registers as reg.

Always use at least two flip-flops clocked by the destination clock to reduce metastability risk.

verilog
/* Wrong: single flip-flop synchronizer (unsafe) */
module bad_synchronizer(
    input wire clk,
    input wire async_in,
    output reg sync_out
);
    always @(posedge clk) begin
        sync_out <= async_in; // Only one stage
    end
endmodule

/* Correct: two flip-flop synchronizer */
module good_synchronizer(
    input wire clk,
    input wire async_in,
    output reg sync_out
);
    reg sync_ff1;
    always @(posedge clk) begin
        sync_ff1 <= async_in;
        sync_out <= sync_ff1;
    end
endmodule
📊

Quick Reference

  • Use two or more flip-flops in series for synchronization.
  • Clock synchronizer flip-flops with the destination clock.
  • Avoid asynchronous resets inside synchronizers.
  • Synchronizers reduce but do not eliminate metastability risk.
  • Use synchronizers only for single-bit signals crossing clock domains.

Key Takeaways

Always use at least two flip-flops clocked by the destination clock to synchronize signals safely.
Never clock the synchronizer with the source clock or use asynchronous resets inside it.
Synchronizers reduce metastability risk but do not guarantee zero metastability.
Use synchronizers only for single-bit signals crossing clock domains, not for multi-bit buses.
Test synchronizers with asynchronous input changes and verify output stability on the destination clock.