Skip to main content

System Verilog Inheritance



System Verilog Inheritance

System Verilog supports OOPS Inheritance which allows a user to inherit the class properties including the task, functions as well variables. System Verilog supports single inheritance as well as multiple inheritance.

Elaboration - Consider a case where we have declared a class named parent  and we want to its properties to be shared with other classes in the module or program too. Obviously re-writing the code with properties inside each child class will come first in our mind but that doesn’t sound great. It will certainly consume more script data and time too. So to cover this idea is what inheritance is all about.

Example – Your family has your Dad, Mom, son and a little daughter. So your Dad ( or your Mom ) is our Parent Class. You and your sister are the child classes inheriting from Parent Class. Since both children possess habits and behavior of parents. The habits and behavior are the methods that have been inherited from the parents (Parent Class).

Okay let us start with some examples.

This example is of single class inheritance. The software tool used here is Questasim 10.0b.

Code –

class Parent; //Parent Class
  task hell;
    $display("This is task-hell of Parent");
  endtask:hell
endclass:Parent

class Ben extends Parent; //Child Class
  task heaven;
    $display("Ben Task");
  endtask:heaven
endclass:Ben

module mainishere;
  initial begin
  Parent p = new;
  Ben q = new;
  p.hell(); //parent task
  q.heaven(); //child task
  q.hell(); //Calling super class task
end
endmodule

We have a parent class with task named hell and a child class named Ben inheriting Parent with child class named heaven.
Parent p = new;   --> This will create an instance of parent without argument
                                    Constructor.
Ben q = new;  -->  This will create an instance of child class Ben without argument constructor.

p.hell();   --> This line will call the task named hell from Parent Class.

q.heaven();   -->This line will call the task named heaven from Child Class Ben.

q.hell();    --> This line will call the inherited task hell from Parent Class. Since we have inherited thus Ben has all properties of Parent class that is why we have q(dot)hell.

Here is the Output

The first line is parent call. The second is child call. The third is child inheriting Parent Call.

Some important facts about subclasses -:

  • A subclass can be used to override the tasks and functions to that of the super class. 
  • It can also have other codes for method and function as well. 
  • Methods and functions in subclass can be used as static with overriding enabled.
  • Subclass enables a way to hide the inherited data from the super class.
Note- Subclass does not inherit new constructor and private data members
Another example of using functions as well.

class Parent; //Parent Class
  function hell;
    $display("This is function-hell of Parent");
  endfunction:hell
endclass:Parent

class Ben extends Parent; //Child Class
  function heaven;
    $display("Ben Function");
  endfunction:heaven
endclass:Ben

module mainishere;
  initial begin
  Parent p = new;
  Ben q = new;
  p.hell(); //parent task
  q.heaven(); //child task
  q.hell(); //Calling super class task
end
endmodule

Here is the output which is similar to that of task.


NOTE - In case if we have a function and a task with same name then that will result in an error and will not compile. In the above code another task was named hell and then compiled to get this error.

Inheritance of Subclass


We can also inherit a class which is already inherited. This grand child possess all super powers of its super class as well as super class of its super class (the Parent Class).

To define a grand child we changed code to this -

class Parent; //Parent Class
  function hell;
    $display("This is function-hell of Parent");
  endfunction:hell
  task ParentTask;
    $display("This is ParentTask");
  endtask:ParentTask
endclass:Parent
class Ben extends Parent; //Child Class
  function heaven;
    $display("Ben Function");
  endfunction:heaven
endclass:Ben

class Grand extends Ben;
  function earth;
    $display("Child of Child class");
  endfunction:earth
endclass:Grand
module mainishere;
  initial begin
  Parent p = new;
  Ben q = new;
  Grand g = new;
  p.hell(); //parent task
  q.heaven(); //child task
  q.hell(); //Calling super class task
  g.ParentTask(); //Calling super of super class
  g.earth();//
end
endmodule

Here is the output describing the working of Grand class.


Grand has inherited Ben which has inherited Parent. So Grand can access members of Parent and hence we have used here g.ParentTask();


Inheritance Non-Argument/Argument Constructor


Now we have defined a function named new i.e. constructor of parent, however have not been provided with arguments. Follow the below example and observe the output of a non-argument based constructor

class Parent; //Parent Class
  function new();
    $display("This is the constructor of Parent");
  endfunction
  task ParentTask;
    $display("Inside Parent Task");
  endtask:ParentTask
endclass:Parent
class Ben extends Parent; //Child Class
  function heaven;
    $display("Ben Function");
  endfunction:heaven
