Part 3 · Factory & Configuration · Intermediate

Resource Pool Patterns: Scopes, Typed Pools, and Global Knobs

Naming conventions, typed resource pools, package-level defaults, and patterns for publishing simulation-wide knobs without config_db path sprawl.

Scope naming conventions

resource_db keys are scope string + field name . Consistent scope names prevent collisions when multiple VIPs and tests share one simulation.

diagram
[UVM][CONFIG] recommended scope taxonomy

  "global"           simulation-wide knobs (verbosity cap, timeout scale)
  "vip.<name>"       package-level VIP defaults
  "test.<name>"      test-family overrides (optional)
  "debug"            temporary debug resources (remove before release)

field names: snake_case, prefixed by domain
  max_outstanding, apb_default_timeout_ns, scoreboard_enable
systemverilog
function void init_protocol_resources();
  uvm_resource_db#(int)::set("vip.apb", "default_timeout_ns", 5000, null);
  uvm_resource_db#(int)::set("global", "max_outstanding", 8, null);
  uvm_resource_db#(bit)::set("global", "enable_scoreboard", 1, null);
endfunction

Key takeaways

  • Use hierarchical scope strings even though lookup is flat — it documents ownership.

  • Centralize resource_db sets in package init or top, not scattered in agents.

  • Prefer config_db when the value is instance-specific.

Common pitfalls

  • Generic scope names like "default" that collide across packages.

  • Writing resource_db entries from every agent build_phase.

  • Using resource_db for vif handles — always use config_db for interfaces.


Typed pool patterns and precedence

Typed pools isolate resources by type. Understand precedence when multiple entries share scope and name.

Read patterns

systemverilog
int timeout_ns;
if (uvm_resource_db#(int)::read_by_name("vip.apb", "default_timeout_ns", timeout_ns))
  cfg.timeout_ns = timeout_ns;

// Fallback: first int resource of this type (use sparingly)
int any_cap;
void'(uvm_resource_db#(int)::read_by_type(any_cap));
diagram
[CONFIG] precedence ladder

1) config_db get on instance path (most specific)
2) resource_db read_by_name(scope, name)
3) resource_db read_by_type (least specific — avoid in production)

document which level owns each knob

Pool audit and cleanup

systemverilog
function void dump_int_resources();
  `uvm_info("RES_POOL", "dumping int resources", UVM_LOW)
  uvm_resource_db#(int)::dump();
endfunction

// Remove stale debug entry before nightly
void'(uvm_resource_db#(int)::delete_by_name("debug", "temp_verbosity"));
  • Dump typed pools once at test start in debug builds.

  • Delete temporary debug resources in report_phase or test teardown.

  • Never depend on read_by_type when multiple entries of same type exist.

Common pitfalls

  • Assuming read_by_type order is stable across simulators or UVM versions.

  • Leaving debug scope entries that override production globals.

  • Publishing the same name under different types — confusing dump output.