Part 6 · Agents & Protocol IP · Intermediate

Cfg Validation Checks: Fail-Fast Legality and Topology Coherence

Layer validation for field legality, integration binding, and topology coherence before run-phase behavior begins.

Validation layers and boundaries

Good validation gates structural construction and prevents deep runtime failures. Combine class constraints, semantic validators, and component-level coherence checks.

diagram
[UVM][AGT][DRV][TLM] validation stack

layer 1 class constraints:
  bounds and direct dependencies

layer 2 cfg.validate():
  semantic and integration-aware checks

layer 3 wrapper checks:
  mode -> topology coherence

layer 4 child checks:
  local mandatory requirements
diagram
[CFG] severity policy

fatal:
  null mandatory handles, illegal ranges, structural contradictions

warning:
  deprecated or ignored optional fields

info:
  normalization/defaults applied
  • Run core checks in build/end_of_elaboration for deterministic failure points.

  • Return actionable messages with offending values.

  • Keep validation side-effect free; normalization belongs in separate methods.


validate() and wrapper gating example

systemverilog
class spi_agent_cfg extends uvm_object;
  `uvm_object_utils(spi_agent_cfg)

  uvm_active_passive_enum is_active = UVM_ACTIVE;
  virtual spi_if vif;
  int unsigned timeout_cycles = 256;
  int unsigned cs_hold_cycles = 1;
  bit send_rsp = 1;
  bit enable_checks = 1;

  function bit validate(ref string err);
    if (timeout_cycles < 8) begin
      err = "timeout_cycles must be >= 8";
      return 0;
    end
    if (cs_hold_cycles > 64) begin
      err = "cs_hold_cycles must be <= 64";
      return 0;
    end
    if (is_active == UVM_ACTIVE && vif == null) begin
      err = "active mode requires non-null vif";
      return 0;
    end
    err = "";
    return 1;
  endfunction
endclass

function void build_phase(uvm_phase phase);
  string err;
  super.build_phase(phase);
  if (!uvm_config_db#(spi_agent_cfg)::get(this, "", "cfg", cfg))
    `uvm_fatal("NOCFG", "spi_agent_cfg missing")

  if (!cfg.validate(err))
    `uvm_fatal("BADCFG", $sformatf("invalid cfg: %s", err))
endfunction
systemverilog
function void end_of_elaboration_phase(uvm_phase phase);
  super.end_of_elaboration_phase(phase);

  if (cfg.is_active == UVM_ACTIVE) begin
    if (drv == null || sqr == null)
      `uvm_fatal("TOPO", "active mode requires drv+sqr")
  end

  if (mon == null)
    `uvm_fatal("TOPO", "monitor must exist in both active/passive modes")
endfunction
  • Call validate immediately after cfg get.

  • Gate topology creation decisions with validated cfg.

  • Cross-check cfg mode against actual constructed components.


Validation checklist and CI hooks

diagram
[UVM][AGT][DRV][TLM] validation checklist

cfg object:
  [ ] required fields set
  [ ] ranges legal
  [ ] dependencies coherent

binding:
  [ ] vif non-null when required
  [ ] mode override precedence resolved

topology:
  [ ] active -> drv+sqr+mon
  [ ] passive -> mon only

run-safety:
  [ ] one cfg summary log per instance
diagram
[CFG] CI strategy

smoke test should assert:
  cfg validate passes
  topology coherence passes
  no fatal/warning spikes from deprecations

regression metadata should capture:
  effective cfg summary
  seed + test id

Key takeaways

  • Fail-fast validation prevents expensive deep-debug cycles.

  • Layered checks catch both field legality and structural coherence issues.

  • Severity discipline keeps hard failures visible and optional issues informative.

  • CI smoke gates should include cfg validation and effective-summary capture.

Common pitfalls

  • Continuing after null-handle or structural validation failures.

  • Scattered validation logic with inconsistent semantics.

  • Warnings used where fatal behavior is required.

  • No topology checks after cfg-driven build decisions.