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.

diagram
[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
diagram
[AGT] role matrix

wrapper:
  structure + connections + outward contract

sequencer:
  arbitration and item scheduling

driver:
  protocol-accurate pin driving

monitor:
  passive reconstruction and publication
  • Keep role ownership strict and reviewable.

  • Avoid duplicating logic across driver and monitor domains.

  • Use shared cfg to coordinate behavior consistently.


Role-specific implementation snippets

systemverilog
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
diagram
[UVM][AGT] ownership boundaries

driver must not:
  randomize sequence intent

monitor must not:
  drive DUT pins

sequencer must not:
  encode pin-level protocol timing
  • Use 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

  1. Monitor exists in both active and passive modes.

  2. Driver-sequencer pair exists only in active mode.

  3. Wrapper analysis export receives monitor stream in all modes.

  4. Cfg is visible to every child component that needs behavior knobs.

  5. Child components are factory-created for override flexibility.

diagram
[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 policy

Key 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.