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.

diagram
[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 drift
systemverilog
task 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)
endtask

Key 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

systemverilog
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)
endfunction
  • Keep 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

  1. Reproduce original failing seed with trace enabled.

  2. Confirm cfg set/get counts and failure counters.

  3. Verify expected cfg type at each boundary.

  4. Run smoke + one stress test with the fix.

  5. Rerun the exact failing seed to confirm closure.

diagram
[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_phase

Key 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.