A class is a
type that includes data and subroutines (functions and tasks) that operate
on that data. A class’s data is referred to as class properties,
and its subroutines are called methods, both are members of the
class. The class properties and methods, taken together, define the
contents and capabilities of some kind of object.
For example, a packet might
be an object. It might have a command field, an address, a sequence
number, a time stamp, and a packet payload. In addition, there are various
things than can be done with a packet: initialize the packet, set the
command, read the packet’s status, or check the sequence number. Each
Packet is different, but as a class, packets have certain intrinsic
properties that can be captured in a definition.
//data or class properties
bit [3:0] command;
bit [40:0] address;
bit [4:0] master_id;
command = IDLE;
address = 41’b0;
master_id = 5’bx;
// public access entry points
command = 0; address = 0; master_id = 5’bx;
task issue_request( int delay );
// send request to bus
function integer current_status();
current_status = status;
A class defines a data type.
An object is an instance of that class. An object is used by first
declaring a variable of that class type (that holds an object handle) and
then creating an object of that class (using the new function) and
assigning it to the variable.
Packet p; // declare a variable
of class Packet
p = new; // initialize
variable to a new allocated object of the class Packet
The variable p is said to
hold an object handle to an object of class Packet. Uninitialized object
handles are set by default to the special value null. An
uninitialized object can be detected by comparing its handle with null.
For example: The task task1
below checks if the object is initialized. If it is not, it creates a new
object via the new command.
task1(integer a, obj_example myexample);
if (myexample == null)
myexample = new;
Accessing non-static members
or virtual methods via a null object handle is illegal. The
result of an illegal access via a null object is indeterminate, and
implementations can issue an error.
are referenced using an object handle. There are some differences
between a C pointer and a SystemVerilog object handle. C pointers give
programmers a lot of latitude in how a pointer can be used. The rules
governing the usage of SystemVerilog object handles are much more
restrictive. A C pointer can be incremented for example, but a
SystemVerilog object handle cannot. In addition to object handles,
introduces the chandle data type for use with the DPI Direct
(such as incrementing)
|For arbitrary data types
|Dereference when null
|Assignment to an address
of a data type
|Unreferenced objects are
The data fields of an object
can be used by qualifying class property names with an instance name.
Using the earlier example, the commands for the Packet object p can be
used as follows:
Packet p =
Any data-type can be declared
as a class property, except for net types since they are incompatible with
dynamically allocated data.
An object’s methods can be
accessed using the same syntax used to access class properties:
Packet p = new;
status = p.current_status();
Note that the assignment to status is not:
status = current_status(p);
The focus in object-oriented
programming is the object, in this case the packet, not the function call.
Also, objects are self-contained, with their own methods for manipulating
their own properties. So the object doesn’t
have to be passed as an
argument to current_status(). A class’ properties are freely and broadly
available to the methods of the class, but each method only accesses the
properties associated with its object, i.e., its instance.
SystemVerilog does not require the complex memory allocation and
deallocation of C++. Construction of an
object is straightforward and garbage collection, as in Java, is implicit
and automatic. There can be no memory
leaks or other subtle behavior that is so often the bane of C++
SystemVerilog provides a mechanism for initializing an instance at the
time the object is created. When an
object is created, for example
Packet p = new;
The system executes the new function associated with the class:
command = IDLE;
Note that new is now
being used in two very different contexts with very different semantics.
The variable declaration creates an object of class Packet. In the course
of creating this instance, the new function is invoked, in which
any specialized initialization required can be done. The new
function is also called the class constructor.
The new operation is
defined as a function with no return type, and like any other function, it
must be nonblocking.
Even though new does
not specify a return type, the left-hand side of the assignment determines
the return type.
Class properties that include
an initializer in their declaration are initialized before the execution
of the userdefined class constructor. Thus, initializer values can be
overridden by the class constructor. Every class has a default (built-in)
new method. The default constructor first calls its parent class
constructorand then proceeds to initialize each member of the current
object to its default (or uninitialized value).
It is also possible to pass
arguments to the constructor, which allows run-time customization of an
= new(STARTUP, $random, $time);
//where the new initialization task in Packet might now look
function new(int cmd = IDLE, bit[12:0] adrs = 0,
int cmd_time );
command = cmd;
address = adrs;
time_requested = cmd_time;
The conventions for arguments are the same as for any other procedural
subroutine calls, such as the use of
To understand more go through the simple example given in the next