Example: documenting UVM¶
The extension documents the full UVM library end-to-end from its NaturalDocs-commented source — the project’s Phase-2 acceptance target. A real build produces ~5700 documented objects in a few seconds.
This page is generated live from the UVM sources in this repository (fetched
by ivpm into packages/uvm). Scroll to Rendered UVM reference for the rendered
output.
Configuration¶
Point the extension at uvm_pkg.sv as the build-unit root, with the UVM source
directory on the include path:
extensions = ["sphinx_systemverilog"]
sv_build_units = ["/path/to/uvm/src/uvm_pkg.sv"]
sv_include_dirs = ["/path/to/uvm/src"]
sv_doc_style = "naturaldocs"
uvm_pkg.sv `includes the entire library, so a single build unit
elaborates all of UVM into one project-wide index.
What you get:
Inheritance —
uvm_object extends uvm_void,uvm_component extends uvm_report_object, etc., with an inheritance diagram.Members —
externmethod prototypes (which UVM uses throughout) are documented with their signatures.Groups — UVM
Group:headers (Seeding,Identification, …) become labeled subsections.Prose — detached
// Function -- NODOCS -- nameblocks, separated from their prototypes by@uvm-ieeeannotations, are associated correctly, with<xref>and~code~markup converted.
Documenting the whole library at once¶
Rather than listing classes by hand, generate the entire UVM API tree with a single whole-tree directive:
.. autosvsummary::
:packages: uvm_pkg
:kinds: class
Diagnostics¶
UVM elaborates with many benign lint-style warnings (width truncation, dangling
else, …). These are not surfaced as build warnings; they are counted and
reported once at INFO level. Only genuine parse errors are surfaced.
Rendered UVM reference¶
When the UVM sources are present, the classes below are pulled directly from
them (otherwise this section is empty — run ivpm update -a to fetch UVM).
- class uvm_object extends uvm_void[source]¶
The uvm_object class is the base class for all UVM data and hierarchical classes. Its primary role is to define a set of methods for such common operations as
create,copy,compare,print, andrecord. Classes deriving from uvm_object must implement the pure virtual methods such ascreateandget_type_name.
- function new(string name)[source]¶
Creates a new uvm_object with the given instance
name. Ifnameis not supplied, the object is unnamed.
Seeding
- function reseed()[source]¶
Calls
srandomon the object to reseed the object using the UVM seeding mechanism, which sets the seed based on type name and instance name instead of based on instance position in a thread.If
get_uvm_seedingreturns 0, then reseed() does not perform any function.
Identification
- function set_name(string name)[source]¶
Sets the instance name of this object, overwriting any previously given name.
- function get_name()[source]¶
Returns the name of the object, as provided by the
nameargument in thenewconstructor orset_namemethod.
- function get_full_name()[source]¶
Returns the full hierarchical name of this object. The default implementation is the same as
get_name, as uvm_objects do not inherently possess hierarchy.Objects possessing hierarchy, such as
uvm_components, override the default implementation. Other objects might be associated with component hierarchy but are not themselves components. For example, <uvm_sequence #(REQ,RSP)> classes are typically associated with a <uvm_sequencer #(REQ,RSP)>. In this case, it is useful to override get_full_name to return the sequencer’s full name concatenated with the sequence’s name. This provides the sequence a full context, which is useful when debugging.
- static function get_inst_count()[source]¶
Returns the current value of the instance counter, which represents the total number of uvm_object-based objects that have been allocated in simulation. The instance counter is used to form a unique numeric instance identifier.
- static function get_type()[source]¶
Returns the type-proxy (wrapper) for this object. The
uvm_factory’s type-based override and creation methods take arguments ofuvm_object_wrapper. This method, if implemented, can be used as convenient means of supplying those arguments.The default implementation of this method produces an error and returns
null. To enable use of this method, a user’s subtype must implement a version that returns the subtype’s wrapper.For example:
| class cmd extends uvm_object; | typedef uvm_object_registry #(cmd) type_id; | static function type_id get_type(); | return type_id::get(); | endfunction | endclass
Then, to use:
| factory.set_type_override(cmd::get_type(),subcmd::get_type());
This function is implemented by the `uvm_*_utils macros, if employed.
- function get_object_type()[source]¶
Returns the type-proxy (wrapper) for this object. The
uvm_factory’s type-based override and creation methods take arguments ofuvm_object_wrapper. This method, if implemented, can be used as convenient means of supplying those arguments. This method is the same as the staticget_typemethod, but uses an already allocated object to determine the type-proxy to access (instead of using the static object).The default implementation of this method does a factory lookup of the proxy using the return value from
get_type_name. If the type returned byget_type_nameis not registered with the factory, then anullhandle is returned.For example:
| class cmd extends uvm_object; | typedef uvm_object_registry #(cmd) type_id; | static function type_id get_type(); | return type_id::get(); | endfunction | virtual function type_id get_object_type(); | return type_id::get(); | endfunction | endclass
This function is implemented by the `uvm_*_utils macros, if employed.
- function get_type_name()[source]¶
This function returns the type name of the object, which is typically the type identifier enclosed in quotes. It is used for various debugging functions in the library, and it is used by the factory for creating objects.
This function must be defined in every derived class.
A typical implementation is as follows:
| class mytype extends uvm_object; | … | static function string type_name(); return “myType”; endfunction : type_name | | virtual function string get_type_name(); | return type_name; | endfunction
We define the
type_namestatic method to enable access to the type name without need of an object of the class, i.e., to enable access via the scope operator,mytype::type_name.
Creation
- function create(string name)[source]¶
The
createmethod allocates a new object of the same type as this object and returns it via a base uvm_object handle. Every class deriving from uvm_object, directly or indirectly, must implement the create method.A typical implementation is as follows:
| class mytype extends uvm_object; | … | virtual function uvm_object create(string name=””); | mytype t = new(name); | return t; | endfunction
- function clone()[source]¶
The
clonemethod creates and returns an exact copy of this object.The default implementation calls
createfollowed bycopy. As clone is virtual, derived classes may override this implementation if desired.
Printing
- function print(uvm_printer printer)[source]¶
The
printmethod deep-prints this object’s properties in a format and manner governed by the givenprinterargument; if theprinterargument is not provided, the globaluvm_default_printeris used. Seeuvm_printerfor more information on printer output formatting. See alsouvm_line_printer,uvm_tree_printer, anduvm_table_printerfor details on the pre-defined printer “policies,” or formatters, provided by the UVM.The
printmethod is not virtual and must not be overloaded. To include custom information in theprintandsprintoperations, derived classes must override thedo_printmethod and use the provided printer policy class to format the output.
- function sprint(uvm_printer printer)[source]¶
The
sprintmethod works just like theprintmethod, except the output is returned in a string rather than displayed.The
sprintmethod is not virtual and must not be overloaded. To include additional fields in theprintandsprintoperation, derived classes must override thedo_printmethod and use the provided printer policy class to format the output. The printer policy will manage all string concatenations and provide the string tosprintto return to the caller.
- function do_print(uvm_printer printer)[source]¶
The
do_printmethod is the user-definable hook called byprintandsprintthat allows users to customize what gets printed or sprinted beyond the field information provided by the `uvm_field_* macros, <Utility and Field Macros for Components and Objects>.The
printerargument is the policy object that governs the format and content of the output. To ensure correctprintandsprintoperation, and to ensure a consistent output format, theprintermust be used by alldo_printimplementations. That is, instead of using$displayor string concatenations directly, ado_printimplementation must call through theprinter'sAPI to add information to be printed or sprinted.An example implementation of
do_printis as follows:| class mytype extends uvm_object; | data_obj data; | int f1; | virtual function void do_print (uvm_printer printer); | super.do_print(printer); | printer.print_field_int(“f1”, f1, $bits(f1), UVM_DEC); | printer.print_object(“data”, data); | endfunction
Then, to print and sprint the object, you could write:
| mytype t = new; | t.print(); | uvm_report_info(“Received”,t.sprint());
See
uvm_printerfor information about the printer API.
- function convert2string()[source]¶
This virtual function is a user-definable hook, called directly by the user, that allows users to provide object information in the form of a string. Unlike
sprint, there is no requirement to use auvm_printerpolicy object. As such, the format and content of the output is fully customizable, which may be suitable for applications not requiring the consistent formatting offered by theprint/sprint/do_printAPI.Fields declared in <Utility Macros> macros (`uvm_field_*), if used, will not automatically appear in calls to convert2string.
An example implementation of convert2string follows.
| class base extends uvm_object; | string field = “foo”; | virtual function string convert2string(); | convert2string = {“base_field=”,field}; | endfunction | endclass | | class obj2 extends uvm_object; | string field = “bar”; | virtual function string convert2string(); | convert2string = {“child_field=”,field}; | endfunction | endclass | | class obj extends base; | int addr = ‘h123; | int data = ‘h456; | bit write = 1; | obj2 child = new; | virtual function string convert2string(); | convert2string = {super.convert2string(), | $sformatf(” write=%0d addr=%8h data=%8h “,write,addr,data), | child.convert2string()}; | endfunction | endclass
Then, to display an object, you could write:
| obj o = new; | uvm_report_info(“BusMaster”,{“Sending:n “,o.convert2string()});
The output will look similar to:
| UVM_INFO @ 0: reporter [BusMaster] Sending: | base_field=foo write=1 addr=00000123 data=00000456 child_field=bar
Recording
- function record(uvm_recorder recorder)[source]¶
The
recordmethod deep-records this object’s properties according to an optionalrecorderpolicy. The method is not virtual and must not be overloaded. To include additional fields in the record operation, derived classes should override thedo_recordmethod.The optional
recorderargument specifies the recording policy, which governs how recording takes place. Seeuvm_recorderfor information.A simulator’s recording mechanism is vendor-specific. By providing access via a common interface, the uvm_recorder policy provides vendor-independent access to a simulator’s recording capabilities.
- function do_record(uvm_recorder recorder)[source]¶
The
do_recordmethod is the user-definable hook called by therecordmethod. A derived class should override this method to include its fields in a record operation.The
recorderargument is policy object for recording this object. A do_record implementation should call the appropriate recorder methods for each of its fields. Vendor-specific recording implementations are encapsulated in therecorderpolicy, thereby insulating user-code from vendor-specific behavior. Seeuvm_recorderfor more information.A typical implementation is as follows:
| class mytype extends uvm_object; | data_obj data; | int f1; | function void do_record (uvm_recorder recorder); | recorder.record_field(“f1”, f1, $bits(f1), UVM_DEC); | recorder.record_object(“data”, data); | endfunction
Copying
- function copy(uvm_object rhs, uvm_copier copier)[source]¶
The copy makes this object a copy of the specified object.
The
copymethod is not virtual and should not be overloaded in derived classes. To copy the fields of a derived class, that class should override thedo_copymethod.
- function do_copy(uvm_object rhs)[source]¶
The
do_copymethod is the user-definable hook called by thecopymethod. A derived class should override this method to include its fields in acopyoperation.A typical implementation is as follows:
| class mytype extends uvm_object; | … | int f1; | function void do_copy (uvm_object rhs); | mytype rhs_; | super.do_copy(rhs); | $cast(rhs_,rhs); | field_1 = rhs_.field_1; | endfunction
The implementation must call
super.do_copy, and it must $cast the rhs argument to the derived type before copying.
Comparing
- function compare(uvm_object rhs, uvm_comparer comparer)[source]¶
Deep compares members of this data object with those of the object provided in the
rhs(right-hand side) argument, returning 1 on a match, 0 otherwise.The
comparemethod is not virtual and should not be overloaded in derived classes. To compare the fields of a derived class, that class should override thedo_comparemethod.The optional
comparerargument specifies the comparison policy. It allows you to control some aspects of the comparison operation. It also stores the results of the comparison, such as field-by-field miscompare information and the total number of miscompares. If a compare policy is not provided, then the globaluvm_default_comparerpolicy is used. Seeuvm_comparerfor more information.
- function do_compare(uvm_object rhs, uvm_comparer comparer)[source]¶
The
do_comparemethod is the user-definable hook called by thecomparemethod. A derived class should override this method to include its fields in a compare operation. It should return 1 if the comparison succeeds, 0 otherwise.A typical implementation is as follows:
| class mytype extends uvm_object; | … | int f1; | virtual function bit do_compare (uvm_object rhs,uvm_comparer comparer); | mytype rhs_; | do_compare = super.do_compare(rhs,comparer); | $cast(rhs_,rhs); | do_compare &= comparer.compare_field_int(“f1”, f1, rhs_.f1); | endfunction
A derived class implementation must call
super.do_compare()to ensure its base class’ properties, if any, are included in the comparison. Also, the rhs argument is provided as a generic uvm_object. Thus, you must$castit to the type of this object before comparing.The actual comparison should be implemented using the uvm_comparer object rather than direct field-by-field comparison. This enables users of your class to customize how comparisons are performed and how much miscompare information is collected. See uvm_comparer for more details.
Packing
- function pack_ints(ref int unsigned$[] intstream, uvm_packer packer)[source]¶
The pack methods bitwise-concatenate this object’s properties into an array of bits, bytes, or ints. The methods are not virtual and must not be overloaded. To include additional fields in the pack operation, derived classes should override the
do_packmethod.The optional
packerargument specifies the packing policy, which governs the packing operation. If a packer policy is not provided, the globaluvm_default_packerpolicy is used. Seeuvm_packerfor more information.The return value is the total number of bits packed into the given array. Use the array’s built-in
sizemethod to get the number of bytes or ints consumed during the packing process.
- function pack_longints(ref longint unsigned$[] longintstream, uvm_packer packer)[source]¶
@uvm-ieee 1800.2-2020 auto 5.3.10.1
- function do_pack(uvm_packer packer)[source]¶
The
do_packmethod is the user-definable hook called by thepackmethods. A derived class should override this method to include its fields in a pack operation.The
packerargument is the policy object for packing. The policy object should be used to pack objects.A typical example of an object packing itself is as follows
| class mysubtype extends mysupertype; | … | shortint myshort; | obj_type myobj; | byte myarray[]; | … | function void do_pack (uvm_packer packer); | super.do_pack(packer); // pack mysupertype properties | packer.pack_field_int(myarray.size(), 32); | foreach (myarray) | packer.pack_field_int(myarray[index], 8); | packer.pack_field_int(myshort, $bits(myshort)); | packer.pack_object(myobj); | endfunction
The implementation must call
super.do_packso that base class properties are packed as well.If your object contains dynamic data (object, string, queue, dynamic array, or associative array), and you intend to unpack into an equivalent data structure when unpacking, you must include meta-information about the dynamic data when packing as follows.
For queues, dynamic arrays, or associative arrays, pack the number of elements in the array in the 32 bits immediately before packing individual elements, as shown above.
For string data types, append a zero byte after packing the string contents.
For objects, pack 4 bits immediately before packing the object. For
nullobjects, pack 4’b0000. For non-nullobjects, pack 4’b0001.
When the `uvm_field_* macros are used, <Utility and Field Macros for Components and Objects>, the above meta information is included.
Packing order does not need to match declaration order. However, unpacking order must match packing order.
Unpacking
- function unpack_ints(ref int unsigned$[] intstream, uvm_packer packer)[source]¶
The unpack methods extract property values from an array of bits, bytes, or ints. The method of unpacking
mustexactly correspond to the method of packing. This is assured if (a) the samepackerpolicy is used to pack and unpack, and (b) the order of unpacking is the same as the order of packing used to create the input array.The unpack methods are fixed (non-virtual) entry points that are directly callable by the user. To include additional fields in the
unpackoperation, derived classes should override thedo_unpackmethod.The optional
packerargument specifies the packing policy, which governs both the pack and unpack operation. If a packer policy is not provided, then the globaluvm_default_packerpolicy is used. See uvm_packer for more information.The return value is the actual number of bits unpacked from the given array.
- function unpack_longints(ref longint unsigned$[] longintstream, uvm_packer packer)[source]¶
@uvm-ieee 1800.2-2020 auto 5.3.11.1
- function do_unpack(uvm_packer packer)[source]¶
The
do_unpackmethod is the user-definable hook called by theunpackmethod. A derived class should override this method to include its fields in an unpack operation.The
packerargument is the policy object for both packing and unpacking. It must be the same packer used to pack the object into bits. Also, do_unpack must unpack fields in the same order in which they were packed. Seeuvm_packerfor more information.The following implementation corresponds to the example given in do_pack.
| function void do_unpack (uvm_packer packer); | int sz; | super.do_unpack(packer); // unpack super’s properties | sz = packer.unpack_field_int(myarray.size(), 32); | myarray.delete(); | for(int index=0; index<sz; index++) | myarray[index] = packer.unpack_field_int(8); | myshort = packer.unpack_field_int($bits(myshort)); | packer.unpack_object(myobj); | endfunction
If your object contains dynamic data (object, string, queue, dynamic array, or associative array), and you intend to
unpackinto an equivalent data structure, you must have included meta-information about the dynamic data when it was packed.For queues, dynamic arrays, or associative arrays, unpack the number of elements in the array from the 32 bits immediately before unpacking individual elements, as shown above.
For string data types, unpack into the new string until a
nullbyte is encountered.For objects, unpack 4 bits into a byte or int variable. If the value is 0, the target object should be set to
nulland unpacking continues to the next property, if any. If the least significant bit is 1, then the target object should be allocated and its properties unpacked.
Configuration
- local function m_pack(inout uvm_packer packer)[source]¶
**** Internal Methods and Properties *** Do not use directly
- local property string m_leaf_name[source]¶
The print_matches bit causes an informative message to be printed when a field is set using one of the set methods.
- function set_int_local(string field_name, uvm_pkg::uvm_bitstream_t value, bit recurse)[source]¶
@uvm-compat for compatibility with 1.2
- class uvm_sequence_item extends uvm_transaction[source]¶
The base class for user-defined sequence items and also the base class for the uvm_sequence class. The uvm_sequence_item class provides the basic functionality for objects, both sequence items and sequences, to operate in the sequence mechanism.
- function get_type_name()[source]¶
Returns the value given by the string parameter,
Tname. This method overrides the method inuvm_object_wrapper.
- static function get_type()[source]¶
Static function that returns the static type handle. The return type is this_type, which is the type of the parameterized class.
- function get_object_type()[source]¶
Returns the type-proxy (wrapper) for this object. The
uvm_factory’s type-based override and creation methods take arguments ofuvm_object_wrapper. This method, if implemented, can be used as convenient means of supplying those arguments. This method is the same as the staticget_typemethod, but uses an already allocated object to determine the type-proxy to access (instead of using the static object).The default implementation of this method does a factory lookup of the proxy using the return value from
get_type_name. If the type returned byget_type_nameis not registered with the factory, then anullhandle is returned.For example:
| class cmd extends uvm_object; | typedef uvm_object_registry #(cmd) type_id; | static function type_id get_type(); | return type_id::get(); | endfunction | virtual function type_id get_object_type(); | return type_id::get(); | endfunction | endclass
This function is implemented by the `uvm_*_utils macros, if employed.
- function get_sequence_id()[source]¶
private
Get_sequence_id is an internal method that is not intended for user code. The sequence_id is not a simple integer. The get_transaction_id is meant for users to identify specific transactions.
These methods allow access to the sequence_item sequence and transaction IDs. get_transaction_id and set_transaction_id are methods on the uvm_transaction base_class. These IDs are used to identify sequences to the sequencer, to route responses back to the sequence that issued a request, and to uniquely identify transactions.
The sequence_id is assigned automatically by a sequencer when a sequence initiates communication through any sequencer calls (i.e. `uvm_do_*, wait_for_grant). A sequence_id will remain unique for this sequence until it ends or it is killed. However, a single sequence may have multiple valid sequence ids at any point in time. Should a sequence start again after it has ended, it will be given a new unique sequence_id.
The transaction_id is assigned automatically by the sequence each time a transaction is sent to the sequencer with the transaction_id in its default (-1) value. If the user sets the transaction_id to any non-default value, that value will be maintained.
Responses are routed back to this sequences based on sequence_id. The sequence may use the transaction_id to correlate responses with their requests.
- function set_item_context(uvm_sequence_base parent_seq, uvm_sequencer_base sequencer)[source]¶
Set the sequence and sequencer execution context for a sequence item
- function get_use_sequence_info()[source]¶
These methods are used to set and get the status of the use_sequence_info bit. Use_sequence_info controls whether the sequence information (sequencer, parent_sequence, sequence_id, etc.) is printed, copied, or recorded. When use_sequence_info is the default value of 0, then the sequence information is not used. When use_sequence_info is set to 1, the sequence information will be used in printing and copying.
- function set_id_info(uvm_sequence_item item)[source]¶
Copies the sequence_id and transaction_id from the referenced item into the calling item. This routine should always be used by drivers to initialize responses for future compatibility.
- function set_sequencer(uvm_sequencer_base sequencer)[source]¶
Sets the default sequencer for the sequence to sequencer. It will take effect immediately, so it should not be called while the sequence is actively communicating with the sequencer.
- function get_sequencer()[source]¶
Returns a reference to the default sequencer used by this sequence.
- function set_parent_sequence(uvm_sequence_base parent)[source]¶
Sets the parent sequence of this sequence_item. This is used to identify the source sequence of a sequence_item.
- function get_parent_sequence()[source]¶
Returns a reference to the parent sequence of any sequence on which this method was called. If this is a parent sequence, the method returns
null.
- function set_depth(int value)[source]¶
The depth of any sequence is calculated automatically. However, the user may use set_depth to specify the depth of a particular sequence. This method will override the automatically calculated depth, even if it is incorrect.
- function get_depth()[source]¶
Returns the depth of a sequence from its parent. A parent sequence will have a depth of 1, its child will have a depth of 2, and its grandchild will have a depth of 3.
- function is_item()[source]¶
This function may be called on any sequence_item or sequence. It will return 1 for items and 0 for sequences (which derive from this class).
- function get_root_sequence_name()[source]¶
Provides the name of the root sequence (the top-most parent sequence).
- function get_root_sequence()[source]¶
Provides a reference to the root sequence (the top-most parent sequence).
- function get_sequence_path()[source]¶
Provides a string of names of each sequence in the full hierarchical path. A “.” is used as the separator between each sequence.
Reporting Interface
- function uvm_get_report_object()[source]¶
Returns the nearest uvm_report_object when called. From inside a uvm_component, the method simply returns
this.See also the global version of
uvm_get_report_object.
- function uvm_report_enabled(int verbosity, uvm_pkg::uvm_severity severity, string id)[source]¶
Returns 1 if the configured verbosity for this severity/id is greater than or equal to
verbosityelse returns 0.See also
get_report_verbosity_leveland the global version ofuvm_report_enabled.
- function uvm_report(uvm_pkg::uvm_severity severity, string id, string message, int verbosity, string filename, int line, string context_name, bit report_enabled_checked)[source]¶
- function uvm_report_info(string id, string message, int verbosity, string filename, int line, string context_name, bit report_enabled_checked)[source]¶
- function uvm_report_warning(string id, string message, int verbosity, string filename, int line, string context_name, bit report_enabled_checked)[source]¶
- function uvm_report_error(string id, string message, int verbosity, string filename, int line, string context_name, bit report_enabled_checked)[source]¶
- function uvm_report_fatal(string id, string message, int verbosity, string filename, int line, string context_name, bit report_enabled_checked)[source]¶
These are the primary reporting methods in the UVM. uvm_sequence_item derived types delegate these functions to their associated sequencer if they have one, or to the global reporter. See
uvm_report_object::Reportingfor details on the messaging functions.