SourceSV Verification Directory

Virtual Keyword

Virtual keyword enables a child class to override a method defined in its parent class. When a virtual keyword is prefixed before a method in the parent class and if the base class handle is pointed to the extended class, then the extended class method handle will get assigned to the base class handle.

  • Once the virtual keyword is used for the parent class method, all the extended child classes become virtual.

Syntax

// declaration
virtual function display();
   // execute code
endfunction

// usage
parent_class = child_class;   // parent class is pointed to the child class
parent_class.display();       // this calls the funtion display() in the base class if virtual keyword
                              // is NOT used, if the virtual keyword is used the function display() will
                              // execute from the child class

In cases where the parent class and child class have methods with the same name and arguments, the method that gets executed depends on whether the method is declared as virtual or non-virtual in the parent class. The table below illustrates the behavior for both virtual and non-virtual method declarations in parent and child classes. The method column indicates the origin of the method execution.

Parent ClassChild ClassMethod Execution
Non-VirtualNon-VirtualChild Method
Non-VirtualVirtualChild Method
VirtualNon-VirtualParent Method
VirtualVirtualParent Method

From the table, it can be observed that if the method in the parent class is not declared as virtual, the method will be executed from the child class. Conversely, if the method in the parent class is declared with the virtual keyword, the method from the parent class will be executed.

Example Code

// Parent class
class parent_class;
   // class properties or variables
  int a, b, s;

   // task method
  task func1 (int a,b);
    s      = a + b;
    $display("Parent Class => a = %0d , b = %0d, sum s = %0d", a, b, s);
  endtask

   virtual task func2 (int a,b);
    s      = a + b;
    $display("Parent Class => a = %0d , b = %0d, sum s = %0d", a, b, s);
  endtask

endclass

// Child Class
class child_class extends parent_class;
  // class properties or variables
  int a, b, m;

  // task method
  task func1 (int a,b);
    m      = a * b;
    $display("Child Class  => a = %0d , b = %0d, mul m = %0d", a, b, m);
  endtask

  virtual task func2 (int a,b); // good practice to declare a class method as virtual
    m      = a * b;
    $display("Child Class  => a = %0d , b = %0d, mul m = %0d", a, b, m);
  endtask

endclass

module tb_virtual_keyword;

  parent_class pr_obj;          // declare a handle for parent class
  child_class cl_obj;           // declare a handle for child class


   initial begin
     cl_obj = new( );           // construct an object

     pr_obj = cl_obj;           // WHEN THE CHILD CLASS HANDLE POINTS TO THE PARENT CLASS HANDLE

     $display("------------ Non-Virtual Method ------------");
     pr_obj.func1(30,10);       // access a method

     $display("-------------- Virtual Method --------------");
     pr_obj.func2(30,10);       // access a method

   end

endmodule

Execute the code in EDA Playground

Points to Remember

  1. Always declare base class methods as virtual so that existing base class handles will refer to the function override in the child class.