SystemVerilog Datatype: Class (Part 3)

Previous: Data encapsulation | Next: Class scope resolution

Be Abstract, Be Virtual - Abstract Classes, Virtual Methods

Recall from our earlier discussion that a subclass extends the definition of a base class.

Now, suppose you only need various subclasses that extend one single base class in your application, but you do not need (and do not want anyone else to access) the base class itself. In order to encapsulate the use of the base class, you declare it as virtual. If we want Triangle to be such a base class, then the following example shows how to do it.

 
   virtual class Triangle;
   ...
   endclass

In this example, the base class Triangle can be extended by other subclasses, but Triangle itself can not be instantiated. A virtual base class is also called an abstract class.

The keyword virtual can also be used to qualify a method (in a virtual or regular class). In this case, the method contains only an empty prototype definition, the actual definition is contained within each subclass, if it uses that method.

The following example ilustrates this. Here, Triangle is a virtual class that has a virtual method (in this case, a task) fillIt(). The virtual task definition is empty, and the real definition is provided inside the subclass Trapezoid.

   virtual class Triangle;
      ...
      virtual task fillIt (struct rgb color); 
      endtask // empty declaration
   endclass

   class Trapezoid extends Triangle;
      point p4;
      task fillIt (struct rgb color);
         ... // detail definition here
      endtask
   endclass

Polymorphism

Polymorphism, according to Merriam-Webster online dictionary, is 'the quality or state of being able to assume different forms.' The phenomenon of polymorphism perhaps can be best explained by the following example. Here, triangle_array is an array of base class Triangle. Trapezoid is a sub-class of Triangle and just like Triangle that has a method fillIt(). Since there is a common method name, as we know, an object instance will choose the method corresposding to its class. The variables t and tzpd are object instances of Triangle and Trapezoid respectively. Now, assume index is a variable that is available only during run time (perhaps it is an input from an external file).

 
   Triangle [NN:0] triangle_array;

   class Trapezoid extends Triangle; 
   ... 
   task fillIt;
      ...
   endtask   
   endclass 

   Triangle  t    = new;
   Trapezoid tpzd = new;

   ...
   if (index) 
      triangle_array[0] = t;
   else 
      triangle_array[0] = tpzd;
   ...
   triangle_array[0].fillIt(); 
      // The all important task call
   ...

Now carefully note the last few lines of the above code snippet. We are assigning to triangle_array[0] a variable based on a run time value. Moreover, the right hand side of this assignment can be the base class or a sub class. There is no way for a compiler to know the content of triangle_array[0] until the run time. However, due to polymorphism, we are allowed to do the assignment.

Also notice that we are allowed to call triangle_array[0].fillIt() which will point to the appropriate method (either the fillIT() method of Triangle or the fillIT() method of Trapezoid). All these are decided at the run time.

Previous: Data encapsulation | Next: Class scope resolution

Share/Save/Bookmark



Verification Management
Join Verification Management Group


Shop Amazon - Contract Cell Phones & Service Plans

Book of the Month