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

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • Start Here4
  • UVM Foundations14
    • What Is UVM?
      • Why UVM Exists: History and Goals
      • What UVM Standardizes (and What You Own)
      • Components vs Objects: Hierarchy, Lifetime, and Phases
      • Objects That Copy, Compare and Print
      • The Stimulus, Check, and Coverage Triangle
      • Your First UVM Testbench
      • The DMA Bench: Full Source, Part 1
      • The DMA Bench: Full Source, Part 2
      • The DMA Bench: Full Source, Part 3
    • Testbench Architecture and Environment Composition
  • UVM Phases & Simulation Lifecycle26
  • Factory & Configuration15
  • Transaction-Level Modeling (TLM)13
  • UVM Sequences & Stimulus21
  • UVM Agents & Protocol VIP21
  • Environment & Test Classes11
  • Checking & Coverage in UVM21
  • UVM Register Abstraction Layer (RAL)22
  • Advanced UVM in Practice13
  • Debug & Regression10
  • Coding Practice47
  • Verification in Industry Practice10
  • Senior Prep: Architecture, Leadership and Interviews32
Loading lesson

‹What Is UVM?
  1. Topics
  2. UVM Verification
  3. UVM Foundations
  4. What Is UVM?
  5. Why UVM Exists: History and Goals

Part 1 · Foundations · Intermediate

Why UVM Exists: History and Goals

Why UVM exists: the OVM and VMM split, how Accellera and IEEE ended it, the three problems UVM solves in the DMA bench, and when it is overkill.

