Object Overriding in UVM factory
The uvm_object or sequence overriding is similar to the uvm_component overriding factory mechanism that returns the derived object handle using a base class handle. For overriding uvm_object or sequences, type overriding is recommended to use since instance overriding requires a hierarchical path. But instance override is also possible provided the correct instance path has been mentioned either by arbitrary string or get_full_name() call.
Example with set_type_override
class base_obj extends uvm_object;
`uvm_object_utils(base_obj)
function new(string name = "base_obj");
super.new(name);
endfunction
virtual function display();
`uvm_info(get_type_name(), $sformatf("inside base_obj"), UVM_LOW);
endfunction
endclass
class child_obj extends base_obj;
`uvm_object_utils(child_obj)
function new(string name = "child_obj");
super.new(name);
endfunction
function display();
`uvm_info(get_type_name(), "inside child_obj", UVM_LOW);
endfunction
endclass
class my_test extends uvm_test;
`uvm_component_utils(my_test)
base_obj obj_b;
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);
base_obj::type_id::set_type_override(child_obj::get_type());
obj_b = base_obj::type_id::create("obj_b");
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);
obj_b.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
-------------- -------------
base_obj child_obj
All types registered with the factory: 53 total
Type Name
---------
base_obj
child_obj
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 - @1809
----------------------------------
UVM_INFO testbench.sv(26) @ 0: reporter [child_obj] inside child_obj
Example with set_inst_override
class base_obj extends uvm_object;
`uvm_object_utils(base_obj)
function new(string name = "base_obj");
super.new(name);
endfunction
virtual function display();
`uvm_info(get_type_name(), $sformatf("inside base_obj"), UVM_LOW);
endfunction
endclass
class child_obj extends base_obj;
`uvm_object_utils(child_obj)
function new(string name = "child_obj");
super.new(name);
endfunction
function display();
`uvm_info(get_type_name(), "inside child_obj", UVM_LOW);
endfunction
endclass
class my_test extends uvm_test;
`uvm_component_utils(my_test)
base_obj obj_b;
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);
//base_obj::type_id::set_inst_override(child_obj::get_type(), "this.obj_b");
// or
base_obj::type_id::set_inst_override(child_obj::get_type(), "get_full_name().obj_b");
obj_b = base_obj::type_id::create("obj_b");
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);
obj_b.display();
endtask
endclass
module tb_top;
initial begin
run_test("my_test");
end
endmodule
Output:
#### Factory Configuration (*)
Instance Overrides:
Requested Type Override Path Override Type
-------------- --------------------- -------------
base_obj get_full_name().obj_b child_obj
No type overrides are registered with this factory
All types registered with the factory: 53 total
Type Name
---------
base_obj
child_obj
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 - @1809
----------------------------------
UVM_INFO testbench.sv(14) @ 0: reporter [base_obj] inside base_obj
Note: For parameterized classes, an overriding class should have the same parameter values.
Example for set_type_override_by_type with parameterized classes
class component_A #(parameter ID_WIDTH = 8) extends uvm_component;
bit [ID_WIDTH-1:0] id;
`uvm_component_param_utils(component_A #(ID_WIDTH))
function new(string name = "component_A", uvm_component parent = null);
super.new(name, parent);
id = 1;
endfunction
virtual function display();
`uvm_info(get_type_name(), $sformatf("inside component_A: ID_WIDTH = %0d, id = %0d", ID_WIDTH, id), UVM_LOW);
endfunction
endclass
class component_B #(int ID_WIDTH = 8) extends component_A #(ID_WIDTH);
bit [ID_WIDTH-1:0] id;
`uvm_component_param_utils(component_B #(ID_WIDTH))
function new(string name = "component_B", uvm_component parent = null);
super.new(name, parent);
id = 2;
endfunction
function display();
`uvm_info(get_type_name(), $sformatf("inside component_B: ID_WIDTH = %0d, id = %0d", ID_WIDTH, id), UVM_LOW);
endfunction
endclass
class my_test extends uvm_test;
`uvm_component_utils(my_test)
component_A #(32) 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 #(32)::get_type(), component_B #(32)::get_type());
// or
//component_A #(32)::type_id::set_type_override(component_B #(32)::get_type());
comp_A = component_A #(32)::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
-------------- -------------
<unknown> <unknown>
All types registered with the factory: 53 total
Type Name
---------
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 - @1805
comp_A uvm_component - @1874
----------------------------------------
UVM_INFO testbench.sv(30) @ 0: uvm_test_top.comp_A [uvm_component] inside component_B: ID_WIDTH = 32, id = 2
If an overriding class has different parameter values, factory overriding will fail.
class component_A #(parameter ID_WIDTH = 8) extends uvm_component;
bit [ID_WIDTH-1:0] id;
`uvm_component_param_utils(component_A #(ID_WIDTH))
function new(string name = "component_A", uvm_component parent = null);
super.new(name, parent);
id = 1;
endfunction
virtual function display();
`uvm_info(get_type_name(), $sformatf("inside component_A: ID_WIDTH = %0d, id = %0d", ID_WIDTH, id), UVM_LOW);
endfunction
endclass
class component_B #(int ID_WIDTH = 8) extends component_A #(ID_WIDTH);
bit [ID_WIDTH-1:0] id;
`uvm_component_param_utils(component_B #(ID_WIDTH))
function new(string name = "component_B", uvm_component parent = null);
super.new(name, parent);
id = 2;
endfunction
function display();
`uvm_info(get_type_name(), $sformatf("inside component_B: ID_WIDTH = %0d, id = %0d", ID_WIDTH, id), UVM_LOW);
endfunction
endclass
class my_test extends uvm_test;
`uvm_component_utils(my_test)
component_A #(32) 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 #(32)::get_type(), component_B #(64)::get_type());
// or
component_A #(32)::type_id::set_type_override(component_B #(16)::get_type());
comp_A = component_A #(32)::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:
UVM_FATAL @ 0: reporter [FCTTYP] Factory did not return a component of type '<unknown>'. A component of type 'uvm_component' was returned instead. Name=comp_A Parent=my_test contxt=uvm_test_top
UVM Tutorials