In SystemVerilog, class handles are essential for working with objects. A class variable, like pkt
, is simply a name used to refer to an object. However, until this handle is assigned to an object, it remains null. At this point, the class object does not exist.
What Is a Class Handle in SystemVerilog?
A class handle in SystemVerilog points to a particular object of that class. Without the proper assignment, this handle remains null, and no object exists for it to refer to. Let’s explore how this works through examples.
Example 1: Class Handle Initialized to Null
In the first example, we define a class Packet
that contains a single member variable count
. The count
stores integer values. Initially, the handle pkt
is null, so it does not refer to any object.
// Define a class Packet with a member count
class Packet;
int count;
endclass
module tb;
// Declare a handle for the class Packet
// Initially, the handle points to NULL
Packet pkt;
initial begin
// Check if the handle pkt is null
if (pkt == null)
$display ("Packet handle 'pkt' is null");
// Attempt to display the count value (will cause an error)
$display ("count = %0d", pkt.count);
end
endmodule
Expected Output:
Packet handle 'pkt' is null
count = ncsim: *E,TRNULLID: NULL pointer dereference.
File: ./testbench.sv, line = 18, pos = 33
Scope: tb
Time: 0 FS + 0
Explanation: At this stage, pkt
is null. Therefore, trying to access pkt.count
results in a runtime error: NULL pointer dereference.
Example 2: Creating a New Class Object
To resolve the issue above, we must invoke the new()
function to create an instance of the class Packet
. This makes the handle point to an actual object.
// Define the Packet class again
class Packet;
int count;
endclass
module tb;
// Declare a handle for the class Packet
Packet pkt;
initial begin
// Check if the handle pkt is null before object creation
if (pkt == null)
$display ("Packet handle 'pkt' is null");
// Create a new object of class Packet
pkt = new();
// Check if pkt is still null
if (pkt == null)
$display ("What's wrong, pkt is still null?");
else
$display ("Packet handle 'pkt' is now pointing to an object, and not NULL");
// Display the class member count
$display ("count = %0d", pkt.count);
end
endmodule
Expected Output:
Packet handle 'pkt' is null
Packet handle 'pkt' is now pointing to an object, and not NULL
count = 0
ncsim: *W,RNQUIE: Simulation is complete.
Explanation: After calling pkt = new();
, the handle pkt
now points to a valid object. We can access the count
member, and its default value is 0
because no value has been assigned yet.
Example 3: Sharing Handles Between Variables
You can assign a class handle to another variable. This means both handles will point to the same instance of the class object.
// Define the Packet class with a member count
class Packet;
int count;
endclass
module tb;
// Declare two handles for the class Packet
Packet pkt, pkt2;
initial begin
// Create an object of class Packet and assign a value to count
pkt = new();
pkt.count = 16'habcd;
// Display the count value using pkt handle
$display ("[pkt] count = 0x%0h", pkt.count);
// Assign pkt handle to pkt2
pkt2 = pkt;
// Display the count value using pkt2 handle
$display ("[pkt2] count = 0x%0h", pkt2.count);
end
endmodule
Expected Output:
[pkt] count = 0xabcd
[pkt2] count = 0xabcd
ncsim: *W,RNQUIE: Simulation is complete.
Explanation: Here, both pkt
and pkt2
now refer to the same object in memory. When we modify pkt.count
, the change is reflected in pkt2.count
as well.
SystemVerilog Class Handle: Key Takeaways
- Class handles are pointers to objects in SystemVerilog.
- A handle starts as null until assigned to an object created with the
new()
function. - Assignment of handles between variables does not create new objects, but instead, multiple handles point to the same object.
- Always check if the handle is null before accessing members, or it may lead to runtime errors.
Comparison of Class Handle Scenarios
Scenario | Expected Behavior | Outcome |
---|---|---|
Handle pkt before object creation | Null handle | Runtime error when accessing pkt.count |
Handle pkt after calling new() | Handle points to an object | Access to object members is possible |
Assigning pkt to pkt2 | Both handles point to the same object | Both pkt and pkt2 share the same data |
Conclusion
SystemVerilog class handles are a fundamental concept when working with objects. These handles allow you to reference and manipulate class objects in your simulations. Always ensure that a handle is assigned to an object before attempting to access its members to avoid errors.