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.
// CORRECT — factory-aware, overrideable
drv = apb_driver::type_id::create("drv", this);
// WRONG — override cannot replace this instance
drv = new("drv", this);[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 consistencyKey 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
// 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"
);[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
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();
endfunctionPrint 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.
[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.