3.1.3.3. Identifying Synchronizer CDC Issues
However, improper synchronizer implementation is a common cause of CDC issues. For correct synchronizer implementation, you must ensure the following:
- The destination of an asynchronous transfer forms a chain of two or more registers, with each register in the same clock domain as the destination of the transfer.
- No combinational logic is present between any of the registers in the chain.
- No combinational logic is present on the path to the first register in the chain.
The following Verilog HDL and VHDL examples show how to define a three-stage synchronizer. These synchronizers take an asynchronous input signal from one clock domain, and then produce a synchronized output signal for use in another clock domain.
Both examples implement the synchronizer as a chain of three flipflops (sync_ff). The asynchronous input signal ( async_in) is captured by the first flipflop on the rising edge of the clock signal (clk) of the destination domain. The signal then propagates through the second and third flipflops, with each stage providing additional time for the signal to stabilize. The output of the third flipflop (sync_out) is then used within the destination clock domain, significantly reducing the risk of metastability.
Three-Stage Synchronizer Example (Verilog HDL)
module three_stage_synchronizer (
input wire clk, // Clock signal of the destination domain
input wire async_in, // Asynchronous input signal from the source domain
output reg sync_out // Synchronized output signal for the destination domain
);
reg [2:0] sync_ff; // 3 flip-flops for the synchronizer chain
always @(posedge clk) begin
sync_ff[0] <= async_in; // First stage captures the asynchronous input
sync_ff[1] <= sync_ff[0]; // Second stage
sync_ff[2] <= sync_ff[1]; // Third stage
end
assign sync_out = sync_ff[2]; // Output from the third stage
endmodule
Three-Stage Synchronizer Example (VHDL)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity three_stage_synchronizer is
Port (
clk : in STD_LOGIC; -- Clock signal of the destination domain
async_in : in STD_LOGIC; -- Asynchronous input signal from the source domain
sync_out : out STD_LOGIC -- Synchronized output signal for the destination domain
);
end three_stage_synchronizer;
architecture Behavioral of three_stage_synchronizer is
signal sync_ff : STD_LOGIC_VECTOR(2 downto 0); -- 3 flip-flops for the synchronizer chain
begin
process(clk)
begin
if rising_edge(clk) then
sync_ff(0) <= async_in; -- First stage captures the asynchronous input
sync_ff(1) <= sync_ff(0); -- Second stage
sync_ff(2) <= sync_ff(1); -- Third stage
end if;
end process;
sync_out <= sync_ff(2); -- Output from the third stage
end Behavioral;
The following topics describe how to identify and constrain CDCs in synchronizers.