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 Foundations18
    • What Is UVM?
    • The UVM Class Library Map: Base Classes You Will Live In
    • Components vs Objects: Hierarchy, Lifetime, and Phases
    • Testbench Architecture and Environment Composition
    • Verification Plan Basics: Features, Goals, and Traceability
    • The Stimulus, Check, and Coverage Triangle
  • UVM Phases & Simulation Lifecycle94
  • Factory & Configuration37
  • Transaction-Level Modeling (TLM)42
  • UVM Sequences & Stimulus44
  • UVM Agents & Protocol VIP71
  • Environment & Test Classes55
  • Checking & Coverage in UVM37
  • UVM Register Abstraction Layer (RAL)53
  • Advanced UVM in Practice44
  • Debug & Regression10
  • Coding Practice47
  • Senior Prep: Architecture, Leadership and Interviews92
  • Verification in Industry Practice10
Loading lesson

‹UVM Foundations
  1. Topics
  2. UVM Verification
  3. UVM Foundations
  4. Components vs Objects: Hierarchy, Lifetime, and Phases

Part 1 · Foundations · Intermediate

Components vs Objects: Hierarchy, Lifetime, and Phases

The fundamental split between uvm_component (persistent, phased, tree-resident) and uvm_object (transient data that flows through the tree) — with constructors, lifetimes, and ownership rules.

On this page

    Two hierarchies, two lifetimes

    A UVM testbench is built from exactly two kinds of class. Components form a static tree that exists for the whole simulation: env, agent, driver, monitor, scoreboard, test. Objects are transient data — sequence_items, sequences, and configuration objects — that are created, passed around, and discarded while the components run.

    Diagram
    COMPONENTS (built once at build_phase, live for the whole sim)
      test
       └ env
          └ agent
             ├ driver      <-- a sequence_item OBJECT flows in here each transfer
             ├ monitor
             └ sequencer
    
    OBJECTS (created and destroyed constantly during run_phase)
      my_item #42  ->  my_item #43  ->  my_item #44  ->  ...  (transient)

    Side by side in code

    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
    // COMPONENT: has a parent, lives in the tree, participates in phases
    class my_driver extends uvm_driver #(my_item);
      `uvm_component_utils(my_driver)
      function new(string name, uvm_component parent);  // name + parent
        super.new(name, parent);
      endfunction
      task run_phase(uvm_phase phase);                  // phase callback
        forever begin
          seq_item_port.get_next_item(req);
          // drive req onto the pins ...
          seq_item_port.item_done();
        end
      endtask
    endclass
    
    // OBJECT: no parent, no phases, just data + randomization
    class my_item extends uvm_sequence_item;
      `uvm_object_utils(my_item)
      rand bit [31:0] addr;
      rand bit [31:0] data;
      rand bit        write;
      function new(string name = "my_item");            // name only
        super.new(name);
      endfunction
    endclass
    • Components: env, agent, driver, monitor, sequencer, scoreboard, subscriber, test.

    • Objects: sequence_items (transactions), sequences, config objects, register models.

    • Only components receive phase callbacks; objects are manipulated inside those callbacks.


    Lifetime and ownership

    Component lifetime

    A component is constructed exactly once during build_phase and persists until the simulation ends. Its parent owns it; its full hierarchical name (e.g. uvm_test_top.env.agt.drv) is fixed and is the key used by config_db and the factory.

    Object lifetime

    An object is created on demand, often thousands of times per test. SystemVerilog's automatic garbage collection reclaims it once no handle refers to it. Because objects are cheap and transient, you clone them rather than share a single handle when you need an independent copy.

    design.sv
    1
    2
    3
    4
    my_item original = my_item::type_id::create("original");
    my_item snapshot;
    original.randomize();
    $cast(snapshot, original.clone());   // deep copy — independent lifetime

    Choosing the right base class

    Use this decision rule whenever you create a new class:

    1. Does it have a fixed place in the testbench and need phases? → uvm_component.

    2. Is it data that flows between components or gets randomized? → uvm_object (usually uvm_sequence_item).

    3. Is it a knob bundle handed down via config_db? → uvm_object (a config class).

    Key takeaways

    • If it has a simulation lifecycle role and a tree position, it is a component.

    • If it is payload, configuration, or ephemeral algorithm state, it is an object.

    • Components are built once and live forever; objects are created and discarded constantly.

    Common pitfalls

    • Extending uvm_component for pure data bags — use uvm_object or a struct instead.

    • Storing component handles inside sequence_items without a clear ownership story, creating dangling references.

    • Sharing one sequence_item handle across consumers instead of cloning, so a later mutation corrupts earlier data.

    Previous

    15 / 658

    Next: Testbench Architecture and Environment Composition

    Up next

    Up nextTestbench Architecture and Environment Composition

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • What Is UVM?
    • The UVM Class Library Map: Base Classes You Will Live In
    • Verification Plan Basics: Features, Goals, and Traceability