Part 6 · Agents & Protocol IP · Intermediate
Standard Internals: Canonical Agent Composition and Responsibilities
Break down standard agent internals and enforce role boundaries across sequencer, driver, monitor, and wrapper orchestration.
Canonical component set
Across protocols, the internal pattern remains stable: one cfg object, one monitor, optional driver+sequencer in active mode, and wrapper-level analysis exports.
[UVM][AGT] canonical internals
eth_agent
├─ eth_cfg cfg
├─ eth_monitor mon (always)
├─ eth_sequencer sqr (active only)
├─ eth_driver drv (active only)
└─ uvm_analysis_port #(eth_item) ap[AGT] role matrix
wrapper:
structure + connections + outward contract
sequencer:
arbitration and item scheduling
driver:
protocol-accurate pin driving
monitor:
passive reconstruction and publicationKeep role ownership strict and reviewable.
Avoid duplicating logic across driver and monitor domains.
Use shared cfg to coordinate behavior consistently.
Role-specific implementation snippets
class eth_sequencer extends uvm_sequencer #(eth_item);
`uvm_component_utils(eth_sequencer)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
endclass
class eth_driver extends uvm_driver #(eth_item);
`uvm_component_utils(eth_driver)
virtual eth_if vif;
eth_cfg cfg;
function void build_phase(uvm_phase phase);
super.build_phase(phase);
if (!uvm_config_db#(eth_cfg)::get(this, "", "cfg", cfg))
`uvm_fatal("NOCFG", "driver missing cfg")
vif = cfg.vif;
endfunction
endclass
class eth_monitor extends uvm_monitor;
`uvm_component_utils(eth_monitor)
uvm_analysis_port #(eth_item) ap;
function new(string name, uvm_component parent);
super.new(name, parent);
ap = new("ap", this);
endfunction
endclass[UVM][AGT] ownership boundaries
driver must not:
randomize sequence intent
monitor must not:
drive DUT pins
sequencer must not:
encode pin-level protocol timingUse ownership boundaries as code-review checklist items.
Keep driver and monitor transaction models aligned for checking.
Preserve type compatibility across sequence, driver, and analysis paths.
Standard internal invariants
Monitor exists in both active and passive modes.
Driver-sequencer pair exists only in active mode.
Wrapper analysis export receives monitor stream in all modes.
Cfg is visible to every child component that needs behavior knobs.
Child components are factory-created for override flexibility.
[AGT] invariant violation examples
missing monitor in passive mode
-> no observability at integration
driver exists in passive mode
-> contention risk on DUT-driven bus
cfg not forwarded to monitor
-> inconsistent decode/check policyKey takeaways
Canonical internals should be predictable and protocol-agnostic.
Role boundaries prevent architecture drift and hidden coupling.
Invariants provide fast review and triage anchors.
Consistent internal composition improves VIP portability.
Common pitfalls
Allowing monitor to depend on driver state for decode decisions.
Duplicating protocol parameters outside cfg object.
Violating active/passive internal shape invariants.
Bypassing factory creation in child components.