Constrained randomization in SystemVerilog

Constrained randomization

As the name says random variable will get random value on randomization. In some situations it is required to control the values getting assigned on randomization, this can be achieved by writing constraints. By writing constraints to a random variable, the user can get specific value on randomization. constraints to a random variable shall be written in constraint blocks.

Constraint blocks

  • Constraint blocks are class members like tasks, functions, and variables
  • Constraint blocks will have a unique name within a class
  • Constraint blocks consist of conditions or expressions to limit or control the values for a random variable
  • Constraint blocks are enclosed within curly braces { }
  • Constraint blocks can be defined inside the class or outside the class like extern methods, constraint block defined outside the class is called as extern constraint block

Constraint block syntax

constraint <constraint_block_name> { <condition/expression>; 
                                              ...
                                    <condition/expression>; }

Constraint block examples

constraint addr_range { addr > 5; }

where, addr_range is constraint block name
addr is constrained in such a way that on randomization addr will get a value greater than 5.

Constraint block inside the class

In the below example,
constraint block is defined inside the class.

class packet;
  rand  bit [3:0] addr;

  constraint addr_range { addr > 5; }
endclass

module constr_blocks;
  initial begin
    packet pkt;
    pkt = new();
   repeat(10) begin
      pkt.randomize();
      $display("\taddr = %0d",pkt.addr);
    end
  end
endmodule

Simulator Output

addr = 14
addr = 10
addr = 9
addr = 8
addr = 9
addr = 6
addr = 10
addr = 14
addr = 12
addr = 8

Click to execute on   

Constraint block outside the class

In the below example,
constraint block is declared inside the class and defined outside the class.

class packet;

  rand  bit [3:0] addr;
  //constraint block declaration
  constraint addr_range;
endclass

//constraint implementation outside class body
constraint packet::addr_range { addr > 5; }

module extern_constr;
  initial begin
    packet pkt;
    pkt = new();

    repeat(10) begin
      pkt.randomize();
      $display("\taddr = %0d",pkt.addr);
    end
  end
endmodule

Simulator Output

addr = 14
addr = 10
addr = 9
addr = 8
addr = 9
addr = 6
addr = 10
addr = 14
addr = 12
addr = 8

Click to execute on   

Constraint Inheritance

Like class members, constraints also will get inherited from parent class to child class. Constraint blocks can be overridden by writing constraint block with the same name as in parent class.

In the example below,
Constraint to an addr > 5 of the parent class is overridden with constraint addr < 5 in child class.

class packet;
  rand  bit [3:0] addr;
  constraint addr_range { addr > 5; }
endclass

class packet2 extends packet;
  constraint addr_range { addr < 5; } //overriding constraint of parent class
endclass

module const_inhe;
  initial begin
    packet pkt1;
    packet2 pkt2;

    pkt1 = new();
    pkt2 = new();

    $display("------------------------------------");
    repeat(5) begin
      pkt1.randomize();
      $display("\tpkt1:: addr = %0d",pkt1.addr);
    end

    $display("------------------------------------"); 
    repeat(5) begin
      pkt2.randomize();
      $display("\tpkt2:: addr = %0d",pkt2.addr);
    end
    $display("------------------------------------");
  end
endmodule

Simulator Output

------------------------------------
pkt1:: addr = 14
pkt1:: addr = 10
pkt1:: addr = 9
pkt1:: addr = 8
pkt1:: addr = 9
------------------------------------
pkt2:: addr = 0
pkt2:: addr = 1
pkt2:: addr = 2
pkt2:: addr = 0
pkt2:: addr = 2
------------------------------------

Click to execute on   

❮ Previous Next ❯

SystemVeilog Randomization Methods

Randomization Methods

SystemVerilog randomization provides a built-in method randomize. The randomize() method generates random values for all the active random variables of an object, subject to the active constraints. Variables declared with the rand keyword will get random values on the object.randomize() method call.The randomize() method returns 1 if the randomization is successful i.e on randomization it’s able to assign random values to all the random variables, otherwise, it returns 0.

randomize method associated with below callbacks,

  • pre_randomize
  • post_randomize

