Part 6 · Agents & Protocol IP · Intermediate
Rand Constraints in Cfg: Controlled Policy Exploration with Replayability
Use constrained random cfg fields to sweep environment policy safely while preserving deterministic replay and clear intent.
Why randomize config policy
Cfg randomization explores policy envelopes (timing, depth, retry, error rates) while sequence randomization explores transaction content. Combined, they broaden coverage with control.
[UVM][AGT][DRV][TLM] two-level randomization
level 1 cfg randomization:
choose legal policy envelope
timeout, gap, outstanding, error-rate knobs
level 2 sequence randomization:
choose specific transactions inside envelope
benefit:
richer behavior space with bounded legality[CFG] replayability contract
if cfg randomize() is used:
log seed context
log effective values
keep constraints deterministic
avoid hidden time-dependent mutationsRandomize policy knobs, not mandatory integration handles.
Bound all ranges to realistic protocol capabilities.
Print one concise cfg summary per run for replay.
Constraint example and scenario biasing
class stream_agent_cfg extends uvm_object;
`uvm_object_utils(stream_agent_cfg)
uvm_active_passive_enum is_active = UVM_ACTIVE;
virtual stream_if vif;
rand int unsigned max_outstanding;
rand int unsigned req_gap_min_cycles;
rand int unsigned req_gap_max_cycles;
rand int unsigned timeout_cycles;
rand bit enable_backpressure;
rand int unsigned backpressure_pct;
rand bit inject_err;
rand int unsigned inject_err_pct;
constraint c_ranges {
max_outstanding inside {[1:16]};
req_gap_min_cycles inside {[0:8]};
req_gap_max_cycles inside {[req_gap_min_cycles:64]};
timeout_cycles inside {[64:4096]};
backpressure_pct inside {[0:100]};
inject_err_pct inside {[0:100]};
}
constraint c_dependency {
if (!enable_backpressure) backpressure_pct == 0;
if (!inject_err) inject_err_pct == 0;
if (is_active == UVM_PASSIVE) max_outstanding == 1;
}
constraint c_bias {
max_outstanding dist { [1:4] := 3, [5:8] := 6, [9:16] := 1 };
timeout_cycles dist { [64:512] := 8, [513:4096] := 2 };
}
endclassfunction void build_phase(uvm_phase phase);
stream_agent_cfg cfg;
super.build_phase(phase);
cfg = stream_agent_cfg::type_id::create("cfg");
if (!cfg.randomize() with {
enable_backpressure == 1;
backpressure_pct inside {[10:40]};
timeout_cycles <= 1024;
})
`uvm_fatal("CFG_RAND", "stream_agent_cfg randomization failed")
`uvm_info("CFG_RAND",
$sformatf("out=%0d gap=[%0d,%0d] to=%0d bp=%0d/%0d err=%0d/%0d",
cfg.max_outstanding,
cfg.req_gap_min_cycles,
cfg.req_gap_max_cycles,
cfg.timeout_cycles,
cfg.enable_backpressure,
cfg.backpressure_pct,
cfg.inject_err,
cfg.inject_err_pct),
UVM_LOW)
endfunctionUse `dist` to bias practical center cases without losing corners.
Express dependencies directly in constraints for reviewability.
Inline constraints should specialize scenarios, not redefine legality.
Layering strategy and anti-patterns
Use layered constraints: base legality in cfg class, scenario shaping in test inline constraints, and post-randomize assertions for derived invariants.
[UVM][AGT][DRV][TLM] layering model
base class constraints:
legal envelope for all tests
test inline constraints:
campaign-specific policy shaping
validation checks:
cross-field semantics and topology coherence
runtime:
consume resolved policy as read-only[CFG] anti-pattern map
anti-pattern:
unconstrained percentages/timeouts
effect:
unrealistic and noisy regressions
anti-pattern:
hidden procedural coercion in post_randomize
effect:
opaque effective values
anti-pattern:
randomizing cfg mid-run without protocolized reconfig
effect:
non-replayable behaviorKey takeaways
Cfg randomization is high-value when legality and replayability are explicit.
Constraint layering keeps global policy reusable and local scenarios flexible.
Dependency rules in constraints are easier to maintain than procedural fixes.
Effective-value logging is mandatory for diagnosing random-policy regressions.
Common pitfalls
Randomizing required handles like vif.
Contradictory constraints that fail intermittently under overrides.
No seed/effective-value logs for random cfg runs.
Mutating cfg during run without explicit reconfiguration protocol.