Part 3 · Factory & Configuration · Intermediate

config_db vs Parameters: Choosing the Right Mechanism

When to use uvm_config_db vs SystemVerilog #() parameters, module-level defparams, and plusargs — decision criteria and hybrid patterns.

Two configuration worlds

SystemVerilog #() parameters resolve at elaboration time in the static HDL world. uvm_config_db resolves at simulation run time in the dynamic UVM world. Each has a natural domain.

diagram
[HDL] static elaboration          [UVM] dynamic runtime
  ───────────────────────          ───────────────────────
  module #(.WIDTH(32))              class driver
  parameter WIDTH                    uvm_config_db#get(vif)
  defparam u_dut.WIDTH=64            config_db#set/get in build_phase

  fixed at compile/elab              mutable per test, per run
  no UVM hierarchy                   hierarchical path lookup

Decision matrix

diagram
Use #() parameters / defparam when:
  • DUT/generator RTL width/generics fixed at elaboration
  • Interface parameterization (data width, ID width)
  • Values never change between tests in same elaboration

Use uvm_config_db when:
  • Passing virtual interface handles to UVM components
  • Test-specific agent policy (active/passive, timeout, coverage)
  • Values set in test build_phase, consumed in env/agent build_phase
  • Hierarchical scoping needed (per-agent overrides)

Use plusargs when:
  • Regression command-line knobs (+TIMEOUT=5000)
  • Debug overrides without recompiling
  • Values read once at test start, then pushed into config_db

Hybrid pattern — plusargs into config_db

systemverilog
function void build_phase(uvm_phase phase);
  apb_config acfg = apb_config::type_id::create("acfg");
  acfg.apply_defaults();

  int timeout;
  if ($value$plusargs("TIMEOUT=%d", timeout))
    acfg.timeout_ns = timeout;

  uvm_config_db#(apb_config)::set(this, "env.apb", "cfg", acfg);
  super.build_phase(phase);
endfunction
diagram
[CONFIG][UVM] hybrid flow

  RTL params      DUT/interface elaboration (compile time)
  plusargs        test intent override (sim start)
  config_db       UVM component policy (build_phase)
  factory         class substitution (build_phase, before create)

  do not use config_db for RTL widths — too late, wrong layer
  • Bridge plusargs into config objects — don't scatter plusarg reads in agents.

  • Keep RTL parameters out of UVM classes — use config objects for TB policy.

  • Document which layer owns each knob in your project's config spec.

Key takeaways

  • Parameters for static HDL; config_db for dynamic UVM component policy.

  • Plusargs are a test entry point — normalize into config_db early.

  • Never try to change RTL parameters from config_db — elaboration already happened.

Common pitfalls

  • Using defparam in run-time initial blocks expecting UVM to see it.

  • Reading plusargs in every agent instead of once in test.

  • Mixing parameter and config_db for the same knob — two sources of truth.