pre randomize and post randomize methods

  • On calling randomize(), pre_randomize() and post_randomize() functions will get called before and after the randomize call respectively
  • Users can override the pre_randomize() and post_randomize() functions

pre_randomize

the pre_randomize function can be used to set pre-conditions before the object randomization.

For example, Users can implement randomization control logic in pre_randomize function. i.e randomization enable or disable by using rand_mode() method.

post_randomize

the post_randomization function can be used to check and perform post-conditions after the object randomization.

For example, Users can override the randomized values or can print the randomized values of variables.

randomization method examples

Implementing pre and post randomize methods

In the below example,
pre and post randomized methods are implemented in the class, on calling obj.randomize() pre and post will get called.

class packet;
  rand  bit [7:0] addr;
  randc bit [7:0] data;   
  
  //pre randomization function
  function void pre_randomize();
    $display("Inside pre_randomize");
  endfunction
  
  //post randomization function
  function void post_randomize();
    $display("Inside post_randomize");
    $display("value of addr = %0d, data = %0d",addr,data);
  endfunction
endclass

module rand_methods;
  initial begin
    packet pkt;
    pkt = new();
    pkt.randomize();
  end
endmodule

Simulator Output

Inside pre_randomize
Inside post_randomize
value of addr = 110, data = 129

Click to execute on   

randomization control from pre_randomize method

In the example below,
Paket has two variables, addr, and wr_rd.

assuming wr_rd = 0 read operation.
wr_rd = 1 write operation.

In order to perform write followed by reading to the same addr, randomization of addr is controlled based on the previous randomization value of wr_rd. this controlling is done in pre_randomize() function.

//class
class packet;
  rand  bit [7:0] addr;
  randc bit       wr_rd;
        bit       tmp_wr_rd;     

  //pre randomization function - disabling randomization of addr,
  //if the prevoius operation is write.
  function void pre_randomize();
    if(tmp_wr_rd==1) addr.rand_mode(0);
    else                 addr.rand_mode(1);
  endfunction

  //post randomization function - store the wr_rd value to tmp_wr_rd
  //and display randomized values of addr and wr_rd
  function void post_randomize();
    tmp_wr_rd = wr_rd;
    $display("POST_RANDOMIZATION:: Addr = %0h,wr_rd = %0h",addr,wr_rd);
  endfunction
endclass

module rand_methods;
  initial begin
    packet pkt;
    pkt = new();

    repeat(4) pkt.randomize();
  end
endmodule

Simulator Output

POST_RANDOMIZATION:: Addr = 6e,wr_rd = 1
POST_RANDOMIZATION:: Addr = 6e,wr_rd = 0
POST_RANDOMIZATION:: Addr = 88,wr_rd = 1
POST_RANDOMIZATION:: Addr = 88,wr_rd = 0

Click to execute on   

❮ Previous Next ❯

Systemverilog Disable Randomization

Disable randomization

The variable declared without rand or randc will not get random values on randomization. what if for some reason it is required not to generate a random value for a random variable. Yes, it is possible to disable the randomization of a variable by using the systemverilog randomization method rand_mode.

rand_mode method

The rand_mode() method is used to disable the randomization of a variable declared with the rand/randc keyword.

  • rand_mode(1) means randomization enabled
  • rand_mode(0) means randomization disabled
  • The default value of rand_mode is 1, i.e enabled
  • Once the randomization is disabled, it is required to make rand_mode(1) enable back the randomization
  • rand_mode can be called as SystemVerilog method, the randomization enables/disable status of a variable can be obtained by calling vairble.rand_mode().
  • the rand_mode method returns 1 if randomization is enabled else returns 0

rand_mode syntax

<object_hanlde>.<variable_name>.rand_mode(enable);
//enable = 1, randomization enable
//enable = 0, randomization disable

randomization disable examples

without randomization disable

In the below example,
The class packet has random variables addr and data, on randomization, these variables will get random value.

class packet;
  rand byte addr;
  rand byte data;   
endclass

