[Day-6] Abstract
Photo by Jené Stephaniuk

[Day-6] Abstract

It's been quite some time now since the last article was published. Let's start with something new today. A very useful topic to discuss in object-oriented programming. The Virtual class and method.

What do we do with it?

First, let's go back a bit and think about the overriding of class properties. If you can recall from Day-3, you can see that as long as we have different class handles announced and instantiated(or assigned) for both child and parent classes, then even if we have similar named properties in different classes, all will work differently, none of them will override each other.

But!

What if we want to override the methods? What if we want to announce the name at first and later on, in any of the inherited child classes, we want to describe the methods?

This is something we are going to discuss today. To start with it, let's first understand what's the significance of the word virtual in SystemVerilog.

Virtual means, unreal. Something that does not have real existence. It means we use virtual when we want to replace a property with a new, real one.

Virtual Class

Now, there are two different uses of virtual keywords. First, when we want to replace the class itself, including all of the values of it's properties, we will put the virtual keyword before class. Let's see the example below:

virtual class Packet;
   int address ;

   function new ();
       address = 20;
   endfunction

   function display ();
		$display ("[Base] addr=0x%0h", address);
   endfunction
endclass

class ExtPacket extends Packet;

	// This is a new variable only available in child class
	int data_ext;

    function new (int addr, data);
      super.new (); 	// Calls 'new' method of parent class
      address = addr;
      data_ext = data;
   endfunction

    function display ();
       $display ("[Ext Child] addr=0x%0h data=0x%0h", address, data_ext);
	endfunction
endclass

module tb;
   Packet bc;
   ExtPacket sc;
   
   initial begin
       sc = new (32'hfeed_beef, 32'h1234_5678);
      bc = sc;
      bc.display();
    end
endmodule        

Output:

# [Base] addr=0xfeedbeef        
Even though we have announced the value of the address as 20 in the virtual parent class named Packet, the printed value in the display method of Packet class got the value from child class.

The reason behind this is that the memory location for the values of the virtual class Packet does not exist. It actually takes values from the similar properties of its child class. Which we have provided as 32'hfeed_beef which can be seen in the output window at the end.

Now, what if we instantiated the virtual class? As we know from the previous discussion(day-1), instantiation gives the handle a memory location. So, what if we do something like this?

virtual class Packet;
   int address ;

   function new (int addr);
       address = addr;
   endfunction

   function display ();
		$display ("[Base] addr=0x%0h", address);
   endfunction
endclass

module tb;
   Packet bc;
   
   initial begin
      bc = new(20);
      bc.display();
    end
endmodule        

Output:

# ** Fatal: testbench.sv (17): Class allocator method 'new' called on abstract class 'Packet'.        
Meaning, we can't instantiate or provide memory location to virtual class. However, works that we desire to do upon it need to be done by first creating a derived class(inherit a child off) of the virtual class at-first, assign the class handle of the child class to parent class and then calling the methods of the virtual parent class.

Seems like a process huh? The process is actually a very good tool to automate things and make things reusable. We are going to see the usefulness of this process pretty soon.

So, virtual class is something that we have discussed so far. But what is virtual methods?

Virtual Method

Like virtual classes, virtual method is not so rigorous! Even if we don't have a method definition in the child class, the method can be called by the class handle like any other, general method. For example:

class Packet;
   int address;

  function new (int addr);
       address = addr;
   endfunction

   virtual function display ();
		$display ("[Base] addr=0x%0h", address);
   endfunction
endclass

class ExtPacket extends Packet;

	// This is a new variable only available in child class
	int data_ext; 	

    function new (int addr, data);
      super.new (addr); 	// Calls 'new' method of parent class
      data_ext = data;
   endfunction
endclass

