In reply to tfitz:
Just to add to Tom’s response: (since I had most of it typed up before I saw his)
There is no requirement to use uvm_config_db in any phase as long as you can guarantee that the set(), or any overriding set() occurs before the corresponding get(). You also need to make sure you do the get() before you need to use anything that needs the configuration data. The build_phase is the natural place to do all set/gets from the top-level of your test down to the bottom level drivers and monitors.
Another consideration is the get() operation is a very time consuming operation because of all the string look-ups it has to so. That is why is is best to get() the data in the run_phase and store it an a class variable. That way all the subsequent phases will have the data without having to get() it again. Since the agent, driver, and monitor classes are tightly coupled, it might be OK to get the virtual interface from the config_db in the agent, and directly set it in the monitor and driver. But any other hierarchical crossings should be avoided.