module rand_methods;
  initial begin
    packet pkt;
    pkt = new();
    
    //calling randomize method
    pkt.randomize();
    
    $display("\taddr = %0d \t data = %0d",pkt.addr,pkt.data);
  end
endmodule

Simulator Output

addr = 110 data = 116

Click to execute on   

randomization disable for a class variable

In the below example,
The class packet has random variables addr and data, randomization is disabled for a variable addr, on randomization only data will get random value. The addr will not get any random value.
rand_mode() method is called in a display to know the status.

class packet;
  rand byte addr;
  rand byte data;   
endclass

module rand_methods;
  initial begin
    packet pkt;
    pkt = new();
    
    //disable rand_mode of addr variable of pkt
    pkt.addr.rand_mode(0);
    
    //calling randomize method
    pkt.randomize();
    
    $display("\taddr = %0d \t data = %0d",pkt.addr,pkt.data);
    
    $display("\taddr.rand_mode() = %0d \t data.rand_mode() = %0d",pkt.addr.rand_mode(),pkt.data.rand_mode());
  end
endmodule

Simulator Output

addr = 0 data = 110
addr.rand_mode() = 0 data.rand_mode() = 1

Click to execute on   

randomization disable for all class variable

In the below example,
randomization for all the class variable is disabled by calling obj.rand_mode(0);

class packet;
  rand byte addr;
  rand byte data;   
endclass

module rand_methods;
  initial begin
    packet pkt;
    pkt = new();
    
    $display("\taddr.rand_mode() = %0d \t data.rand_mode() = %0d",pkt.addr.rand_mode(),pkt.data.rand_mode());
    
    //disable rand_mode of object
    pkt.rand_mode(0);
    
    //calling randomize method
    pkt.randomize();
    
    $display("\taddr = %0d \t data = %0d",pkt.addr,pkt.data);
    
    $display("\taddr.rand_mode() = %0d \t data.rand_mode() = %0d",pkt.addr.rand_mode(),pkt.data.rand_mode());
  end
endmodule

Simulator Output

addr.rand_mode() = 1 data.rand_mode() = 1
addr = 0 data = 0
addr.rand_mode() = 0 data.rand_mode() = 0

Click to execute on   

❮ Previous Next ❯

SystemVerilog Randomization

randomization in SystemVerilog

Randomization is the process of making something random; SystemVerilog randomization is the process of generating random values to a variable. Verilog has a $random method for generating the random integer values. This is good for randomizing the variables alone, but it is hard to use in case of class object randomization. for easy randomization of class properties, SystemVerilog provides rand keyword and randomize() method.

random variables

The class variables which get random values on randomization are called random variables. In order to make variables as random variables, Class variables need to be declared using the rand and randc type-modifier keywords.

Following types can be declared as rand and randc,

  • singular variables of any integral type
  • arrays
  • arrays size
  • object handle’s

rand keyword

Variables declared with the rand keyword are standard random variables. Their values are uniformly distributed over their range.

rand bit [3:0] addr;

addr is a 4-bit unsigned integer with a range of 0 to 15. on randomization this variable shall be assigned any value in the range 0 to 15 with equal probability.

randc keyword

randc is random-cyclic. For the variables declared with the randc keyword, on randomization variable values don’t repeat a random value until every possible value has been assigned.

randc bit wr_rd;

In order to randomize the object variables, the user needs to call randomize() method.

example:

object.randomize();

randomization example

In the example below,
Two variables addr1 and addr2 of same bit type are declared as rand and randc respectively, observe the randomized values of addr1 and addr2.

addr1 – takes the random value on every randomization
addr2 – takes the random value on every randomization, but takes random value until every possible value has been assigned

//class
class packet;
  rand  bit [2:0] addr1;
  randc bit [2:0] addr2; 
endclass

module rand_methods;
  initial begin
    packet pkt;
    pkt = new();
    repeat(10) begin
      pkt.randomize();
      $display("\taddr1 = %0d \t addr2 = %0d",pkt.addr1,pkt.addr2);
    end
  end
endmodule

Simulator Output