On this page

    The interviewer leans back and asks the warm-up question: why does UVM exist? Most candidates say "for reuse" and stop. The interviewer nods and asks the real question: reuse of what, by whom, and what did people do before? A one-word answer to a history question tells the interviewer you have used UVM but never thought about it. What is the two-minute answer that shows you have?

    The idea: one plug shape for verification IP

    Think of travel adapters. Before a standard socket, every country's appliances needed their own plug, and an appliance built for one market was useless in the next. Verification in the 2000s was the same. Each simulator vendor promoted its own class-based methodology (a base-class library plus rules for using it), and a piece of verification IP (VIP: a reusable agent, checker or model for a protocol such as AXI or PCIe) written for one methodology would not plug into a testbench built on another.

    UVM is the standard socket. It is a SystemVerilog base-class library and a set of conventions that every major simulator supports, so an AXI agent bought from one company plugs into a testbench written at another, and an engineer who moves teams recognises the same component names, phases and factory calls on day one. It does not replace SystemVerilog; every UVM testbench is SystemVerilog code that happens to extend the same base classes.

    The picture: how the camps merged

    Lineage diagram: eRM to URM to OVM, AVM to OVM, RVM to VMM, OVM to UVM with VMM ideas, then IEEE 1800.2.
    Two lineages: Cadence and Mentor's OVM, and Synopsys's VMM. Accellera built UVM on OVM and folded in VMM ideas; IEEE then standardised it.

    The dates that matter in an interview are few. Accellera's Verification IP Technical Subcommittee formed in 2008, chose OVM as the base, and released UVM 1.0EA in May 2010 and UVM 1.0 in February 2011. UVM 1.1d (2013) and UVM 1.2 (2014) followed and are still what many teams run. IEEE ratified the API as IEEE 1800.2 in 2017 and revised it in 2020. What changed between 1.2 and 1800.2, and how to write code that runs on both, is on UVM 1.2 vs IEEE 1800.2 at a glance.

    Build it: the three problems, seen in the DMA bench

    "Reuse" is really three separate problems, and the course's DMA bench shows a solution to each one. Naming all three is what separates a strong answer from a slogan.

    Problem

    What UVM provides

    Where you see it in the DMA bench

    Reuse across blocks and projects

    Agents that work active or passive, configured from outside

    One axis_agent class serves the input (active) and the output (passive)

    Scale across a team

    A fixed build and connect order, and standard TLM ports between components

    The env builds its agents and scoreboard, then wires monitors to scoreboard ports, with no ordering code of its own

    Intent separated from infrastructure

    The factory and config_db, so a test changes behaviour without editing the env

    dma_truncate_test swaps the stream driver for a fault-injecting one

    The third row is the one interviewers probe, because it is the least obvious. Here is the whole test that injects a short-packet fault into the DMA. Notice what it does not touch: the env, the agent, the sequence. It asks the factory to build a different driver class wherever an axis_driver would have been built, and then runs a normal job.

    design.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    // snippet: from the course DMA bench
    // Factory override: the stream driver cuts each packet short, so the DMA must
    // stop early and report ERR. No sequence or env file changes.
    class dma_truncate_test extends dma_base_test;
      `uvm_component_utils(dma_truncate_test)
    
      function new(string name, uvm_component parent);
        super.new(name, parent);
      endfunction
    
      function void build_phase(uvm_phase phase);
        axis_driver::type_id::set_type_override(axis_truncating_driver::get_type());
        super.build_phase(phase);                // the env is created after the override
      endfunction
    
      task run_phase(uvm_phase phase);
        dma_job_cfg job = dma_job_cfg::type_id::create("job");
        bit [31:0] status;
        phase.raise_objection(this);
        if (!job.randomize() with { len == 8; }) `uvm_fatal("RAND", "dma_job_cfg randomize failed")
        run_job(job, 8, status);
        if (status[2] !== 1'b1) `uvm_error("STATUS", $sformatf("ERR not set after a short packet: STATUS=%08h", status))
        else `uvm_info("TRUNC", "DMA reported ERR for the short packet, as expected", UVM_LOW)
        #100ns;
        phase.drop_objection(this);
      endtask
    endclass

    The override is registered before super.build_phase() builds the env, so when the agent later calls axis_driver::type_id::create, the factory returns an axis_truncating_driver instead. Without a factory, the same fault would need an if (inject_error) flag threaded through the driver, the agent and every test that does not want it.

    Watch it run

    From the course's run of the bench (Verilator with the open-source UVM library; times in ps):

    Diagram
    UVM_INFO dma_tb.sv(520) @ 275000: uvm_test_top.env.in_agt.drv [TRUNC] TLAST forced on beat 3
    UVM_INFO dma_tb.sv(761) @ 385000: uvm_test_top [TRUNC] DMA reported ERR for the short packet, as expected
    UVM_INFO dma_tb.sv(411) @ 485000: uvm_test_top.env.sb [SB] 4 words matched, 0 mismatched
    • The first line comes from uvm_test_top.env.in_agt.drv: the same instance path as always, now holding the overriding class. The env never knew.

    • The DMA reported ERR, which is what its spec promises for an early TLAST (The DMA you will verify).

    • The scoreboard matched the four words that did go through. Same scoreboard, same env, new scenario.

    What breaks: the bench that could not grow

    Here is the pattern UVM was invented to stop, as many teams lived it before 2010. A block bench is written as a module full of tasks: drive_packet(), check_output(), and sixty directed tests that call them in different orders. It works. Then the block goes into a subsystem, and the subsystem team needs the same checking with a different stimulus source; they copy the tasks and edit them. Then someone needs fault injection, and an inject_error argument is added to drive_packet(), which means editing all sixty tests to pass 0. A year later there are three diverging copies of the checker, and a bug fixed in one is still live in the other two.

    None of that is a skill problem; it is a structure problem. The fix is the structure UVM enforces: a driver that only drives, a monitor that only watches, a scoreboard fed by monitors, and a factory so that new behaviour arrives as a new class rather than a new flag. The cost is real (more files, more boilerplate, a learning curve), and for a tiny block with one engineer and no reuse, a plain SystemVerilog or cocotb bench can be the better choice. Saying so in an interview is a senior answer, not a heresy.

    Interview

    "Why UVM? What would you lose with a plain SystemVerilog testbench?"

    A weak answer: "UVM is the industry standard and it gives reuse." It repeats the question.

    A strong answer: "Before UVM, OVM and VMM VIP couldn't be shared, so UVM gave everyone one base library. In practice it solves three things: agents that work active at block level and passive at chip level, a fixed build and connect order so twenty people's components fit together, and the factory and config_db so a test changes behaviour without editing the env. What you lose with plain SV is mostly that third one; what you pay with UVM is boilerplate and ramp-up, so for a small one-off block I might not use it."

    Expect the follow-ups: Name something UVM took from VMM (the register layer's design is the usual example) and When would you not use UVM? (a small block with no reuse, a quick formal-friendly unit test, or a Python-first team using cocotb).

    Check yourself Your team's VIP vendor ships an AXI agent written for UVM 1.2. Your testbench uses a 1800.2 library. What is the risk, and where does it come from?

    The agent may use UVM 1.2 API that the 1800.2 standard removed, such as starting_phase or set_config_int. Whether it compiles depends on how much compatibility your library keeps. The risk comes from the 1.2 to 1800.2 transition, not from the OVM/VMM history: UVM itself is the shared base, but its versions differ in their edges.

    Check yourself A colleague says "UVM is just a SystemVerilog coding style." What is right and wrong about that?

    Right that UVM is not a language: every UVM testbench is SystemVerilog and compiles as SystemVerilog. Wrong that it is just a style: it is a class library with real machinery (phasing, the factory, config_db, TLM, objections, the register layer) that you call and extend, plus conventions that make independently written components fit together.

    Next: if UVM is a library plus conventions, where exactly does the library stop and your code begin? What UVM standardizes draws that line.

    Related topics

    • UVM 1.2 vs IEEE 1800.2

    • The factory

    • Bridge to UVM

    Previous

    5 / 280

    Next: What UVM Standardizes (and What You Own)

    Up next

    Up nextWhat UVM Standardizes (and What You Own)

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Components vs Objects: Hierarchy, Lifetime, and Phases
    • Objects That Copy, Compare and Print
    • The Stimulus, Check, and Coverage Triangle