Thought Leadership

The UVM Factory Revealed, Part 2

Introduction

This is a follow up to last week’s high-level post on the UVM Factory. Now let’s get technical! Here are the SystemVerilog Object-Oriented Programming concepts behind the factory.

What is a type_id?

Last week you saw that your verification project will be more stable if you create objects with the UVM Factory instead of calling the class constructor, new().

drv = x_driver::type_id::create(…);

But what is type_id? Is it the UVM Factory? A class? How about a floor polish and a dessert topping? Actually, it is none of the above; it is just a type.

A riddle wrapped in a macro

What is in the uvm_object_utils and uvm_component_utils macros? They are almost identical, except the first assumes the class constructor has one argument, and the second assumes there are two. Let’s focus on a transaction class.

class Txn extends uvm_sequence_item;
  `uvm_object_utils(Txn)
  function new(string name=”Txn”);
    super.new(name);
  endfunction
  …
endclass

For this class, the macro defines type_id as follows.

typedef uvm_object_registry#(Txn,"Txn") type_id;

You are creating a new object, so the handle is still null, and you can’t call its methods with handle.type_id.create(). The uvm_object_registry has static methods, which you call with the class::type_id::create() syntax.

The create() method essentially just calls uvm_factory::create_object_by_type(). That method looks through an array of type overrides to see if you ever called set_type_override() for this class, then calls new() for the base or override class. For components, where new() has two arguments, there is a parallel set of classes and methods such as uvm_component_registry and create_component_by_type().

Every class needs a unique identifier, which is its “type”. The Txn class’s type_id proxy creates a single instance of itself, a “singleton instance”, and the “type” is just a handle to that instance. The following overrides the Txn class with the derived TxnPlus. The call to TxnPlus::get_type() returns a handle to the proxy object so that create() can construct a TxnPlus object.

Txn::type_id::set_type_override( TxnPlus::get_type() );

The above description is for the UVM type-based factory.

What’s my name?

When I was first learning UVM, I couldn’t figure out how it constructed the test object from the +UVM_TESTNAME=my_test command line switch. In SystemVerilog I can get the string “my_test” from the switch, but how does UVM turn that into an object?

Did you know that the UVM factory has a parallel, string-based flow? That is why the typedef for type_id has a second argument, the class name string.

   typedef uvm_object_registry#(Txn,"Txn") type_id;

If you look up uvm_root::run_test(), there is a call to factory.create_component_by_name(…). The string from the command line switch is passed in, and this method constructs that object, or the override one.

Imagine that the factory is a printing press. If you load a drum with a base image, it will print base text. If you load a drum with a derived image, it will print the new text.

The UVM Factory prints objects
The UVM string-based Factory can print base and derived objects

You know my name, look up my number

Why was the type-based factory added? There is a problem with the string-based factory. What if my transaction class is parameterized and I have two specializations?

class Txn #(WIDTH) extends uvm_sequence_item;
  `uvm_object_utils(Txn)
  rand [WIDTH-1:0] data;
endclass

Txn #(16) txn16;
Txn #(32) txn32;

This defines two unrelated types, Txn#(16) and Txn#(32). If you only have the original class name, “Txn”, you can’t construct these two types. That is why UVM added the type-based factory.

Conclusion

Both UVM Factories allow you to create objects, either the base type or a derived, without changing the call to create(). This keeps your code base stable, reducing the verification time and ultimately the time to market.

Learn More

You can learn more about this including Oriented Programming with the Siemens SystemVerilog for Verification and UVM courses. They are offered in instructor led format by our industry expert instructors, or in a self-paced on-demand format. They 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 these topics 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.sw.siemens.com/verificationhorizons/2023/01/25/the-uvm-factory-revealed-part-2/