Tutorials

Learn More

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

  1. Type Override
  2. 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

  1. set_type_override_by_type
  2. 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