addr1 = 6 addr2 = 4
addr1 = 4 addr2 = 3
addr1 = 2 addr2 = 0
addr1 = 6 addr2 = 6
addr1 = 1 addr2 = 7
addr1 = 3 addr2 = 5
addr1 = 7 addr2 = 1
addr1 = 6 addr2 = 2
addr1 = 4 addr2 = 7
addr1 = 4 addr2 = 6

Click to execute on   

❮ Previous Next ❯

SystemVerilog Classes Extern Methods

SystemVerilog External Methods

If the definition of the method written outside the body of the class then the method is called an external method.

  • external function. The definition of the function written outside the class body is referred to as an external function
  • external task. The definition of the task written outside the class body is referred to as an external task
  • to do this, need to declare the method (Function/Task) with an externkeyword in the class body along with
    • any qualifiers (local, protected or virtual)
    • full argument list
  • The extern qualifier indicates that the body of the method (its implementation) is to be found outside the class declaration
  • Before the method name, the class name should be specified with a class resolution operator to specify to which class the method corresponds to.

Note:

  • Number of arguments, arguments name and argument type should match between method declaration and method definition

External function example

In the example below,
The function display is declared inside the class with the extern keyword, and the definition of the function is written outside the class.

//class with extern function
class packet;
  bit [31:0] addr;
  bit [31:0] data;

  //function declaration - extern indicates out-of-body declaration
  extern virtual function void display();
endclass

//function implementation outside class body
function void packet::display();
  $display("Addr = %0d Data = %0d",addr,data);
endfunction
  
module extern_method;
  initial begin
    packet p;
    p = new();
    p.addr = 10;
    p.data = 20;
    p.display();
  end
endmodule

Simulator Output

Addr = 10 Data = 20

Click to execute on

External task example

In the example below,
The task display is declared inside the class with the extern keyword, and the definition of the task is written outside the class.

//class with extern function
class packet;
  bit [31:0] addr;
  bit [31:0] data;

  //task declaration - extern indicates out-of-body declaration
  extern virtual task display();
endclass

//task implementation outside class body
task packet::display();
  $display("Addr = %0d Data = %0d",addr,data);
endtask
  
module extern_method;
  initial begin
    packet p;
    p = new();
    p.addr = 10;
    p.data = 20;
    p.display();
  end
endmodule

Simulator Output

Addr = 10 Data = 20

Click to execute on

External function with arguments

In the below examples,
an external function is declared and defined with arguments.

arguments name mismatch

Change in argument name between method declaration and method definition will lead to a compilation error.

class packet;
  
  //function declaration - extern indicates out-of-body declaration
  extern virtual function void display(bit [31:0] addr, data );
endclass

   //function implementation outside class body
    function void packet::display(bit [31:0] addr_t, data_t);
      $display("Addr = %0d Data = %0d",addr_t,data_t);
    endfunction
    
module extern_method;
  initial begin
    packet p;
    p = new();
    p.display(20,30); 
  end
endmodule

Simulator Output

Error-[ECMDSMPD] Mismatched method definition
testbench.sv, 11
External class method definition should match prototype declaration.
Argument names do not match. The signature of function 'packet::display'
should match the corresponding prototype declaration at: "testbench.sv", 7.

Click to execute on

arguments name match

class packet;
  
  //function declaration - extern indicates out-of-body declaration
  extern virtual function void display(bit [31:0] addr, data );
endclass

   //function implementation outside class body
    function void packet::display(bit [31:0] addr, data);
      $display("Addr = %0d Data = %0d",addr,data);
    endfunction
    
module extern_method;
  initial begin
    packet p;
    p = new();
    p.display(20,30); 
  end
endmodule

Simulator Output

Addr = 20 Data = 30

Click to execute on

❮ Previous Next ❯

SystemVerilog Scope Resolution Operator ::

Scope Resolution Operator ::

The class scope operator :: is used to specify an identifier defined within the scope of a class.

  • Classes and other scopes can have the same identifiers
  • The scope resolution operator uniquely identifies a member of a particular class

Class Resolution operator allows access to static members (class properties and methods) from outside the class, as well as access to public or protected elements of super classes from within the derived classes.

