0% found this document useful (0 votes)
15 views29 pages

EE5530 - Lecture15 - Virtual Interfaces

This document provides an overview of advanced object-oriented programming (OOP) concepts in SystemVerilog including inheritance, composition, polymorphism, and virtual interfaces. It discusses how inheritance allows classes to extend existing classes to reuse and modify properties and methods. Composition is used when one class contains instances of other classes. The document also provides examples of multilevel inheritance, overriding base class members using the super keyword, and calling parent class constructors from derived classes.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views29 pages

EE5530 - Lecture15 - Virtual Interfaces

This document provides an overview of advanced object-oriented programming (OOP) concepts in SystemVerilog including inheritance, composition, polymorphism, and virtual interfaces. It discusses how inheritance allows classes to extend existing classes to reuse and modify properties and methods. Composition is used when one class contains instances of other classes. The document also provides examples of multilevel inheritance, overriding base class members using the super keyword, and calling parent class constructors from derived classes.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 29

Lecture 15

Advanced OOP
Memory Read
1. Explain IPC?

2. What is an event?

3. What is a semaphore?

4. What are mail boxes in Systemverilog?

5. How to kill the threads?


Synchronized Threads Using a Mailbox and Event
You may want the two threads to use a handshake so
that the Producer does not get ahead of the
class Consumer;
Consumer. The Consumer already blocks, waiting for task run;
the Producer using a mailbox. The Producer needs to int i;
block, waiting for the Consumer to finish the trans- repeat (3) begin
action. This is done by adding a blocking statement mbx.get(i);
to the Producer such as an event, or a second $display("Consumer: after get(%0d)", i);
mailbox. ->handshake;
end
program automatic mbx_evt; endtask
event handshake; endclass
class Producer; initial begin
task run; p = new();
for (int i=1; i<4; i++) begin c = new();
$display("Producer: before put(%0d)", i); // Run the producer and consumer in parallel
mbx.put(i); fork
@handshake; p.run();
$display("Producer: after put(%0d)", i); c.run();
end join
endtask end
endclass endprogram
Basic Transactor

class Agent;
mailbox gen2agt, agt2drv;
Transaction tr;
function new(mailbox gen2agt, agt2drv);
this.gen2agt = gen2agt;
this.agt2drv = agt2drv;
endfunction
task run();
forever begin
gen2agt.get(tr); // Get transaction from upstream block
... // Do some processing
agt2drv.put(tr); // Send it to downstream block
end
endtask
task wrap_up(); // Empty for now
endtask
endclass
Advanced OOP and Virtual Interfaces
Inheritance and Composition
Inheritance: (is-a relationship)
• Allows users to extend existing classes, making minor modifications. Extending
the “Automobile” class example, users might create subclasses for “sedan”,
“truck”, “van”, etc. The “van” class might also have a “minivan” subclass. Etc. In
these cases, the subclass IS-A superclass. i.e. a “sedan” is a “Automobile”.
• When using inheritance, the sub-class “inherits” all the parents public/protected
data properties and methods. It is allowed to override them, or use them as-is.

Composition: (has-a relationship)


• Composition is used for the case where one object HAS-A instance of another
class. For example, an “Automobile” class might have 4 instances of a “wheel”
class. In this case, a wheel is not an “Automobile”, so inheritance should not be
used.
SystemVerilog Inheritance
An Inheritance is the concept of OOP which allows users to create an extended class from the existing
class. The existing class is commonly known as base class or parent class and the newly created extended
class is known as a derived class or child class or subclass. The “extends” keyword is used to inherit the
child class from its base class.

 Child class has access to class properties and class methods of its base class. Thus, inheritance grants
re-usability.

 Along with existing class properties and methods, a derived class can also add new properties and
methods based on the requirement.

 A child class can modify its base class properties and methods without disturbing the base class.

 Multilevel inheritance is also possible in SystemVerilog. A derived class can also further extended,
