Verification

Reset handling in UVM

By CourseTron Team ·  9 min read ·  Updated Oct 2026 💬 𝕏 in f
Table of Contents
    ? Print / Save as PDF

    In short: Robust UVM reset handling means designing drivers, monitors and sequencers that detect reset assertion, abort or flush in-flight transactions, resynchronize cleanly on de-assertion, and are exercised by on-the-fly reset sequences coordinated through phase jumps or a dedicated reset-handling thread.

    Ask a verification engineer what breaks first on a new SoC and the honest answer is usually "the reset." A well-written UVM environment can pass thousands of random transactions and still fall apart the moment a watchdog or power-management block asserts an asynchronous reset in the middle of a burst. Reset handling is one of the most common interview topics for a reason: it exposes whether you understand UVM's object lifetime, phasing, and the boundary between the testbench and the DUT. This article walks through reset-aware components, phase jumps, and on-the-fly reset testing with concrete patterns you can drop into a real environment.

    Why reset is hard in a class-based testbench

    The RTL handles reset in one line: always @(posedge clk or negedge rst_n). The testbench has no such luxury. UVM components are long-lived objects; a driver's run_phase is a forever loop that pulls items from the sequencer and wiggles pins. When reset fires asynchronously, three things happen at once and all of them are your problem:

    • The driver may be mid-handshake — it has driven valid=1 and is waiting for ready that will now never come.
    • The monitor is halfway through reconstructing a transaction and is about to emit a corrupt object to the scoreboard.
    • The sequencer still has a queue of items and a sequence blocked inside finish_item().

    If you ignore any of these, you get phantom protocol errors, scoreboard mismatches on transactions that never really completed, and hung simulations where a sequence waits forever on an item that reset silently killed.

    A useful mental model: the DUT forgets everything on reset in zero time, but your testbench objects remember. Reset handling is the discipline of forcing the testbench to forget in lock-step with the hardware.

    Reset-aware drivers: fork, join_any, disable fork

    The classic pattern makes the driver run two threads concurrently — one that drives transactions, one that watches for reset — and lets reset win the race. The fork...join_any plus disable fork idiom is the idiomatic UVM way to do this:

    task run_phase(uvm_phase phase);
      forever begin
        @(negedge vif.rst_n);           // wait until out of reset region
        fork
          get_and_drive();              // normal stimulus loop
          @(negedge vif.rst_n) ;        // reset watchdog
        join_any
        disable fork;                   // kill whichever thread lost
        reset_signals();                // park pins to safe default
      end
    endtask

    The key ideas: join_any returns the instant either thread finishes, reset asserts and the disable fork terminates the half-driven get_and_drive() thread, and reset_signals() drives all outputs back to their idle values (for example valid=0, wdata='x) so the DUT sees a clean interface. Without the parking step, a stale valid can get sampled on the first post-reset clock and inject a ghost transaction.

    Reset-aware driver: thread model Driver run_phase forever get_and_drive() stimulus thread @(negedge rst_n) reset watchdog join_any first thread wins disable fork then park pins CourseTron · coursetron.com
    The driver runs stimulus and a reset watchdog in parallel; join_any + disable fork let reset abort an in-flight item, then pins are parked.

    Reset-aware monitors and sequences

    Monitors need the same reset guard. A monitor should discard any partially-sampled transaction on reset rather than send it onward — otherwise your scoreboard sees a truncated packet and flags a false mismatch. Wrap the collection loop with the identical fork/join_any structure and, on reset, simply continue without calling analysis_port.write().

    Sequences deserve attention too. A sequence blocked in finish_item() when reset hits will hang unless the sequencer's items are flushed. Modern UVM gives you uvm_sequencer::stop_sequences() to clear the queue, but the cleaner approach is a top-level reset sequence that calls it, or a virtual sequence that uses p_sequencer to coordinate a graceful drain.

    Rule of thumb for on-the-fly reset: the number of transactions the scoreboard expects to complete must exactly match what survived reset. Count aborted items on both the driver and monitor side, or your end-of-test check will be off by the in-flight depth.

    Phase jumping: resetting the testbench, not just the pins

    Sometimes you want the whole environment to re-run its configuration — re-randomize registers, re-establish a link-training handshake — after a hard reset. That is what UVM phase jumps are for. From inside a phase you can call:

    phase.jump(uvm_pre_reset_phase::get());

    This rewinds the run-time phase schedule back to pre_reset, so the ordered reset / configure / main / shutdown phases execute again. Phase jumps are powerful but blunt: every component's runtime phase is affected, and objections must be managed carefully or the jump will not take. Use them for full environment restarts (think a DUT that re-enumerates on USB bus reset), and use the local driver/monitor fork pattern for routine mid-test resets. The two techniques solve different granularities of the same problem — a distinction worth rehearsing before an interview and covered in depth in our UVM phases explained guide.

    TechniqueScopeUse when
    fork/join_any + disable forkSingle component (driver/monitor)Routine mid-burst reset; stimulus resumes
    Reset sequence + stop_sequences()Sequencer + sequencesFlush queued items cleanly
    phase.jump(pre_reset)Whole run-time phase scheduleFull re-configuration / re-enumeration
    Separate reset agentDedicated reset driverProgrammable reset timing / randomized pulses
    Phase jump back to pre_reset pre_reset reset configure main shutdown phase.jump(uvm_pre_reset_phase::get()) rewinds the schedule: reset, configure, main, shutdown run again CourseTron · coursetron.com
    A phase jump rewinds the run-time schedule to pre_reset, so the ordered phases execute again.

    On-the-fly reset testing as a live signal

    The payoff of all this plumbing is the on-the-fly reset test: a background sequence that asserts reset at random, legal points during active traffic and verifies the DUT and testbench both recover. The animation below shows the essence — transactions streaming across the bus until a reset pulse arrives and flushes the pipeline back to idle.

    On-the-fly reset flushes the bus data bus rst_n active traffic idle after reset reset asserts: in-flight items dropped CourseTron · coursetron.com
    Live on-the-fly reset: packets stream until an asynchronous reset pulse fires, the in-flight items are dropped, and traffic restarts from idle. Built with SMIL — no JavaScript.

    Simulators treat this consistently across the big three — Synopsys VCS, Cadence Xcelium and Siemens Questa all support UVM 1.2/IEEE 1800.2 phasing and the disable fork semantics shown here — but watch for subtle differences in how each handles objection draining during a phase jump. If you are building these flows as part of structured training, our partners at ChipXpert VLSI training run hands-on reset-testing labs on exactly these three tools.

    Common pitfalls

    • Forgetting to park pins. A stale valid or req sampled on the first post-reset clock creates a ghost transaction.
    • Driving during reset. Some protocols (AXI, APB) require master outputs to be stable/idle while reset is low; driving live data violates the spec and can mask real bugs.
    • Scoreboard double-counting. If the monitor emits a partial item that reset also aborts in the DUT, expected and actual counts diverge.
    • Objection deadlock on phase jump. Raised objections not dropped before jump() stall the schedule.

    Want to build these components from scratch? CourseTron's Advanced UVM course has a full module on reset-aware agents, phase jumps and on-the-fly reset regressions, with graded labs on VCS and Questa. Explore it on our courses page.

    Frequently asked questions

    What is the difference between a reset-aware driver and a reset agent?

    A reset-aware driver guards its own stimulus loop against reset using fork/join_any so it can abort in-flight items. A reset agent is a separate UVM agent whose only job is to drive the reset signal itself, often with randomized pulse timing, so you can program when reset happens. Large environments use both.

    When should I use phase jumping instead of a local reset guard?

    Use a local fork/disable-fork guard for routine mid-test resets where stimulus simply resumes. Use phase.jump(pre_reset) when the whole environment must re-run its configuration — register programming, link training, or device re-enumeration — after a hard reset.

    How do I stop sequences hanging when reset hits?

    Call stop_sequences() on the affected sequencer (typically from a coordinating reset sequence or virtual sequence) to flush queued items, and make sure any sequence blocked in finish_item() has a reset-handling branch so it does not wait forever on an item reset has killed.

    Why does my scoreboard mismatch only on reset tests?

    Almost always an in-flight accounting error: the monitor emitted a partially-sampled transaction, or the driver's aborted item was counted as complete. Make both sides drop partial items on reset and reconcile the expected count against what actually finished.

    Reset handling ties together everything UVM teaches about object lifetime and phasing. Master it and you will debug far faster across the whole environment — and if your project needs a verified reset methodology built for you, Avecas design and verification services delivers reset-robust UVM environments for production silicon. For a deeper dive into the adjacent topic, read our UVM virtual sequencer guide.

    Advertisement