Tutorials

Learn More

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