UVM-22: UVM Debug & Command Line — VLSI Trainers
VLSI Trainers UVM Series · UVM-22
UVM Series · UVM-22

UVM Debug & Command Line

The complete UVM built-in debug toolkit — print_topology, factory debug, TLM port connectivity checks, all the key plusargs, reading plusargs programmatically, and a structured debug checklist for the most common testbench failures.

📋 print_topology

print_topology() prints the complete component hierarchy — every component, its type, and its dot-path name. Called from end_of_elaboration_phase, it gives a snapshot of the fully-connected testbench before simulation starts.

// ── Print topology from end_of_elaboration_phase ──────────
function void end_of_elaboration_phase(uvm_phase phase);
  uvm_top.print_topology();
  // Or using a specific printer for tabular format:
  uvm_top.print_topology(new uvm_tree_printer());
endfunction

// ── Enable automatically without modifying source ─────────
// In testbench initial block:
uvm_top.enable_print_topology = 1;

// ── Sample output:
// -------------------------------------------------------
// Name                   Type                  Size  Value
// -------------------------------------------------------
// uvm_test_top           gpio_base_test         -     -
//   m_env                gpio_env               -     -
//     m_agent            gpio_agent             -     -
//       m_drv            gpio_driver            -     -
//       m_mon            gpio_monitor           -     -
//       m_seqr           gpio_sequencer         -     -
//     m_sb               gpio_scoreboard        -     -

Use print_topology to verify:

📋 Factory Debug

// ── Print all registered types and active overrides ───────
function void end_of_elaboration_phase(uvm_phase phase);
  uvm_factory::get().print(1);  // 1 = include overrides
endfunction

// ── Output shows: type registrations + override table
// #### Factory registered types (72 total): ####
// gpio_driver
// gpio_monitor
// ...
// #### Overrides registered: ####
// Type Overrides:
//   gpio_driver  →  fast_gpio_driver
// Instance Overrides:
//   uvm_test_top.env.agent.m_drv: gpio_driver → error_driver

// ── Debug what type would be created at a specific path ───
uvm_factory::get().debug_create_by_type(
  gpio_driver::get_type(),
  "uvm_test_top.m_env.m_agent",
  "m_drv");

// ── Verify a specific component's actual type ─────────────
// After build — print the type name of a created component
`uvm_info("TST", $sformatf("Driver type: %s",
  m_env.m_agent.m_drv.get_type_name()), UVM_LOW)

📋 TLM Port Debug

When analysis ports are not delivering transactions, debug_connected_to() and debug_provided_to() trace the full connection path from any port or export.

// ── Debug analysis port connections ───────────────────────
function void end_of_elaboration_phase(uvm_phase phase);
  // Show everything connected TO a port (downstream)
  m_env.m_agent.m_mon.ap.debug_connected_to();

  // Show what provides TO an export (upstream)
  m_env.m_sb.analysis_export.debug_provided_to();
endfunction

// ── Sample output from debug_connected_to:
// uvm_test_top.m_env.m_agent.m_mon.ap
// |
// +-- [via uvm_test_top.m_env.m_agent.ap]
// |   |
// |   +-- uvm_test_top.m_env.m_sb.analysis_export
// |   |
// |   +-- uvm_test_top.m_env.m_cov.analysis_export

// ── Quick check: is the port connected to anything? ───────
if (m_agent.ap.size() == 0)
  `uvm_warning("CHK", "Analysis port has no subscribers!")

📋 config_db Debug

// ── Dump all config_db entries of a given type ────────────
function void end_of_elaboration_phase(uvm_phase phase);
  uvm_config_db #(gpio_agent_cfg)::dump();
  uvm_config_db #(virtual apb_if)::dump();
endfunction

// ── Sample output:
// UVM_INFO @ 0: reporter [UVM/CFG/DB/DUMP]
// +--------------+--------------------------------+--------+
// |Scope         | Name                           | Value  |
// +--------------+--------------------------------+--------+
// |uvm_test_top.m_env.m_agent| cfg              | ...    |

// ── Command-line trace — every set() and get() logged ─────
// +UVM_CONFIG_DB_TRACE
// Shows: SET [scope] key=value and GET [scope] key → found/not found

// ── Programmatic check — does an entry exist? ─────────────
if (!uvm_config_db #(gpio_agent_cfg)::exists(
      this, "", "cfg"))
  `uvm_warning("CFG", "No agent config in db — check test build_phase")

📋 Plusargs Reference

All UVM-standard plusargs are passed on the simulator command line. They require no source code changes or recompilation:

PlusargEffect
+UVM_TESTNAME=my_testSelects which test class run_test() instantiates
+UVM_VERBOSITY=UVM_HIGHSets global verbosity for all components
+uvm_set_verbosity=path,id,level,phaseSets verbosity for a specific component path and optional ID/phase filter
+UVM_TIMEOUT=5ms,YESSets simulation timeout. YES overrides any programmatic set_timeout()
+UVM_MAX_QUIT_COUNT=20,YESSets max errors before stopping. YES overrides programmatic setting.
+UVM_OBJECTION_TRACELogs every raise and drop with component path and count — essential for hung sim debug
+UVM_PHASE_TRACELogs every phase transition — start, ready_to_end, complete
+UVM_CONFIG_DB_TRACELogs every config_db set() and get() with scope, name, and result
+uvm_set_type_override=Orig,SubApplies a factory type override at runtime — no source change
+uvm_set_inst_override=Orig,Sub,pathApplies a factory instance override at runtime
+uvm_set_config_int=path,name,valueSets an integer config_db value from command line
+uvm_set_config_string=path,name,valueSets a string config_db value from command line
+uvm_set_action=severity,id,actionOverrides report action for a severity+ID combination
+UVM_FACTORY_TRACELogs every factory create() call with the resolved type
+UVM_RESOURCE_DB_TRACELogs every resource_db operation (alternative to config_db trace)

📋 Reading Plusargs Programmatically

Tests and sequences can read custom plusargs from the command line using $value$plusargs or uvm_cmdline_processor. This allows test behaviour to be controlled from the simulator invocation without modifying source.

// ── SystemVerilog built-in plusarg reading ────────────────
int    num_txns  = 100;   // default
string test_mode = "normal";

// Read integer: vsim ... +num_txns=500
if ($value$plusargs("num_txns=%d", num_txns))
  `uvm_info("TEST", $sformatf("Running %0d transactions", num_txns), UVM_LOW)