Scope resolution operator example

In the Below example,
A static member of the class is accessed outside the class by using class resolution operator ::

//class
class packet;
         bit [31:0] addr;
  static bit [31:0] id;

  function display(bit [31:0] a,b);
    $display("Values are %0d %0d",a,b);
  endfunction
endclass

module sro_class;
  int id=10;
  initial begin
    packet p;
    p = new();
    packet::id = 20;
    p.display(packet::id,id);
  end
endmodule

Simulator Output

Values are 20 10

Click to execute on

❮ Previous Next ❯

SystemVerilog Virtual Method

Virtual Methods in SystemVerilog

SystemVerilog Methods declared with the keyword virtual are referred to as virtual methods.

Virtual Methods,

  • Virtual Functions
  • Virtual Tasks

Virtual Functions

A function declared with a virtual keyword before the function keyword is referred to as virtual Function

Virtual Task

Task declared with a virtual keyword before the task keyword is referred to as virtual task

About Virtual Method

In a virtual method,
If the base_class handle is referring to the extended class, then the extended class method handle will get assigned to the base class handle.

In the below explanation, extended_class is an extended class of base_class.

base_class     b_c;
extended_class e_c;

Considering both the class’s has the method display().

assigning e_c to b_c,

b_c = e_c;

On calling b_c.display()

  • if display() method in base_class is virtual, then extended class display method will get called
  • if display() method in base_class is non-virtual, then base class display method will get called

Virtual function syntax

virtual function function_name;
  
  //Function definition
endfunction

Virtual task syntax

virtual task task_name;
  //task definition
endtask

Virtual Method Examples

Method without virtual keyword

In the below example,
the method inside the base class is declared without a virtual keyword, on calling method of the base class which is pointing to the extended class will call the base class method.

class base_class;
  
  function void display;
    $display("Inside base_class");
  endfunction
  
endclass
 
class extended_class extends base_class;
  
  function void display;
    $display("Inside extended class");
  endfunction
  
endclass

module virtual_class;
  initial begin
    base_class     b_c;
    extended_class e_c;
    
    e_c = new();
    b_c = e_c;
    
    b_c.display();
  end
endmodule

Simulator Output

Inside base_class

Click to execute on

A method with virtual keyword

In the below example,
the method inside the base class is declared with a virtual keyword, on calling method of the base class which is pointing to an extended class will call the extended class method.

class base_class;
  
  virtual function void display;
    $display("Inside base_class");
  endfunction
  
endclass
 
class extended_class extends base_class;
  
  function void display;
    $display("Inside extended_class");
  endfunction
  
endclass
 
module virtual_class;
  initial begin
    base_class     b_c;
    extended_class e_c;
    
    e_c = new();
    b_c = e_c;
    
    b_c.display();
  end
endmodule

Simulator Output

Inside extended_class

Click to execute on

❮ Previous Next ❯

Abstract Class in SystemVerilog

Abstract Class

SystemVerilog class declared with the keyword virtual is referred to as an abstract class.

  • An abstract class sets out the prototype for the sub-classes.
  • An abstract class cannot be instantiated, it can only be derived.
  • An abstract class can contain methods for which there are only a prototype and no implementation, just a method declaration.
Abstract Class SystemVerilog
Abstract Class SystemVerilog

Abstract class Syntax

virtual class abc;
  //Class defination
endclass

Abstract Class Examples

Instantiating virtual class

In the below example, Creating an object of a virtual class. An abstract class can only be derived, creating an object of a virtual class leads to a compilation error.

//abstract class
virtual class packet;
  bit [31:0] addr;
endclass
module virtual_class;
  initial begin
    packet p;
    p = new();
  end
endmodule

Simulator Output

virtual_class, "p = new();"
Instantiation of the object 'p' can not be done because its type 'packet' is
an abstract base class.
Perhaps there is a derived class that should be used.

Click to execute on

Deriving virtual class

In the below example, An abstract class is derived and written extend the class and creating it.

//abstract class
virtual class packet;
  bit [31:0] addr;
endclass
 
class extended_packet extends packet;
  function void display;
    $display("Value of addr is %0d", addr);
  endfunction
