Unable to access class properties in a UVM factory overriden class

Hi,

In my testbench, I have a class called nspi_master_agent and a parameterized class nspi_master_agent_param#(SOME_PARAMS_HERE) which is derived from nspi_master_agent. And this nspi_master_agent has a uvm_sequencer in it.

typedef uvm_sequencer #(payload_data) nspi_sequencer;
 
class nspi_master_agent extends uvm_agent;
  ...
  nspi_sequencer m_seqr;
  ...
  `uvm_component_utils(nspi_master_agent)
  ...
endclass

class nspi_master_agent_param#(VARIOUS_PARAMETERS_HERE) extends nspi_master_agent;
  nspi_sequencer m_seqr;
  ...
  `uvm_component_param_utils(nspi_master_agent_param#(VARIOUS_PARAMETERS_HERE))
  ...
  virtual function void build_phase(uvm_phase phase);
     super.build_phase(phase);
     ...
     m_seqr = nspi_sequencer::type_id::create("m_seqr", this);
     ...
  endfunction
  ...
endclass

In my uvm_test class, I overrode nspi_master_agent with nspi_master_agent_param class

for (int i=0;i!=NUM_ETH_PORT; i++) begin 
      set_inst_override_by_type(($sformatf("ne_buf_env.ne_buf_nspi_agt_ne_wrch[%0d]", i)), nspi_master_agent::get_type(), nspi_master_agent_param#(PASSING_PARAM_VALUE)::get_type() );  
end

In my uvm_env class, I created several nspi_master_agent objects

for (int i=0; i!=NUM_ETH_PORT; i++) begin
      ne_buf_nspi_agt_ne_wrch[i] = nspi_master_agent::type_id::create($sformatf("ne_buf_nspi_agt_ne_wrch[%0d]", i), this);
end

Also in my test class, I would like to pass the sequencer handle inside a nspi_master_agent object to a uvm_sequencer_base handle inside my test class.

virtual task main_phase(uvm_phase phase);
uvm_sequencer_base   nspi_msqr;
...
nspi_msqr=ne_buf_env.ne_buf_nspi_agt_ne_wrch[0].m_seqr;
...
endtask

However, after running the simulation, the nspi_msqr will get a null value, and after some debug, I found that
“ne_buf_env.ne_buf_nspi_agt_ne_wrch[0]” is actually referring to the original nspi_master_agent which never got created (I tried to access a property which only exists in the derived nspi_master_agent_param class and VCS give me a compilation error saying that property doesn’t exist in ne_buf_env.ne_buf_nspi_agt_ne_wrch[0] object)

Thus I wonder why am I referring to the original class in

nspi_msqr=ne_buf_env.ne_buf_nspi_agt_ne_wrch[0].m_seqr;

And how should I correcty pass the m_seqr handle to my test class?

Thanks so much in advance!!

In reply to peterjin:

At least one of your problems is you declared m_seqr in both nspi_master_agent and nspi_master_agent_param. You should never redeclare a variable with the same name in both classes.

In reply to dave_59:

Hi Dave,

Thanks for your reply!

Actually, that agent is our company’s legacy code. And they used to launch the sequence by setting sequencer’s default_sequence in the following fashion: (part of my job is to convert the sequence launching method from “default_sequence associating” to using virtual sequence)

for (int i=0; i!=NUM_ETH_PORT; i++) begin 
      uvm_config_db #(uvm_object_wrapper)::set(this, $sformatf("ne_buf_nspi_agt_ne_wrch[%0d].m_seqr.main_phase", i), "default_sequence", nebuf_nspi_sequence::get_type());
end

I wonder why in the above code (in enviroment component), .m_seqr is correctly referred to the m_seqr inside nspi_master_agent_param class?

In reply to peterjin:

Use access method which makes use of polymorphism to get sequencer according to objects you create.

Even if you have override and create extended class objects, parent handle still remains same. And using parent handle you can only access parent properties or functions and extended class functions if virtual.

Access m_seqr like this,

class A;
  my_seq m_seqr; // Class A property
  //Create object for m_seqr
  //..

  virtual function my_seq getSeq();
    return m_seqr;
  endfunction
endclass

class B extends A;
  my_seq m_seqr; // Class B property
  //Create object for m_seqr
  //..

  function my_seq getSeq();
    return m_seqr;
  endfunction
endclass

Issue is not with declaring same handle name m_seqr in both the class. But it’s how inheritance works when using parent=child handle assignments.

In reply to MayurKubavat:

That solves the problem, thanks so much for your help!

Hao