ℹ️ Select 'Choose Exercise', or randomize 'Next Random Exercise' in selected language.

Choose Exercise:
Timer 00:00
WPM --
Score --
Acc --
Correct chars --

Verilog Clock Domain Crossing (CDC) Synchronizer

Verilog

Goal -- WPM

Ready
Exercise Algorithm Area
1module clk_domain_crosser (
2input wire clk_src,
3input wire reset_src,
4input wire data_in,
5
6input wire clk_dest,
7input wire reset_dest,
8output reg data_out
9);
10
11// Internal signals
12reg data_sync1;
13reg data_sync2;
14
15// Synchronizer for data_in from clk_src domain to clk_dest domain
16// First flop captures data in source domain, potentially going metastable
17always @(posedge clk_src or posedge reset_src) begin
18if (reset_src) begin
19data_sync1 <= 1'b0;
20end else begin
21data_sync1 <= data_in;
22end
23end
24
25// Second flop samples the output of the first flop in the destination domain.
26// This helps resolve metastability.
27always @(posedge clk_dest or posedge reset_dest) begin
28if (reset_dest) begin
29data_sync2 <= 1'b0;
30end else begin
31data_sync2 <= data_sync1;
32end
33end
34
35// Assign the output of the second flop to the output port.
36// This signal is now synchronized to the destination clock domain.
37always @(posedge clk_dest or posedge reset_dest) begin
38if (reset_dest) begin
39data_out <= 1'b0;
40end else begin
41data_out <= data_sync2;
42end
43end
44
45// Edge case: If reset_dest is asserted, ensure data_out is cleared.
46// This is handled by the always @(posedge clk_dest or posedge reset_dest) block.
47
48// Edge case: If reset_src is asserted, data_in is effectively ignored
49// and data_sync1 will eventually be cleared, propagating to data_out.
50
51endmodule
Algorithm description viewbox

Verilog Clock Domain Crossing (CDC) Synchronizer

Algorithm description:

This Verilog module implements a standard two-flop synchronizer, a common technique for safely transferring asynchronous signals between different clock domains. It mitigates the risk of metastability by sampling the input signal twice in the destination clock domain. This is essential in complex System-on-Chip (SoC) designs where multiple clock frequencies are present.

Algorithm explanation:

The `clk_domain_crosser` module uses two flip-flops clocked by the destination clock (`clk_dest`) to synchronize an input signal (`data_in`) from a source clock domain (`clk_src`). The first flip-flop (`data_sync1`) captures the `data_in` signal. If `data_in` changes near the edge of `clk_src`, `data_sync1` might enter a metastable state. The second flip-flop (`data_sync2`), clocked by `clk_dest`, samples `data_sync1`. Since `clk_dest` is asynchronous to `clk_src`, the probability of `data_sync1` being metastable when `data_sync2` samples it is significantly reduced, and the second flop will resolve it to a stable logic level (0 or 1). The output `data_out` is then assigned the value of `data_sync2`. Both clock domains have their own reset signals for independent initialization. The space complexity is O(1) as it uses a fixed number of registers. The time complexity for synchronization is two clock cycles of the destination clock.

Pseudocode:

Define input signals: clk_src, reset_src, data_in.
Define output signals: clk_dest, reset_dest, data_out.
Define internal registers: data_sync1, data_sync2.

On positive edge of clk_src or posedge reset_src:
  If reset_src is high:
    Set data_sync1 to 0.
  Else:
    Set data_sync1 to data_in.

On positive edge of clk_dest or posedge reset_dest:
  If reset_dest is high:
    Set data_sync2 to 0.
    Set data_out to 0.
  Else:
    Set data_sync2 to data_sync1.
    Set data_out to data_sync2.

Handle edge cases: Ensure resets clear the respective flip-flops.