Thought Leadership

Groups of Class Specializations in SystemVerilog

Introduction

In a previous post, I said that in SystemVerilog, once you specialize a class, you can not make a group of them. Oops! Turns out that UVM does this all this time. You just need to know where to start.

Just to be clear, you are making a group of handles, an array. Every object is separate, and thus cannot organized into an array.

Where’s my sequencer?

Here is an example of a group of specialized classes. Your design may speak several protocols, so your UVM testbench needs multiple agents. In UVM, an agent speaks one protocol, such as USB or AXI. Inside the agent, a sequencer picks incoming transactions and sends them to the driver. The uvm_sequencer class is specialized for a single flavor of transactions, like these declarations.

// Inside the AXI agent class
uvm_sequencer #(axi_txn) axi_sqr; // A sequencer for AXI transactions

// Inside the USB agent class
uvm_sequencer #(usb_txn) usb_sqr; // A sequencer for USB transactions

How can your testbench organize all those sequencers? What if your testbench declared an array of handles to hold these? Is the following code legal?

uvm_sequencer sqr_array[string];

sqr_array["AXI"] = axi_sqr; // Compile error

sqr_array["USB"] = usb_sqr; // Compile error

This won’t compile because when you specialized the class uvm_sequencer, it created a new type, and this is not compatible with the base uvm_sequencer, or the USB specialization. The full example requires a lot of support code, so let’s make a smaller example, without UVM.

Back to basics

There is a solution, which you can see by peeking at the UVM source code where the parameterized class uvm_sequencer is eventually extended from the non-parameterized class, uvm_sequencer base.

Let’s make a simple base class with a name property, and no parameters. The function print() displays the class name.

class Base;
  virtual function void print();
    $display("class Base");
  endfunction
endclass

Now make a derived class that has a integer parameter.

class Dparm #(int N=42) extends Base;
  bit [N-1:0] p;
  function void print();
    $display("Dparm#(%0d)", N);
  endfunction
endclass

Get organized!

Pool of parameterized handles in SystemVerilog
Pool of parameterized handles in SystemVerilog

Now you can make a group of handles. Declare them as an associative array of the base type, called a pool. Also declare another base handle, and a few of the derived type with different specializations.

  Base bpool[string], b; // Pool of base handles, and temp
  Dparm#(1) d1;   // Derived with #1
  Dparm#(2) d2;  // Derived with #2

Does this work? Can you really make an array of handles that point to different specializations? Try this on your favorite simulator and see what happens.

  initial begin
    b = new("b");        // Base handle to base object
    bpool["b"] = b;      // Save in base pool
    d1 = new("d1");       // Dparm#(1) object
    bpool["d1"] = d1;     // Save in base pool
    d2 = new("d2");       // Dparm#(2) object
    bpool["d2"] = d2;     // Save in base pool
    $display("Print the object types");
    foreach (pool[i])    // Wade through pool
      pool[i].print();   // and print objects
  end

Passing and assigning handles

You can assign a handle of a specialized type to a base handle. Here is a module-level function that calls the print() method.

function void print(input Base b_arg);
  b_arg.print();
endfunction

You can call it as follows.

print(b);     // Print base object
print(d1);    // Print some specialized types
print(d2);    // Equivalent to: b_arg = d2;

What if you want to assign to a derived specialized handle from a base handle? I’m out of space, so you are going to have to peek at a previous SystemVerilog OOP post and see what works.

Conclusion

When you specialize a parameterized class, you are creating a new type, incompatible with other specializations. However, if the parameterized class extends a base class, you can assign a specialized handle to a base handle.

Learn More

You can learn more about these topics including Oriented Programming with the Siemens SystemVerilog for Verification course. It is offered in instructor led format by our industry expert instructors, or in a self-paced on-demand format. It can also be tailored to address your specific design goals and show you how to set up an environment for reuse for additional designs.  Also, you can now earn a digital badge/level 1 certificate by taking our Advanced Topics Badging Exam. This will enable you to showcase your knowledge of this topic by displaying the badge in your social media and email signature.

Chris Spear

Chris brings over forty years of EDA expertise to Siemens customers. Holding a degree in electrical engineering from Cornell University, Chris has developed deep roots in the EDA industry, including as a Principal Application Consultant. Chris is also an industry author, writing the 2012 best-selling “SystemVerilog for Verification” and developing the IEEE standard for random seeding and File I/O PLI package that is part of SystemVerilog. Having taught thousands of engineers around the world, Chris is driven by a passion for learning new techniques and then helping others learn best practices for hardware verification. Outside of work, you may see Chris bicycling over 12,000-foot mountain passes.

More from this author

Leave a Reply

This article first appeared on the Siemens Digital Industries Software blog at https://blogs.stage.sw.siemens.com/verificationhorizons/2023/04/25/groups-of-class-specializations-in-systemverilog/