Configuration object casting problem in the hierarchical tb

Hi,

I have the following configuration object hierarchy (a-b-c) in which every subclass brings some new additional properties:

class cfg_a extends uvm_object;
endclass : cfg_a
class cfg_b extends cfg_a;
endclass : cfg_b
class cfg_c extends cfg_b;
endclass : cfg_c

The same amount of layers (a, b, c) is also applied to the UVM test and env hierarchy as follows:

// UVM test hierarchy (a-b-c)
class test_base_a extends uvm_test;
  cfg_a cfg_a_inst;
  ...
  function void build_phase(uvm_phase phase)
    ...
    uvm_config_db#(uvm_object)::set(null, "*", "cfg", cfg_a_inst);
  endfunction
endclass : test_base_a
class test_base_b extends test_base_a;
  cfg_b cfg_b_inst;
  ...
  cfg_a_inst = cfg_b_inst;
  ...
endclass : test_base_b
class test_base_c extends test_base_b;
  cfg_c cfg_c_inst;
  ...
  cfg_a_inst = cfg_c_inst;
  ...  
endclass : test_base_c

// UVM env hierarchy (a-b-c)
class env_base_a extends uvm_test;
  cfg_a cfg_a_inst;
  uvm_object cfg_inst;
  ...
  function void build_phase(uvm_phase phase)
    ...
    uvm_config_db#(uvm_object)::get(null, "*", "cfg", cfg_inst);
    $cast(cfg_a_inst, cfg_inst);
  endfunction
endclass : env_base_a
class env_base_b extends env_base_a;
  cfg_b cfg_b_inst;  // cfg_b_inst is used to configure layer-b specific agents.
  ...
  $cast(cfg_b_inst, cfg_inst);
  if (cfg_b_inst.has_some_agent) ...
  ...
endclass : env_base_b
class env_base_c extends env_base_b;
  cfg_c cfg_c_inst;  // Layer-c specific configuration.
  ...
  $cast(cfg_c_inst, cfg_inst);
  ...  
endclass : env_base_c

If I run test in the layer-c (test_base_c), which in turn instantiates env_base_c and passes cfg_c object handle to config_db, how can I perform configuration object cast in the env_base_b which is inherited? In that case, $cast(cfg_b_inst, cfg_inst); won’t work because cfg_inst object is not assignment compatible with cfg_b_inst, right? How should I overcome this issue, any proposals? I am open for better ideas.

Thanks!

-ilia

In reply to ilia:
You didn’t show when any cfg objects are constructed, and when you called super.build_phase().

The thing to do here is use a factory override before calling super.build(). Then the $cast will work because the object retireved by config_db get() will be of the correct type.

class test_base_a extends uvm_test;
  cfg_a cfg_inst;
  ...
  function void build_phase(uvm_phase phase)
    cfg_inst = cfg_a::type_id::create("cfg_inst);
    uvm_config_db#(uvm_object)::set(null, "*", "cfg", cfg_inst);
  endfunction
endclass : test_base_a
class test_base_b extends test_base_a;
  function void build_phase(uvm_phase phase)
    set_type_override_by_type( cfg_a::get_type(), cfg_b::get_type() );
    super.build_phase(phase);
endclass : test_base_b

This assumes env is also being overridden in sync with the cfg and test.