Part 6 · Agents & Protocol IP · Intermediate
Per-Field Knobs: Orthogonal Controls and Semantic Precision
Design per-field knobs that are composable, clearly scoped, and easy to validate and debug across agent components.
Knob taxonomy and semantics
Treat every knob as part of your integration API. One knob should control one axis, with units, default, and consumer documented.
[UVM][AGT][DRV][TLM] knob taxonomy
mode knobs:
is_active, enable_driver
driver timing knobs:
req_gap_*_cycles, timeout_cycles
handshake knobs:
send_rsp, max_outstanding, retry_limit
checker knobs:
enable_checks, strict_mode
debug knobs:
trace_cfg, trace_tlm, dump_n_first[CFG] naming pattern
boolean:
enable_<feature>
count/range:
<name>_count, <name>_min, <name>_max
time:
<name>_cycles
ratio/probability:
<name>_pctAvoid generic fields like `mode2` or `policy` without semantics.
Capture units in field names to reduce misconfiguration.
Keep debug knobs separate from functional behavior knobs.
Reference design with consumer mapping
class uart_agent_cfg extends uvm_object;
`uvm_object_utils(uart_agent_cfg)
uvm_active_passive_enum is_active = UVM_ACTIVE;
virtual uart_if vif;
// Driver timing
int unsigned tx_start_delay_cycles = 1;
int unsigned rx_timeout_cycles = 512;
// TLM/response
bit send_rsp = 1;
bit include_framing_status = 1;
// Checker policy
bit enable_frame_check = 1;
bit strict_parity_check = 1;
// Fault policy
bit inject_noise = 0;
int unsigned inject_noise_pct = 0;
// Debug
bit trace_cfg = 0;
bit trace_rx = 0;
bit trace_tx = 0;
function new(string name = "uart_agent_cfg");
super.new(name);
endfunction
endclass[UVM][AGT][DRV][TLM] consumer map
agent wrapper consumes:
is_active
driver consumes:
tx_start_delay_cycles, rx_timeout_cycles, inject_*
sequencer/sequence path consumes:
send_rsp and response schema knobs
monitor/checker consumes:
strict_parity_check, enable_frame_check, trace_rx/txFields without consumers are dead knobs and should be removed.
Document consumer mapping to simplify code review.
Avoid hidden derived behavior that couples unrelated knobs.
Coherence checks and review checklist
function bit validate_knobs(ref string msg);
if (rx_timeout_cycles < 16) begin
msg = "rx_timeout_cycles must be >= 16";
return 0;
end
if (inject_noise_pct > 100) begin
msg = "inject_noise_pct must be <= 100";
return 0;
end
if (!inject_noise && inject_noise_pct != 0) begin
msg = "inject_noise_pct non-zero while inject_noise=0";
return 0;
end
msg = "";
return 1;
endfunction[UVM][AGT][DRV][TLM] knob review checklist
[ ] single-purpose semantics
[ ] explicit units and legal bounds
[ ] documented consumers
[ ] dependencies validated
[ ] effective values included in cfg dump
[ ] no overlap with existing knobsKey takeaways
Per-field knobs should be orthogonal, bounded, and consumer-mapped.
Semantic naming and units reduce ambiguity during integration.
Validation catches contradictory knob combinations before runtime.
Review knobs as API surface, not local implementation details.
Common pitfalls
Overloaded knobs controlling multiple behavior axes.
Dead knobs with no active consumers.
No validation for dependency pairs like enable/percentage.
Adding knobs without dump visibility or documentation.