You are on page 1of 2

1. What is callbacks in system Verilog?

Callbacks are used by tests to add new functionality to the driver without editing the driver
class. Following types of new functionality can be added using callbacks:
Inject errors
Drop the transaction
Delay the transaction
Synchronize this transaction with others
Put the transaction in the scoreboard (for data comparison as explained by friends above)
Gather functional coverage data

We may have to create a verification environment that can be used for all the tests. Test program
should be able to inject new code without modifying original classes. Any change in the
transaction(like injecting errors, inserting delays, synchronizing this transaction with others, put
the transaction in scoreboard, gather functional coverage data) can be achieved by callback
routine without changing the original classes.
The callback task is created in the top level test and called from the driver, lowest level of

2. Polymorphism basically allows subclasses to implement an interface from a common base class. To be able to do that,
functions and/or tasks in SV are declared as virtual functions/tasks to allow subclasses to override the behavior of the
function/task, or add to the behavior if there is a call to super. In general, virtual methods allow a subclass referenced by a
base pointer/handle to call the subclass's implementation of a virtual method, rather than whatever implementation is
defined in the base class.
An abstract class is a base class that is not intended to be instantiated, but serves to provide an interface that all
subclasses derived from it should implement. In SV, an abstract class is declared virtual, and it can declare prototypes for
virtual functions/tasks that are pure virtual methods. Pure virtual methods have no implementation in the abstract base
class (ABC), but specifies a requirement for subclasses that they must provide implementations to the pure virtual
For a very simple and contrived example, if Shape is an ABC (makes no sense to instantiate a "shape"), and there are two
classes derived from it -- Circle and Triangle,
virtual class Shape; // Abstract base class. pure virtual function int unsigned area(); // No
implementation for pure virtual method. endclass : Shape

class Circle extends Shape;

int unsigned radius;
virtual function int unsigned area(); // Derivatives of Circle can override this.
return PI * radius * radius; // Assume PI is a global constant defined somewhere.
endfunction : area
endclass : Circle

class Triangle extends Shape;

int unsigned base, height;
function int unsigned area(); // Derivatives of Triangle cannot override this.
return (base * height) / 2;
endfunction : area
endclass : Triangle
program main;
Shape s[2]; // Base handles.
Circle c = new;
Triangle t = new;
initial begin
c.radius = 3;
t.base = 9;
t.height = 12;
s[0] = c;
s[1] = t;
$display("The area of the circle is %0d.", s[0].area());
$display("The area of the triangle is %0d.", s[1].area());
endprogram : main
Since I've used integers for simplicity, the answers should be 28 and 54, illustrating how the type-specific method is called
through the base handle.
One application is collecting objects of different packet types in an array declared with the base packet type, assuming
those packet types are derived from that base. You could iterate through such an array, and call a virtual method that all of
these types declare, but implemented differently across the subclasses. In this way, when you handle the collection in the
array, you do not care about the specific types of the objects. Instead, you only concern yourself with the common
interface that the subclasses implement.
The UVM is a very good example of how polymorphism is used throughout its implementation.