uvm_object¶
- class uvm.base.uvm_object.UVMObject(name: str)[source]¶
Bases:
sv_obj
The
UVMObject
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 ascreate
,copy
,compare
,print
, andrecord
. Classes deriving fromUVMObject
must implement methods such ascreate
andget_type_name
.Group: Seeding
- Variables
use_uvm_seeding (bool) – This bit enables or disables the UVM seeding
mechanism. It globally affects the operation of the
reseed
method.When enabled, UVM-based objects are seeded based on their type and full hierarchical name rather than allocation order. This improves random stability for objects whose instance names are unique across each type. The
UVMComponent
class is an example of a type that has a unique instance name.- type_id = None¶
- depth = 0¶
- m_inst_count = 214¶
- use_uvm_seeding = True¶
- uvm_global_copy_map = {}¶
- reseed() None [source]¶
Calls
srandom
on 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 the
use_uvm_seeding
static variable is set to 0, then reseed() does not perform any function.
- set_name(name: str)[source]¶
Sets the instance name of this object, overwriting any previously given name.
- Parameters
name (str) – Name for the object.
- get_name() str [source]¶
Returns the name of the object, as provided by the
name
argument in thenew
constructor orset_name
method.- Returns
Name of the object.
- Return type
- get_full_name() str [source]¶
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.
- 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.
- Return type
- classmethod get_inst_count() int [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.
- Return type
- get_type() None [source]¶
Returns the type-proxy (wrapper) for this object. The
UVMFactory
’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
None
. To enable use of this method, a user’s subtype must implement a version that returns the subtype’s wrapper.For example:
class cmd(UVMObject): type_id = None @classmethod def get_type(cls): return cls.type_id.get()
Then, to use:
factory.set_type_override(cmd.get_type(), subcmd.get_type())
This function is implemented by the uvm_*_utils functions, if employed.
Returns:
- get_object_type() Any [source]¶
Function: get_object_type
Returns the type-proxy (wrapper) for this object. The uvm_factory’s type-based override and creation methods take arguments of
uvm_object_wrapper
. This method, if implemented, can be used as convenient means of supplying those arguments. This method is the same as the staticget_type
method, 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_name
is not registered with the factory, then aNone
handle is returned.For example:
class cmd (UVMObject): type_id = UVMObjectRegistry() @classmethod def type_id get_type(cls): return type_id.get() def get_object_type(self): return cmd.type_id.get()
This function is implemented by the `uvm_*_utils macros, if employed.
Returns:
- get_type_name() str [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 (UVMObject): ... type_name = "mytype" def get_type_name(self): return my_type.type_name
We define the
type_name
static variable 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~.- Returns
Type name of the object.
- Return type
- create(name='') UVMObject [source]¶
Group: Creation
The
create
method 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 (UVMObject): ... def create(self, name=""): mytype t = mytype(name) return t
- Parameters
name (str) – Name of the created object.
- Returns
New object.
- Return type
obj
- clone() UVMObject [source]¶
The
clone
method creates and returns an exact copy of this object.The default implementation calls
create
followed bycopy
. As clone is virtual, derived classes may override this implementation if desired.- Returns
Clone of the object.
- Return type
- print_obj(printer=None) None [source]¶
Group: Printing
Function: print
The
print
method deep-prints this object’s properties in a format and manner governed by the givenprinter
argument; if theprinter
argument is not provided, the globaluvm_default_printer
is used. See uvm_printer for more information on printer output formatting. See alsouvm_line_printer
,uvm_tree_printer
, anduvm_table_printer
for details on the pre-defined printer “policies,” or formatters, provided by the UVM.The
print
method is not virtual and must not be overloaded. To include custom information in theprint
andsprint
operations, derived classes must override thedo_print
method and use the provided printer policy class to format the output.- Parameters
printer (UVMPrinter) – Printer that is used in printing.
- sprint(printer=None) str [source]¶
The
sprint
method works just like theprint
method, except the output is returned in a string rather than displayed.The
sprint
method is not virtual and must not be overloaded. To include additional fields in theprint
andsprint
operation, derived classes must override thedo_print
method and use the provided printer policy class to format the output. The printer policy will manage all string concatenations and provide the string tosprint
to return to the caller.- Parameters
printer (UVMPrinter) – Printer that is used in printing.
- Returns
String representation of the object.
- Return type
- do_print(printer) None [source]¶
The
do_print
method is the user-definable hook called byprint
andsprint
that 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
printer
argument is the policy object that governs the format and content of the output. To ensure correctprint
andsprint
operation, and to ensure a consistent output format, theprinter
must be used by alldo_print
implementations. That is, instead of using ~$display~ or string concatenations directly, ado_print
implementation must call through the ~printer’s~ API to add information to be printed or sprinted.An example implementation of
do_print
is as follows:class mytype (UVMObject): 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:
t = mytype() t.print() uvm_report_info("Received",t.sprint())
See
UVMPrinter
for information about the printer API.- Parameters
printer (UVMPrinter) – Printer that is used in printing.
- convert2string() str [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 a uvm_printer policy 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_print
API.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(UVMObject): field = "foo" def convert2string(self): return "base_field=" + self.field class Obj2(UVMObject): field = "bar" def convert2string() convert2string = "child_field=" + self.field class Obj(Base): addr = 0x123 data = 0x456 write = 1 child = Obj2() def convert2string(self): convert2string = super().convert2string() + sv.sformatf(" write=%0d addr=%8h data=%8h ",write,addr,data) + child.convert2string() Then, to display an object, you could write: .. code-block:: python o = Obj() uvm_report_info("BusMaster", "Sending:
” + 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
- Returns:
str: Object converted into string.
- record(recorder=None) None [source]¶
Group: Recording
The
record
method deep-records this object’s properties according to an optionalrecorder
policy. The method is not virtual and must not be overloaded. To include additional fields in the record operation, derived classes should override thedo_record
method.The optional
recorder
argument specifies the recording policy, which governs how recording takes place. See uvm_recorder for 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.
- Parameters
recorder (UVMRecorder) –
- do_record(recorder) None [source]¶
The
do_record
method is the user-definable hook called by therecord
method. A derived class should override this method to include its fields in a record operation.The
recorder
argument 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 therecorder
policy, thereby insulating user-code from vendor-specific behavior. See uvm_recorder for more information.A typical implementation is as follows:
class mytype (UVMObject): data_obj data int f1 def do_record (self, recorder): recorder.record_field("f1", f1, sv.bits(f1), UVM_DEC) recorder.record_object("data", data)
- Parameters
recorder (UVMRecorder) – Recorder policy object.
- copy(rhs: UVMObject)[source]¶
The copy makes this object a copy of the specified object.
The
copy
method is not virtual and should not be overloaded in derived classes. To copy the fields of a derived class, that class should override thedo_copy
method.- Parameters
rhs (UVMObject) – An object to be copied.
- do_copy(rhs) None [source]¶
The
do_copy
method is the user-definable hook called by thecopy
method. A derived class should override this method to include its fields in acopy
operation.A typical implementation is as follows:
class mytype (UVMObject): ... field_1 = 0 def do_copy(self, rhs): super.do_copy(rhs) # Optionanl type checking field_1 = rhs.field_1
The implementation must call
super().do_copy
, and can optionally do type checking before copying.- Parameters
rhs (UVMObject) – Object to be copied.
- compare(rhs, comparer=None) bool [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
compare
method is not virtual and should not be overloaded in derived classes. To compare the fields of a derived class, that class should override thedo_compare
method.The optional
comparer
argument 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_comparer
policy is used. See uvm_comparer for more information.- Parameters
rhs (UVMObject) – Object to be compared against.
comparer (UVMComparer) – Comparer policy object.
- Returns
True if objects match, False otherwise.
- Return type
- do_compare(rhs, comparer) bool [source]¶
The
do_compare
method is the user-definable hook called by thecompare
method. 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 (UVMObject): ... f1 = 0 def do_compare(self, rhs, comparer): do_compare = super.do_compare(rhs,comparer) # Optional type checking do_compare &= comparer.compare_field_int("f1", f1, rhs.f1) return do_compare
A derived class implementation must call
super().do_compare
to ensure its base class’ properties, if any, are included in the comparison. If type matching is required instead of duck-typing, the user can also implemented this checking.The actual comparison should be implemented using the
UVMComparer
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. SeeUVMComparer
for more details.- Parameters
rhs (UVMObject) –
comparer (UVMComparer) –
- Returns
True if objects match, False otherwise.
- Return type
- pack_ints(intstream: List, packer=None) Any [source]¶
Function: pack_ints
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_pack> method.
The optional
packer
argument specifies the packing policy, which governs the packing operation. If a packer policy is not provided, the global <uvm_default_packer> policy is used. See <uvm_packer> for more information.The return value is the total number of bits packed into the given array. Use the array’s built-in
size
method to get the number of bytes or ints consumed during the packing process.
- do_pack(packer) None [source]¶
Function: do_pack
The
do_pack
method is the user-definable hook called by the <pack> methods. A derived class should override this method to include its fields in a pack operation.The
packer
argument 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(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(len(myarray), 32) for index in range(len(myarray): packer.pack_field_int(myarray[index], 8) packer.pack_field_int(myshort, sv.bits(myshort)) packer.pack_object(myobj) endfunction
The implementation must call ~super.do_pack~ so 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
None
objects, pack 4’b0000. For non-None
objects, pack 4’b0001.
When the uvm_field_* macros are used, <Utility and Field Macros for Components and Objects>, the above meta information is included provided the <uvm_packer::use_metadata> variable is set for the packer.
Packing order does not need to match declaration order. However, unpacking order must match packing order.
- unpack_ints(intstream, packer=None) Any [source]¶
The unpack methods extract property values from an array of bits, bytes, or ints. The method of unpacking
must
exactly correspond to the method of packing. This is assured if (a) the samepacker
policy 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 <unpack> operation, derived classes should override the <do_unpack> method.
The optional
packer
argument specifies the packing policy, which governs both the pack and unpack operation. If a packer policy is not provided, then the globaluvm_default_packer
policy is used. See uvm_packer for more information.The return value is the actual number of bits unpacked from the given array.
- set_object_local(field_name: str, value: UVMObject, clone=1, recurse=1)[source]¶
These methods provide write access to integral, string, and uvm_object-based properties indexed by a
field_name
string. The object designer choose which, if any, properties will be accessible, and overrides the appropriate methods depending on the properties’ types. For objects, the optionalclone
argument specifies whether to clone thevalue
argument before assignment.The global
uvm_is_match
function is used to match the field names, sofield_name
may contain wildcards.An example implementation of all three methods is as follows.
class mytype(UVMObject): def __init__(self, name): super().__init__(name) self.myint = 0 self.mybyte = 0 self.myshort = 0 self.mystring = "" self.myobj = None # provide access to integral properties def set_int_local(self, field_name, value): if (uvm_is_match (field_name, "myint")): self.myint = value elif (uvm_is_match (field_name, "mybyte")): selef.mybyte = value # provide access to string properties def set_string_local(self, field_name, value): if (uvm_is_match (field_name, "mystring")): self.mystring = value # provide access to sub-objects def set_object_local(self, field_name, value,clone=1): if (uvm_is_match (field_name, "myobj")): if (value is not None): tmp = None # if provided value is not correct type, produce error if (!$cast(tmp, value)): # error else: if(clone) self.myobj = tmp.clone() else self.myobj = tmp else: myobj = None # value is None, so simply assign None to myobj end ...
Although the object designer implements these methods to provide outside access to one or more properties, they are intended for internal use (e.g., for command-line debugging and auto-configuration) and should not be called directly by the user.