this is multilevel inheritance.
Inheritance
A Child_trans is an extended class from its parent_trans (base class). A child_class can access its base
class properties (data variable) and methods (disp_p function)

class parent_trans;
bit [31:0] data; module class_example;
initial begin
function void disp_p(); child_trans c_tr;
$display("Value of data = %0h", data); c_tr = new();
endfunction c_tr.data = 5; // child class is updating property of its
endclass base class
c_tr.id = 1;
class child_trans extends parent_trans;
int id; c_tr.disp_p(); // child class is accessing method of its
base class
function void disp_c(); c_tr.disp_c();
$display("Value of id = %0h", id); end
endfunction endmodule
endclass
Multilevel Inheritance
Multilevel Inheritance Example
class parent_trans;
bit [31:0] data_p;

function void disp_p();


$display("parent_trans: Value of data = %0h", data_p);
endfunction class child_A_trans extends child1_trans;
endclass bit [31:0] data_cA;

class child1_trans extends parent_trans; function void disp_cA();


bit [31:0] data_c1; $display("child_A_trans: Value of data = %0h", data_cA);
endfunction
function void disp_c1(); endclass
$display("child1_trans: Value of data = %0h", data_c1);
endfunction class child_B_trans extends child_A_trans;
endclass bit [31:0] data_cB;

class child2_trans extends parent_trans; function void disp_cB();


bit [31:0] data_c2; $display("child1_2_trans: Value of data = %0h", data_cB);
endfunction
function void disp_c2(); endclass
$display("child2_trans: Value of data = %0h", data_c2);
endfunction
endclass
Multilevel Inheritance Example
module class_example;
initial begin
child_B_trans cB_tr;
cB_tr = new();
cB_tr.data_p = 2;
cB_tr.data_c1 = 4;
cB_tr.data_cA = 6;
parent_trans: Value of data = 2
cB_tr.data_cB = 8;
child1_trans: Value of data = 4
//cB_tr.data_c2 = 3;
child_A_trans: Value of data = 6
// Not possible as child_B_trans is not child class of
child1_2_trans: Value of data = 8
child2_trans.

cB_tr.disp_p();
cB_tr.disp_c1();
cB_tr.disp_cA();
cB_tr.disp_cB();
end
endmodule
Overriding base class members
class parent_trans;
bit [31:0] data = 100; module class_example;
int id = 1; initial begin
child_trans c_tr;
function void display(); c_tr = new();
$display("Base: Value of data = %0d and id = %0d", data, id); c_tr.display();
endfunction end
endclass endmodule

class child_trans extends parent_trans;


bit [31:0] data = 200;
int id = 2; Child: Value of data = 200 and id = 2

function void display();


$display("Child: Value of data = %0d and id = %0d", data, id);
endfunction
endclass
Super keyword in classes
Parent class members are overridden by its derived class on access by child class handle if both class
members have the same name for class properties and methods. To refer to base class members in such
a context, the super keyword is useful.

class parent_trans;
bit [31:0] data; module class_example;
initial begin
function void display(); child_trans c_tr;
$display("Base: Value of data = %0h", data); c_tr = new();
endfunction
endclass c_tr.data = 5;
c_tr.display();
class child_trans extends parent_trans; end
bit [31:0] data; endmodule

function void display();


super.data = 3; Base: Value of data = 3
super.display(); Child: Value of data = 5
$display("Child: Value of data = %0h", data);
endfunction
endclass
Example with arguments in the constructor
By default, the SystemVerilog compiler calls super.new() function calls automatically from extended
class. But if there are any arguments used in the new() function call, then the user has to call
super.new(<argument_list>) explicitly. The super.new() function call shall be the first line in the
derived class constructor because the parent class must be initialized before the derived class.

class parent_trans;
bit [31:0] data; module class_example;
initial begin
function new(bit [31:0] data); child_trans c_tr;
this.data = data; 00
c_tr = new(5, 7);
$display("Base: Value of data = %0h", data);
end
endfunction
endclass endmodule

