Part 5 · Sequences · Intermediate
Encapsulation & Placement: Where Virtual Sequences Live
Env vs agent ownership, package organization, agent protocol rules, and keeping tests thin.
Ownership rules — agents vs env
The division is clear: agents own protocol , env owns scenarios . An APB agent provides apb_wr_seq, apb_rd_seq, and apb_burst_seq — sequences that know APB signals and timing. The env (or a dedicated sequences package) provides dma_xfer_vseq, chip_boot_vseq, and pcie_stress_vseq — sequences that know cross-agent storylines.
[SEQ] ownership matrix
AGENT (apb_agent) ENV (soc_env)
───────────────── ──────────────
apb_wr_seq dma_xfer_vseq
apb_rd_seq chip_stress_vseq
apb_burst_seq soc_boot_vseq
apb_sequencer soc_virtual_sequencer
Knows: PSEL, PADDR, protocol Knows: DMA flow, multi-bus order
Reusable: any SoC with APB Specific: this chip's scenariosPackage organization
Typical file layout separates agent sequences from virtual sequences:
soc_tb/
agents/
apb_agent/
apb_agent_pkg.sv // agent, driver, monitor, sequencer
apb_sequences.sv // apb_wr_seq, apb_rd_seq [SEQ]
axi_agent/
axi_sequences.sv // axi_burst_seq, axi_single_seq
env/
soc_env.sv // agents + v_sqr
soc_virtual_sequencer.sv
sequences/
dma_sequences.sv // dma_xfer_vseq, prog_dma_seq [VSEQ]
chip_scenarios.sv // chip_stress_vseq, boot_vseq
tests/
dma_test.sv // thin — starts one vseqAgent sequences ship with agent VIP — portable across projects.
Virtual sequences ship with env/sequences package — project-specific.
Tests import env package; env imports agent packages.
[VSEQ] Never put dma_xfer_vseq inside apb_agent — couples VIP to SoC story.
Agent encapsulation — what agents must not know
An agent must not reference other agents, env, or virtual sequencers. It exposes its sequencer; the env wires cross-agent coordination. This lets you reuse the AXI agent in a block-level test (no vseq) and a chip-level test (with vseq) unchanged.
[UVM] agent purity rules
ALLOWED in apb_agent:
apb_driver, apb_monitor, apb_sequencer
apb_wr_seq, apb_rd_seq (APB protocol only)
config knobs: idle_cycles, error_injection
FORBIDDEN in apb_agent:
reference to axi_agent or axi_sqr
dma_xfer_vseq or any cross-agent scenario
soc_virtual_sequencer handle// WRONG — agent knows about another agent
class apb_dma_helper_seq extends uvm_sequence;
task body();
this.start(p_sequencer); // APB item
env.axi_agent.sqr... // ✗ agent reaching into env/axi
endtask
endclass
// RIGHT — virtual sequence in env package
class dma_xfer_vseq extends uvm_sequence;
task body();
prog.start(p_sequencer.apb_sqr);
wr.start(p_sequencer.axi_sqr);
endtask
endclassThin tests — one vseq, one objection
The test's only job is to configure the environment, randomize scenario knobs, start the top-level virtual sequence, and manage phase objections. All scenario intelligence lives in the vseq class — reusable across directed, random, and regression tests.
class dma_random_test extends soc_base_test;
`uvm_component_utils(dma_random_test)
task run_phase(uvm_phase phase);
dma_xfer_vseq vseq = dma_xfer_vseq::type_id::create("vseq");
if (!vseq.randomize())
`uvm_fatal("TEST", "vseq randomize failed")
phase.raise_objection(this, "dma_random_test");
vseq.start(env.v_sqr);
phase.drop_objection(this, "dma_random_test");
endtask
endclass[VSEQ] test thinness checklist
✓ Test creates ONE top-level vseq
✓ Test randomizes vseq knobs (or uses config_db)
✓ Test starts vseq on env.v_sqr
✓ Test manages objection around vseq.start()
✗ Test does NOT start sub-sequences on agent.sqr directly
✗ Test does NOT contain fork/join scenario logicKey takeaways
Agents own protocol sequences; env owns scenario virtual sequences.
Virtual sequencer lives in env, sibling to agents.
Tests start one top-level vseq on env.v_sqr — stay thin.
Never put vseqs inside agent VIP — breaks reuse and encapsulation.
Common pitfalls
dma_xfer_vseq inside apb_agent package — SoC coupling in reusable VIP.
Test starting prog.start(env.apb_agent.sqr) directly — scenario sprawl.
Virtual sequencer inside an agent — other agents cannot connect handles.
Mega-test with 200 lines of fork/join — belongs in a vseq class.