Hi. I encountered this problem while trying to achieve something in OVM, but I think my question can be narrowed to this case:
I would like to parameterize an object by a parameter of the object containing it:
class A#(int AA = 0);
function new();
$display("A=%0d", AA);
endfunction
endclass
class B#(type T = int, int BB = 0);
T#(BB) t1 = new();
T#(BB+1) t2 = new();
endclass
program d;
B#(A,5) c1 = new();
B#(A,8) c2 = new();
initial
begin
$display("thats it.");
end
endprogram
I thought this code should produce this output:
A=5
A=6
A=8
A=9
thats it.
But in fact I’m getting:
A=0
A=0
A=0
A=0
thats it.
which I guess is related to the warnings I get:
Warning-[TMPO] Too many parameter overrides
The extra parameter overrides will be ignored.
Source info: t1
The code you have written is not legal, you should have gotten a compiler error. The problem is there is no way in SystemVerilog to reference a generic parameterized class and later specialize it with a parameter override. As soon as you reference the generic class name A, it becomes a parameterized class with the default parameter values.
When you wrote
B#(A,5) c1 = new();
B#(A,8) c2 = new();
It is implicitly
B#(A#(),5) c1 = new();
B#(A#(),8) c2 = new();
And then the T in the class B expands to
A#()#(BB) t1 = new();
A#()#(BB+1) t2 = new();
It is very unfortunate the SystemVerilog chose to allow A to meanA#() instead of requiring the empty #().
If you need a workaround, I’ll have to know more about how you want to use the parameters.
Your answer makes much sense (though it really is unfortunate that SystemVerilog does work like that).
I guess I’ll just try to dance around this kind of behavior.