Difficulty: Medium · Puzzle 5 of 6 · Topic: Factory Override Puzzles
Two env variants construct `agent` differently in `build_phase`. Which one honors test-level component override?
class agent extends uvm_component;
`uvm_component_utils(agent)
function new(string name, uvm_component parent); super.new(name, parent); endfunction
endclass
class agent_ext extends agent;
`uvm_component_utils(agent_ext)
function new(string name, uvm_component parent); super.new(name, parent); endfunction
endclass
class env_a extends uvm_env;
`uvm_component_utils(env_a)
agent agt;
function new(string name, uvm_component parent); super.new(name, parent); endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
agt = agent::type_id::create("agt", this);
endfunction
endclass
class env_b extends uvm_env;
`uvm_component_utils(env_b)
agent agt;
function new(string name, uvm_component parent); super.new(name, parent); endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
agt = new("agt", this);
endfunction
endclassComponent overrides require factory path; direct constructor call skips factory.
1) `env_a` uses `type_id::create`, so override `agent -> agent_ext` is honored.
2) `env_b` uses direct `new`, so override is bypassed.
3) Result: env_a gets `agent_ext`, env_b gets `agent`.Answer: Only `env_a` honors component override because it constructs through factory `create`.
Checked by running the code in Verilator 5; the printed output supports the answer above. A hand-written model of the documented UVM 1.2 factory rule (not the UVM library): create applies the override, a direct new never does.
Direct component `new` in build_phase is a frequent reason overrides 'mysteriously' do nothing; `env_b` also compiles and runs fine, so nothing flags it.
Would this differ for objects created in `run_phase` versus components in `build_phase`? Model answer: the override rule is the same for objects: `type_id::create` honours it at any time and `new` never does. The difference is timing: components must be created in `build_phase` (before the hierarchy is fixed) and overrides must already be registered then, whereas objects such as sequence items can be created and overridden any time during `run_phase`.
Only env_a honors the component override. It constructs the agent through the factory create call, so the override to agent_ext applies. The env_b component uses direct new, which bypasses the factory entirely, so it gets the plain agent. The trap is thinking an override affects every construction, so I would search for direct new calls on components.