Specializing a parameterized class by a parameter of it's containing class

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

Can someone tell me what am I doing wrong?

Thanks!
Or.

In reply to orlevi:

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.

In reply to dave_59:

Thanks for the prompt answer!

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.

Thanks again!