Tutorials

Learn More

The virtual keyword is used while defining the class method (virtual methods) and the class itself (Abstract class)

virtual functions and tasks in SystemVerilog

A virtual method is a virtual function or task from the base class which can be overridden by a method of its child class having the same signature (same method name and arguments).

In simple words, 

When a child class handle is assigned to its base class. On calling a method using a base class handle, the base class method will be executed. On declaring a method as a virtual method, a base class handle can call the method of its child class.

Note: Once a virtual keyword is used for a base class method, all corresponding methods in derived classes become virtual. It is not necessary to put the ‘virtual’ keyword for derived class methods.

Let’s understand it with the below examples.

In both examples, a child class object is created, and then it is assigned to the base class handle.

parent_trans p_tr;
child_trans c_tr;
c_tr = new();
p_tr = c_tr;

Example without virtual keyword

Notice that in the below example base class display() method is called when it is not declared as virtual.

class parent_trans;
  bit [31:0] data;
  int id;
  
  function void display();
     $display("Base: Value of data = %0h and id = %0h", data, id);
  endfunction
endclass

class child_trans extends parent_trans;
  function void display();
    $display("Child: Value of data = %0h and id = %0h", data, id);
  endfunction  
endclass

module class_example;
  initial begin
    parent_trans p_tr;
    child_trans c_tr;
    c_tr = new();
    
    p_tr = c_tr;
    p_tr.data = 5;
    p_tr.id = 1;
    p_tr.display();
  end
endmodule

Output:

Base: Value of data = 5 and id = 1

Example with virtual keyword

Notice that in the below example child class display() method when it is declared as virtual.

class parent_trans;
  bit [31:0] data;
  int id;
  
  virtual function void display();
    $display("Base: Value of data = %0d and id = %0d", data, id);
  endfunction
endclass

class child_trans extends parent_trans;
  bit [31:0] data;
  int id;
  function void display();
    $display("Child: Value of data = %0d and id = %0d", data, id);
  endfunction  
endclass

module class_example;
  initial begin
    parent_trans p_tr;
    child_trans c_tr;
    c_tr = new();
    
    p_tr = c_tr;
    c_tr.data = 10;
    c_tr.id = 2;
    
    p_tr.data = 5;
    p_tr.id = 1;
    p_tr.display();
  end
endmodule

Output:

Child: Value of data = 10 and id = 2

Example with virtual keyword with different signature (Difference in argument list)

Both base and child class should have the same number of arguments otherwise, a compilation error is expected. Notice that the child class display method has only one argument whereas the base class display method has two arguments.

class parent_trans;
  bit [31:0] data;
  int id;
  
  virtual function void display(bit [31:0] data, int id);
     $display("Base: Value of data = %0h and id = %0h", data, id);
  endfunction
endclass

class child_trans extends parent_trans;
  function void display(bit [31:0] data);
    $display("Child: Value of data = %0h", data);
  endfunction  
endclass

module class_example;
  initial begin
    parent_trans p_tr;
    child_trans c_tr;
    c_tr = new();
    
    p_tr = c_tr;
    p_tr.data = 5;
    p_tr.id = 1;
    p_tr.display(p_tr.data, p_tr.id);
  end
endmodule

Output:

Error-[SV-INACF] Invalid number of args to class function
  Too few arguments in class-method 'display' in derived class 'child_trans'.
  Base class-method declared at "testbench.sv", 7
  Derived class-method declared at "testbench.sv", 13
  Please make sure that correct number of arguments are specified.

Example with virtual keyword with the same signature

Notice that in both base and child classes, the display method has two arguments.

class parent_trans;
  bit [31:0] data;
  int id;
  
  virtual function void display(bit [31:0] data, int id);
     $display("Base: Value of data = %0h and id = %0h", data, id);
  endfunction
endclass

class child_trans extends parent_trans;
  function void display(bit [31:0] data, int id);
    $display("Child: Value of data = %0h and id = %0h", data, id);
  endfunction  
endclass

module class_example;
  initial begin
    parent_trans p_tr;
    child_trans c_tr;
    c_tr = new();
    
    p_tr = c_tr;
    p_tr.data = 5;
    p_tr.id = 1;
    p_tr.display(p_tr.data, p_tr.id);
  end
endmodule

Output:

Child: Value of data = 5 and id = 1

System Verilog Tutorials