Difficulty: Medium · Puzzle 3 of 6 · Topic: Parameterized Class Puzzles
A handle of a non-parameterized base holds an `agent#(int)`. Predict each `$cast` result and the final line.
class base_agent; endclass
class agent #(type T = int) extends base_agent;
T last;
endclass
initial begin
base_agent b;
agent#(int) ai, ai2;
agent#(byte) ab;
bit ok;
ai = new();
b = ai;
$display("to_byte=%0d", $cast(ab, b));
ok = $cast(ai2, b);
$display("to_int=%0d same=%0d", ok, (ai2 == ai));
b = new();
$display("plain_base_to_int=%0d", $cast(ai2, b));
end`$cast` checks the runtime object type. Each specialization is its own class, and they only share the non-parameterized parent.
1) `b` holds an `agent#(int)` object. `agent#(byte)` is a different class that merely shares the parent `base_agent`, so the cast to it fails: `to_byte=0`, and `ab` is not assigned.
2) The cast to `agent#(int)` matches the runtime type, so it succeeds and `ai2` holds the same object: `to_int=1 same=1`. The cast is a separate statement (`ok = $cast(ai2, b);`) because a `$display` that both performs the cast and reads `ai2` in its arguments depends on argument evaluation order, which the LRM does not define.
3) After `b = new()` the object is a plain `base_agent`, which is not an `agent#(int)`, so the cast fails: `plain_base_to_int=0`.
4) Used as a function, `$cast` returns 0 on failure and does not stop the run; as a task (`$cast(ai2, b);`) a failure is a runtime error.Answer: Prints `to_byte=0`, `to_int=1 same=1`, `plain_base_to_int=0`. A cast succeeds only to the exact specialization of the runtime object (or its parents); sibling specializations share a base but are unrelated to each other.
Checked by running the code in Verilator 5; the printed output supports the answer above. The shown code run in Verilator: $cast succeeds only to the exact specialization of the runtime object.
A common base lets you store both specializations in one handle type, but it does not make them interchangeable: casting to the wrong specialization fails at run time, not compile time.
Why is a `$cast` to `agent#(byte)` useless even though both are `agent`? Model answer: because `agent#(int)` and `agent#(byte)` are two unrelated classes with the same parent, so no object is ever both. If you need common behaviour, put it in virtual methods of `base_agent`, not in a cast.
It prints to_byte equals 0, to_int equals 1 with same equal to 1, and plain_base_to_int equals 0. A cast succeeds only to the exact specialization of the runtime object, or to its parents. The int and byte agents merely share a base and are unrelated to each other, and a plain base object is not an int agent. The trap is expecting a shared base to make siblings castable, so I would check the runtime type of the object.