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

ScenarioExpected BehaviorOutcome
Handle pkt before object creationNull handleRuntime error when accessing pkt.count
Handle pkt after calling new()Handle points to an objectAccess to object members is possible
Assigning pkt to pkt2Both handles point to the same objectBoth 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.

Scroll to Top