Difficulty: Medium · Puzzle 1 of 6 · Topic: Factory Override Puzzles
Both type and instance overrides are configured. Predict concrete type for each create path.
class base_item extends uvm_sequence_item;
`uvm_object_utils(base_item)
function new(string name="base_item"); super.new(name); endfunction
endclass
class ecc_item extends base_item;
`uvm_object_utils(ecc_item)
function new(string name="ecc_item"); super.new(name); endfunction
endclass
class poison_item extends base_item;
`uvm_object_utils(poison_item)
function new(string name="poison_item"); super.new(name); endfunction
endclass
initial begin
base_item a, b;
base_item::type_id::set_type_override(ecc_item::get_type());
base_item::type_id::set_inst_override(
poison_item::get_type(),
"uvm_test_top.env.agentA.seqr.a"
);
a = base_item::type_id::create("a", null, "uvm_test_top.env.agentA.seqr");
b = base_item::type_id::create("b", null, "uvm_test_top.env.agentB.seqr");
$display("a=%s b=%s", a.get_type_name(), b.get_type_name());
endThe factory matches an instance override against the full path of the object being created, which is the context string plus `.` plus the object's name.
1) The full path for `a` is `uvm_test_top.env.agentA.seqr` + `.a` = `uvm_test_top.env.agentA.seqr.a`, which equals the registered instance path, so the instance override applies: `poison_item`.
2) The full path for `b` is `uvm_test_top.env.agentB.seqr.b`. No instance override matches it, so the factory falls back to the type override: `ecc_item`.
3) Instance overrides take precedence over type overrides whenever one matches, regardless of which was registered first.
4) Result prints `a=poison_item b=ecc_item`.Answer: Prints `a=poison_item b=ecc_item`: the instance override matches the full path `...agentA.seqr.a`, and an instance override beats the type override; `b` has no instance match and gets the type override.
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 instance path must match the full context.name path.
The instance path must include the leaf name: registering only `...agentA.seqr` (the parent context) matches nothing, because `create` matches against `{context}.{name}`, and the override is silently ignored, so `a` would fall back to `ecc_item`.
How would wildcard instance paths affect this result? Model answer: a path such as `uvm_test_top.env.agentA.seqr.*` would also match `a` (and every other name created under that context), so it would give `poison_item` for all of them. A path that stops at the parent, `...agentA.seqr`, matches nothing and `a` becomes `ecc_item`. (Based on UVM 1.2 documented factory behaviour.)
It prints a equals poison_item and b equals ecc_item. The instance override matches the full path for a, and an instance override beats a type override. The b object has no instance match, so it falls back to the type override. The trap is getting the full path wrong, so I would print the full names and check them against the registered path.