What is the difference between uvm_config_db and uvm_resource_db?

Hi

I would like to know What is the difference between uvm_config_db and uvm_resource_db ?
Please let me know the difference between the the two config_db’s, when it can be used and how it is used with an example?
I went through so many articles but it is vague and unclear.can some one point me with the expamples and usage ?

-Thanks,
-Raja.

Don’t worry about the differences, and just use uvm_config_db.
uvm_config_db is a convenience layer built on top of uvm_resource_db, but that convenience is very important. In particular, uvm_resource_db uses a “last write wins” approach. The uvm_config_db, on the other hand, looks at where things are in the hierarchy up through end_of_elaboration, so “parent wins.” Once you start start_of_simulation, the config_db becomes “last write wins.”

In reply to tfitz:

Hi tfitz,

Thanks alot for the reply.

It would be really helpful if you can give explaination on this last write approach/last write wins.
Please can you give with an exmaple if possible to see the difference.
This would be really helpful.

-Thanks,
-Sravan

In reply to rajasravan:

Can you please comment on this.

-Thanks,
-Sravan.

In reply to rajasravan:

The build-time behavior of uvm_config_db is explained in the Advanced UVM video course. If a test and an env both set a config_db value during build-time, the test’s value will be used because it is higher in the component hierarchy. This is what you would expect.
However, using the uvm_resource_db, since build_phase() is called top-down, the env’s build_phase is called after the test’s, so the env value would overwrite the test value.
Once start_of_simulation_phase is reached, a write using either the config_db or the resource_db will overwrite whatever is currently in the database for that specific parameter. This is what we mean by “last write wins.”

1 Like

In reply to tfitz:

Hi,

This is really helpful to my understading.And i can see the main difference betwee uvm_config_db and uvm_resource_db is “When you want to share object and access it from different location without using the hierarchy you can use uvm_resource_db.” Can you comment on this?

uvm_config_db :: set function parameter

static function void set( uvm_component cntxt,
string inst_name,
string field_name,
T value )

uvm_resource_db :: set function parameter

static function void set( input string scope,
input string name,
T val,
input uvm_object accessor = null )

There is no instance name in resource_db.

-Thanks,
-Sravan.

In reply to rajasravan:

Using the resource_db requires that the scope (arbitrary string) for the set and get match. For trivial environments this isn’t difficult. However, for complex environments, including IP from different sources, it’s more difficult to manage. That, along with some other non-intuitive behaviors of the resource_db is why you should always just use the config_db.
I have never written a testbench that required using the resource_db and I suggest you do the same.
Good luck,
-Tom

In reply to tfitz:

Thanks alot Tom.For the valuable & informative reply.

-Thanks,
-Sravan.

In reply to tfitz:

Hi Tom,
I tried one example with uvm_resource_db.
But it is not working as you explained for uvm_resource_db during build_phase.
In uvm_resource_db also top hierarchy win during build_phase.

class my_agent extends uvm_agent;
  `uvm_component_utils (my_agent)
  int var1;
  function new (string name = "my_agent", uvm_component parent = null);
   super.new(name, parent);
  endfunction
  function void build_phase (uvm_phase phase);
    super.build_phase (phase);
    if(!uvm_resource_db #(int)::read_by_name("", "var1", var1, this))
      `uvm_error ("GET-FAIL", "not able to get value")
    else 
      `uvm_info ("GET-PASS", $sformatf("var1=%0d", var1), UVM_NONE)
  endfunction
endclass

/////////////////
class my_env extends uvm_env;
  `uvm_component_utils (my_env)
  int var1;
  my_agent agnt;
  function new (string name = "my_env", uvm_component parent = null);
    super.new(name, parent);
  endfunction
  function void build_phase (uvm_phase phase);
    super.build_phase (phase);
    agnt = my_agent::type_id::create("angt", this);
    var1 = 60;
    uvm_resource_db #(int)::set("*", "var1", var1, this);
    `uvm_info ("SET", $sformatf("From ENV=%0d", var1), UVM_NONE)
  endfunction
endclass

/////////////////
class my_test extends uvm_test;
  `uvm_component_utils (my_test)
  int var1;
  my_env env;
  function new (string name = "my_test", uvm_component parent = null);
    super.new(name, parent);
  endfunction
  function void build_phase (uvm_phase phase);
    super.build_phase (phase);
    env = my_env::type_id::create("env", this);
    var1 = 70;
    uvm_resource_db #(int)::set("*", "var1", var1, this);
    `uvm_info ("SET", $sformatf("From TEST=%0d", var1), UVM_NONE) 
  endfunction
  task run_phase (uvm_phase phase);
    phase.raise_objection(this);
    #500;
    phase.drop_objection(this);
  endtask
endclass

///////////////
module top();
  initial begin
    run_test("my_test");
  end
endmodule

//Output:
//UVM_INFO @ 0: reporter [RNTST] Running test my_test...
//UVM_INFO testbench.sv(15) @ 0: uvm_test_top [SET] From TEST=70
//UVM_INFO design.sv(36) @ 0: uvm_test_top.env [SET] From ENV=60
//UVM_INFO design.sv(14) @ 0: uvm_test_top.env.angt [GET-PASS] var1=70
//UVM_INFO /apps/vcsmx/etc/uvm-1.1/src/base/uvm_objection.svh(1267) @ 500: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase

Here I set value 70 from test, 60 from env, and getting value 70 in agent instead of 60.
Can you please explain what is wrong I am doing here?

In reply to Sagar Shah:

Your code appears to be working correctly. ‘my_test’ is above ‘my_env’. Also, his suggestion was to NOT use the resource_db.

From the file resource.svh:

// Multiple resources that have the same name are stored in a queue.
// Each resource is pushed into a queue with the first one at the front
// of the queue and each subsequent one behind it. The same happens for
// multiple resources that have the same type. The resource queues are
// searched front to back, so those placed earlier in the queue have
// precedence over those placed later.

In reply to dhserfer:

The configuration database is implemented on top of the resource database. The resource database
is a pool of name-value pairs each associated with a scope string.
The configuration database associates this scope string with full hierarchical names in the component hierarchy such that entriesin the configuration database, but not the resource database, are tied to the component hierarchy.

In reply to chr_sue:

For the code that is provided, each of the uvm_resource_db::set functions are identical and performed in the build phases of the my_test and my_env components. If the ‘names’ are the same, don’t they utilize the same queue (and my_test build_phase ‘sets’ the head of the queue)?

In reply to dhserfer:

The resource_db commands have only two lookup arguments, the scope and the name. Both are strings.
The accessor, last argument, is used only for auditting. You do not have to provide an actual argument, because it has a default value.
The config_db commands have 3 lookup arguments, the contxt, the scope and the name. The contxt is not a simple string, it is of type uvm_component. The cntxt and name argument give you more flexibility when defining what you want to set or get. Typical arguments for the contxt are ‘this’, indicating the lookup-path is a relative path from the component where the command was issued and ‘null’ indicating there is nothing above, meaning an absolute path.

In reply to chr_sue:

Hi chr, what it the meaning of the scope in resouce_db?
why do we need the scope?
Thanks!