Part 11 · Senior Prep · Intermediate
Reuse Config Strategy: cfg Objects and Hierarchy Scoping
Config-driven reuse across hierarchy levels — cfg object layering, config_db scoping, is_active propagation, and plusarg mapping without leaking VIP internals.
Config as the reuse API
The cfg object is the only configuration path into a VIP. Integrators set knobs via config_db; they never poke agent internals.
[ARCH][SENIOR][UVM] config layering
chip_cfg
├─ cpu_subsys_cfg
│ └─ bus_cfg (is_active=PASSIVE)
└─ io_subsys_cfg
└─ pin_agent_cfg (is_active=ACTIVE)
test.build_phase:
create chip_cfg
apply level-specific defaults
uvm_config_db::set(this, "*", "cfg", chip_cfg)class chip_cfg extends uvm_object;
`uvm_object_utils(chip_cfg)
cpu_subsys_cfg cpu_cfg;
io_subsys_cfg io_cfg;
function void apply_soc_defaults();
cpu_cfg.bus_cfg.is_active = UVM_PASSIVE;
io_cfg.pin_cfg.is_active = UVM_ACTIVE;
cpu_cfg.bus_cfg.enable_scoreboard = 0; // chip SB owns checking
endfunction
function void apply_block_defaults();
cpu_cfg.bus_cfg.is_active = UVM_ACTIVE;
cpu_cfg.bus_cfg.enable_scoreboard = 1;
endfunction
endclassKey takeaways
Cfg layering mirrors hierarchy — chip_cfg wraps subsys_cfg wraps block cfg.
apply_*_defaults() encodes level-specific policy in one place.
config_db scoping with wildcards must be documented and tested.
Common pitfalls
Flat cfg with 200 fields and no hierarchy grouping.
Plusargs parsed inside agent instead of test pushing cfg.
Multiple config_db sets overwriting same field without clear precedence.
config_db scoping patterns
Senior config strategy defines exact set/get paths and validates them in smoke tests.
Scoping conventions
[ARCH][SENIOR][UVM] config_db scoping rules
test → env:
set(this, "env", "cfg", chip_cfg)
env → agents:
set(this, "agt*", "cfg", bus_cfg) // wildcard for all agents
agent get:
get(this, "", "cfg", cfg) // relative to agent instance
rule: set always above get in build_phase orderfunction void build_phase(uvm_phase phase);
super.build_phase(phase);
chip_cfg cfg = chip_cfg::type_id::create("cfg");
cfg.apply_soc_defaults();
cfg.apply_plusarg_overrides(); // test owns plusarg → cfg mapping
uvm_config_db#(chip_cfg)::set(this, "env", "cfg", cfg);
env = chip_env::type_id::create("env", this);
endfunctionPlusarg mapping policy
Only test (or base_test) parses plusargs into cfg fields.
Agents read cfg — never call uvm_cmdline_processor directly.
Document every plusarg in test README with default and valid range.
Smoke test verifies plusarg override reaches agent cfg.
function void apply_plusarg_overrides();
int tmp;
if ($value$plusargs("ACTIVE=%d", tmp))
cpu_cfg.bus_cfg.is_active = uvm_active_passive_enum'(tmp);
endfunction# verify config propagation
simv +UVM_TESTNAME=chip_test +ACTIVE=0 -l cfg_passive.log
grep "is_active=PASSIVE" cfg_passive.logCommon pitfalls
Agent reading plusargs — breaks reuse at different hierarchy levels.
Wildcard set too broad — unintended agents receive wrong cfg.
Cfg object shared by reference mutated by one agent affecting all.