Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutRoadmapCareersInternshipsFAQContactPrivacyTerms
Skip to lesson

Course contents

  • RTL Foundations36
  • Combinational Design25
  • Sequential Design27
  • FSM & Control27
  • Timing & Clocking39
  • Reset & CDC34
    • Reset Architecture
      • Reset Is a System Contract
      • Async Assert, Sync Deassert
      • Reset Tree Planning
      • Reset Sequencing and POR Controller
      • What a Reset Costs
    • Metastability and Synchronisation
    • Asynchronous FIFO
    • CDC Protocols
    • Reset Domain Crossing
    • CDC Verification
  • Memory & Buses57
  • Advanced RTL28
  • Senior & Interview76
  • Glossary and Notation
Loading lesson

←Reset Architecture
  1. Topics
  2. RTL Design
  3. Reset & CDC
  4. Reset Architecture
  5. Async Assert, Sync Deassert
On this page

    Part 6 of 9, lesson 2 of 34Part 6 of 9/Reset & CDC/Lesson 2 of 34Intermediate

    Async Assert, Sync Deassert

    A reset synchroniser chain that asserts at once and releases on a clock edge.

    If reset releases close to a clock edge, the reset flop can go metastable and the design starts in an unknown state. A short flop chain with a constant 1 at its input keeps assertion immediate and moves the release onto the domain clock.

    After this lesson you can: draw the reset synchroniser, name the asynchronous pin and the tied input, and explain why release takes at least two clock edges.

    The problem with asynchronous release

    A flop with an asynchronous reset has two timing requirements at release: recovery (reset must go away at least t_rec before the next clock edge) and removal (and not within t_rem after the previous one). If reset releases at a random instant, it may violate one of them.

    The flop can then go metastable, like a data input that changes at the wrong moment. The fix passes the release through a short chain of flops clocked by the domain clock.

    The chain's flops reset asynchronously, so assertion is immediate. Their input is a constant 1, so only the release travels down the chain, one stage per clock edge.

    Reset synchroniser

    Reset synchroniser: the release travels through two flops, one clock edge per stage.

    The first flop in the chain can go metastable if the release lands in its recovery window. The second flop gives it a full clock period to settle, as with a data synchroniser.

    Two stages are the usual minimum. Three suit very fast clocks or high-reliability designs. In the code below STAGES must be 2 or more: an elaboration-time check rejects 1, because a single flop has no second stage to let a metastable output settle.

    Common mistakes

    The raw arst_n necessarily drives the reset-synchronizer stages. Ordinary downstream functional sinks instead use the domain's qualified reset; do not bypass that release contract even for one sink. A directly released functional flop can violate recovery/removal regardless of fanout. Synchronizer settling/reliability and downstream reset-tree timing remain separate implementation checks.

    Be ready to draw this circuit, say which pin is asynchronous (the clear), what the D input of the first flop is (tied to 1) and why release takes at least two edges.

    Check yourself The release lands 0.1 ns before a clock edge. How many clock edges until srst_n rises, and what is the hazard at the first flop?

    In ideal RTL, exactly two subsequent rising edges. Phase changes elapsed time, not that edge count. In hardware the first stage can violate recovery/removal and resolve late, delaying release; there is no deterministic three-edge ceiling. Reliability requires characterised cells and implementation timing.

    Simulation: one source, two release times

    The waveform below is simulation output for one asynchronous source released through a two-flop synchroniser in each of two unrelated clock domains. How to read it: one slot is one cycle of clk_a, and each slot shows the values just after that slot's rising clk_a edge; clk_b shows its own level at each slot, so a clk_b rise drawn at a slot boundary happened during the slot before. The release is driven 1 ns after the slot-2 clk_a edge (t = 26 ns), so it is drawn before the edges that release each domain.

    • While arst_n is low (slots 0 and 1) both rst_a_n and rst_b_n are low: assertion needs no clock.

    • arst_n rises in slot 2. rst_a_n follows in slot 4, after two clk_a edges (slots 3 and 4).

    • rst_b_n stays low until slot 5, after two edges of the slower clk_b (the rises drawn in slots 3 and 5), so the two domains leave reset at different times.

    • Each domain releases on its own clock; no domain logic sees the raw arst_n.

    Testbench

    reset_sync.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    `timescale 1ns/1ps
    
    // Asynchronous assert, synchronous release.
    module reset_sync #(parameter int STAGES = 2) (
      input  logic clk,
      input  logic arst_n,           // asynchronous reset input (from a pin or another domain)
      output logic srst_n            // reset for this clock domain
    );
      if (STAGES < 2) begin : g_stages_check       // legal range: STAGES >= 2
        $error("reset_sync: STAGES must be at least 2");
      end
      logic [STAGES-1:0] sr;
      always_ff @(posedge clk or negedge arst_n)
        if (!arst_n) sr <= '0;                      // assert: immediately, no clock needed
        else         sr <= {sr[STAGES-2:0], 1'b1};  // release: shifts in 1s, one stage per clock
      assign srst_n = sr[STAGES-1];
    endmodule
    

    Property

    How the test checks it

    Assertion is immediate

    0.001 ns after arst_n falls, srst_n is already 0

    Release is aligned to the clock

    Every rising edge of srst_n coincides with a clock edge (off_edge_changes == 0)

    Ideal release takes two clock edges

    Exactly two rising edges strictly after the release instant

    Finite phase coverage

    200 pseudo-random release instants, not exhaustive or physical reliability evidence

    • Recovery and removal are the setup and hold of reset release. A release at a random instant can violate either one.

    • Assertion needs no clock. Release takes two edges of the domain's own clock (STAGES must be 2 or more), so two domains release at different times.

    • Only the synchroniser sees the raw arst_n. Every other sink uses the domain's qualified reset.

    Rule of thumb: assert asynchronously, release synchronously.

    How this was checked

    Source checker, run with Icarus Verilog 13.0 (2026-10-16): prints PASS. It uses 200 pseudo-random releases to check ideal, zero-delay RTL assertion and exactly two subsequent release edges. Release is offset from clock edges to avoid simulator scheduling races. The finite check contains no analogue resolution model and proves neither MTBF nor recovery/removal signoff.

    • Practice: Debugging metastability from asynchronous reset deassertion

    • Code lab: Build a reset synchroniser

    • Interview: run a mock interview on this topic

    Related topics

    • Reset tree planning

    Previous

    156 / 350

    Next: Reset Tree Planning

    Up next

    Up nextReset Tree Planning

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • Reset Sequencing and POR Controller
    • What a Reset Costs
    clk_aarst_nrst_a_nclk_brst_b_n
    Simulation output: one asynchronous reset source released through a per-domain synchroniser in each of two unrelated clock domains