Difficulty: Hard · Puzzle 4 of 6 · Topic: Factory Override Puzzles
A wildcard instance override and an exact instance override both match the path of `a0`. Predict the types of `a0` and `a1`.
class base_item extends uvm_object;
`uvm_object_utils(base_item)
function new(string name="base_item"); super.new(name); endfunction
endclass
class dbg_item extends base_item;
`uvm_object_utils(dbg_item)
function new(string name="dbg_item"); super.new(name); endfunction
endclass
class perf_item extends base_item;
`uvm_object_utils(perf_item)
function new(string name="perf_item"); super.new(name); endfunction
endclass
initial begin
base_item a0, a1;
// registered first: wildcard
base_item::type_id::set_inst_override(
perf_item::get_type(),
"uvm_test_top.env.agent*.seqr.*"
);
// registered second: exact
base_item::type_id::set_inst_override(
dbg_item::get_type(),
"uvm_test_top.env.agent0.seqr.a0"
);
a0 = base_item::type_id::create("a0", null, "uvm_test_top.env.agent0.seqr");
a1 = base_item::type_id::create("a1", null, "uvm_test_top.env.agent1.seqr");
$display("a0=%s a1=%s", a0.get_type_name(), a1.get_type_name());
endCount how many overrides match `a0`'s full path, then recall how the factory chooses among several matching instance overrides.
1) The full path of `a0` is `uvm_test_top.env.agent0.seqr.a0`. It matches both the wildcard (`agent*`, `.*`) and the exact entry. `a1` (`...agent1.seqr.a1`) matches only the wildcard.
2) UVM does not rank overrides by specificity. Matching instance overrides for a type are checked in registration order and the first match is used.
3) The wildcard was registered first, so `a0` gets `perf_item`; the exact entry is shadowed and never used.
4) `a1` gets `perf_item` as well. Result: `a0=perf_item a1=perf_item`.
5) To make the exact entry win, register it before the wildcard.Answer: Prints `a0=perf_item a1=perf_item`. There is no specificity ranking: the first registered matching instance override wins, and the wildcard was registered first, shadowing the exact `dbg_item` entry.
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): the first matching instance override wins, so registration order decides.
"Exact beats wildcard" is a common but false mental model carried over from CSS or routing tables. The factory only sees an ordered list, so a broad wildcard registered early quietly hides every later, more specific override.
How would you debug this at runtime using factory print/debug APIs? Model answer: call `uvm_factory::get().print(1)` (or `factory.print()` in a test) to list the instance override table in order, and `factory.debug_create_by_type(base_item::get_type(), "uvm_test_top.env.agent0.seqr", "a0")` to print which override matched for that path; then reorder the registrations or tighten the wildcard.
Both a0 and a1 are perf_item. UVM does not rank overrides by specificity, and the first registered matching instance override wins. The wildcard was registered first, so it shadows the exact entry for a0. The trap is expecting the most specific path to win, and the fix is to register the exact entry before the wildcard.