// Read string: vsim ... +test_mode=stress
if ($value$plusargs("test_mode=%s", test_mode))
  `uvm_info("TEST", $sformatf("Mode: %s", test_mode), UVM_LOW)

// Check flag presence: vsim ... +enable_cov
if ($test$plusargs("enable_cov"))
  m_env_cfg.has_coverage = 1;

// ── UVM Command Line Processor (richer API) ───────────────
uvm_cmdline_processor clp = uvm_cmdline_processor::get_inst();
string vals[$];

// Get all plusarg values matching a pattern
int found = clp.get_arg_values("+num_txns=", vals);
if (found > 0)
  num_txns = vals[0].atoi();

// Check if a plusarg exists at all
if (clp.get_arg_matches("+UVM_VERBOSITY=", vals))
  `uvm_info("TEST", "Verbosity override from command line", UVM_LOW)

📋 Debug Checklist

A structured checklist for the most common UVM testbench failures:

SymptomFirst thing to checkTool / plusarg
Simulation hangs (run_phase never ends)Which component holds the last objection+UVM_OBJECTION_TRACE
Simulation ends immediately (no stimulus)Was raise_objection() ever called?+UVM_OBJECTION_TRACE
Wrong component type instantiatedWas factory override set before create()?uvm_factory::get().print(1)
config_db::get() returns 0Does the set() scope match the get() component path?+UVM_CONFIG_DB_TRACE
Virtual interface is null in driverWas set() called before run_test()?+UVM_CONFIG_DB_TRACE
Scoreboard never receives transactionsIs the analysis port connected?m_mon.ap.debug_connected_to()
Wrong component in hierarchyWas the correct child created in build_phase?uvm_top.print_topology()
Phase transition unexpectedWhich phase fired and when?+UVM_PHASE_TRACE
Component not built (passive when expected active)Is is_active set correctly in config?print_topology() + config_db dump
Spurious factory errorsIs the substitute type registered and extending original?uvm_factory::get().print(1)
Too much / too little outputWhat is the current verbosity per component?+UVM_VERBOSITY=UVM_HIGH
Test fails immediately on first errorIs max_quit_count too low?+UVM_MAX_QUIT_COUNT=50,YES

Recommended debug_phase pattern

// ── Add to base_test end_of_elaboration_phase ─────────────
function void end_of_elaboration_phase(uvm_phase phase);
  // 1. Verify component hierarchy
  uvm_top.print_topology();

  // 2. Verify factory registrations and overrides
  uvm_factory::get().print(1);

  // 3. Verify config_db entries for agent configs
  uvm_config_db #(gpio_agent_cfg)::dump();

  // 4. Verify analysis port connections
  m_env.m_agent.ap.debug_connected_to();
endfunction

// ── Controlled by a plusarg — off by default ──────────────
function void end_of_elaboration_phase(uvm_phase phase);
  if ($test$plusargs("UVM_DEBUG_TB")) begin
    uvm_top.print_topology();
    uvm_factory::get().print(1);
    uvm_config_db #(gpio_agent_cfg)::dump();
  end
endfunction
// Run with: vsim tb_top +UVM_DEBUG_TB

📋 Quick Reference

ToolWhat it showsWhen to use
uvm_top.print_topology()Full component hierarchy with typesVerify build phase completed correctly
uvm_factory::get().print(1)All registered types + active overridesVerify factory overrides were applied
port.debug_connected_to()Full downstream connection tree from a portVerify analysis port wiring
export.debug_provided_to()Full upstream connection to an exportTrace where an export’s data comes from
config_db #(T)::dump()All entries of type T in config_dbDebug config_db get() returning 0
config_db #(T)::exists(this,"","key")Boolean — does this key exist?Pre-check before calling get()
+UVM_TESTNAME=nameSelects test classSwitch tests without recompile
+UVM_VERBOSITY=UVM_HIGHGlobal verbosity levelIncrease detail for debug sessions
+UVM_OBJECTION_TRACEEvery raise/drop with component pathDiagnose hung simulations
+UVM_PHASE_TRACEEvery phase start/endDebug unexpected phase transitions
+UVM_CONFIG_DB_TRACEEvery set() and get() with scope and resultDebug config_db mismatches
+UVM_FACTORY_TRACEEvery factory create() with resolved typeVerify override is applied at create() time
+UVM_MAX_QUIT_COUNT=N,YESError threshold before stoppingCollect more errors before simulation ends
+uvm_set_type_override=O,SFactory type override at runtimeSwitch component variant without recompile
$value$plusargs("key=%d", var)Read custom plusarg value into variableParameterise tests from command line
Scroll to Top