Difficulty: Easy · Puzzle 4 of 6 · Topic: UVM Phases and Objections
UVM 1.2. base_env builds its agent in build_phase. my_env extends it, overrides build_phase to add a scoreboard, and forgets `super.build_phase(phase)`. Where does it fail and why?
class base_env extends uvm_env;
`uvm_component_utils(base_env)
my_agent agent;
function new(string name, uvm_component parent); super.new(name, parent); endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
agent = my_agent::type_id::create("agent", this);
endfunction
endclass
class my_env extends base_env;
`uvm_component_utils(my_env)
my_sb sb;
function new(string name, uvm_component parent); super.new(name, parent); endfunction
function void build_phase(uvm_phase phase);
sb = my_sb::type_id::create("sb", this); // no super.build_phase(phase)
endfunction
function void connect_phase(uvm_phase phase);
agent.mon.ap.connect(sb.exp_imp);
endfunction
endclassWhich build_phase creates `agent`, and is it called at all?
1) my_env.build_phase overrides base_env.build_phase completely; without super.build_phase the base's body never runs.
2) So `agent` is never created and stays null.
3) Nothing complains during build. The failure is a null-handle dereference at the first use, in my_env.connect_phase (`agent.mon`), at time 0.
4) Fix: call super.build_phase(phase) first (and in every derived build_phase; it also runs the UVM base build_phase work).Answer: agent is never created (null); the null dereference shows up in my_env.connect_phase at time 0, not in build.
Checked by running the code in Verilator 5; the printed output supports the answer above. Hand-written model of the documented UVM 1.2 behaviour in plain SystemVerilog (Verilator), not the UVM library: a base class that builds in build(); the derived override without super leaves the base's child null.
The error is reported where `agent` is used (connect_phase, a different phase and function from the cause) and it is a simulator null-object error, not a UVM message, so the log never mentions build_phase or super.
Is it enough to move the `agent` creation into my_env.build_phase instead? Model answer: it would work for this one class, but any other class deriving from base_env would repeat the problem, and skipping super.build_phase also skips uvm_component's own build_phase work (in UVM 1.2 that is where automatic configuration of `uvm_field_*` fields from uvm_config_db is applied), so always call super.