With help from Uvm_config_db can we set in lower Hierarchy(Ex -Agent) and get values in Upper Hierarchy(Ex-Env)

Hi,
initention is to show changes to the top level hierachy through config db -:
I am trying below snippet to achieve this but it is not working. Need Help

In below snippet I have agent as lower hierarchy and env as upper hierarchy
agent - Doing set of some value
env - Doing get.

$display/ERRor - Get is not successful

module config_db_m();

   import uvm_pkg::*;
  `include "uvm_macros.svh"

 class agent extends uvm_agent;  // agent class
    `uvm_component_utils(agent)
    int a;
     uvm_component my_parent;  
 
    function new(string name = "agent",uvm_component parent=null);      
      super.new(name,parent);
      endfunction
   
    function void build_phase(uvm_phase phase);
      super.build_phase(phase);
    endfunction

function void connect_phase(uvm_phase phase);
 uvm_component my_parent = this.get_parent();  // setting upper hierarchy as uvm_component 
super.connect_phase(phase);
 uvm_config_db #(int)::set(my_parent,"*","low",100); //doing set of value low pointer as 100
endfunction

endclass
   
  class env extends uvm_env;   // class env 
     `uvm_component_utils(env)
    int _low;
    agent a_h;
     function new(string name = "env",uvm_component parent=null);      
      super.new(name,parent);
      endfunction
   
    function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      a_h = agent::type_id::create("a_h",this);
        endfunction
     
     task run_phase(uvm_phase phase);
phase.raise_objection(this);
      if(!uvm_config_db #(int)::get(null,"","low",_low))  // get in env 
        $display("Get is not successful ");
phase.drop_objection(this);
     endtask
     
  endclass
  initial
    begin
      run_test("env");   
    end
 
endmodule 

In reply to Harjot:

Within your env your uvm_config_db#( int ) :: get is incorrect .

Instead of


if(!uvm_config_db #(int)::get(null,"","low",_low)) // null is incorrect

it should be


//  'this'  since  we  want  to  fetch  here  i.e  env  component
if(!uvm_config_db #(int)::get( this ,"","low",_low)) 

In reply to ABD_91:

// ‘this’ since we want to fetch here i.e env component
if(!uvm_config_db #(int)::get( this ,“”,“low”,_low))

I corrected,using this insted of null , but still issue is not resolved

Something else i am missing.

In reply to Harjot:

I missed out on the set part . Please change it to ::


uvm_config_db #(int)::set(my_parent,"","low",100);  // "*"  changed  to  ""

Via the above change , the value is visible to following TB hierarchy ::

uvm_test_top ( your env in this case as it’s argument to run_test )

In your initial code due to "" during set , the value was visible to TB hierarchy :: uvm_test_top. .

So only child components ( due to . )* of env can fetch the value

The env itself isn’t able to fetch it .

To successfully fetch using “*” during set ::


uvm_config_db #(int)::set(my_parent,"*","low",100);

Your get should look like ::


if( !uvm_config_db #(int)::get( get_child("a_h") ,"","low",_low ) )  // get in env 
        $display("Get is not successful ");

Although it’s your env which fetches the value , it acts as child component of env during fetch

In reply to Harjot:

Hi Harjot, I have made changes in your code.
“set” method must be in the build_phase of agent.
In “get” method replace the context with “this” instead of null and use `uvm_error message report in place of $display

You can follow this up

In reply to Yeptho:

This solution is incorrect. You can do the set() method in any phase, as long as it precedes any get().

The issue has to do with the use of “*” when setting. This changes the scope of the set which prevents the get() in the parent from finding the value.

This is the proper solution, although this isn’t recommended and you should never use the config_db to pass anything from a sub-component to a parent. As the name implies, the config_db is designed for configuration information only.


import uvm_pkg::*;
`include "uvm_macros.svh"

class agent extends uvm_agent;  // agent class
  `uvm_component_utils(agent)
  int a;
  
  function new(string name = "agent",uvm_component parent=null);
    super.new(name,parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
  endfunction
  
  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    uvm_config_db #(int)::set(get_parent(),"","low",100); //doing set of value low pointer as 100
  endfunction
endclass

class env extends uvm_env;   // class env
  `uvm_component_utils(env)
  int _low;
  agent a_h;
  
  function new(string name = "env",uvm_component parent=null);
    super.new(name,parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    a_h = agent::type_id::create("a_h",this);
  endfunction
  
  task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    if (!uvm_config_db #(int)::get(this,"","low",_low)) begin  // get in env 
      `uvm_fatal(get_name(), "Get is not successful");
    end
    else begin
      `uvm_info(get_name(), $sformatf("Get is successful - Value is %0d", _low), UVM_MEDIUM);
    end
    phase.drop_objection(this);
  endtask
endclass

module config_db_m();
  initial begin
    run_test("env");
  end
endmodule