← RTL Design Interviews

Interview Question · Code Writing

Write a Reset Synchronizer

L1 JuniorL2 Mid-Levelresetsynchronizerscdc

The Question

The interviewer asks

Write a reset synchronizer that asserts reset at once and releases it in step with the clock.

Reveal the Model Answer

Use two flops with an asynchronous reset pin, both driven by the incoming reset. The first flop's D is tied to 1, and the second flop takes the first one's output. Reset clears both at once, with no clock. On release, a 1 moves through the two flops, so rst_n rises on the second edge. Only the first flop can go metastable, and the second gives it a cycle to settle.

reset_sync: Assert at Once, Release Two Edges LaterArrows show signals. rst_n_in clears both flops asynchronously. The first flop's D input is tied to 1.
reset_sync: assert at once, release two edges laterArrows show signals. rst_n_in clears both flops asynchronously. The first flop's D input is tied to 1. manager rst_n_in from the pin manager 1'b1 constant bridge q1 first flop bridge rst_n_out second flop completer a_q, s_q every flop of thedomain async clearasync clearDDrst_n_sync
  1. Assertion

    rst_n_in falls. Both flops clear at once, with no clock, and the domain is in reset immediately. In the lab this is the e5+5ns line, a_q=0.

    Follow the calls, values and waits
    1. data reset (0): rst_n_in → rst_n_out
    2. data reset (0): rst_n_out → a_q, s_q
  2. First edge after release

    q1 captures the 1. If the release fell inside q1's window, q1 may be late or metastable; it has a whole period to settle before anything reads it.

    Follow the calls, values and waits
    1. data release (1): 1'b1 → q1
  3. Second edge

    rst_n_out takes the 1 from q1. It changes just after an edge, far from every window in the domain.

    Follow the calls, values and waits
    1. data release (1): q1 → rst_n_out
  4. Third edge

    Every flop in the domain sees the release at the same edge and counts. In the lab both counters count from edge 4 after power-on, and from edge 8 after the pulse.

    Follow the calls, values and waits
    1. data release (1): rst_n_out → a_q, s_q
Read the diagram as text
  • rst_n_in: from the pin
  • 1'b1: constant
  • q1: first flop
  • rst_n_out: second flop
  • a_q, s_q: every flop of the domain
  • rst_n_in → q1: async clear
  • rst_n_in → rst_n_out: async clear
  • 1'b1 → q1: D
  • q1 → rst_n_out: D
  • rst_n_out → a_q, s_q: rst_n_sync

The synchronizer is two $_DFF_PN0_ flops on this flow. Its first flop can still go metastable; the second gives it a period to settle.

The synchronizer with the clock stopped during reset, then released between edges.

RUNIcarus Verilog · in your browser
Edit the code, then run it
Expected: clock stopped, arst_n=0: rst_n=0 rst_n released at rising edge 2 after release PASS: asserted with no clock, released on a clock edge

Self-Check

Tick each key point you covered in your answer.

What Interviewers Listen For (Junior)

A good junior answer writes two flops with an asynchronous reset and D tied high. It says why the assertion needs no clock.

Cross-Questions

Where the interviewer goes next. Open a node to practise that follow-up.

