Failed to get variable value from the uvm_config_db

Hi everyone. I’m having a problem when I try to connect variable number of agent’s driver with the same number of DUT ports.

My goal is to connect each driver with only one input port.

When agents are created in environment, I used uvm_config_db#()::set() method to associate current driver with corresponding port.
This is where i get fatal error, because, uvm_config_db#()::get() didn’t retrieve or couldn’t find port_id value in the database.

Here are my codes for env and driver.

// prrs_driver
class prrs_driver extends uvm_driver #(eth_pkt);

`uvm_component_utils(prrs_driver)

virtual prrs_if vif; // virtual interface handle

// queue for fetching data
eth_pkt pkt_queue[$];

eth_pkt pkt;

// port selection variable
int port_id;

function new(string name = “prrs_driver”, uvm_component parent = null);
super.new(name, parent);
endfunction

// Driver build phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
if(!uvm_config_db #(virtual prrs_if)::get(this, “*”, “prrs_if”, vif))
`uvm_fatal(“NOVIF”,{“virtual interface must be set for: “,get_full_name(),”.vif”})

 if(!uvm_config_db #(int drv_num)::get(this, "", "prrs_env", drv_num))
   `uvm_fatal("NOVIF",{"Driver haven't received port_id value ",get_full_name()})    

endfunction : build_phase

// Driving transactions
virtual task run_phase(uvm_phase phase);
// Initialisation
vif.pi_read_req = 0;
vif.po_dout = 'h0;

forever begin 
  `uvm_info(get_type_name(), $sformatf("Waiting for the driver to get data"), UVM_LOW)
  seq_item_port.get_next_item(pkt); 
  drive_item(pkt);
  seq_item_port.item_done();
  `uvm_info(get_full_name(), $sformatf("%0t: Transaction done.", $time), UVM_LOW)
end

endtask : run_phase

endclass : prrs_driver

// prrs_env
class prrs_env extends uvm_env;

// UVM factory
`uvm_component_utils(prrs_env)

// Agent handle
prrs_agent m_agent[NUMBER_OF_INPUTS];

// Scoreboard handle
prrs_scoreboard m_scbd;

// Configuration object handle
prrs_config m_cfg;

int port_id = 0;

// Environment class constructor
function new(string name = “prrs_env”, uvm_component parent = null);
super.new(name, parent);
endfunction

// --------------------------------------------------------------------//
// Environment build phase
// Nunber of the agents is same as the number of DUT inputs
// --------------------------------------------------------------------//
function void build_phase(uvm_phase phase);
super.build_phase(phase);
for(int i = 0; i < NUMBER_OF_INPUTS; i++)begin
m_agent[i] = prrs_agent::type_id::create({“m_agent_”,$sformatf(“%0d”, i)}, this);
`uvm_info(get_full_name(), $sformatf(“Agent %0d created at %0t ns”, i, $time), UVM_HIGH);

  uvm_config_db #(int)::set(this, "m_agent[i].m_drv", "port_id", port_id);
  
  port_id++;
end

  m_scbd = prrs_scoreboard::type_id::create("m_scbd", this);
  `uvm_info(get_full_name(), $sformatf("Scoreboard created at %0t ns", $time), UVM_HIGH);

endfunction : build_phase

endclass : prrs_env

I would apprecciate any kind of help or advice regarding this problem.
Thanks in advance. :)

In reply to stole_994:

The names of your agents don’t match your hierarchical names, which is why your config_db calls don’t match. The path in the config_db::set() is “m_agent[0].m_drv”. The name is “m_agent_0.m_drv”. You need to make them match.

In reply to cgales:

Thanks, I didnt’t pay attention to that detail. This is how I changed set and get methods, so everything works now.

// in environment
for(int i = 0; i < NUMBER_OF_INPUTS; i++)begin
m_agent[i] = prrs_agent::type_id::create({“m_agent[”,$sformatf(“%0d”, i), “]”}, this);
`uvm_info(get_full_name(), $sformatf(“Agent %0d created at %0t ns”, i, $time), UVM_HIGH);

  uvm_config_db #(int)::set(this, "*", "drv_num", port_num);
  
  port_num++;
end

port_num is previously declared as static port_num = 0;

// in driver
if(!uvm_config_db #(int)::get(this, “m_env.*”, “drv_num”, drv_num))
`uvm_fatal(“NOVIF”,{"Driver haven’t received port_id value ",get_full_name()})

But there is something else I want to ask now. It seems that when for loop is evaluated, only last one counts, which leaves only last port driven, while others remain empty.
What can I do to solve that problem?

In reply to stole_994:

By using “*” as the second parameter in your set() call, you are making a global configuration object. When each agent calls get(), they will get the last value set(). You want to target the set() to the correct hierarchy like you were trying to accomplish in your first post.

In reply to cgales:

Thank you, everything works fine now.