Verification

UVM phases

By CourseTron Team ·  7 min read ·  Updated Oct 2026 💬 𝕏 in f
Table of Contents
    🖨  Download / Print this guide (PDF)

    In short: uvm phases are the ordered, callback-driven steps every UVM component executes so that a testbench is built, connected, and run in a predictable sequence across all components. The build/connect/end_of_elaboration phases construct and wire the hierarchy top-down, while the time-consuming run phase simulates the stimulus and uses objections to decide when the test ends.

    What Is uvm phases?

    In the Universal Verification Methodology, uvm phases are a fixed set of synchronization points that the simulator walks through for every component derived from uvm_component. Instead of each engineer inventing their own order for building objects, wiring ports, and launching stimulus, UVM defines a common schedule. The base class library calls virtual methods such as build_phase(), connect_phase(), and run_phase() on your components at exactly the right moment, so a monitor, driver, and scoreboard written by three different people still assemble and start in a coherent way.

    Phases fall into two families. Function phases consume zero simulation time and execute top-down or bottom-up through the hierarchy. The run phase is a task that consumes simulation time and runs all components in parallel. This separation is what lets UVM guarantee that nothing starts driving pins before the entire environment has been built and connected.

    The Common Phases and Their Order

    UVM ships a pre-defined list of common phases, invoked in this order:

    1. build_phase — constructs child components and configures them. Runs top-down so a parent can set config_db values a child reads during its own build.
    2. connect_phase — binds TLM ports, exports, and analysis connections. Runs bottom-up, because children must exist and expose their ports before a parent can connect them.
    3. end_of_elaboration_phase — the last chance to adjust the now-complete hierarchy, print the topology, or check configuration. Runs bottom-up; no more construction should happen here.
    4. start_of_simulation_phase — a bottom-up hook for printing banners or initial register state just before time advances.
    5. run_phase — the single time-consuming task where drivers, monitors, and sequencers do their work in parallel.
    6. extract / check / report / final — bottom-up function phases that pull results out of the scoreboard, compare them, report pass/fail, and clean up.

    Because build_phase is top-down, the environment is created before its agents, and agents before their drivers. The direction flips for connect_phase so the leaves are ready to be wired into their parents.

    Build goes down, connect goes upbuild_phase: top-downenvironmentagentdriverconnect_phase: bottom-upenvironmentagentdriverParent is built before child, so it can set config_db values.Children expose ports first, then parents wire them.CourseTron · coursetron.com
    Direction of build_phase (parent before child) versus connect_phase (child before parent) through environment, agent and driver.
    Key fact: build_phase runs top-down (parent before child) while connect_phase and every post-run cleanup phase run bottom-up (child before parent). Getting this direction wrong is the single most common cause of null-handle crashes in a new UVM environment.
    UVM phase execution orderbuild_phasetop-downconnect_phasebottom-upend_of_elaborationbottom-upstart_of_simulationbottom-uprun_phase (task)consumes timeextract / checkbottom-upreport / finalbottom-upFunction phases take zero time; run_phase is the one task that consumes it.CourseTron · coursetron.com
    UVM phases in the order they are invoked, with the direction each walks the hierarchy.

    Why Phasing Matters

    Without a shared schedule, verification components would race each other. A driver might try to get a transaction from a sequencer that has not been constructed yet, or a scoreboard's analysis export might be null when a monitor tries to write to it. Phasing removes those races by contract: every component is guaranteed to be fully built and connected before any of them begins driving stimulus.

    Phasing also makes reuse possible. A verification IP block dropped into a new project behaves identically because the integrator cannot accidentally change when its internals come to life. The methodology, not the user, owns the ordering.

    Objections and Ending the Test

    Only the run phase (and the optional run-time sub-phases) can consume simulation time, which raises the question: how does UVM know when to stop? The answer is objections. A component that needs the simulation to keep running calls phase.raise_objection(this) at the start of its activity and phase.drop_objection(this) when finished. The run phase continues as long as at least one objection is outstanding; when the count returns to zero, UVM ends the phase and advances to extract/check/report.

    Typically a sequence or the top-level test raises an objection before starting stimulus and drops it after the last transaction drains. A set_drain_time() can hold the phase open briefly so trailing responses are captured. Forgetting to raise an objection makes a test finish at time zero; forgetting to drop one makes it hang until the timeout.

    Objections keep run_phase openTest / sequenceraise_objectionrun_phasestays openextract / checkreport / finalOutstanding objectionsCount above zero: run_phase continues. Back to zero: the phase ends.No objection raised: test ends at time zero. Never dropped: it hangs.CourseTron · coursetron.com
    The test raises an objection, run_phase runs while any objection is outstanding, and extract/check/report follows when the count returns to zero.

    Runtime Sub-Phases and Custom Phases

    Alongside the single run_phase, UVM defines twelve finer-grained runtime phases that run in parallel schedules: reset, configure, main, and shutdown, each with pre_ and post_ variants. These let teams coordinate activity, for example keeping a reset driver in the reset phase while register configuration waits for the configure phase. In practice many teams use only run_phase for simplicity and reserve the sub-phases for complex, multi-interface environments. Engineers can also define custom phases and domains to synchronize independent clock or power domains.

    Learn this hands-on

    Real projects and industry tool flows, with certification.

    Explore CourseTron Courses →

    uvm phases — Interview FAQ

    Which UVM phases consume simulation time?

    Only the run phase and its runtime sub-phases (reset, configure, main, shutdown and their pre_/post_ variants) are tasks that consume time. All other phases — build, connect, end_of_elaboration, start_of_simulation, extract, check, report, and final — are functions that execute in zero time.

    Why does build_phase run top-down but connect_phase bottom-up?

    Construction must flow from parent to child so a parent can create its children and pass configuration down before the child builds. Connection flows the other way because a parent can only bind to ports and exports that its children have already created, so the children must be fully built first.

    What happens if no component raises an objection in run_phase?

    The run phase ends immediately at time zero because UVM sees nothing keeping it alive. The simulation jumps straight to the extract/check/report phases, usually producing an empty or failing test. You raise an objection to hold the phase open and drop it when your stimulus is complete.

    Can you add work after the hierarchy is built but before time advances?

    Yes. end_of_elaboration_phase is the correct place to inspect or lightly adjust the completed topology and print it, and start_of_simulation_phase is where you print initial state or banners just before the run phase begins. Neither should construct new components.

    Related: UVM testbench architecture · the VLSI Glossary · all courses.

    Advertisement