How to override instance of class extended from uvm_transaction using "set_inst_override_by_type"?

My requirement is to override multiple instances of configuration class with different types(extended from same configuration base class), which is extended from uvm_transaction. Method(s) “set_inst_override_by_type/name” is working fine for classes extended from uvm_components. uvm user-guide is not saying that these method will not work for classes extended from uvm_transaction/object.

Method set_type_override_type is working fine to override type of class extended from uvm_object/transaction. But this will not resolve my problem, as want to override multiple instances of same type with multiple types.

Can any one answer, why methods “set_inst_override_by_type/name” are not working for overriding classes extended from uvm_object / uvm_transaction ?

Here is similar example which replicates problem. class A_ovr is successfully overridden as it is extended from uvm_component in-directly, but class B_ovr and B_override are extended from uvm_object and not able to override using same method.

class A extends uvm_agent;
  `uvm_component_utils(A)
  
  function new (string name="A", uvm_component parent);
    super.new(name, parent);
    `uvm_info(get_full_name, $sformatf("A new"), UVM_LOW);
  endfunction : new

  virtual function hello();
    `uvm_info(get_full_name, $sformatf("HELLO from Original A class"), UVM_LOW);
  endfunction : hello

endclass : A
--------------------------------------------------------------
class A_ovr extends A;
  `uvm_component_utils(A_ovr)
  
  function new (string name="A_ovr", uvm_component parent);
    super.new(name, parent);
    `uvm_info(get_full_name, $sformatf("A_ovr new"), UVM_LOW);
  endfunction : new

  function hello();
    `uvm_info(get_full_name, $sformatf("HELLO from override A_ovr class"), UVM_LOW);
  endfunction : hello
endclass : A_ovr 
--------------------------------------------------------------
class B extends uvm_object;
  `uvm_object_utils(B)
  
  function new (string name="B");
    super.new(name);
    `uvm_info(get_full_name, $sformatf("B new"), UVM_LOW);
  endfunction : new

  virtual function hello();
    `uvm_info(get_full_name, $sformatf("HELLO from Original B class"), UVM_LOW);
  endfunction : hello

endclass : B
---------------------------------------------------------------
class B_ovr extends B;
  `uvm_object_utils(B_ovr)
  
  function new (string name="B_ovr");
    super.new(name);
    `uvm_info(get_full_name, $sformatf("B_ovr new"), UVM_LOW);
  endfunction : new

  function hello();
    `uvm_info(get_full_name, $sformatf("HELLO from override B_ovr class"), UVM_LOW);
  endfunction : hello
endclass : B_ovr
--------------------------------------------------------------
class B_override extends B_ovr;
  `uvm_object_utils(B_override)
  
  function new (string name="B_override");
    super.new(name);
    `uvm_info(get_full_name, $sformatf("B_override new"), UVM_LOW);
  endfunction : new

  function hello();
    `uvm_info(get_full_name, $sformatf("HELLO from override B_override class"), UVM_LOW);
  endfunction : hello
endclass : B_override
--------------------------------------------------------------
class environment extends uvm_env;

  `uvm_component_utils_begin(environment)
  `uvm_component_utils_end

  A a1;
  B b1, b2;

  function new(string name="environment", uvm_component parent);
    super.new(name, parent);
  endfunction : new

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    a1 = A::type_id::create("a1", this);
    b1 = B::type_id::create("b1");
    b2 = B::type_id::create("b2");

    a1.hello(); // This will print from overridden class A_ovr. 
    b1.hello(); // This will print from base class B.
    b2.hello(); // This will print from base class B.
  endfunction : build_phase

endclass : environment
--------------------------------------------------------------
class test extends uvm_test;

  `uvm_component_utils(test)

  environment env;

  function new(string name = "test", uvm_component parent = null);
    super.new(name, parent);
  endfunction : new

  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    env = environment::type_id::create("env", this);

    `uvm_info(get_full_name, $sformatf("TEST set_inst_override_by_type"), UVM_LOW);
    factory.set_inst_override_by_type(A::get_type(), A_ovr::get_type(),  {get_full_name, ".", "env.a1"}); // Working
    factory.set_inst_override_by_type(B::get_type(), B_ovr::get_type(),  {get_full_name, ".", "env.b1"}); // Not working
    factory.set_inst_override_by_type(B::get_type(), B_override::get_type(),  {get_full_name, ".", "env.b2"}); // Not working

//  Alternative way is also not working !!!
//            `uvm_info(get_full_name, $sformatf("TEST set_inst_override_by_name"), UVM_LOW);
//            factory.set_inst_override_by_name("A", "A_ovr",  {get_full_name, ".", "env.a1"}); // Working
//            factory.set_inst_override_by_name("B", "B_ovr",  {get_full_name, ".", "env.b1"}); // Not working
//            factory.set_inst_override_by_name("B", "B_override",  {get_full_name, ".", "env.b2"}); // Not working

    factory.print(); // This will print info about overridden classes.
  endfunction : build_phase
