Part 5 · Sequences · Intermediate
Factory Library Overrides: set_type_override_by_type
Swap library candidates via factory without editing the library, per-test stress variants, and override scope.
Why factory overrides on libraries
A sequence library hard-codes candidate types at compile time. When a regression needs a stress variant of one candidate — longer bursts, more errors, different constraints — editing the library affects every test. The UVM factory lets you replace a registered type with a derived type in
test build_phase via set_type_override_by_type, so the library still calls axi_rand_burst_seq::get_type() but UVM constructs axi_stress_burst_seq instead.
[UVM] factory indirection
library selects: axi_rand_burst_seq::get_type()
│
│ factory lookup
▼
set_type_override registered?
YES → construct axi_stress_burst_seq (derived, same interface)
NO → construct axi_rand_burst_seq (original)Stress variant and override
// Derived stress variant — same base, aggressive knobs
class axi_stress_burst_seq extends axi_rand_burst_seq;
`uvm_object_utils(axi_stress_burst_seq)
function new(string name = "axi_stress_burst_seq");
super.new(name);
num_bursts = 50;
allow_errors = 1;
endfunction
constraint stress_len {
burst_len dist { 7 := 60, 15 := 40 }; // longer bursts
}
endclass
// In test build_phase — swap without touching axi_seq_lib source
class test_axi_stress_lib extends uvm_test;
function void build_phase(uvm_phase phase);
super.build_phase(phase);
set_type_override_by_type(
axi_rand_burst_seq::get_type(),
axi_stress_burst_seq::get_type()
);
endfunction
task run_phase(uvm_phase phase);
axi_seq_lib lib = axi_seq_lib::type_id::create("lib");
lib.selection_mode = UVM_SEQ_LIB_RAND;
phase.raise_objection(this);
lib.start(env.axi_agent.sqr); // when lib picks burst, gets stress variant
phase.drop_objection(this);
endtask
endclassOverride is by type, not instance — every create() of axi_rand_burst_seq gets stress.
Derived class must be factory-registered (`uvm_object_utils) and compatible interface.
set in build_phase before env constructs sequences that might create the type.
Override scope and per-test control
Factory overrides can be global or instance-scoped. For libraries, type-level override is the common case:
// Global type override — entire test hierarchy
set_type_override_by_type(
axi_rand_burst_seq::get_type(),
axi_stress_burst_seq::get_type()
);
// Instance override — only this env's sequences (when using create_by_type with parent)
set_inst_override_by_type(
env.axi_agent.sqr,
axi_rand_burst_seq::get_type(),
axi_stress_burst_seq::get_type()
);Walkthrough — library pick with override active
Legend: [STIM] [SEQ] [UVM]
T0 test build_phase: set_type_override_by_type(burst → stress_burst)
T1 test run_phase: lib.start(axi_sqr)
T2 library random pick: axi_rand_burst_seq::get_type()
T3 [UVM] factory: override hit → type_id::create returns axi_stress_burst_seq
T4 stress_burst.body(): num_bursts=50, long burst_len dist
T5 send_beat × hundreds → driver busy → regression stress achieved
T6 next pick might be axi_error_inj_seq — no override, original runsOnly the overridden type is swapped. Other library candidates run unchanged — targeted stress without a separate library class.
Integration patterns
One library, many tests: default test uses stock types; stress test sets override in build_phase.
Plusarg-gated override: if ($test$plusargs("STRESS")) set_type_override… in build_phase.
Override error_inj_seq with directed_err_seq for bug-hunt without new library registration.
Print factory overrides at UVM_MEDIUM in build_phase — confirms which test variant is active.
function void build_phase(uvm_phase phase);
super.build_phase(phase);
if ($test$plusargs("AXI_STRESS")) begin
set_type_override_by_type(
axi_rand_burst_seq::get_type(),
axi_stress_burst_seq::get_type()
);
`uvm_info("TEST", "factory: burst → stress_burst override active", UVM_LOW)
end
endfunctionKey takeaways
set_type_override_by_type swaps library candidates without editing library source.
Derived stress variants extend original — same start() interface, different constraints.
Override in build_phase; plusarg gate for regression matrix from one test binary.
Common pitfalls
Override target not factory-registered — create returns wrong type or fatal.
Stress subclass breaks base send_beat contract — override buys bugs, not stress.
set_type_override after sequences already created — too late, instances already built.
Forgetting override is test-local — global override in package pollutes other tests.