Part 5 · Sequences · Intermediate

Virtual Sequences & Multi-Agent Coordination

Hub — multi-agent scenarios, virtual sequencers, p_sequencer, fork/join patterns, and encapsulation rules.

Overview

Chip-level verification scenarios span multiple buses and agents. A DMA transfer might program registers over APB, poll an interrupt, and verify memory over AXI — three agents, three sequencers, one coordinated story. A virtual sequence orchestrates sub-sequences on those real sequencers without driving pins itself. A virtual sequencer holds handles to real sequencers but has no driver connection.

This topic breaks virtual sequences into five lessons: the coordination problem, virtual sequencer wiring in connect_phase, p_sequencer declaration, fork/join orchestration patterns, and where vseqs live in the hierarchy.

Lessons in this topic

  1. Coordination Problem — DMA+APB+AXI scenario and why tests cannot reach into agents.

  2. Virtual Sequencer Wiring — soc_virtual_sequencer, connect_phase handle assignment.

  3. p_sequencer Declare — uvm_declare_p_sequencer and dma_xfer_vseq walkthrough.

  4. Fork/Join Patterns — join, join_any, layered virtual sequences.

  5. Encapsulation & Placement — env vs agent ownership, thin tests.

Virtual layer in the stimulus stack

diagram
Legend: [STIM] [SEQ] [VSEQ] [UVM]

  [VSEQ] VIRTUAL LAYER — orchestrates, does not drive pins

  TEST
    │
    │  chip_scenario_vseq.start(env.v_sqr)
    ▼
  ┌─────────────────────────────────────────────────────────────┐
  │ [VSEQ] dma_xfer_vseq (virtual sequence)                     │
  │   prog_dma_seq.start(p_sequencer.apb_sqr)   ──► APB agent   │
  │   fork axi_rd / axi_wr on p_sequencer.axi_sqr ──► AXI agent │
  └─────────────────────────────────────────────────────────────┘
         │ uses handles in
         ▼
  ┌─────────────────────────────────────────────────────────────┐
  │ [UVM] soc_virtual_sequencer — NO driver                     │
  │   apb_sqr ──► apb_agent.sequencer ──► apb_driver ──► DUT   │
  │   axi_sqr ──► axi_agent.sequencer ──► axi_driver ──► DUT   │
  │   dma_sqr ──► dma_agent.sequencer ──► dma_driver ──► DUT   │
  └─────────────────────────────────────────────────────────────┘

  [SEQ] Sub-sequences on real sequencers produce items
  [VSEQ] Virtual sequence only calls sub-sequences.start()

The virtual layer keeps scenario logic reusable and agents encapsulated. Each sub-lesson expands one box in this diagram.

diagram
[VSEQ] virtual vs real sequence

  REAL sequence (apb_wr_seq):
    start_item(req)  finish_item(req)  driver  DUT pins  [STIM]

  VIRTUAL sequence (dma_xfer_vseq):
    sub_seq.start(p_sequencer.apb_sqr)  — delegates to real sequencer
    NO start_item on vseq itself — no driver port connected

Key takeaways

  • Virtual sequencer = handle bundle to real sequencers; no driver.

  • Virtual sequence = orchestrator; starts sub-sequences on p_sequencer handles.

  • Tests start one top-level vseq on env.v_sqr — stay thin.

  • Agents own protocol sequences; env owns scenario virtual sequences.

Common pitfalls

  • Virtual sequence calling start_item — no driver connected; UVM fatal.

  • Null p_sequencer handles — connect_phase missed agent.sqr assignment.

  • Putting vseqs inside agent VIP — breaks SoC-level reuse.