Part 3 · Factory & Configuration · Intermediate

Resources & Field Debug: Symptom-First Triage

Deterministic debug workflow for missing config, resource_db lookup failures, shallow copy bugs, and field macro compare mismatches.

Debug boundary order

Troubleshoot resource and field problems in strict order: set ownership, path/scope match, type match, FLAGS semantics, then compare logic.

diagram
[UVM][CONFIG] triage matrix

missing cfg at build:
  config_db set/get path mismatch or set after get

global knob wrong:
  resource_db scope/name typo or stale debug override

shallow copy in scoreboard:
  missing uvm_field_object on nested item

compare false mismatch:
  UVM_NOCOMPARE needed OR custom do_compare required

huge slow logs:
  UVM_ALL_ON print on large array in hot loop
systemverilog
function void build_phase(uvm_phase phase);
  super.build_phase(phase);
  `uvm_info("DBG", $sformatf("full_name=%s", get_full_name()), UVM_LOW)
  if (!uvm_config_db#(env_cfg)::get(this, "", "cfg", cfg))
    `uvm_fatal("NOCFG", $sformatf("cfg not set for %s", get_full_name()))
endfunction

Key takeaways

  • Boundary-first debugging localizes config failures before run_phase.

  • Dump config_db and resource_db when path or scope is uncertain.

  • Compare mismatches often trace to FLAGS or missing uvm_field_object.

Common pitfalls

  • Debugging compare logic before confirming copy semantics are deep.

  • Chasing random seeds before reproducing with a deterministic smoke cfg.

  • Ignoring uvm_config_db::dump() output when get returns false.


Deterministic debug toolkit

Keep low-cost diagnostics always available so resource and field failures are reproducible across seeds.

Instrumentation primitives

systemverilog
function void log_resource_state(string tag);
  `uvm_info(tag, "=== config_db dump ===", UVM_LOW)
  uvm_config_db::dump();
  `uvm_info(tag, "=== int resource_db dump ===", UVM_LOW)
  uvm_resource_db#(int)::dump();
endfunction

function void debug_compare(bus_txn exp, bus_txn act);
  `uvm_info("CMP_EXP", exp.sprint(), UVM_MEDIUM)
  `uvm_info("CMP_ACT", act.sprint(), UVM_MEDIUM)
  if (!exp.compare(act)) `uvm_error("CMP", "field compare failed")
endfunction
diagram
[CONFIG] recommended always-on counters

- config_get_fail_count (per component)
- resource_read_miss_count
- compare_fail_count (scoreboard)
- sprint_call_count (detect hot-path verbosity leaks)

Issue reproduction checklist

  1. Reproduce with one deterministic seed and UVM_LOW verbosity.

  2. Print consumer get_full_name() and verify set path alignment.

  3. Run uvm_config_db::dump() and typed resource_db::dump().

  4. Confirm field macros include uvm_field_object for nested items.

  5. Inspect FLAGS on fields excluded from compare.

  6. Only then override do_compare or tune sequence stimulus.

diagram
[UVM] pass criteria

smoke seed passes twice identically
and
config_db dump shows expected entries at consumer path
and
copy+compare succeeds on cloned reference model txn

Key takeaways

  • Ordered dumps beat random verbosity increases.

  • Clone-then-compare on one known-good txn isolates field macro bugs.

  • Document set/get paths in comments at both publisher and consumer.

Common pitfalls

  • Turning on UVM_FULL before establishing which pool is wrong.

  • Fixing compare without verifying copy depth on nested objects.

  • Skipping post-fix rerun of the exact failing seed and log capture.