Factory Overriding
Based on the requirement, the behavior of the testbench can be changed by substituting one class with another when it is constructed. This facility of the uvm factory allows users to override the class without editing or recompiling the code.
How factory overriding happens?
A factory can be thought of as a look-up table and a factory component wrapper class can be accessed using type_id which is used in create method and returns a resultant handle. Using the polymorphism concept, the factory override mechanism returns a derived type handle using a base type handle. This means when the create method is being called for the base class type, uvm_factory will return a pointer to an object of a derived class type.
Factory overriding ways
- Type Override
- Instance Override
Note: The factory override ways are applicable for both uvm components and uvm objects.
Type override in UVM factory
In a type override, a substitute component class type is created instead of an original component class in the testbench hierarchy. This applies to all instances of that component type.
Methods of type override in UVM factory
- set_type_override_by_type
- set_type_override_by_name
Syntax for set_type_override_by_type:
function void set_type_override_by_type (uvm_object_wrapper original_type,
uvm_object_wrapper override_type,
bit replace = 1)
Syntax for set_type_override_by_name:
function void set_type_override_by_name (string original_type_name,
string override_type_name,
bit replace = 1)
Example with set_inst_override_by_type
`include "uvm_macros.svh"
import uvm_pkg::*;
class component_A extends uvm_component;
`uvm_component_utils(component_A)
function new(string name = "component_A", uvm_component parent = null);
super.new(name, parent);
endfunction
virtual function display();
`uvm_info(get_type_name(), $sformatf("inside component_A"), UVM_LOW);
endfunction
endclass
class component_B extends component_A;
`uvm_component_utils(component_B)
function new(string name = "component_B", uvm_component parent = null);
super.new(name, parent);
endfunction
function display();
`uvm_info(get_type_name(), "inside component_B", UVM_LOW);
endfunction
endclass
class my_test extends uvm_test;
`uvm_component_utils(my_test)
component_A comp_A;
function new(string name = "my_test", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
uvm_factory factory = uvm_factory::get();
super.build_phase(phase);
set_type_override_by_type(component_A::get_type(), component_B::get_type());
comp_A = component_A::type_id::create("comp_A", this);
factory.print();
endfunction
function void end_of_elaboration_phase(uvm_phase phase);
super.end_of_elaboration_phase(phase);
uvm_top.print_topology();
endfunction
task run_phase(uvm_phase phase);
super.run_phase(phase);
comp_A.display();
endtask
endclass
module tb_top;
initial begin
run_test("my_test");
end
endmodule
Output:
#### Factory Configuration (*)
No instance overrides are registered with this factory
Type Overrides:
Requested Type Override Type
-------------- -------------
component_A component_B
All types registered with the factory: 53 total
Type Name
---------
component_A
component_B
my_test
(*) Types with no associated type name will be printed as <unknown>
####
UVM_INFO /xcelium20.09/tools//methodology/UVM/CDNS-1.2/sv/src/base/uvm_root.svh(605) @ 0: reporter [UVMTOP] UVM testbench topology:
--------------------------------------
Name Type Size Value
--------------------------------------
uvm_test_top my_test - @1807
comp_A component_B - @1876
--------------------------------------
UVM_INFO testbench.sv(26) @ 0: uvm_test_top.comp_A [component_B] inside component_B
Example with set_type_override_by_name
`include "uvm_macros.svh"
import uvm_pkg::*;
class component_A extends uvm_component;
`uvm_component_utils(component_A)
function new(string name = "component_A", uvm_component parent = null);
super.new(name, parent);
endfunction
virtual function display();
`uvm_info(get_type_name(), $sformatf("inside component_A"), UVM_LOW);
endfunction
endclass
class component_B extends component_A;
`uvm_component_utils(component_B)
function new(string name = "component_B", uvm_component parent = null);
super.new(name, parent);
endfunction
function display();
`uvm_info(get_type_name(), "inside component_B", UVM_LOW);
endfunction
endclass
class my_test extends uvm_test;
`uvm_component_utils(my_test)
component_A comp_A;
function new(string name = "my_test", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
uvm_factory factory = uvm_factory::get();
super.build_phase(phase);
factory.set_type_override_by_name("component_A", "component_B");
comp_A = component_A::type_id::create("comp_A", this);
factory.print();
endfunction
function void end_of_elaboration_phase(uvm_phase phase);
super.end_of_elaboration_phase(phase);
uvm_top.print_topology();
endfunction
task run_phase(uvm_phase phase);
super.run_phase(phase);
comp_A.display();
endtask
endclass
module tb_top;
initial begin
run_test("my_test");
end
endmodule
Output:
#### Factory Configuration (*)
No instance overrides are registered with this factory
Type Overrides:
Requested Type Override Type
-------------- -------------
component_A component_B
All types registered with the factory: 53 total
Type Name
---------
component_A
component_B
my_test
(*) Types with no associated type name will be printed as <unknown>
####
UVM_INFO /xcelium20.09/tools//methodology/UVM/CDNS-1.2/sv/src/base/uvm_root.svh(605) @ 0: reporter [UVMTOP] UVM testbench topology:
--------------------------------------
Name Type Size Value
--------------------------------------
uvm_test_top my_test - @1807
comp_A component_B - @1878
--------------------------------------
UVM_INFO testbench.sv(26) @ 0: uvm_test_top.comp_A [component_B] inside component_B
UVM Tutorials