Re: How polymorphism (virtual functons + inheritance )in systemverilog
Polymorphism basically allows subclasses to implement an interface from a common base class. To be able to do that, functions and/or tasks in SV are declared as virtual functions/tasks to allow subclasses to override the behavior of the function/task, or add to the behavior if there is a call to super. In general, virtual methods allow a subclass referenced by a base pointer/handle to call the subclass's implementation of a virtual method, rather than whatever implementation is defined in the base class.
An abstract class is a base class that is not intended to be instantiated, but serves to provide an interface that all subclasses derived from it should implement. In SV, an abstract class is declared virtual, and it can declare prototypes for virtual functions/tasks that are pure virtual methods. Pure virtual methods have no implementation in the abstract base class (ABC), but specifies a requirement for subclasses that they must provide implementations to the pure virtual methods.
For a very simple and contrived example, if Shape is an ABC (makes no sense to instantiate a "shape"), and there are two classes derived from it -- Circle and Triangle,
virtual class Shape; // Abstract base class.
pure virtual function int unsigned area(); // No implementation for pure virtual method.
endclass : Shape
class Circle extends Shape;
int unsigned radius;
virtual function int unsigned area(); // Derivatives of Circle can override this.
return PI * radius * radius; // Assume PI is a global constant defined somewhere.
endfunction : area
endclass : Circle
class Triangle extends Shape;
int unsigned base, height;
function int unsigned area(); // Derivatives of Triangle cannot override this.
return (base * height) / 2;
endfunction : area
endclass : Triangle
program main;
Shape s[2]; // Base handles.
Circle c = new;
Triangle t = new;
initial begin
c.radius = 3;
t.base = 9;
t.height = 12;
s[0] = c;
s[1] = t;
$display("The area of the circle is %0d.", s[0].area());
$display("The area of the triangle is %0d.", s[1].area());
end
endprogram : main
One application is collecting objects of different packet types in an array declared with the base packet type, assuming those packet types are derived from that base. You could iterate through such an array, and call a virtual method that all of these types declare, but implemented differently across the subclasses. In this way, when you handle the collection in the array, you do not care about the specific types of the objects. Instead, you only concern yourself with the common interface that the subclasses implement.
The UVM is a very good example of how polymorphism is used throughout its implementation.