Basic OOP
Prof. C. Prayline Rajabai
SENSE, VIT University
Basic OOP topics
• Why OOP
• OOP terminology
• Classes
• Objects
• Custom constructors
• Static variables/methods
• Classes within classes
• Handles
• Copying objects
Verification using System Verilog 2
Why OOP?
• Gains in productivity/maintainability/thoroughness
• Strongly couples data with code that manipulates it.
• Allows the testbench to be reused
• Facilitates testing at the transaction level
• SystemVerilog allows inheritance and polymorphism
Verification using System Verilog 3
Comparison of Verilog with OOP in SV
HDL OOP
Verilog SystemVerilog
Block definition module class
Block instance instance object
Block name instance name handle
Data Types registers & wires
Properties:
Variables
Executable Code behavioral blocks Methods: tasks
(always, initial), and functions
tasks, functions
Communication Ports or task task/function
between blocks calls calls, mailboxes,
semaphores, etc.
Verification using System Verilog 4
Module Vs Class
• Objects are dynamic, modules are static
• Objects are created and destroyed as needed
• Instances of classes are objects
• A handle points to an object
• Object handles can be passed as argument
• Object memory can be copied or compared
• Instances of modules cannot be passed, copied or compared
• Classes can be inherited whereas modules cannot.
• Classes can be modified via inheritance without impacting existing
users
• Modifications to modules will impact all existing users
Verification using System Verilog 5
Class
• Class is a data type
• Class includes two members
• Data – class properties
• Subroutines(tasks & functions) – class methods
class class_name;
//Declare class properties
//Define class constructor
//(used to initialize class properties)
//Define class methods
endclass: class_name
Verification using System Verilog 6
Class Example
class Transaction;
bit [31:0] addr, crc, data[8]; properties or variables
function void display; method
$display(“Transaction: %h”, addr);
endfunction : display
fuction void calc_crc; method
crc = addr ^ data.xor;
endfunction : calc_crc
endclass: Transaction
Verification using System Verilog 7
Class Object
• Class is a data type – Object is the instance of a class
• How to create objects
• Declare object – class_name object_name;
• Create object – object_name = new();
Verification using System Verilog 8
Creating objects - Example
• Objects are instance of a class
• Call new()to allocate space for the object
Transaction tr;
tr = new();
handle
Object
Allocates space for the object of class
Transaction
tr now points to the object
OR
Transaction tr = new();
Verification using System Verilog 9
Where to define (and use) a Class
A class can be defined in:
1. program
2. module
3. package
A class can be used in:
1. module
2. program
3. package
Note : Define related classes in a package
Verification using System Verilog 10
Class in a package
package abc;
class Transaction;
// Class body
endclass
endpackage
program automatic test;
import abc::*;
Transaction tr;
// Test code
endprogram
Verification using System Verilog 11
Class Exercise
•Create a class called MemTrans that contains the following
members:
•An 8-bit data_in of logic type
•A 4-bit address of logic type
•A void function that prints out the value of data_in and
address
•Construct a MemTrans object in an initial block
Verification using System Verilog 12
Class Exercise - Solution
class MemTrans;
logic [7:0] data_in;
logic [3:0] address;
function void print;
$display(“Data_in = %h, address = %h”, data_in, address);
endfunction
endclass
initial begin
MemTrans MyMemTrans;
MyMemTrans = new();
end
// or
initial begin
MemTrans MyMemTrans = new();
end Verification using System Verilog 13
Custom Constructor
• For every class SystemVerilog creates a default new()
• Memory space is allocated
• All variables initialized to their default value
• Use a custom constructor to override this behavior
class Transaction;
logic [31:0] addr, crc, data[8];
function new();
addr = 3;
data = '{default:5};
endfunction
endclass
Verification using System Verilog 14
Custom Constructor with arguments
• Make the custom constructor more flexible by passing in values
• Defaults are used if argument(s) are not passed
class Transaction;
logic [31:0] addr, crc, data[8];
function new(logic [31:0] a=3, d=5);
addr = a;
data = '{default:d};
endfunction
endclass
Transaction tr1 = new(10);
Transaction tr2 = new(, 6);
Transaction tr3 = new(10, 6);
Transaction tr4 = new(.a(10), .d(6));
Verification using System Verilog 15
Custom Constructor Exercise
Using your MemTrans class create a custom constructor so that
data_in and address are both initialized to 0.
Verification using System Verilog 16
Custom Constructor Exercise - Solution
class MemTrans;
logic [7:0] data_in;
logic [3:0] address;
function void print;
$display(“Data_in = %h, address = %h”, data_in, address);
endfunction
function new;
data_in = 8’h0;
address = 4’h0;
endfunction
endclass
Verification using System Verilog 17
Custom Constructor with args Exercise
Using your MemTrans class create a custom constructor so that
data_in and address are both initialized to 0 but can also be
initialized through arguments passed into the constructor
1. Create 2 new MemTrans objects
2. Initialize address to 2 in the 1st object, passing arguments by
name
3. Initialize data_in to 3 and address to 4 in the 2nd object,
passing arguments by name.
Verification using System Verilog 18
Custom Constructor with args Exercise-
Solution
class MemTrans;
logic [7:0] data_in;
logic [3:0] address;
function void print;
$display(“Data_in = %h, address = %h”, data_in, address);
endfunction
function new(logic [7:0] data_init = 0, logic [3:0] address_init = 0);
data_in = data_init;
address = address_init;
endfunction
endclass
initial begin
MemTrans mt1, mt2;
mt1 = new(.address_init(2));
mt2 = new(.data_init(3), .address_init(4));
end Verification using System Verilog 19
Object Deallocation
Transaction t1, t2; t1 = null, t2=null
t1 = new(); t2=null, t1 Object mem t1
t2 = t1; t2
t2 t1
t1 = new();
Object mem t1 Object mem t1_new
t2 t1 = null
t1 = null; Object mem t1 Object B
Verification using System Verilog 20
Using Objects
Similar to Verilog use the “.” notation to access variables and
routines of a class
class Transaction;
bit [31:0] addr, crc, data[8];
function void display;
$display(“Transaction: %h”, addr);
endfunction
fuction void calc_crc;
crc = addr ^ data.xor;
endfunction
endclass
Transaction t;
t = new();
Usage:
t.addr = 32’h42;
t.display();
Verification using System Verilog 21
Using Objects Exercise
Using the previous MemTrans exercise assign the address of the
first object to 4’hF after construction
Use the print function to print out the values of data_in and
address for the 2 objects.
Explicitly deallocate the 2nd object.
Verification using System Verilog 22
Using Objects Exercise - Solution
class MemTrans;
logic [7:0] data_in;
logic [3:0] address;
function void print;
$display(“Data_in = %h, address = %h”, data_in, address);
endfunction
function new(logic [7:0] data_init = 0, logic [3:0] address_init = 0);
data_in = data_init;
address = address_init;
endfunction
endclass
initial begin
MemTrans mt1, mt2;
mt1 = new(, .address_init(2));
mt2 = new(3, 4);
mt1.address = 4’hF;
mt1.print;
$display("-------------------");
mt2.print;
mt2 = null; Verification using System Verilog 23
end
Defining Methods Outside of the Class
• Done to keep the class definition readable
• Define a prototype of the method in the class
• Use the extern keyword to indicate the full definition is external
class PCI_Tran;
bit [31:0] addr, data;
extern function void display();
endclass
Specify the class that the function is defined for
function void PCI_Tran::display();
$display(“%0t: PCI: addr = %h, data = %h”,
$time, addr, data);
endfunction
Verification using System Verilog 24
Static Variables vs. Global Variables
• Global variable has no limits on manipulation
• Local variables that are not shared with any other object
• Static variable:
• Can only be modified by objects of one class
• Shared among all objects
• Associated with the class, not the object
• Single copy for all the objects
class Transaction;
static int count = 0;
int id;
function new();
id = count++;
endfunction
endclass
Verification using System Verilog 25
Static/Global Variables (cont)
initial begin
Transaction t1, t2, t3;
t1 = new();
$display("First id = %0d, count = %0d", t1.id, t1.count);
t2 = new();
$display("Second id = %0d, count = %0d", t2.id, t2.count);
t3 = new();
$display(“Third id = %0d, count = %0d", t3.id, t3.count);
end
# First id = 0, count = 1
# Second id = 1, count = 2
# Third id = 2, count = 3
If count was not declared as static:
# First id = 0, count = 1
# Second id = 0, count = 1
# Third id = 0, count = 1using System Verilog
Verification 26
Accessing Static Variables.....
• Only one copy of a static variable exists.
• Memory for static variables is allocated once the class is declared
• Static variables can be accessed through the class or handle
initial begin
Transaction t1, t2;
$display("1) Transaction::count = %0d", Transaction::count);
t1 = new();
$display("First id = %0d, count = %0d", t1.id, t1.count);
t2 = new();
$display("Second id = %0d, count = %0d", t2.id, t2.count);
$display("2) Transaction::count = %0d", Transaction::count);
end
# 1) Transaction::count = 0
# First id = 0, count = 1
# Second id = 1, count = 2
# 2) Transaction::countVerification
= 2 using System Verilog 27
Static Variables Exercise
Using the previous MemTrans exercise create a static variable
last_address that holds the initial value of the address variable
from the most recently created object, as set in the constructor.
After allocating objects of class MemTrans (done in last exercise)
print out the current value of last_address.
Verification using System Verilog 28
Static Variables Exercise - Solution
class MemTrans;
logic [7:0] data_in; logic [3:0] address;
static logic [3:0] last_address;
function void print;
$display(“Data_in = %h, address = %h”, data_in, address);
endfunction
function new(logic [7:0] data_init = 0, logic [3:0] address_init = 0);
data_in = data_init;
address = address_init;
last_address = address;
endfunction
endclass
Verification using System Verilog 29
Static Variables Exercise – Solution(cont)
initial begin
MemTrans mt1, mt2;
mt1 = new(, .address_init(2));
mt2 = new(3, 4);
mt1.print;
mt2.print;
//$display("last_address is %h", MemTrans::last_address); or
$display("last_address is %h", mt2.last_address);
mt2 = null;
end
Verification using System Verilog 30
Static Methods
Manipulating static variables with a method accessed with the class
name requires a static method
class Transaction;
static int count = 0;
int id;
function new();
id = count++;
endfunction
static function void dec_count();
--count;
endfunction dec_count must be declared as static
endclass
Transaction::dec_count();
$display("Transaction.count = %0d", Transaction::count);
# Transaction.count = 1
Verification using System Verilog 31
Static Methods Exercise
Using the previous MemTrans exercise create a static method
called print_last_address that prints out the value of static
variable last_address
After allocating objects of class MemTrans, call the method
print_last_address to print out the value of
last_address
Verification using System Verilog 32
Static Methods Exercise - Solution
class MemTrans;
logic [7:0] data_in;
logic [3:0] address;
static logic [3:0] last_address;
function void print;
$display(“Data_in = %h, address = %h”, data_in, address);
endfunction
function new(logic [7:0] data_init = 0, logic [3:0] address_init = 0);
data_in = data_init;
address = address_init;
MemTrans::last_address = address;
endfunction
static function void print_last_address;
$display("last_address is %h", last_address);
endfunction
Verification using System Verilog 33
endclass
Static Methods Exercise – Solution(Cont)
initial begin
MemTrans mt1, mt2;
mt1 = new(, .address_init(2));
mt2 = new(3, 4);
m1.address = 4’hF;
mt1.print;
mt2.print;
MemTrans::print_last_address; or mt2.print_last_address; <-
don’t recommend this.
mt2 = null;
end
Verification using System Verilog 34
this keyword
• Keyword this allows unambiguous reference to class
variables/methods, etc.
• Commonly used in custom constructors where argument to
constructor matches a class variable.
class Scoping; class Scoping;
string name; string name;
function new(string new_name); function new(string name);
name = new_name; this.name = name;
endfunction endfunction
endclass endclass
Verification using System Verilog 35
Using one Class Inside Another
• Objects of a class can be created inside another class
• Enables reuse
class Statistics;
time startT; // Transaction start time
static int ntrans = 0; // Transaction count
static time total_elapsed_time = 0;
function void start();
startT = $time;
endfunction
function void stop();
time how_long = $time - startT;
ntrans++; // Another trans completed
total_elapsed_time += how_long;
endfunction
endclass
Verification using System Verilog 36
Using Statistics inside another Class
class BusTran;
bit [31:0] addr, src, data[8], crc;
Statistics stats;
function new();
stats=new();
endfunction
task create_packet();
// Fill packet with data
stats.start();
...... // Transmit packet
stats.stop();
endtask
endclass
Verification using System Verilog 37
Compilation Order Issue
• Compilation order of classes is not as lenient as modules
• Example: two classes each need a handle to the other.
class Transaction;
Statistics stats; Invalid type 'Statistics'.
endclass
class Statistics;
endclass
typedef class Statistics;
class Transaction;
Statistics stats;
endclass
class Statistics;
endclass
Verification using System Verilog 38
Passing objects/handles to methods
• What happens when an object is passed to a method?
• The handle to the object is passed, not the object.
• A copy of the handle is made
task generator; task transmit(input Transaction trans);
Transaction gen; ...........
gen =new; endtask
transmit(gen);
endtask
object of class
gen trans
Transaction
Verification using System Verilog 39
Copying Objects
• Pass a copy of an object to a method to keep it from being modified
• Any custom constructor is not called
Transaction src, dst;
class Transaction;
initial begin
bit [31:0] addr;
src = new();
static int count = 0;
src.stats.StartT=42;
int id;
Statistics stats;
src
id=0 startT=42
stats
function new(); dst = new src;
stats = new()
id = count++; src
id=0 startT=42 96
endfunction
stats
endclass
dst
id=0
stats
dst.stats.StartT = 96;
Verification using System Verilog 40
Writing a Deep Copy Function
Suggested for all but the most trivial classes
class Transaction; class Statistics;
bit [31:0] addr; time startT;
static int count = 0;
int id; function Statistics copy();
Statistics stats; copy = new();
copy.startT = startT;
function new();
endfunction
stats = new();
endclass
id = count++;
endfunction
function Transaction copy();
copy = new(); UVM data macros do this
copy.addr = addr; for you automatically!
copy.stats = stats.copy();
endfunction
endclass
Verification using System Verilog 41
Using the Deep Copy Function
Transaction src, dst;
initial begin
src = new();
src.stats.StartT=42; src id=0 startT=42
stats
id=0 startT=42
src stats
dst = src.copy();
dst
id=1 startT=42
stats
src
id=0 startT=42
stats
dst.stats.StartT = 96;
end id=1
dst stats startT=96
Verification using System Verilog 42
Inheritance
• What if there is a class that does almost everything you need
and missing only one small feature?
– Inheritance – build upon existing classes.
• Ability of a class to inherit properties and methods from
another class(superclass) is called Inheritance.
• If class A inherits from class B, then B is called super
(Parent)class of A and A is called subclass(Child) of B.
• Objects of a subclass can be used where objects of the
corresponding superclass are expected.
• A subclass inherits all the members from its superclass(Except
the custom constructor), but subclass can invoke super class
constructor using “super” keyword.
Verification using System Verilog
Inheritance
class parent_class;
bit [31:0] addr;
endclass
class child_class extends parent_class;
bit [31:0] data;
endclass
module inheritence;
initial begin
child_class c = new();
c.addr = 10;
c.data = 20;
$display(“Addr= %0d Data = %0d",c.addr,c.data);
end
endmodule
Verification using System Verilog 44
Inheritance - Example
class Packet;
int addr;
function new (int addr);
this.addr = addr;
endfunction
function display ();
$display ("[Parent] addr=0x%0h", addr);
endfunction
endclass
Verification using System Verilog 45
Inheritance - Example
class ExtPacket extends Packet;
int data;
function new (int addr, data);
super.new (addr);
this.data = data;
endfunction
function display ();
$display ("[Child] addr=0x%0h data=0x%0h",
addr, data);
endfunction
endclass
Verification using System Verilog 46
Inheritance - Example
module tb;
Packet bc; // pc stands for BaseClass
ExtPacket sc; // sc stands for SubClass
initial begin
bc = new (32'hface_cafe);
bc.display ();
sc = new (32'hfeed_feed, 32'h1234_5678);
sc.display ();
end
endmodule
Verification using System Verilog 47
Polymorphism
• Ability of subclass to override the behavior (method) of super
class is called polymorphism.
• A method in the parent class can be declared as virtual which
will enable all the child class to override the behavior of the
method.
Polymorphism
Parameterized class
• A facility to develop generic Value parameterized Class:
class whose objects can be
instantiated to have different
array sizes or data types.
Type parameterized Class:
Verification using System Verilog 51