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 Here6
  • SystemVerilog Language Foundations28
  • Object-Oriented SystemVerilog for Verification30
  • Constraint Randomization — Interview-Critical Deep Dive36
  • SystemVerilog Assertions — Interview-Critical Deep Dive40
  • Functional Coverage in SystemVerilog22
  • Testbench Architecture in SystemVerilog23
    • Testbench Anatomy & Layering
    • Stimulus: Generators, Transactions & Drivers
    • Monitors, Scoreboards & Reference Models
    • Self-Checking Tests & Regression
    • From Hand-Built TB to UVM
      • Concept Mapping: TB to UVM
      • What UVM Automates (and What It Costs)
      • Migrating a TB to UVM
  • Advanced Language & Integration25
  • Senior & Interview Preparation21
  • Principal-Level Verification28
Loading lesson

‹From Hand-Built TB to UVM
  1. Topics
  2. SystemVerilog
  3. Testbench Architecture in SystemVerilog
  4. From Hand-Built TB to UVM
  5. What UVM Automates (and What It Costs)

Part 6 · Testbench Architecture · Intermediate

What UVM Automates (and What It Costs)

Phasing, factory, config db, reporting, and TLM — hand-built versions vs the UVM call, and the costs of the framework.

On this page

    Five automations in one table

    Each piece of UVM automation replaces code that teams otherwise write and debug by hand. The last column points at the UVM course, which owns the full teaching of each mechanism.

    Automation

    Hand-built version

    UVM call

    UVM course

    Phasing

    Constructor, connect, and run ordered by hand

    Phases run in order for every component

    Phase overview

    Factory

    Case statement swapping driver types

    set_type_override_by_type in the test

    Factory overview

    Config

    Config object threaded through constructors

    uvm_config_db::set and get by path

    Config db

    Reporting

    Logger class with levels and scopes

    uvm_info with verbosity and id filtering

    Reporting and verbosity

    TLM

    One mailbox per consumer, wired by hand

    ap.write(t) broadcasts to subscribers

    Analysis ports

    A logger in both worlds

    A verbosity-filtered logger is the smallest pair that shows the trade. The hand-built version is a few lines that the team fully controls.

    The UVM half below is not run in this course's checks because it needs the UVM library, which the course's simulators here do not have.

    design.sv
    // not-run: fragment that needs the UVM library, which is not installed for the course runner
    `uvm_info("DRV", "txn sent", UVM_MEDIUM)
    if (!uvm_config_db#(int)::get(this, "", "verbosity", verbosity)) verbosity = 1;

    Testbench

    The plain half below runs under Icarus and proves the same idea: levels filter lines, and flagged lines are counted.

    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
    module tb_log_demo;
      int verbosity;
      int shown;
      int flagged;
    
      task log_line(int level, int code);
        if (level <= verbosity) begin
          shown = shown + 1;
          $display("LOG level=%0d code=%0d", level, code);
          if (code >= 100) flagged = flagged + 1;
        end
      endtask
    
      initial begin
        verbosity = 2; shown = 0; flagged = 0;
        log_line(1, 1);    // shown
        log_line(2, 2);    // shown
        log_line(3, 3);    // hidden: level 3 is above verbosity 2
        log_line(1, 100);  // shown and flagged
        log_line(2, 101);  // shown and flagged
        if (shown == 4 && flagged == 2)
          $display("PASS: verbosity 2 showed 4 of 5 lines and flagged 2");
        else
          $fatal(1, "FAIL: shown=%0d flagged=%0d", shown, flagged);
        $finish;
      end
    endmodule

    The price tag

    None of the automation is free. The costs are worth naming precisely, because “UVM is heavy” is too vague to act on.

    • Learning curve: phasing semantics, factory registration, config db match rules, and sequence arbitration each take study before a newcomer is productive.

    • Debug opacity: a trace through factory creation and phase callbacks is far longer than new() and a mailbox, and a missing config db set fails at run time where a constructor argument would fail at compile time.

    • Boilerplate: registration macros and phase signatures add ceremony to every class, even trivial ones.

    • Bring-up weight: for a small block with one agent, the framework can cost more engineer time than the hand-built equivalent.

    Project shape

    Hand-built testbench

    UVM

    One block, one agent, short-lived

    Fastest bring-up

    Framework overhead dominates

    Multi-agent SoC env, long-lived, many tests

    Wiring and reuse pain grows

    Factory, config db, and sequences pay off

    Team of 1-2

    Full control

    High ramp cost

    Team of 10 or more, VIP reuse

    Everyone reinvents wheels

    Shared vocabulary, plug-in VIP

    Rule of thumb: the more agents, tests, engineers, and years a testbench must serve, the better UVM amortizes its costs.

    A hand-built testbench stays the right call for a small short-lived block with no VIP reuse and a team that cannot absorb the ramp. Keep the layered structure from this part, and a later migration stays mechanical.

    Common mistakes

    Common pitfall

    Two opposite errors recur: adopting UVM for a two-week block testbench, where the ramp outlasts the project, and hand-wiring a multi-agent multi-year environment, where reuse pain compounds. Match the framework to the project shape, not to dogma.

    Interview

    Likely questions: “What is the factory for, concretely?” — swap driver or transaction types from the test without touching the env, replacing a hand-maintained case statement. “When would you skip UVM?” — small short-lived block, no VIP reuse, unfamiliar team, tight schedule.

    Check yourself An environment builds its drivers with new() instead of the factory. What does the team pay, and what does it lose?

    It pays the UVM ceremony and loses the override benefit: no test can substitute types without editing the environment. Either use the factory everywhere or skip UVM for the block.

    Check yourself A uvm_config_db::get misses and fails silently at run time. What would the hand-built equivalent have done?

    A missing constructor argument fails at compile time. That shift from compile-time to run-time errors is the debug-opacity cost, so check every get result and centralize path strings.

    Related topics

    • Factory overview

    • Config db

    Previous

    184 / 259

    Next: Migrating a TB to UVM

    Up next

    Up nextMigrating a TB to UVM

    Sign in to save progress

    Practice this lessonReport an error