You should not use it because we tell you not to use it. ;-)
Seriously, the uvm_resource_db is the underlying mechanism that supports the uvm_config_db, it’s just that the uvm_config_db includes the notion of hierarchy so during build_phase, the higher component in the hierarchy wins if there’s a conflict. After that, it’s last-write-wins. The uvm_resource_db API is somewhat arcane and doesn’t always do what you’d expect.
I have a little problem with uvm_config_db’s set and get: They don’t take the argument “scope”. In my case, I have multiple ENV’s (uvm_env) instantiated in my top level uvm_test. These are arrays of ENV’s. Each ENV has its own config object that it creates during build phase and passes down its hierarchy. This is how I do it:
At lower components, this is how I get the config objects:
if (!uvm_resource_db #(usb_env_config)::read_by_type(get_full_name(), usb_env_cfg, this))
uvm_report_fatal(get_full_name(), "Failed to get usb_env_cfg");
Notice that I don’t really care (and I shouldn’t in this case) about the string name of the config object. But I care about the hierarchical string name where the config object is created ( {get_full_name(), “.*”} ). These lower components that need the config object are also used in the other ENV’s.
How do you suggest I implement the same thing using uvm_config_db?
if (!uvm_resource_db #(usb_env_config)::read_by_type(get_full_name(), usb_env_cfg, this))
uvm_report_fatal(get_full_name(), “Failed to get usb_env_cfg”);
would be
if (!uvm_config_db #(usb_env_config)::get(this, "", xHCI_usb_env_cfg, usb_env_cfg))
`uvm_fatal(get_full_name(), "Failed to get usb_env_cfg");
The ‘this’ pointer in the uvm_config_db::set() call gives you the hierarchical string name where the config object is created. This hierarchical name will also uniquify the path down to the lower level components, so the string name is irrelevant, really. In the same way that you document that the component requires an object of usb_env_cfg type so your ‘read_by_type(get_full_name()’ does the right thing, you can simply document that the config_object for the component is called ‘cfg_obj’ (or whatever you prefer) and use uvm_config_db.
I don’t think I made it clear that the lower component cannot use xHCI_usb_env_cfg in its “get”. The lower component does not know the name of the config object is xHCI_usb_env_cfg. Basically, there are two ENV’s that use the same lower components as well as the same config class usb_env_config. One ENV calls the config object xHCI_usb_env_cfg and the other one calls it BDCI_usb_env_cfg.
My point is that you can simply use a generic name for the config object in the lower-level component. It doesn’t even matter if both lower components use the same name, since they’ll be distinguished by the “this” context of the parent doing the set() call.
Having said that, if you really prefer using the uvm_resourece_db, then please do. I was simply pointing out that you don’t really need to.
I have a new question: we know if there are two uvm_config_db::set’s to the same config object, one in uvm_test and one in uvm_env based class, even though build_phase is executed top-down, the configuration that was set in uvm_test wins.
However, I have some BFM’s in my testbench that still use the old OVM set_config*. Whose OVM set_config would win, uvm_test’s or uvm_env’s?