Double Flip-Flop Synchronizer for CDC

As we discussed in the previous blog one of the methods to solve metastability is the Double Flop Synchroniser method. This method consists of two cascaded D flip-flops that sample the input signal with the destination clock. This design can reduce the risk of metastability by adding a buffer stage between the source and the destination logic. The double flip-flop synchronizer can help mitigate the issues related to clock domain crossing (CDC) in data or control signals in any design.

Figure 1: Scheme for double flip-flop synchronizer

In the above figure, three flip-flops are used. Output of flip flop A is QA, Output of flip flop B is QB1, and Output of flip flop C is QB2. Input given to the flip-flop A will always be either 1 or 0. Output QA is given as input to B flip-flop. Flip-flop A is connected to clock A so output QA will reflect the rising edge of clock A. However we can see a change in the set-up time for signal QA when it reaches flip-flop B. This will result in a metastable state in the output QB. Now another flip flop C is connected whose input is QB. We must note that flip-flops B and C are connected to clock signal B. Adding flip-flop C gives buffer time. The purpose of adding this flip flop C is so that the output is delayed by one clock cycle. This ensures the point of metastability we had previously observed in QB1 is delayed thus producing accurate results.

Verilog Code for Double Flip-Flop Synchronizer

module d_ff (
    input clk,
    input d,
    output reg q
);

always @(posedge clk)
begin
    q <= d;
end

endmodule 

module d_ff_chain (
    input clkA,
    input clkB,
    input d,
    output  qa, // Output of the first D flip-flop
    output  qb1, // Output of the second D flip-flop
    output qb2 // Output of the third D flip-flop
);
wire intermediate_q1, intermediate_q2;

// Instantiate the first D flip-flop controlled by clkA
d_ff dff1 (
    .clk(clkA),
    .d(d),
    .q(qa) // Rename the output to qa
);

// Instantiate the second D flip-flop controlled by clkB
d_ff dff2 (
    .clk(clkB),
    .d(qa), // Connect to the output of the first D flip-flop
    .q(qb1) // Rename the output to qb1
);

// Instantiate the third D flip-flop controlled by clkB
d_ff dff3 (
    .clk(clkB),
    .d(qb1), // Connect to the output of the second D flip-flop
    .q(qb2) // Rename the output to qb2
);

endmodule
module tb;

	// Inputs
	reg clkA;
	reg clkB;
	reg d;

	// Outputs
	wire qa;
	wire qb1;
	wire qb2;

	// Instantiate the Unit Under Test (UUT)
	d_ff_chain uut (
		.clkA(clkA), 
		.clkB(clkB), 
		.d(d), 
		.qa(qa), 
		.qb1(qb1), 
		.qb2(qb2)
	);

	initial 
	begin
		// Initialize Inputs
		clkA = 1'b0;
		clkB = 1'b1;
		d = 1'b1;
		end 

	always #10 clkA =~clkA;
always #10 clkB = ~clkB;

initial begin
#20 d = 1'b0;
#20 d = 1'b1;
#20 d = 1'b0;
#20 d = 1'b1;
#20 d = 1'b0;
#20 d = 1'b1;
#20 d = 1'b0;
#20 d = 1'b1;
#20 d = 1'b0;
#20 d = 1'b1;
#20 d = 1'b0;
#20 d = 1'b1;

   end    
endmodule

Simulation Results

Three cases are studied for the double flip-flop synchronizer to solve CDC issues. These cases are shown below

1. Source and destination clocks are of same frequency but of different phases.

Figure 2: Source and destination clock speeds are same but have different phase differences.

2. The source clock is slower than destination clock

Figure 3: Destination clock speed is twice than the source clock.

In this scenario, destination clock speed is two times faster than the source clock. Data signal is aligned with the positive edge of the destination clock but width of the data signal is twice the width of clock signal.

3. The source clock is faster than destination clock

Figure 4: Destination clock is slower than the source clock.

In this scenario, double flip-flop technique fails to solve the CDC issue. Data cannot be transferred faster domain to slower domain.

Shopping Basket