Draft preview. Lessons are being written and reviewed.

Digital Design / Module 10: Clock domain crossing

55. Pulse crossing fast to slow

Avoid losing narrow pulses.

Lecture coming soon

See it move

The idea

A one-cycle pulse in a fast may be shorter than a slow clock's period. It can fall between edges, in which case the slow domain simply never sees it. A two-flop doesn't help, since no edge sampled the pulse in the first place.

The toggle synchronizer

Convert the short event into a lasting change. Each source pulse flips a toggle flop. A flipped level stays there indefinitely, so the destination can't miss it. There, a synchronizer brings the level across, and an edge detector turns any change into a new pulse.

// Source domain: each pulse flips the level
always_ff @(posedge clk_a)
  if (!rst_a_n)   tog <= 1'b0;
  else if (pulse) tog <= ~tog;

// Destination domain: synchronize, then detect any edge
always_ff @(posedge clk_b)
  if (!rst_b_n) s <= 3'b000;
  else          s <= {s[1:0], tog};

assign pulse_b = s[2] ^ s[1];

The limit

Pulses must be far enough apart. If two pulses arrive before the destination sees the first toggle, the level flips and then flips back, and both events disappear. As a guide, allow at least two to three destination clock cycles between source pulses. Above this rate, use a or a .

Above, compare direct sampling with the toggle path. Direct sampling catches only the pulses that happen to align with an edge, while the toggle path keeps them all, as long as they obey the spacing.

Handshake alternative

With a handshake, the source holds a request until the destination acknowledges it. This needs no rate assumptions, because the source simply waits, but it takes several cycles per event.

Common mistake

Stretching the pulse to a fixed width instead. That can work if you truly know both clock frequencies, but it fails silently if a clock changes later on. Toggle or handshake solutions don't depend on the frequency ratio in the same fragile way.

Key ideas

  • Short pulses can fall between slow-clock edges.
  • Toggle synchronizer: convert to toggle, synchronize, then edge-detect.
  • Limit how quickly pulses may repeat.

Lab: Clock crossing lab

Your exercise

Build a toggle pulse synchronizer.

Find the bug

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

What goes wrong: Only every second source pulse produces a destination pulse.

Interview questions

coreFast-to-slow pulse crossing?

basicA 400 MHz domain sends one-cycle pulses directly into a two-flop synchronizer on a 50 MHz clock. Roughly what fraction of pulses are seen?

basicWould adding a third synchronizer stage help a fast-to-slow pulse crossing that loses pulses?

coreThis destination side of a toggle synchronizer passes a test with one pulse, but in a test with six pulses only three arrive. What is wrong?

always @(posedge clk_b)
  if (!rst_b_n) s <= 3'b000;
  else          s <= {s[1:0], tog};

assign pulse_b = s[1] & ~s[2];   // rising edge only

coreA toggle synchronizer carries pulses from a 250 MHz domain to a 25 MHz domain. Allowing two to three destination cycles between pulses, what minimum pulse spacing should the source guarantee?

coreTwo source pulses arrive closer together than one destination period on a toggle synchronizer. Is one of them lost, or both?

coreWhen would you use a request and acknowledge handshake instead of a toggle synchronizer for single events?

advancedA designer stretches each one-cycle pulse to 16 ns so a 14 ns destination clock always sees it. Later the destination clock moves to 20 ns. What happens?

advancedA toggle synchronizer has separate resets in each domain. The source domain is reset alone while its toggle flop holds 1. What does the destination see?

Practise these 9 questions with animations