UVM configuration NULL pointer dereference Problem

In reply to sylvainb:

In reply to UVM_LOVE:
Where do you create the apb_master_config m_cfg? It should be created before you post it in the uvm_config_db in the build_phase of your apb_basic_test

I can get m_cfg properties after created apb_master_config as your recommend.
But Virtual interface is not still NULL, But other properties are good in configuration.

I added the creation apb_master_config in test class as your recommands, as the below,

class apb_basic_test extends uvm_test;
  int packets;
  
  `uvm_component_utils_begin(apb_basic_test)
  `uvm_field_int(packets,UVM_ALL_ON)
  `uvm_component_utils_end

  apb_master_config m_cfg;
  apb_master_environment apb_environment;//evironment handle 
  apb_sequence seq;//sequence handle

  
  function new(string name="apb_basic_test", uvm_component parent);
    super.new(name,parent);
    `uvm_info(get_type_name(),"the objection test object has been built",UVM_LOW);
  endfunction
 
  virtual function void build_phase(uvm_phase phase);
    uvm_config_int::set(this, "*", "recording_detail", 1);
    super.build_phase(phase);
    m_cfg=apb_master_config::type_id::create("m_cfg",this);

    uvm_config_db #(apb_master_config)::set(this, "*",  "apb_master_config", m_cfg);
    if(!uvm_config_db#(int)::get(this,"","number_of_packets",packets))
      `uvm_info(get_type_name(),"the geting of packets variable failed",UVM_LOW)
      
    apb_environment = apb_master_environment::type_id::create("apb_environment",this);
    seq = apb_sequence::type_id::create("seq", this);
    
   endfunction
  
  virtual function void connect_phase(uvm_phase phase);

    seq.packets = packets;
   `uvm_info(get_type_name(),"the connect phase of the basic_test completed", UVM_LOW)
  endfunction
  

    

And Here’s Agent.

class apb_master_agent extends uvm_agent;

  apb_master_config m_cfg;

  apb_sequencer sequencer;
  apb_master_driver driver;
  apb_monitor monitor;
  apb_master_coverage coverage;

  
  `uvm_component_utils(apb_master_agent)
  
  function new(string name="apb_master_agent", uvm_component parent);
    super.new(name,parent);
  endfunction
  
  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    
    if(!uvm_config_db #(apb_master_config)::get(this, "*", "apb_master_config", m_cfg))
        `uvm_fatal("FATAL MSG", "Configuration object is not set properly")

        `uvm_info(get_type_name(), $psprintf("agent is: %p", m_cfg.active),UVM_LOW)
        `uvm_info(get_type_name(), $psprintf("vif: %p", m_cfg.apb_if), UVM_LOW)

    
    /// Monitor will Always Be Available ///
    monitor=apb_monitor::type_id::create("monitor",this);
    if(monitor==null)
      `uvm_fatal(get_type_name(),"the monitor has not beed built");

    /// Driver & Sequencer will be Implemented only in ACTIVE mode
    if(m_cfg.active == UVM_ACTIVE) begin
        driver=apb_master_driver::type_id::create("driver",this);
        sequencer=apb_sequencer::type_id::create("sequencer", this);
        
        if(sequencer==null)
          `uvm_fatal(get_type_name(),"the sequecer has not been built");
        if(driver==null)
          `uvm_fatal(get_type_name(),"the driver has not been built");
    end
    else
        `uvm_info(get_type_name(), "UVM is PASSIVE", UVM_LOW);

        `uvm_info(get_type_name(), $psprintf("Coverage is: %p", m_cfg.has_functional_coverage),UVM_LOW)
    if(m_cfg.has_functional_coverage) begin
        coverage = apb_master_coverage::type_id::create("coverage", this);
    end 

and the problem class is the monitor especially m_cfg.apb_if has NULL error.

class apb_monitor extends uvm_monitor;

    `uvm_component_utils(apb_monitor)

    virtual apb_interface vapb_intf;
    apb_sequence_item apb_rx;
    apb_master_config m_cfg;

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

uvm_analysis_port #(apb_sequence_item) my_mon_port;

virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    my_mon_port = new ("my_mon_port", this);

endfunction

virtual function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    if(!uvm_config_db #(apb_master_config)::get(this, "*", "apb_master_config", m_cfg))
        `uvm_fatal("FATAL MSG", "Configuration object is not set properly")
    
    vapb_intf = m_cfg.apb_if;
        `uvm_info(get_type_name(), $psprintf("!!!!!!t is: %p", m_cfg.apb_if),UVM_LOW)

endfunction

virtual task run_phase(uvm_phase phase);
    apb_rx = apb_sequence_item::type_id::create("apb_sequence_item");
    forever begin
        @(posedge vapb_intf.pclk)

       
        //USE "if statement" for synchonize between driver and Monitor write() functions in scoreboard.
         if (vapb_intf.penable) begin //USE "if statmenet" for synchonize between driver and Monitor write() functions in scoreboard.

            vapb_intf.collect_data(apb_rx.address, apb_rx.data, apb_rx.acc);

When I check apb_if then I got the NULL.

vapb_intf = m_cfg.apb_if;
        `uvm_info(get_type_name(), $psprintf("!!!!!!t is: %p", m_cfg.apb_if),UVM_LOW)

But When I check the active variavle then I got the UVM_ACTIVE well.


        `uvm_info(get_type_name(), $psprintf("!!!!!!t is: %p", m_cfg.active),UVM_LOW)

and this is my configuration class.

class apb_master_config extends uvm_object;
    `uvm_object_utils(apb_master_config)

    virtual apb_interface apb_if;

    function new (string name = "");
        super.new(name);
    endfunction

    uvm_active_passive_enum active = UVM_ACTIVE;

    logic [1:0] id = 1;
    bit has_functional_coverage = 1;
    bit has_scoreboard = 0;
    logic [31:0] start_adress[15:0];
    logic [31:0] r_data[15:0];
    int no_select_line = 1;

endclass

How to pass the virtual interface by using configuration into other class?