class child_trans extends parent_trans;


bit [31:0] data;

function new(bit [31:0] data_p, data_c); Base: Value of data = 5


super.new(data_p); Child: Value00of data = 7
this.data = data_c;
$display("Child: Value of data = %0h", data);
endfunction

endclass
Virtual functions and tasks in SystemVerilog
A virtual method is a virtual function or task from the base class which can be overridden by a method of its child
class having the same signature (same method name and arguments). In simple words, When a child class handle is
assigned to its base class. On calling a method using a base class handle, the base class method will be executed. On
declaring a method as a virtual method, a base class handle can call the method of its child class.

class parent_trans; module class_example;


bit [31:0] data; initial begin
int id; parent_trans p_tr;
child_trans c_tr;
virtual function void display(); c_tr = new();
$display("Base: Value of data = %0d and id = %0d", data, id);
endfunction p_tr = c_tr;
endclass c_tr.data = 10;
c_tr.id = 2;
class child_trans extends parent_trans;
bit [31:0] data; p_tr.data = 5;
int id; p_tr.id = 1;
function void display(); p_tr.display();
$display("Child: Value of data = %0d and id = %0d", data, id); end
endfunction endmodule
endclass
Child: Value of data = 10 and id = 2
Abstract Class
SystemVerilog class declared with the keyword virtual is referred to as an abstract class.

• An abstract class sets out the prototype for the sub-classes.


• An abstract class cannot be instantiated, it can only be derived.
• An abstract class can contain methods for which there are only a prototype and no implementation, just
a method declaration.
Abstract Class Example

//abstract class
virtual class packet;
bit [31:0] addr;
virtual_class, "p = new();"
Endclass
Instantiation of the object 'p' can not be done because its type
'packet' is
module virtual_class;
an abstract base class.
initial begin
Perhaps there is a derived class that should be used.
packet p;
p = new();
end
endmodule
Abstract Class Example
//abstract class
virtual class packet;
bit [31:0] addr;
endclass

class extended_packet extends packet;


function void display;
$display("Value of addr is %0d", addr);
endfunction Value of addr is 10
endclass

module virtual_class;
initial begin
extended_packet p;
p = new();
p.addr = 10;
p.display();
end
endmodule
Pure Virtual Methods
A virtual method inside an abstract class can be declared with a pure keyword. Such methods only require a
prototype to be specified within the abstract class and the implementation is left to the subclasses
Access Control
By default all the members and methods of a class are accessible from anywhere using the object handle,
sometimes this could corrupt the class members values, which should not be touched at all.
Access control rules that restrict the members of a class from being used outside the class, this is
achieved by prefixing the class members with the keywords, local and protected

class parent_class; module encapsulation;


local bit [31:0] tmp_addr; initial begin
parent_class p_c = new(5);
function new(bit [31:0] r_addr);
tmp_addr = r_addr + 10; p_c.tmp_addr = 20; //Accessing local variable outside the class
endfunction p_c.display();
end
function display(); endmodule
$display("tmp_addr = %0d",tmp_addr);
endfunction
endclass Error- Illegal class variable access
testbench.sv,
Local member 'tmp_addr' of class
'parent_class' is not visible to scope
'encapsulation'.
Accessing Local Variable within the class (Allowed)
class parent_class;
local bit [31:0] tmp_addr;

function new(bit [31:0] r_addr);


tmp_addr = r_addr + 10;
endfunction

function display();
$display("tmp_addr = %0d",tmp_addr); Addr = 15
endfunction
endclass

// module
module encapsulation;
initial begin
parent_class p_c = new(5);
p_c.display();
end
endmodule
Protected class members
class parent_class;
protected bit [31:0] tmp_addr; // module
module encapsulation;
function new(bit [31:0] r_addr); initial begin
tmp_addr = r_addr + 10; parent_class p_c = new(5);
endfunction child_class c_c = new(10);