WhyWhat IfProve ItCompareScale It

  1. Write a Reset Synchronizer
  2. WhyWhy the First Flop's Input Is Tied HighL1 Junior

    Why is the D input of the first flop tied to 1 and not driven by the reset signal?

    Reveal the Model Answer

    The reset already reaches both flops through their reset pins, so D only has to describe the release. With D tied to 1, the only change D ever passes is "leave reset", one edge at a time. The input reset never enters a data path, which keeps it away from any combinational logic.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "Tying D to 1 means the flop is always 1."

    The reset pin overrides D. While reset is asserted, both flops are held at 0 whatever D is.

    Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 8.1.5.3 Asynchronous reset RTL flip-flop models

  3. What IfOne Reset, Several Clock DomainsL2 Mid-Level

    Asked if the block has more than one clock

    What if the block has three clocks? Is one reset synchronizer enough?

    Reveal the Model Answer

    No. Each clock domain needs its own synchronizer, clocked by that domain's clock. A release synchronized to one clock is still asynchronous to the others. The domains then leave reset at different times. So the design must tolerate any release order, or sequence the releases on purpose.

    Two Reset Synchronizers and a Ready FlagArrows show signals. The top row is domain A on clk_a, the bottom row domain B on clk_b.
    Two reset synchronizers and a ready flagArrows show signals. The top row is domain A on `clk_a`, the bottom row domain B on `clk_b`. component rst_n pin shared by bothdomains clk_a ra_q1, rst_a_n release on clk_a clk_a tog_a flips once per event clk_b rb_q1, rst_b_n release on clk_b clk_b t1, t2, t3 two flops, edgedetect ready up_b to up_q2 B is awake, told to A assert at onceassert at oncerst_a_nrst_b_ntoggleup_b
    1. Assert

      The pin falls and both domains are in reset at once, with or without their clocks.

    2. A releases first

      A's clock is running, so two of its edges release A. In the lab that is edge 3.

      Follow the calls, values and waits
      1. data release: ra_q1, rst_a_n → tog_a
    3. A sends too soon

      Without the flag, A sends as soon as it is out of reset. Its toggle reaches flops that are held at 0.

      Follow the calls, values and waits
      1. data event: tog_a → t1, t2, t3
    4. B says it is awake

      The fix: B raises up_b one edge after its release, and the flag crosses into A through two flops. A sends only when ready_a is 1.

      Follow the calls, values and waits
      1. data release: rb_q1, rst_b_n → t1, t2, t3
      2. data ready: t1, t2, t3 → up_b to up_q2
    Read the diagram as text
    • rst_n pin: shared by both domains
    • ra_q1, rst_a_n: release on clk_a
    • tog_a: flips once per event
    • rb_q1, rst_b_n: release on clk_b
    • t1, t2, t3: two flops, edge detect
    • up_b to up_q2: B is awake, told to A
    • rst_n pin → ra_q1, rst_a_n: assert at once
    • rst_n pin → rb_q1, rst_b_n: assert at once
    • ra_q1, rst_a_n → tog_a: rst_a_n
    • rb_q1, rst_b_n → t1, t2, t3: rst_b_n
    • tog_a → t1, t2, t3: toggle
    • t1, t2, t3 → up_b to up_q2: up_b

    The ready flag is a register in B that crosses like any other bit: from a flop, through two flops, into A.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "Synchronize once at the top and fan out to every domain."

    The release is synchronous only to the clock that synchronized it. Every other domain sees an asynchronous release again.

    Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 8.1.6 Multiple clocks and clock domain crossing

  4. Scale ItOrdering Reset Release Across DomainsL3 SeniorL4 Staff

    On a subsystem with many clock domains, how do you plan the order in which they leave reset?

    Reveal the Model Answer

    Write the order into the spec, based on who talks to whom. A receiver should be out of reset before its sender can send, or the sender must wait for a "ready" from it. A small reset controller can release domains in steps, with handshakes through synchronizers. Verification then runs every release order the controller allows.

    Self-Check

    Tick each key point you covered in your answer.

    What Interviewers Listen For (Staff)

    A good staff answer treats reset release as a protocol with its own spec and checks. It also asks how software and power states trigger resets.

    Missed Corner

    "All domains come out of reset at the same time."

    Separate synchronizers on unrelated clocks release at different times. Assuming they are equal is a hidden CDC bug.

    Source Mehta, ASIC/SoC Functional Design Verification (2018) ch. 8.5 CDC Verification Methodology

  5. CompareAsynchronous Assert vs Fully Synchronous ResetL2 Mid-Level

    Compare this synchronizer with a design where reset is synchronized in both directions and every flop uses a synchronous reset.

    Reveal the Model Answer

    A fully synchronous scheme needs a running clock before reset takes effect. The reset must also last long enough to be sampled. In exchange, reset is ordinary data for timing and is filtered against glitches. The asynchronous-assert scheme resets with no clock, which matters at power-up and when clocks are gated. Many teams choose it for that reason.

    Self-Check

    Tick each key point you covered in your answer.

    Missed Corner

    "Both schemes behave the same at power-up."

    Only the asynchronous assert puts flops into reset before the clock starts. The synchronous scheme waits for the first edges.

    Source Cummings, Mills and Golson, Asynchronous & Synchronous Reset Design Techniques - Part Deux (SNUG Boston 2003) §4.2 and 7.0

  6. Prove ItSolve R2.2.1: The Counter That Started EarlySimulator-graded

    Show it, don't just say it: this Silicon Lab problem is graded by the simulator.

    Open Problem R2.2.1

What People Get Wrong

Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.

Misconception

"A reset is just another asynchronous input. Use the normal two-flop synchronizer."

A plain synchronizer needs clock edges to pass reset in. With the clock stopped at power-up, the twin never asserts rst_n.

Run It

A plain two-flop synchronizer on the reset, then the asynchronous-assert form. Both are 2 flops.

RUNIcarus Verilog · in your browser
Edit the code, then run it
Expected: clock stopped, arst_n=0: rst_n=x FAIL: a reset is not just another input; the plain synchronizer cannot assert it without clock edges
See the Fix
module rst_sync (input logic clk, input logic arst_n, output logic rst_n);
  logic meta;
  always_ff @(posedge clk or negedge arst_n)
    if (!arst_n) {rst_n, meta} <= 2'b00;          // assert at once, no clock needed
    else         {rst_n, meta} <= {meta, 1'b1};   // release two edges later
endmodule
module tb;
  logic clk = 0, run = 0, arst_n = 1; logic rst_n;
  rst_sync dut (.clk(clk), .arst_n(arst_n), .rst_n(rst_n));
  always #5 if (run) clk = ~clk;
  int e = 0;
  always @(posedge clk) e++;
  initial begin
    #3 arst_n = 0;                // power-on reset; the PLL has not started the clock yet
    #20;
    $display("clock stopped, arst_n=0: rst_n=%b", rst_n);
    
    run = 1; #22 arst_n = 1;      // the clock runs, then reset is released between edges
    wait (rst_n === 1'b1);
    #1 $display("rst_n released at rising edge %0d after release", e - 2);
    if (rst_n === 1'b1) $display("PASS: asserted with no clock, released on a clock edge");
    $finish;
  end
endmodule

Prints: clock stopped, arst_n=0: rst_n=0 PASS: asserted with no clock, released on a clock edge

Misconception

"One flop is enough, because reset is slow."

The release can land anywhere in the cycle, so the one flop can go metastable. Its output then fans out to every flop in the block.

Source Cummings, Mills and Golson, Asynchronous & Synchronous Reset Design Techniques - Part Deux (SNUG Boston 2003) §7.1

Half-Truth

"After the synchronizer, the reset tree needs no timing checks."

The synchronized release is still an edge on every flop's reset pin. STA must check recovery and removal on that whole tree.

Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 8.1.5.6 Asynchronous reset metastability synchronizers

Learn It, Then Prove It