Draft preview. Lessons are being written and reviewed.

Digital Design / Module 10: Clock domain crossing

59. Reset synchronizers and RDC

Treat reset as a crossing too.

Lecture coming soon

See it move

The idea

Reset deserves as much care as a clock. If it's released at a bad time, flops can go , or different parts of a design can start a cycle apart. A reset fixes this for one , and each domain needs its own.

The reset synchronizer

module reset_sync (input clk, arst_n, output rst_n);
  reg r1, r2;
  always_ff @(posedge clk or negedge arst_n)
    if (!arst_n) begin
      r1 <= 1'b0;
      r2 <= 1'b0;
    end else begin
      r1 <= 1'b1;
      r2 <= r1;
    end
  assign rst_n = r2;
endmodule

Assertion is asynchronous, so reset works without a clock, and reaches every flop at once. Release is synchronized: the 1 must shift through two flops before rst_n goes high, which aligns it to the clock. The first flop can go metastable, as with a normal synchronizer, and the second gives it time to settle.

Reset domain crossings (RDC)

Clocks aren't the only concern. Suppose flop A has async reset R1, and flop B has reset R2 on the same clock. If R1 asserts while B is not in reset, then A's output changes at an arbitrary moment, regardless of the clock. B can capture it during a transition and go metastable, with no clock crossing in sight. This is a reset domain crossing.

Handling RDC

  • Reset the receiver first or at the same time, whenever possible.
  • Isolate signals during reset, by gating them to a safe value.
  • Sequence resets: release upstream blocks in a known order, so that nobody receives data before it can be handled.
  • Run an RDC check. Normal CDC tools don't always cover it.

Multiple clock domains

Each domain has its own synchronizer, driven by a common global reset. Domains leave reset at slightly different times. and that cross between them should be designed to stay quiet until both sides are ready.

Common mistake

Using one synchronized reset in every clock domain. The release is aligned only for the domain it was synchronized to. In any other domain, it's effectively asynchronous, which is exactly what and failures come from.

Key ideas

  • Assert async, de-assert synchronously.
  • Asynchronous resets in one domain can corrupt another.
  • Sequence resets across domains.

Your exercise

Connect reset synchronizers across two clock domains.

Find the bug

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

What goes wrong: Reset releases on the very first clock edge, leaving the first flop no settling time.

Interview questions

coreWhat is RDC?

basicWhy do designs assert reset asynchronously but release it synchronously?

basicWhat are recovery and removal checks?

coreReview this reset synchronizer. What is wrong, and when does its output rise?

module reset_sync_bug (input clk, arst_n, output rst_n);
  reg r1, r2;
  always @(posedge clk or negedge arst_n)
    if (!arst_n) begin r1 <= 1'b0; r2 <= 1'b0; end
    else begin r1 <= 1'b1; r2 <= 1'b1; end
  assign rst_n = r2;
endmodule

coreA design synchronizes reset once to clk_a and uses that reset in both the clk_a and clk_b domains. What is the problem?

coreA sender and a receiver run on the same clock but have separate asynchronous resets. Resetting only the sender corrupts the receiver now and then. Why, and how do you fix it?

coreTwo clock domains leave reset at slightly different times. What should a handshake or FIFO between them do during that gap?

advancedA reset synchronizer drives 50,000 flops. Its release is aligned to the clock, so why can the release still fail timing?

advancedIn an async FIFO, only the write side is reset while traffic is running. The reader later outputs some words a second time. Explain.

Practise these 9 questions with animations