Draft preview. Lessons are being written and reviewed.

Digital Design / Module 10: Clock domain crossing

54. The two-flop synchronizer

Cross a single slowly-changing control bit.

Lecture coming soon

Lab: Clock crossing lab

The idea

A single-bit control signal from another clock domain passes through two flops in the destination domain before use. The first flop may go , and the second gives it a clock cycle to settle.

module sync2 #(parameter STAGES = 2) (
  input  clk, rst_n, async_in,
  output sync_out
);
  (* ASYNC_REG = "TRUE" *) reg [STAGES-1:0] sr;

  always_ff @(posedge clk or negedge rst_n)
    if (!rst_n) sr <= '0;
    else        sr <= {sr[STAGES-2:0], async_in};

  assign sync_out = sr[STAGES-1];
endmodule

The rules

  • Register the source in its own domain first. Combinational logic can , and a glitch might be captured as a real event.
  • No logic between the synchronizer flops. That would reduce settling time, and defeat their purpose.
  • Place them close together. Physical design tools should keep wires short. Attributes like the one above help on FPGAs.
  • Use the output only after the last stage. Reading the first flop's output defeats the whole idea.

What it can't do

It's a tool for a single signal changing slowly compared with the destination clock. A narrow pulse may be missed, because a fast signal may fall between destination edges. A rule of thumb: the source should stay stable for at least 1.5 destination clock periods. A bus can't simply use one per bit either, as the later lessons explain.

Latency

The signal arrives two to three destination cycles later. Your design must tolerate this. The exact number can also vary by one cycle, depending on where the change falls relative to the clock.

Common mistake

Fanning out the first flop's output as well as the second's, or synchronizing the same signal in two separate places. Two synchronizers can settle differently, and resolve a cycle apart, so two parts of your design could disagree. Synchronize once, then distribute the result. The lab above shows data arriving in the destination domain.

Key ideas

  • Works for single-bit level signals.
  • No combinational logic between the stages.
  • The source signal should come directly from a flop.

Your exercise

Write a synchronizer with a parameterised stage count.

Find the bug

This code has one deliberate bug. Read the symptom, then click the line you think is wrong.

What goes wrong: The signal arrives a cycle sooner than expected, and in silicon this design fails occasionally.

Interview questions

coreWhy register the source before crossing?

basicWhat kind of signal is a two-flop synchronizer meant for, and what latency should the receiving logic expect?

basicWhy must there be no combinational logic between the two flops of a synchronizer?

coreReview this synchronizer. It passes every simulation, and the output even arrives one cycle sooner than expected. What is wrong?

module sync2 (input clk, rst_n, d, output q);
  reg s1, s2;
  always @(posedge clk or negedge rst_n)
    if (!rst_n) begin s1 <= 1'b0; s2 <= 1'b0; end
    else        begin s1 <= d;    s2 <= s1;   end
  assign q = s1;
endmodule

coreSomeone puts 0.5 ns of logic between the two synchronizer flops at 500 MHz. With tau = 0.05 ns and 1.8 ns of settling time before the change, by what factor does MTBF drop?

coreA level signal crosses from a 200 MHz domain into a 50 MHz domain through a two-flop synchronizer. Using the 1.5-period rule of thumb, how many source cycles must it stay stable?

coreTwo blocks in the destination domain each have their own synchronizer for the same incoming signal. Occasionally they disagree for one cycle. Why, and what is the fix?

advancedTwo related control bits, enable and mode, come from another clock domain, and each has its own two-flop synchronizer. What can go wrong when both change together?

advancedOn an FPGA, why do engineers mark synchronizer flops with an attribute such as ASYNC_REG, and what is the physical concern on an ASIC?

Practise these 9 questions with animations