Dave’s paper " The Yin and Yang of Object-Oriented Verification "
has a Section Type Compatibility Issues that explains assignment of handles of Parameterized Classes .
The paper however has sample with Type parameterized classes .
I am trying a variation of the code from paper with Value parameterized class .
class Base #( PARAM = 10 ) ;
endclass
class Subtype #( PARAM = 10 ) extends Base #( PARAM ) ;
endclass
Base # ( 10 ) b1 ; // 4 - State Signed parameter of Size 32 !!
Now via Objects of Specialization of Subtype ( handle s1 ) I use Upcasting i.e
b1 = s1 ;
[Q] What’s the Requirement on Value parameter during Specialization of Subtype for the Assignment to be Successful ?
Here are my Observations ::
// 1st Try
parameter int INTS = 10 ;
Subtype #( INTS ) s1 ; // 2 - state Signed parameter of Size 32 .
initial begin
s1 = new() ;
b1 = s1 ; // This is Successful !!
end
// 2nd Try
parameter int unsigned INTU = 10 ;
Subtype #( INTU ) s2 ; // 2 - state Unsigned parameter with Size N Range as [ 31 : 0 ] .
initial begin
s2 = new() ;
b1 = s2 ; // This is Unsuccessful !!
end
// 3rd Try
parameter bit signed [131:100] BIT = 10 ; // Range is different than 31:0 !!
Subtype #( BIT ) s3 ; // 2 - bit Signed parameter of Size 32
initial begin
s3 = new() ;
b1 = s3 ; // This is Successful !!
end
// 4th Try
parameter bit signed [15:0] BIT = 10 ;
Subtype #( BIT ) s4 ; // 2 - bit Signed parameter of Size 16
initial begin
s4 = new() ;
b1 = s4 ; // This is Unsuccessful !!
end
Based on O/P the value ( 10 ) must be same , the Size Must be same [ Range could be different ] ,
Value could 2 - state OR 4 - state ( it doesn't make a difference ) .
What does the LRM say about the rules governing assignment of Parameterized
class handles ? I am unable to find the same anywhere in LRM .
I believe you have found a few deficiencies in the LRM. I believe the intent is that class parameter overrides should work the same as module parameter overrides (See section 23.10 Overriding module parameters in the IEEE 1800-2017 SystemVerilog LRM.
That says overriding an untyped values parameter takes on the type of the final override.
Then section 8.25 say that a class specialization is defied by value parameter when both their type and their value are the same. But it really should to use the matching type rules in section 6.22.1 Matching types.
Unfortunately, I tried this on four different simulators on EDA playground and got four different results with the unsuccessful cases 2 &4.
You can avoid this ambiguity by declaring the base class perimeter with an explicit type.
Have another question about the suggestion to declare the base class value parameter with explicit type , int .
class Base #( int PARAM = 10 ) ; // ' PARAM ' would ALWAYS be int data type .
endclass
Base # ( 10 ) b1 ;
class Subtype #( PARAM = 10 ) extends Base #( PARAM ) ;
endclass
// Irrespective of Specialization for Subtype , Base :: PARAM would ALWAYS be int
Eg :: parameter logic [ 15:0 ] LOGIC_16 = 10 ;
Subtype #( LOGIC_16 ) s5 ;
// Subtype #( LOGIC_S16 ) :: PARAM is logic Unsigned parameter of Size 16
initial begin
s5 = new() ;
b1 = s5 ; // This is Successful but how ??
end
logic unsigned [15:0] ( Specialization of Subtype , s5 ) and int data type ( Specialization of Base , b1 ) are Not Matching types .
However Base #( 10 ) :: PARAM and BASE #( PARAM ) passed via Specialization of Subtype Class ( s5 ) are Matching Types as they are int data type ALWAYS .
The differences in simulator output means that they have a different
understanding of Specialization of Value parameterized class .
class BB #( VALUE = 0 ) ;
const static string t_name = get() ;
static function string get() ;
$display("TIME:%0t Specialization of BB#(%0d) found " , $time , VALUE );
return $sformatf("BB#(%0d)",VALUE) ;
endfunction
endclass
parameter int INT = 10 ;
BB #( INT ) b1 ;
parameter bit signed [31:0] BITS_31_0 = 10 ;
BB #( BITS_31_0 ) b2 ;
// b1 and b2 are Same Specialization , but Simulators do interpret both as different
parameter bit [31:0] BIT_31_0 = 10 ;
BB #( BIT_31_0 ) b3 ;
parameter bit signed [0:31] BITS_0_31 = 10 ;
BB #( BITS_0_31 ) b4 ;
This too gives different Output across Simulators which is an issue for a Value Parameterized class when trying to register in Factory !!
This would be an issue when running same UVM Code across simulators .
As you have mentioned the LRM should use “Matching Type” definition in section 8.25
class Base #( SIZE1 = 10 ) ;
endclass
// Base#(()::SIZE1 below is at default 10 ( 4- state signed type )
class Subtype #( SIZE2 = 1 ) extends Base ;
endclass
Base #(10) b1 ; // 4 - state signed parameter
Using the 4 assignments ( via different specialization of Subtype ) in Original Code ,
I observe all assignments are successful , even though the type parameter
( of handle b1 and Object handles s1 to s4 ) are Not Matching Types !!
parameter int INTS = 10 ;
Subtype #( INTS ) s1 ; // 2 - state Signed parameter of Size 32 .
initial begin
s1 = new() ;
b1 = s1 ;
end
parameter int unsigned INTU = 10 ;
Subtype #( INTU ) s2 ; // 2 - state Unsigned parameter with range [31:0]
initial begin
s2 = new() ;
b1 = s2 ;
end
parameter bit signed [131:100] BIT = 10 ; // Range is different than 31:0 !!
Subtype #( BIT ) s3 ; // 2 - bit Signed parameter of Size 32
initial begin
s3 = new() ;
b1 = s3 ;
end
parameter bit signed [15:0] BIT = 10 ;
Subtype #( BIT ) s4 ; // 2 - bit Signed parameter of Size 16
initial begin
s4 = new() ;
b1 = s4 ;
end
[Q] What makes all the 4 assignments legal in this case ??