function display(); // variable declared as protected cannot be


$display("tmp_addr = %0d",tmp_addr); accessed outside the class
endfunction p_c.tmp_addr = 10;
endclass p_c.display();

class child_class extends parent_class; c_c.incr_addr(); //Accessing protected variable in


function new(bit [31:0] r_addr); extended class
super.new(r_addr); c_c.display();
endfunction end
endmodule
function void incr_addr();
tmp_addr++; Error- Illegal class variable access testbench.sv,
endfunction Protected member 'tmp_addr' of class 'parent_class' is
endclass not visible to scope 'encapsulation'
Data Hiding and Encapsulation

To make data members visible only to the class, use the local
keyword.
class myPacket extends BasePacket;
local int x;

To make data members visible only to the class, or any


subclasses, use the protected keyword.
class myPacket extends BasePacket;
protected int x;

24
Virtual Interfaces
1. An interface represents signals that are used to connect design modules or
testbench to the DUT and commonly known as a physical interface.

2. The design and physical interface are static in nature. Hence, they can not be
used dynamically.

3. In modern testbench, randomized class objects are used and connect to the
design dynamically.

4. Hence, to bridge the gap between the static world of modules and the dynamic
world of objects, a virtual interface is used as a pointer or handle for an actual
interface
Virtual Interfaces

1.The virtual interface must be pointed to the actual or physical interface. This is
also known as virtual interface initialization.

2.Before accessing or driving to the virtual interface, it must be initialized otherwise


it will cause a fatal run-time error as it has a null value.

3.The virtual interfaces can be passed to the functions and tasks as an argument.

4.The virtual interface can be declared as class properties and it initialized an


argument to the constructor or procedurally.
Virtual Interfaces Example
`include "test.sv"
module tb_top;
bit clk; interface mult_if (input logic clk, reset);
bit reset; logic [7:0] a, b;
logic [15:0] out;
always #2 clk = ~clk; logic en;
logic ack;
initial begin endinterface
clk = 0;
module multiplier(mult_if inf);
reset = 1;
#2;
always@(posedge inf.clk or posedge inf.reset) begin
reset = 0;
if(inf.reset) begin
end
inf.out <= 0;
inf.ack <= 0;
mult_if inf(clk, reset);
end
multiplier DUT(inf);
else if(inf.en) begin
test t(inf);
inf.out <= inf.a * inf.b;
inf.ack <= 1;
initial begin
end
$dumpfile("dump.vcd"); $dumpvars;
else inf.ack <= 0;
end
end
endmodule
endmodule
Virtual Interfaces Example
program test(mult_if inf); #25;
class drive; inf.a = 'd20; inf.b = 'd7;
virtual mult_if inf; #5ns inf.en = 1;
#6 inf.en = 0;
// constructor wait(inf.ack);
function new(virtual mult_if inf); $display("%0t: a=%d b=%d, out=%d", $time,
this.inf = inf; // virtual interface intialization inf.a,inf.b,inf.out);
endfunction
#10;
$finish;
task run(); endtask
#5; endclass
inf.a = 'd5; inf.b = 'd6;
inf.en = 1; initial begin
#10 inf.en = 0; drive drv = new(inf);
wait(inf.ack); drv.run();
$display("%0t: a=%d b=%d, out=%d", $time, end
inf.a,inf.b,inf.out); endprogram
Random stimulus to the DUT using a virtual interface.

initial begin
virtual mult_if vif;
drive drv = new();
vif = inf;
repeat(3) begin
assert(drv.randomize());
@(posedge vif.clk);
vif.a = drv.a;
vif.b = drv.b;
#2 vif.en = 1;
#5 inf.en = 0;
wait(vif.ack);
$display("%0t: a=%d b=%d, out=%d", $time, vif.a,vif.b,vif.out);
#20;
end
#10;
$finish;
end

You might also like