Part 7 · Environment & Tests · Intermediate
Config Distribution Debug: Trace Policy From Test to Agent
A boundary-first debug workflow for missing/incorrect config values across test, env, and agent hierarchy.
Boundary-first triage
Debug config failures by walking the pipeline: test creation, set path, env receive, env fanout, agent receive, field validation.
[TEST][ENV][AGT] config triage matrix
agent cfg null:
-> check env fanout set path/key
env cfg null:
-> check test set order/path before env create
wrong field value:
-> inspect mutation timeline and shared-handle writes
intermittent behavior:
-> race from run-phase cfg mutation or randomization drifttask cfg_distribution_smoke(my_env env_h);
if (env_h.cfg == null)
`uvm_fatal("CFG_SMOKE", "env cfg null");
if (env_h.agt_tx.cfg == null || env_h.agt_rx.cfg == null)
`uvm_fatal("CFG_SMOKE", "agent cfg null");
`uvm_info("CFG_SMOKE", "cfg pipeline alive", UVM_LOW)
endtaskKey takeaways
Config bugs are usually boundary bugs, not random mysteries.
A fixed debug order prevents expensive speculation.
Simple smoke checks should guard full regressions.
Common pitfalls
Inspecting sequence behavior before proving cfg propagation.
Ignoring get() return values and relying on side effects.
No smoke test validating all required cfg receivers.
Instrumentation toolkit
Persistent low-cost instrumentation shortens root-cause analysis for config failures.
Trace macros and counters
int unsigned cfg_set_count;
int unsigned cfg_get_count;
int unsigned cfg_get_fail_count;
function void trace_cfg_set(string scope, string key, uvm_object obj);
cfg_set_count++;
`uvm_info("CFG_SET",
$sformatf("scope=%s key=%s type=%s count=%0d",
scope, key, obj.get_type_name(), cfg_set_count),
UVM_LOW)
endfunction
function void trace_cfg_get(bit ok, string key);
cfg_get_count++;
if (!ok) cfg_get_fail_count++;
`uvm_info("CFG_GET",
$sformatf("ok=%0d key=%s total=%0d fail=%0d",
ok, key, cfg_get_count, cfg_get_fail_count),
UVM_LOW)
endfunctionKeep counters on by default in debug/nightly profiles.
Emit summary in report_phase to spot distribution health.
Track key and type names to catch accidental mismatches.
Fix verification checklist
Reproduce original failing seed with trace enabled.
Confirm cfg set/get counts and failure counters.
Verify expected cfg type at each boundary.
Run smoke + one stress test with the fix.
Rerun the exact failing seed to confirm closure.
[DEBUG][UVM] closure evidence
- before: cfg_get_fail_count > 0 at agt_rx
- after : cfg_get_fail_count = 0
- same seed reproduces pass
- no new cfg warnings in report_phaseKey takeaways
Counters plus boundary logs make cfg issues measurable.
Fixes are credible only when validated on original failing seeds.
Config observability should be treated as core infrastructure.
Common pitfalls
Disabling instrumentation after first fix without regression proof.
Merging path changes without smoke and stress verification.
Closing bugs on symptom disappearance instead of boundary evidence.