endclass:Ben

module mainishere;
  initial begin
  Parent p = new;
  Ben q = new;
  p.ParentTask(); //parent task
  q.heaven(); //child task
end
endmodule

Here is the output of the above:


NOTE- Constructors are not inherited from Parent class.

Q. Why “This is the constructor of Parent” repeated twice ?

Ans. This is what we call chained constructors. Reading thoroughly through the code we can find all clues. Firstly we have instantiated Parent thus this displays the first line. The second line is displayed because of instantiation of Ben. Although child class cannot inherit parent class constructor however it can invoke the super class constructor. This way is implicit way of calling super constructor. This is exactly what has happened here. Rest output lines are clear to all.

Q. What are chain constructors ?

Ans. Chained Constructor takes place when a child class instantiation takes place. This instantiation will first invoke the new() method of its super class and then the new() of child class is invoked. This takes place in hierarchy order in a proper way from topmost parent class to lowermost child class.

Super Keyword


Another way of calling constructor of parent class is by using the keyword Super.
Super is a reserved keyword used to refer to the methods and functions of super class from its subclasses. When we have constructor with argument we may get an error stating
---- "Super class constructor has non-default arguments. Arguments can be specified in the "extends" clause or by calling super.new() explicitly."---

This happens because sometimes we don't instantiate the parent class thus not providing the default argument value of new constructor of parent class so when we instantiate child class directly they it will ask for super class constructor default arguments as it has inherited implicitly the new function. Usage of super keyword is very necessary if overriding of function or task is taking place. 

To understand this follow this code - 

class Parent; //Parent Class
  function new(int a);
    $display("This is the constructor of Parent%d",a);
  endfunction
  task ParentTask;
    $display("Inside Parent Task");
  endtask:ParentTask
endclass:Parent

class Ben extends Parent; //Child Class
  function new;
    super.new(5);
    $display("This is the constructor of Child");
  endfunction
  function heaven;
    $display("Ben Function");
  endfunction:heaven
endclass:Ben

module mainishere;
  initial begin
  Parent p = new(6);
  Ben q = new ;
  p.ParentTask(); //parent task
  q.heaven(); //child task
end
endmodule

Here is the output for the above compilation



Parent p = new(6);  --->  This line passes 6 as the argument to the parent class constructor thus we get the output as shown in first line.

Ben q = new; --->   This lines instantiates Ben class constructor which has the command super.new(5); The super.new(5) sends the value 5 not to the super constructor but to the explicitly call new constructor of super class. Thus the seconds line shows the output. Rest lines of output must be easy to clear out. 
Super keyword can also be used to call super class methods and functions.

Here is an example showing explicitly calling a function using super keyword and returning the value

class Parent; //Parent Class
  function new(int a);
    $display("This is the constructor of Parent%d",a);
  endfunction
  task ParentTask;
    $display("Inside Parent Task");
  endtask:ParentTask
  function int add(int a,int b);
    $display("add function called %d %D",a,b);
    return a+b;
  endfunction:add
endclass:Parent

class Ben extends Parent; //Child Class
  int x;
  function new;
    super.new(5);
    x = super.add(6,4);
    $display("The return value is %d",x);
    $display("This is the constructor of Child");
  endfunction
  function heaven;
    $display("Ben Function");
  endfunction:heaven
endclass:Ben

module mainishere;
  initial begin
  Parent p = new(8);
  Ben q = new ;
  p.ParentTask(); //parent task
  q.heaven(); //child task
end

endmodule

Here is the output


Method Overriding

When a child class inherits a parent class it also grabs all the properties, methods and functions from the parent so calling out any method will call the parent method. Thus this can be overridden by using the same function or task name. Super class task or function can only be called explicitly by using the super keyword. This is an effective way of hiding data inherited from superclass although it is rarely used but who know you can surprise someone using this.

Here is the code following all three aspect

           a.      Without Overriding
           b.     With Overriding
     c.   Super calling


For case a(without overriding) comment the line 8-11  from above code.
For case b(with overidding ) uncomment the lines in range 8-11 and comment only line 9.
For case c(with super) uncomment all lines except line 10 and then run.

The output will be this


VSIM 93> is the output for without overriding
VSIM 95> is the output for with overriding
VSIM 99> is the output for with super


Method Overloading

System Verilog Doesn't support Method Overloading.
 If tried an error would pop out regarding "the function name already exists, must not be redefined as a function."
All global and local tasks must follow C conventionalizing with no similar names unless you are overriding it in a child class.

Regards,
Feel free to comment any human error here. :)


Comments