Fatal Error: ELAB2_0036 Unresolved hierarchical reference to "a.m.send.connect./0/" from module "env" (module not found)

Hi, I’m trying to send a transaction from my env class: from monitor to scoreboard.
my monitor is a derived monitor, with the type name: monitor_2. the base class type name is monitor.
To use the derived monitor, I used the command (in my agent class): set_inst_override_by_type(" ",monitor::get_type(), monitor_2::get_type());
but when I run it I get the next error:Fatal Error: ELAB2_0036 Unresolved hierarchical reference to “a.m.send.connect./0/” from module “env” (module not found).

[] my code works fine when I just trying to send the transcation from monitor_2 to scoreboard without the overriding mechanize
[
] here’s a link for all the tb+ design: moving_average(5) - EDA Playground. I added here the relevant classes to the problem in my eyes.

Can you please explain to me why I get this error?



class env extends uvm_env;
`uvm_component_utils(env)
 
  function new(string inst = "e", uvm_component parent = null);
    super.new(inst,parent);
  endfunction
 
scoreboard s;
agent a;
 
  virtual function void build_phase(uvm_phase phase);
  super.build_phase(phase);
    `uvm_info("ENV","env_built",UVM_LOW)
    a = agent::type_id::create("a",this);
    s = scoreboard::type_id::create("s",this);
  endfunction
 

  virtual function void connect_phase(uvm_phase phase);
  super.connect_phase(phase);
    `uvm_info("ENV",$sformatf("type_is:%s",a.m.get_type_name()),UVM_LOW)
    a.m.send.connect(s.no_ref);
  endfunction

endclass
//////////////////////////////////////////////////////////////
class agent extends uvm_agent;
`uvm_component_utils(agent)
 
 
  function new(string inst = "agent", uvm_component parent = null);
    super.new(inst,parent);
    `uvm_info("AGENT","agent_built",UVM_LOW)
  endfunction
 
  monitor m;
  driver d;
  uvm_sequencer #(transaction) seqr;
 uvm_factory factory;
  bit [1:0] test_type;
 
  virtual function void build_phase(uvm_phase phase);
  super.build_phase(phase);
    if(!uvm_config_db#( uvm_factory)::get(this,"","factory",factory))
      `uvm_error("AGN", "Unable to access factroy");
    if(!uvm_config_db#(bit[1:0])::get(this,"","test_type",test_type))
      `uvm_error("AGN", "Unable to access test_type");
    if(test_type==1)
      set_inst_override_by_type(" ",monitor::get_type(), monitor_2::get_type());
    m = monitor::type_id::create("m",this);
    d = driver::type_id::create("d",this);
    seqr = uvm_sequencer #(transaction)::type_id::create("seqr",this);      
    factory.print();
 
  endfunction
 
  virtual function void connect_phase(uvm_phase phase);
  super.connect_phase(phase);
    d.seq_item_port.connect(seqr.seq_item_export);
  endfunction

endclass
  
///////////////////////////////////////////////////////////////////
class monitor extends uvm_monitor;
`uvm_component_utils(monitor)
 
virtual s_if vsif;
transaction t;
integer pixel_counter=0;
integer pixel_value=0;
integer j;


 
  function new(input string inst = "monitor", uvm_component parent = null);
    super.new(inst,parent); 
  endfunction
 
  virtual function void build_phase(uvm_phase phase);
  super.build_phase(phase);
    t = transaction::type_id::create("t");
   
    
    if(!uvm_config_db#(virtual s_if)::get(this,"","vsif",vsif))
  `uvm_error("MON", "Unable to access Interface");
endfunction
 
virtual task run_phase(uvm_phase phase);

    fork
      begin
        forever begin
          @(posedge vsif.start_act)
          t.movavgwin_param=vsif.movavgwin_param; 
          `uvm_info("movavg_param",$sformatf("param is:%p",t.movavgwin_param),UVM_LOW)
        end
      end
      
      begin
        forever begin
          @(negedge vsif.clk);
          if(vsif.vald_din) 
        		t.data_in.push_back(vsif.data_in);                                
        end
      end
       begin
         forever begin
		@(negedge vsif.vald_din);
       //  `uvm_info("data_in",$sformatf("data in is:%p",t.data_in),UVM_LOW)
         end
      end
          
   
      begin
       forever begin        
         @(negedge vsif.clk);
         //checker on the fly:comparing the t.data_out ,that created in the monitor,  to the data_out interface value immediatly, without scoreboard. more accurate to do it without transaction but its comftarable to take the values from transaction and not create new objects here- the downside is that i uses memory by using the queues.
         if(vsif.valid_out) begin
           if(pixel_counter<2**(t.movavgwin_param+1)-1)begin
             t.data_out.push_back(0);
           end           
           else begin      
             pixel_value=0;
             for(int i=j; i<2**(t.movavgwin_param+1)+j; i++) begin
               pixel_value=(pixel_value+t.data_in[i]);
             end
             pixel_value=pixel_value/(2**(t.movavgwin_param+1));
             t.data_out.push_back(pixel_value); 
             j++;           
            
           end 
           `uvm_info("pix",$sformatf("pixel_counter_is:%d",pixel_counter),UVM_DEBUG)
           `uvm_info("data_out_mid",$sformatf("data_out_mid:%p",t.data_out),UVM_DEBUG)
           `uvm_info("vsif.data_out",$sformatf("vsif.data_out_mid:%p",vsif.data_out),UVM_DEBUG)
           if(t.data_out[pixel_counter]!=vsif.data_out)
             `uvm_error("CHECKER_phase_signals", "bad2");
            pixel_counter++; 
         end
       //
       end        
      end
        begin
         forever begin
           @(negedge vsif.valid_out);           
         //  `uvm_info("data_out",$sformatf("data out is:%p",t.data_out),UVM_LOW)
            pixel_counter=0;
            t.data_out.delete();
            t.data_in.delete();
            j=0;
         end
      end
            
     
    join

  
    
    
    
  endtask
 

endclass
////////////////////////////////////////////////////////////////////////////////////////////
class monitor_2 extends monitor;
  `uvm_component_utils(monitor_2)

  uvm_analysis_port #(transaction) send;// Broadcasts a value to all subscribers implementing a uvm_analysis_imp.
  
   function new(input string inst = "monitor", uvm_component parent = null);
    super.new(inst,parent); 
    `uvm_info(get_type_name(), $sformatf("monitor_2"), UVM_LOW);
     send = new("send",this);
  endfunction
 
  virtual function void build_phase(uvm_phase phase);
  super.build_phase(phase);
   if(!uvm_config_db#(virtual s_if)::get(this,"","vsif",vsif))
 	 `uvm_error("MON", "Unable to access Interface");
    t = transaction::type_id::create("t"); 
endfunction  

    
 
virtual task run_phase(uvm_phase phase);
  fork
  	begin
    	forever begin
          @(negedge vsif.clk);
          if(vsif.vald_din) 
       		t.data_in.push_back(vsif.data_in);  
        end
    end
      
    begin
       forever begin
          @(negedge vsif.clk);
         if(vsif.valid_out)            
          	t.data_out.push_back(vsif.data_out);
       end
    end
    
    begin
      forever begin
        @(negedge vsif.valid_out)
          `uvm_info("data_in",$sformatf("data in is:%p",t.data_in),UVM_LOW)
          `uvm_info("data_out",$sformatf("data out is:%p",t.data_out),UVM_LOW)
        	send.write(t);
            t.data_in.delete();
            t.data_out.delete();
      end  
    end
    
    
    
  join
  
  
  
       
endtask
 

endclass
///////////////////////////////////////////////////////////////////////////////////////////
`uvm_analysis_imp_decl(_no_ref)

class scoreboard extends uvm_scoreboard;
`uvm_component_utils(scoreboard)
 
  uvm_analysis_imp_no_ref #(transaction,scoreboard) no_ref;
 
  integer pixel_counter=0;
  integer pixel_value=0;
  integer j=0;
  logic [`DATAWIDTH-1:0] data_out_ref[$];
  
  function new(input string inst = "SCO", uvm_component parent);
    super.new(inst,parent);
    
endfunction
 
 virtual function void build_phase(uvm_phase phase);
  super.build_phase(phase);
   no_ref = new("no_ref", this);
 endfunction
 
 
  virtual function void write_no_ref(transaction t);

                        
endfunction
  
endclass
 


In reply to Dvir:

Your monitors does not have an analysis port. Please double check.
I giess the name should be ‘send’.

In reply to chr_sue:

Thank you, it worked. but I don’t understand why. monitor_2 had an analysis port, monitor didn’t have. why when I added to monitor the analysis port, it worked?

In reply to Dvir:

The path does not exist.
Using Questa a simulator you get this error message.
Could not find field/method name (send) in ‘m’ of ‘a.m.send.connect’.

Looking to the monitor you can see ‘send’ does not exist.

In reply to chr_sue:

but because of the overriding m is not a handle of monitor, its a handle of monitor_2 right now which has an analysis port (look at the code)
I realized that if the derived class has analasys port and the base class doesn’t, I get an error, but if the derived class extends the analasys port from the base class, it works.
can explain why?

In reply to Dvir:

The analysis port is a structural element and not simply a data mebmber of the classes. If you want to extend the base class this element is required.

In reply to chr_sue:

Thank you very much