Correct interpretation of extended class with different parameter than base class?

Hi,

I recently stumbled upon the following code:

class A #(parameter X = 2) extends B #(.X(1));

It seems that different vendor simulators interpret this piece of code different.

  • Is it allowed to specify a different value for the parameter in the child class than in the parent class?
  • If so, what should be the resulting used value in the child code and in the parent code?

Thanks,

Bas

In reply to basarts:

It would help to show a complete example and what different interpretations you are seeing from you you were expecting.

Note that I think you have declared two different parameters X. When you declare A::X, it hides B::X from direct access.

module top;
  
  class B #(parameter X = 2) ;
    function new;
      $display("B::X: %d",X);
    endfunction
  endclass
  class A #(parameter X = 2) extends B #(.X(1));
    function new;
      $display("A::X: %d B::X: %d",X,B::X);
    endfunction
  endclass
  
  A#(3) a = new;
  
endmodule

# B::X:           1
# A::X:           3 B::X:           1

In reply to dave_59:

Thanks for the example Dave!

With simulator 1, I can reproduce your results. Simulator 2 warns about the usage of B::X in the display function within class A, expecting a class specialization of #(). Moreover, simulator 2 returns the output

B::X:           1
A::X:           3 B::X:           2

I also checked the results using

A a = new;

In that case, simulator 1 returns

B::X:           1
A::X:           2 B::X:           1

while simulator 2 returns

B::X:           1
A::X:           2 B::X:           2

I cannot find a clear explanation in the LRM what the expected output should be in this case.

In reply to basarts:

OK, now I see the problem is with the reference to
B::X
using the scope operator :: in class A. The IEEE 1800-2017 SystemVerilog LRM section 8.25.1 Class scope resolution operator for parameterized classes says that reference is illegal without an explicit parameterization. Serves me right for not testing my code first. The $display arguments needs to be written as

      $display("A::X: %d B::X: %d",X,B#(.X(1))::X);

You are probably getting different results because some tools are not trapping the error or just producing a warning and giving unpredictable results.

In reply to dave_59:

Thanks Dave! I’m going to file a ticket somewhere :-)