endclass : test

====================================================================================

In reply to dhaval_rana:

A class object usually can’t be overriden by set_inst_override(as uvm_object’s are not part of the TB component hierarchy), unless some special care is taken during the creation of the object that needs to be overridden.

Add either get_full_name() or some text pattern as the third argument for the create() call during the object creation and use the same as argument for overriding. Example given below:

b1 = B::type_id::create("b1", ,"some_pattern_abc");
factory.set_inst_override_by_type(B::get_type(), B_override::get_type(),  some_pattern_abc.b1);

(You may need to do double check for syntax errors)

Check this UVM cookbook link sequence overrides for complete details.

A class object usually can’t be overriden by set_inst_override(as uvm_object’s are not part of the TB component hierarchy), unless some special care is taken during the creation of the object that needs to be overridden.

Add either get_full_name() or some text pattern as the third argument for the create() call during the object creation and use the same as argument for overriding. Example given below:

b1 = B::type_id::create("b1", ,"some_pattern_abc");
factory.set_inst_override_by_type(B::get_type(), B_override::get_type(),  some_pattern_abc.b1);

(You may need to do double check for syntax errors)
Check this UVM cookbook link sequence overrides for complete details.

In reply to S.P.Rajkumar.V:

Thanks Rajkumar !!!

It works…

Just for curiosity, Is this special take care(“some_pattern_abc”) need for adding object b1 in hierarchy ?

Other way to come over this problem , while crating uvm object use following syntax.

b1 = B::type_id::create(“b1”, this);
Your code will work fine with this syntax also.

In reply to dhaval_rana:

Could be, but I am not sure of the internal specifics.
Hope some one in the forum will respond to your follow-up question.
Or, you can refer the factory create() method source code/documentation.

In reply to Chandra Bhushan Singh:

Other way to come over this problem , while crating uvm object use following syntax.
b1 = B::type_id::create(“b1”, this);
Your code will work fine with this syntax also.

As class B is declared as uvm_object create method expects only one argument.
b1 = B::type_id::create(“b1”, this);
In the above line there might be a argument mismatch issue.
Correct me if i’m overlooking something.

In reply to chetan_s:

In reply to Chandra Bhushan Singh:
As class B is declared as uvm_object create method expects only one argument.
b1 = B::type_id::create(“b1”, this);
In the above line there might be a argument mismatch issue.
Correct me if i’m overlooking something.

see if you see any issue when you have below in a extended class of uvm_component
b1 = B::type_id::create(“b1”, this);
then try the same in an extended class of uvm_object.

In reply to chetan_s:

As class B is declared as uvm_object create method expects only one argument.

That’s incorrect . You might be confused between create arguments with new

The original author seems to have missed out that the 1st Override ( for class A ) worked since 2nd argument was ’ this ’ during call to create during a1 .

Similarly if 2nd argument is passed as ’ this ’ for b1 and b2 the remaining 2 overrides would have worked as well .


    b1 = B::type_id::create("b1", this);
    b2 = B::type_id::create("b2", this); 

The same was suggested by user Chandra as well .