endclass
 
module virtual_class;
  initial begin
    extended_packet p;
    p = new();
    p.addr = 10;
    p.display();
  end
endmodule

Simulator Output

Value of addr is 10

Click to execute on ❮ Previous Next ❯

SystemVerilog Casting

Casting

In Manufacturing, Casting is a process in which liquid metal is converted into the desired object. Similarly, SystemVerilog casting means the conversion of one data type to another datatype.  During value or variable assignment to a variable, it is required to assign value or variable of the same data type. Some situations need assignment of different data type, in such situations, it is necessary to convert data type and assign. Otherwise, the assignment of different data type results in a compilation error. The method of data type conversion is called casting.
In systemVerilog, there are two types of casting,

  • Static casting
  • Dynamic casting

Static casting

  • SystemVerilog static casting is not applicable to OOP
  • Static casting converts one data type to another compatible data types  (example string to int)
  • As the name says ‘Static’, the conversion data type is fixed
  • Static casting will be checked during compilation, so there won’t be run-time checking and error reporting
  • Casting is applicable to value, variable or to an expression
  • A data type can be changed by using a cast ( ‘ ) operation
  • The vale/variable/expression to be cast must be enclosed in parentheses or within concatenation or replication braces

Static casting example

In the below example,
the real type is converted into int type. i.e multiplication of two real numbers results in real value, the result is converted into int and then assigned to a variable of int type.
Note: the casting is applied to expression here.

module casting;
  
  real r_a;
  int  i_a;
  
  initial begin
    
    r_a = (2.1 * 3.2);
    
    //real to integer conversion
    i_a = int'(2.1 * 3.2); //or i_a = int'(r_a);
    
    $display("real value is %f",r_a);
    $display("int  value is %d",i_a);
  end
endmodule

Simulator Output

real value is 6.720000
int  value is           7

Click to execute on

Dynamic casting

  • Dynamic casting is used to, safely cast a super-class pointer (reference) into a subclass pointer (reference) in a class hierarchy
  • Dynamic casting will be checked during run time, an attempt to cast an object to an incompatible object will result in a run-time error
  • Dynamic casting is done using the $cast(destination, source) method
  • With $cast compatibility of the assignment will not be checked during compile time, it will be checked during run-time

Let’s see how we can use the casting,

It is always legal to assign a child class variable to a variable of a class higher in the inheritance tree (parent class).
parent_class = child_class; //allowed

It is never legal to directly assign a super-class (parent class) variable to a variable of one of its subclasses (child class).
 child_class  = parent_class; //not-allowed

However, it is legal to assign a super-class (parent class) handle to a subclass (child class) variable if the super-class (parent class) handle refers to an object of the given subclass(child class).
parent_class = child_class ;
child_class  = parent_class; //allowed because parent_class is pointing to child_class.

Though parent_class is pointing to the child_class, we will get a compilation error saying its not compatible type for the assignment.

This we can over come by make use of $cast method, i.e,

$cast(child_class,parent_class);

Why is it called as dynamic casting?

In the above parent class assignment with child class example. type of parent class is changing dynamically i.e on declaration it is of parent class type, on child class assignment it is of child class type.
Parent class handle during $cast execution is considered for the assignment, so it referred to as dynamic casting.

Dynamic Casting examples

assigning child class handle to parent class handle

class parent_class;
  bit [31:0] addr;
  function display();
    $display("Addr = %0d",addr);
  endfunction
endclass

class child_class extends parent_class;
  bit [31:0] data;
  function display();
    super.display();
    $display("Data = %0d",data);
  endfunction
endclass

module inheritence;
  initial begin
    parent_class p=new();
    child_class  c=new();
    c.addr = 10;
    c.data = 20;
    p = c;        //assigning child class handle to parent class handle
    c.display();
  end
endmodule

Simulator Output

Addr = 10
Data = 20

Click to execute on

assigning parent class handle to child class handle

This assignment is invalid, it leads to a compilation error.

class parent_class;
  bit [31:0] addr;
  function display();
    $display("Addr = %0d",addr);
  endfunction
