Difficulty: Medium · Puzzle 4 of 6 · Topic: Parameterized Class Puzzles
Why does assigning `agent#(req_ext)` to `agent#(req_base)` fail even though `req_ext extends req_base`? Name the fix.
class req_base; endclass
class req_ext extends req_base; endclass
class agent #(type REQ_T = req_base);
REQ_T last_req;
endclass
initial begin
agent#(req_ext) a_ext = new();
agent#(req_base) a_base;
a_base = a_ext;
endEach specialization is its own class. Inheritance between the parameter values says nothing about the specializations.
1) `agent#(req_ext)` and `agent#(req_base)` are two distinct, unrelated classes; neither extends the other.
2) Subtyping of `req_ext` does not imply subtyping of the enclosing parameterized class (SystemVerilog has no covariance of type parameters).
3) The assignment is type-incompatible and fails at compile time; even `$cast` between them fails because they are unrelated.
4) Fix: give `agent` a non-parameterized base (`class agent_base; endclass`, `agent#(T) extends agent_base`) and store `agent_base` handles, or use the same specialization.Answer: Assignment fails at compile time because `agent#(req_ext)` and `agent#(req_base)` are unrelated classes; the parameter relationship does not carry over. Use a common non-parameterized base class.
Not run here: The expected result is a compile-time error, and the harness treats a failed compile as a failed run. Checked by hand: Verilator 5.048 rejects the assignment (an agent#(req_base) handle expects a CLASSREFDTYPE, got a different specialization).. The answer follows the language rules and the solution steps above.
Candidates transfer container covariance expectations from Java or C++ templates into SV/UVM. `$cast` cannot rescue it either, since neither class derives from the other.
What wrapper/interface pattern would you use if you need heterogeneous specialization storage? Model answer: a non-parameterized abstract base class (or interface class) exposing the operations as virtual methods; keep `agent_base` handles in the collection and `$cast` down to a specific `agent#(T)` only where the type is known.
The assignment fails at compile time. The two agent specializations are distinct, unrelated classes, and SystemVerilog has no covariance across type parameters, so extending the parameter does not make the agent a subtype. The trap is assuming the parameter relationship carries over. I would give agent a non-parameterized base and store handles of that base type.