yes, both object classes and component classes can be overridden hence
"ovm_object_utils" and "ovm_componenet_utils"
What is a factory?
ovm_factory - creates objects and components according to user-defined type and instance-based overrides.
ovm_factory is used to manufacture (create) OVM objects and components. Only one instance of the factory is present in a given simulation (termed a singleton). Object and component types are registered with the factory using lightweight proxies to the actual objects and components being created. The
ovm_object_registry #(T,Tname) and
ovm_component_registry #(T,Tname) class are used to proxy
ovm_objects and
ovm_components.
Preregistration requirements:
When overriding by type, the
original_type and
override_type are handles to the types’ proxy objects. Preregistration is not required.
When overriding by name, the
original_type_name typically refers to a preregistered type in the factory. It may, however, be any arbitrary string. Future calls to any of the create_* methods with the same string and matching instance path will produce the type represented by
override_type_name, which must be preregistered with the factory.
It is worth noting that environments that exclusively use the type-based factory methods (*_by_type) do not require type registration. The factory’s type-based methods will register the types involved “on the fly,” when first used. However, registering with the `ovm_*_utils macros enables name-based factory usage and implements some useful utility functions.
A
full_inst_path of “*” is effectively a type override, as it will match all contexts.
Registering order does that matter?
Yes, it does.
When the factory processes instance overrides, the instance queue is processed in order of override registrations, and the first override match prevails. Thus, more specific overrides should be registered first, followed by more general overrides.
How is searching for overrides done?
Override searches are recursively applied, with instance overrides taking precedence over type overrides. If
foo overrides
bar, and
xyz overrides
foo, then a request for
bar will produce
xyz. Recursive loops will result in an error, in which case the type returned will be that which formed the loop. Using the previous example, if
bar overrides
xyz, then
bar is returned after the error is issued.
what is ovm_object_wrapper?
Ah, the very important thing of factory concept. The ovm_object_wrapper provides an abstract interface for creating object and component proxies. Instances of these lightweight proxies, representing every
ovm_object-based and
ovm_component-based object available in the test environment, are registered with the
ovm_factory. When the factory is called upon to create an object or component, it finds and delegates the request to the appropriate proxy.
what does the utility macro for objects/components registry do ?
The `ovm_*_utils macros for simple, non-parameterized classes will register the type with the factory and define the get_type, get_type_name, and create virtual methods inherited from
ovm_object. It will also define a static type_name variable in the class, which will allow you to determine the type without having to allocate an instance.
what about these (factory) utility macros for parameterized classes?
The `ovm_*_param_utils macros for parameterized classes differ from `ovm_*_utils classes in "The get_type_name method and static type_name variable are not defined. You will need to implement these manually"
any name based methods/operations will not work.
http://ovmworld.org/docs_2.1.1/html/files/base/ovm_factory-svh.html