endclass

class child_class extends parent_class;
  bit [31:0] data;

  function display();
    super.display();
    $display("Data = %0d",data);
  endfunction
endclass

module inheritence;
  initial begin
    parent_class p=new();
    child_class  c=new();
    c.addr = 10;
    c.data = 20;
    c = p;        //assigning child class handle to parent class handle
    c.display();
  end
endmodule

Simulator Output

"c = p;"
Expression 'p' on rhs is not a class or a compatible class and hence cannot
be assigned to a class handle on lhs.
Please make sure that the lhs and rhs expressions are compatible.

Click to execute on

assigning parent class handle to child class handle

assigning parent class handle (which is pointing to child class handle) to child class handle, leads to compile error.

class parent_class;
  bit [31:0] addr;

  function display();
    $display("Addr = %0d",addr);
  endfunction
endclass

class child_class extends parent_class;
  bit [31:0] data;
  function display();
    super.display();
    $display("Data = %0d",data);
  endfunction
endclass

module inheritence;
  initial begin
    parent_class p;
    child_class  c=new();
    child_class  c1;
    c.addr = 10;
    c.data = 20;
    p  = c;        //p is pointing to child class handle c.
    c1 = p;        //type check fails during compile time.
    c1.display();
  end
endmodule

Simulator Output

"c1 = p;"
Expression 'p' on rhs is not a class or a compatible class and hence cannot
be assigned to a class handle on lhs.
Please make sure that the lhs and rhs expressions are compatible.

Click to execute on

Use of $cast or casting

In the above example, assigning parent class handle (which is pointing to child class handle) to child class handle is valid but compilation error is observed.
During the compile time, as the handle of p is of parent class type which leads to compile error.

With the use of $cast(), type check during compile time can be skipped.

class parent_class;
  bit [31:0] addr;

  function display();
    $display("Addr = %0d",addr);
  endfunction
endclass

class child_class extends parent_class;
  bit [31:0] data;

  function display();
    super.display();
    $display("Data = %0d",data);
  endfunction
endclass

module inheritence;
  initial begin
    parent_class p;
    child_class  c=new();
    child_class  c1;
    c.addr = 10;
    c.data = 20;

    p = c;         //p is pointing to child class handle c.
    $cast(c1,p);   //with the use of $cast, type chek will occur during runtime

    c1.display();
  end
endmodule

Simulator Output

Addr = 10
Data = 20

Click to execute on

❮ Previous Next ❯

SystemVerilog Super keyword

Super keyword

The super keyword is used in a derived class to refer to the members of the parent class.

  • When class  members are overridden in the derived class, It is necessary to use the super keyword to access members of a parent class
  • With super keyword, it is allowed to access the class members of parent class which is only one level up

If the method of the parent class is overridden in the child class, then using the ‘super’ keyword parent class method can be accessed from the child class.

Super keyword example

Super Keyword
Super Keyword

In below example,

The parent class has the method ‘display’.
Implementing the method display in the child class will override the parent class method.
By calling super.display() from child class, the display method of the parent class can be accessed.

class parent_class;
  bit [31:0] addr;

  function display();
    $display("Addr = %0d",addr);
  endfunction
endclass

class child_class extends parent_class;
  bit [31:0] data;

  function display();
    super.display();
    $display("Data = %0d",data);
  endfunction

endclass

module inheritence;
  initial begin
    child_class c=new();
    c.addr = 10;
    c.data = 20;
    c.display();
  end
endmodule

Simulator Output

Addr = 10
Data = 20

Click to execute on

The below example is by removing the super.display() from the display method of the child class.

class parent_class;
  bit [31:0] addr;

  function display();
    $display("Addr = %0d",addr);
  endfunction
endclass

class child_class extends parent_class;
  bit [31:0] data;

  function display();
    $display("Data = %0d",data);
  endfunction

endclass

module inheritence;
  initial begin
    child_class c=new();
    c.addr = 10;
    c.data = 20;
    c.display();
  end
endmodule

Simulator Output

Data = 20

Click to execute on

❮ Previous Next ❯