Part 2 · Phases & Lifecycle · Intermediate

Factory Create Pattern: type_id::create() and Overrides

Canonical factory usage in build_phase — create vs new, override types, instance overrides, and audit patterns.

create() vs new()

UVM components must be created with type_id::create() so the factory can substitute types. Direct new() bypasses the entire override mechanism.

systemverilog
// CORRECT — factory-aware, overrideable
drv = apb_driver::type_id::create("drv", this);

// WRONG — override cannot replace this instance
drv = new("drv", this);
diagram
[PHASE][UVM] factory decision tree

Need a uvm_component child?
  YES  type_id::create(name, parent)
  NO   plain SV class? use new() only for non-uvm objects

Need test-time substitution?
  YES  factory create + override before create()
  NO   still use create() for consistency

Key takeaways

  • type_id::create() is mandatory for all uvm_component children.

  • Overrides affect only future create() calls, never already-built objects.

  • Log active overrides at test start for regression auditability.

Common pitfalls

  • Mixing new() and create() in the same hierarchy — partial override coverage.

  • set_inst_override with wrong instance path — silent no-match.

  • Global set_type_override leaking across unrelated tests in the same sim.


Override patterns in build_phase

Choose override scope deliberately: type-wide for broad swaps, instance-specific for surgical substitutions.

Type vs instance override

systemverilog
// type override — all future apb_driver creates
apb_driver::type_id::set_type_override(debug_apb_driver::get_type());

// instance override — one specific path only
apb_driver::type_id::set_inst_override_by_type(
  debug_apb_driver::get_type(),
  "uvm_test_top.env.agt_tx.drv"
);
diagram
[PHASE][UVM] override scope ladder

global type override      all creates of that type (use sparingly)
instance override         one path (preferred for scenario tests)
set_inst_override_by_name  string path (error-prone, audit carefully)

Factory audit snippet

systemverilog
function void report_factory_state();
  uvm_factory f = uvm_factory::get();
  f.print(1);
endfunction

function void build_phase(uvm_phase phase);
  apply_factory_overrides();
  super.build_phase(phase);
  report_factory_state();
endfunction
  • Print factory state once per test after all overrides registered.

  • Keep override registration in one virtual method per test base.

  • Document override intent in the reason string or test metadata.

diagram
[PHASE] override debug checklist

- override registered before target create()?
- instance path matches get_full_name() of target?
- expected substituted type appears in topology print?
- only one override owner per target path?

Common pitfalls

  • Applying overrides in connect_phase — components already constructed.

  • Duplicate overrides from base_test and child_test on same instance.

  • Using string class names instead of ::get_type() handles.