Part 6 · Agents & Protocol IP · Intermediate
config_db Wiring: Deterministic Set/Get Paths and Child Propagation
Build robust config_db flow with path hygiene, precedence policy, and guaranteed propagation from env to agent children.
Wiring model and invariants
Reliable config_db wiring follows two invariants: set-before-get and exact-path alignment with hierarchy. Most cfg bugs violate one.
[UVM][AGT][DRV][TLM] wiring timeline
env.build_phase:
create cfg
populate vif/mode/policy
set cfg on agent instance path
create agent instance
agent.build_phase:
get cfg
validate/normalize
set cfg for monitor/driver children
child.build_phase:
get cfg and enforce local requirements[config_db] path hygiene checklist
exact path example:
set(this, "env.bus_agt", "cfg", cfg)
relative child set example:
set(this, "drv", "cfg", cfg)
anti-pattern:
set(null, "*", "cfg", cfg)
// leaks into unrelated instancesName instances predictably to simplify set/get pairing.
Use narrow paths over broad wildcards for deterministic behavior.
Fail fast when mandatory cfg lookup misses.
End-to-end wiring code
class bus_env extends uvm_env;
`uvm_component_utils(bus_env)
bus_agent agt;
function void build_phase(uvm_phase phase);
bus_agent_cfg cfg;
super.build_phase(phase);
cfg = bus_agent_cfg::type_id::create("cfg");
cfg.is_active = UVM_ACTIVE;
cfg.timeout_cycles = 300;
if (!uvm_config_db#(virtual bus_if)::get(this, "", "bus_vif", cfg.vif))
`uvm_fatal("NOVIF", "missing bus_vif in bus_env")
if (!cfg.randomize() with { req_gap_min_cycles <= 2; req_gap_max_cycles <= 8; })
`uvm_fatal("CFG_RAND", "bus_agent_cfg randomization failed")
uvm_config_db#(bus_agent_cfg)::set(this, "agt", "cfg", cfg);
agt = bus_agent::type_id::create("agt", this);
endfunction
endclass
class bus_agent extends uvm_agent;
`uvm_component_utils(bus_agent)
bus_agent_cfg cfg;
bus_driver drv;
bus_monitor mon;
bus_sequencer sqr;
function void build_phase(uvm_phase phase);
super.build_phase(phase);
if (!uvm_config_db#(bus_agent_cfg)::get(this, "", "cfg", cfg))
`uvm_fatal("NOCFG", "cfg missing at bus_agent")
mon = bus_monitor::type_id::create("mon", this);
uvm_config_db#(bus_agent_cfg)::set(this, "mon", "cfg", cfg);
if (cfg.is_active == UVM_ACTIVE) begin
sqr = bus_sequencer::type_id::create("sqr", this);
drv = bus_driver::type_id::create("drv", this);
uvm_config_db#(bus_agent_cfg)::set(this, "drv", "cfg", cfg);
end
endfunction
endclass[UVM][AGT][DRV][TLM] propagation topology
cfg source:
env per-agent instance
cfg consumers:
wrapper (mode decisions)
monitor (always)
driver/sequencer (active mode)
result:
one policy view across command and observation pathsForward one cfg handle to all consumers unless isolation is intentional.
Do not re-randomize child cfg copies; keep policy coherent.
Log resolved cfg after agent get for each instance.
Precedence, overrides, and arrayed agents
Multi-instance benches need explicit precedence contracts and per-index path generation. Otherwise one override silently affects the wrong agent.
foreach (agts[i]) begin
bus_agent_cfg cfg_i;
cfg_i = bus_agent_cfg::type_id::create($sformatf("cfg_%0d", i));
cfg_i.vif = vif_array[i];
cfg_i.is_active = (i == 0) ? UVM_ACTIVE : UVM_PASSIVE;
cfg_i.timeout_cycles = 128 + (i * 64);
uvm_config_db#(bus_agent_cfg)::set(
this, $sformatf("agts[%0d]", i), "cfg", cfg_i);
agts[i] = bus_agent::type_id::create($sformatf("agts[%0d]", i), this);
end[UVM][AGT][DRV][TLM] precedence ladder
highest:
path-specific test override
middle:
env-assigned per-instance cfg field values
lowest:
cfg class defaults
always:
print effective values after get/normalizeKey takeaways
Path-correct config_db wiring is foundational for deterministic agent behavior.
Set-before-get ordering and explicit precedence prevent accidental defaults.
Arrayed agents require index-safe path generation and per-instance visibility.
Single-source cfg propagation keeps driver and monitor aligned.
Common pitfalls
Creating agents before cfg set, causing hidden fallback behavior.
Overusing wildcard paths and unintentionally overriding unrelated instances.
Per-child reconfiguration that drifts from wrapper policy.
No effective cfg logs for multi-instance environments.