Issue with calling this.randomize function

Please refer to the below code.


class A;
 rand  bit[3:0] j;  
  function new();
    this.randomize();
  endfunction
  
endclass
class C;
endclass

class B extends A;
 rand   bit [7:0] x;
// rand   C c1; 

endclass

module top();
  
  B b;
  A a; 
  initial begin
    b=new();
    
    $display(" b %p ",b);
  end
endmodule 


Output

b '{j:'h9, x:'h6c}

Understanding is if this.randomize() is called it will randomize the variable inside the class A only, but what’s been observed is it’s randomizing the variable of class B also.

Is this an issue or understanding is incorrect?

From section 8.7 of the LRM:

If a class does not provide an explicit user-defined new method, an implicit new method shall be provided automatically. The new method of a derived class shall first call its base class constructor [super.new() as described in 8.15]. After the base class constructor call (if any) has completed, each property defined in the class shall be initialized to its explicit default value or its uninitialized value if no default is provided. After the properties are initialized, the remaining code in a user-defined constructor shall be evaluated. The default constructor has no additional effect after the property initialization. The value of a property prior to its initialization shall be undefined.

Since no new() method is provided, the base class constructor (from “A”) will be called (randomize call), and then all variables defined in “B” will be initialized to their default or uninitialized values (‘x’ set to 0).

Three of the four tools on EDA playground follow the LRM. One does not, which is the one you are using. You need to contact the tool vendor for additional support regarding this discrepancy.

In reply to cgales:

I think the question here is about behaviour of “this.randomize” of class A.
this.randomize of class A is randomizing the variable of class B.

From where you call “this.randomize” does not matter here as per my trials. Whether you call this.randomize from “new” or any other place it is still randomizing the variable of class B.

In reply to dharamvir:

randomize() is a built-in virtual method of a class, but it is being called inside the constructor.

The latest IEEE 1800-2017 SystemVerilog LRM recently clarified the behavior of a virtual methods calls from within the chain of base class constructors. The virtual method called will be the same as if the call was not from the constructor, however, variable initializations other than the default initial value will not have occured.

class A;
  rand  bit[7:0] j;  
  function new();
    assert(randomize());
  endfunction
endclass
class C;
endclass
 
class B extends A;
  rand   bit [7:0] w,x=2; // initialization of x happens after calling randomize()
  constraint c { j == x;}
endclass
 
module top();
  B b;
  initial begin
    b=new();
    $display(" b %p ",b);
  end
endmodule 

In reply to dave_59:

Please refer the below code


class A;
 rand  bit[3:0] j;  
  
 virtual function my_function();
    this.randomize();
  endfunction 
  
  virtual function build();
    my_function();
  endfunction

endclass
 
class B extends A;
 rand   bit [7:0] x;
  
  virtual function build();
    super.build();
  endfunction
   
endclass
 
module top();
 
  B b;
  initial begin
    b=new();
    b.build();
    $display(" b %p",b);
  end
endmodule 

Output

vsim -voptargs=+acc=npr

run -all

b '{j:9, x:35}

exit

In this code,though we are calling only the build function which is internally calling this.randomize(); of class A,still, the variable of class B is getting randomized. My understanding is “this” should have a scope of only class A and should not have access to class B variables.

In reply to advaneharshal:

randomize() is a built-in virtual method of every class. The object that “this” refere to is an object of class B. It’s the same as if you had also defined B::my_function

class A;
  rand  bit[3:0] j;  
 
  virtual function void my_function();
    $display("in A::my_function");
    assert(this.randomize());
  endfunction 
 
  virtual function void build();
    this.my_function();
  endfunction
 
endclass
 
class B extends A;
  rand   bit [7:0]  x;
  virtual function void build();
    super.build();
  endfunction
  virtual function void my_function();
    $display("in B::my_function");
    assert(this.randomize());
  endfunction 
endclass
 
module top();
 
  B b;
  initial begin
    b=new();
    b.build();
    $display(" b %p",b);
  end
endmodule