module tb;
   Packet bc;
   ExtPacket sc;

    initial begin
      bc = new(32'hfeed_feed);
      sc = new (32'hfeed_beef, 32'h1234_5678);
      bc = sc;
      bc.display();
    end
endmodule        

Output:

# [Base] addr=0xfeedbeef        

As you can see, the display function in the base class Packet is being displayed.

How are virtual methods different then?

The difference emerges when we define a method in the derived class that is similar to the method name in the parent class. Kind of like this:

class Packet;
   int address;

  function new (int addr);
       address = addr;
   endfunction

   virtual function display ();
		$display ("[Base] addr=0x%0h", address);
   endfunction
endclass

class ExtPacket extends Packet;

	// This is a new variable only available in child class
	int data_ext; 	

    function new (int addr, data);
      super.new (addr); 	// Calls 'new' method of parent class
     address = addr; 
     data_ext = data;
   endfunction

    function display ();
       $display ("[Ext Child] addr=0x%0h data=0x%0h", address, data_ext);
	endfunction
endclass

module tb;
   Packet bc;
   ExtPacket sc;

    initial begin
      bc = new(32'hfeed_feed);
      sc = new (32'hfeed_beef, 32'h1234_5678);
      bc = sc;
      bc.display();
    end
endmodule        

Output:

# [Ext Child] addr=0xfeedbeef data=0x12345678        

As you can see, even though we instantiated the Packet class separately, the display method in the child class replaced the display method in Packet class.

This means we use virtual methods when we want to replace certain parent class property values with the one in the child class.

Pure Virtual

Now, this can sometimes cause confusion or can be honestly ignored or missed in child class. To make sure the methods in the parents class are redefined in the derived class, we can use pure virtual.

What pure virtual keyword does to the method is that,

  1. It makes sure the method is not defined in the base class .
  2. It makes sure the method is defined in the child(derived) class, not in the base class.
  3. It makes sure the method is in a virtual class.

If any of the mentioned three is not maintained, there will be an error. So, a useful way of using pure virtual keywords is:

virtual class Packet;
   int address;

  function new (int addr);
       address = addr;
   endfunction

   pure virtual function display ();
endclass

class ExtPacket extends Packet;

	// This is a new variable only available in child class
	int data_ext; 	
        int address;

    function new (int addr, data);
      super.new (addr); 	// Calls 'new' method of parent class
      address = addr;
      data_ext = data;
   endfunction

    function display ();
       $display ("[Ext Child] addr=0x%0h data=0x%0h", address, data_ext);
    endfunction
endclass

module tb;
   Packet bc;
   ExtPacket sc;

    initial begin
      sc = new (32'hfeed_beef, 32'h1234_5678);

      bc = sc;
      bc.display();
     end
endmodule        

Output:

# [Ext Child] addr=0xfeedbeef data=0x12345678        

This is it! That was everything that is in my knowledge about virtual keywords in SystemVerilog.

The most useful thing about it is reusability as mentioned earlier. How?

Say I have a virtual class that only has the names of the properties in it with virtual keyword (or better, pure virtual keyword). We need it to make sure we have a fixed architecture of our testbench(like UVM).

If so, then we won't have to worry about the base class at all! We can just derive child classes from it and redefine all the methods and properties as of our need!

I am hoping you are going to share your thoughts on it as well.

See you next day!


Disclaimer: The knowledge above is true and rigid by the confidence of all the experiments and resources I went through. But it's not the holy grail of course! I cordially request by connections to add anything that I might have missed while defining class or maybe have mistaken or misinterpreted something. Your cooperation will help me learn and grow more!

If you are new to this article series and kind of lost, I started a 10-day discussion series about Object Oriented Programming using SystemVerilog. Follow the series to learn about my understanding of Object Oriented Programming and add your knowledges as well to make my understanding better in the comments.

要查看或添加评论,请登录

Eraz Ahmed的更多文章

  • [Day-10] Hard but Easy

    [Day-10] Hard but Easy

    Congratulations! Those who have followed the series so far might have a clearer vision of the Object-Oriented…

  • [Day-9] Constant Properties

    [Day-9] Constant Properties

    We are almost at the end of this series and this is what we are going to discuss today..

  • [Day-8] Encapsulate

    [Day-8] Encapsulate

    Regardless of what resource you are looking into, you will definitely come accross the 4 key concepts of Object…

  • [Day: 7] Long Distance Call

    [Day: 7] Long Distance Call

    Accessing class members is a key feature in object-oriented programming that enables developers to get information from…

  • [Day-5] Copy that

    [Day-5] Copy that

    Ah! We have been through 4 days of these series, contesting different hurdles so far. Those who have followed through…

    2 条评论
  • [Day-4] Unraveling the Array of Object Enigma

    [Day-4] Unraveling the Array of Object Enigma

    So far we have been trying to understand what class is, what is the need of it, one or two uses of it, etc. But among…

    4 条评论
  • [Day-3] SystemVerilog Shenanigans: Unraveling Inheritance, Polymorphic Play, and Class Assignments

    [Day-3] SystemVerilog Shenanigans: Unraveling Inheritance, Polymorphic Play, and Class Assignments

    Now that we have a working knowledge of class, handle, and constructor, we are going to go ahead and learn about how we…

    2 条评论
  • [Day-2] What is “this”?

    [Day-2] What is “this”?

    Construction continues…. Up until yesterday, we got to learn about the very fundamentals of class, handle, and the very…

  • [Day-1] Everything about Class

    [Day-1] Everything about Class

    We are going to dedicate this 10-day series to answering 3 basic questions every time starting today. 1.

    2 条评论

社区洞察

其他会员也浏览了