Inheritance is a concept in OOP that allows us to extend a class to create another class and have access to all the properties and methods of the original parent class from the handle of a new class object. The idea behind this scheme is to allow developers add in new properties and methods into the new class while still maintaining access to the original class members. This allows us to make modifications without touching the base class at all.

Example

ExtPacket is extended and hence is a child class of Packet. Being a child class, it inherits properties and methods from its parent. If there exists a function with the same name in both the parent and child class, then its invocation will depend on the type of the object handle used to call that function. In the example below, both Packet and ExtPacket have a function called display(). When this function is called by a child class handle, the child class display() function will be executed. If this function is called by a parent class handle, then the parent class display() function will be executed.

In a previous post, key topics on class handles and objects were discussed which is essential to understand how shallow copy and deep copy works.

Click here to refresh concepts in class handles and objects !

The this keyword is used to refer to class properties, parameters and methods of the current instance. It can only be used within non-static methods, constraints and covergroups. this is basically a pre-defined object handle that refers to the object that was used to invoke the method in which this is used.

Example

A very common way of using this is within the initialization block.

  
  
class Packet;
	bit [31:0] addr;
	
	function new (bit [31:0] addr);
//		addr = addr;          //  Which addr should get assigned ?

		this.addr = addr;     //  addr variable in Packet class should be 
		                      //  assigned with local variable addr in new()
	endfunction
endclass

  

Unless there is ambiguity in assignment, use of this keyword is not generally needed for specifying access to class members in methods.

Each class instance would normally have a copy of each of its internal variables.

  
  
class Packet;
	bit [15:0] 	addr;
	bit [7:0] 	data;
	
	function new (bit [15:0] ad, bit [7:0] d);
		addr = ad;
		data = d;
		$display ("addr=0x%0h data=0x%0h", addr, data);
	endfunction
endclass

module tb;
	initial begin
		Packet 	p1, p2, p3;
		p1 = new (16'hdead, 8'h12);
		p2 = new (16'hface, 8'hab);
		p3 = new (16'hcafe, 8'hfc);
	end
endmodule

  

Each of the class objects p1, p2, p3 will have addr and data variables within it.

Simulation Log
ncsim> run
addr=0xdead data=0x12
addr=0xface data=0xab
addr=0xcafe data=0xfc
ncsim: *W,RNQUIE: Simulation is complete.

A constructor is simply a method to create a new object of a particular class data-type.

Constructors

C/C++ requires complex memory allocation techniques and improper de-allocation could lead to memory leaks and other behavioral issues. SystemVerilog, although not a programming language, is capable of simple construction of objects and automatic garbage collection.

When class constructor is explicity defined

  
  
// Define a class called "Packet" with a 32-bit variable to store address
// Initialize "addr" to 32'hfade_cafe in the new function, also called constructor
class Packet;
  bit [31:0] addr;
 
  function new ();
    addr = 32'hfade_cafe;
  endfunction
endclass
 
module tb;
  
  // Create a class handle called "pkt" and instantiate the class object
  initial begin
    // The class's constructor new() fn is called when the object is instantiated
    Packet pkt = new;   
    
    // Display the class variable - Because constructor was called during 
    // instantiation, this variable is expected to have 32'hfade_cafe;
    $display ("addr=0x%0h", pkt.addr);
  end
endmodule

  

In the example above, variable declaration creates an object of class Packet and will automatically call the new() function within the class. The new() function is called a class constructor and is a way to initialize the class variables with some value. Note that it does not have a return type and is non-blocking.

Simulation Log
ncsim> run
addr=0xfadecafe
ncsim: *W,RNQUIE: Simulation is complete.