Part 3 · Factory & Configuration · Intermediate
Override Timing: Register Before create()
Correct build_phase ordering, too-late override anti-patterns, package-time overrides, and timeline diagrams for test/env build chains.
Golden ordering rule
Overrides affect only future create() calls. Register policy in test build_phase before super.build_phase() triggers env construction.
[FACTORY][UVM] build_phase timeline (correct)
err_test.build_phase
| apply_factory_overrides() <-- overrides registered
| super.build_phase()
| base_test.build_phase
| env = my_env::create()
| my_env.build_phase
| drv = base_driver::create() <-- override applied
| returns err_driverclass err_test extends base_test;
`uvm_component_utils(err_test)
function void build_phase(uvm_phase phase);
apply_factory_overrides();
super.build_phase(phase);
endfunction
virtual function void apply_factory_overrides();
base_driver::type_id::set_type_override(err_driver::get_type());
endfunction
endclassKey takeaways
Too-late overrides are the most common factory bug in real projects.
super.build_phase() usually starts the create chain — override before it.
Treat override registration as phase-0 of test build policy.
Common pitfalls
super.build_phase() first, override second — original type already built.
Override in connect_phase for components created in build_phase.
Assuming re-create will happen automatically after late override.
Too-late patterns and package-time policy
Some codebases register overrides in package initial blocks or env constructors — know trade-offs and visibility risks.
Too-late anti-pattern
function void build_phase(uvm_phase phase);
super.build_phase(phase); // env/agents/drivers already built
base_driver::type_id::set_type_override(err_driver::get_type());
// too late for drv created during super.build_phase
endfunction[FACTORY] too-late symptom signature
factory.print shows override active
BUT
get_type_name() reports base type for target instance
root cause:
create happened before override registrationEarly registration options
Test build_phase before super — preferred and explicit.
base_test::new or early static init — use only with clear docs.
Package init blocks — global blast radius, avoid in reusable VIP.
// Acceptable for global debug policy in dedicated debug package only
initial begin
base_monitor::type_id::set_type_override(verbose_monitor::get_type());
end[UVM][FACTORY] timing checklist
[ ] override registered
[ ] no target create before registration
[ ] super.build_phase after override setup
[ ] elaboration type names verifiedCommon pitfalls
Package-time global overrides leaking across unrelated tests.
Conditional overrides inside env based on plusargs after children built.
Factory set in run_phase expecting rebuild of hierarchy.