Part 5 · Sequences · Intermediate
The Coordination Problem: DMA + APB + AXI Scenario
Why chip-level scenarios need orchestration, the three-agent DMA walkthrough, and test sprawl without virtual sequences.
One scenario, three agents
Consider a DMA engine transfer test: program source address, destination address, and length over the APB config port; write source data to memory over AXI; assert the DMA START bit; wait for completion interrupt; read back destination memory over AXI and compare. This single scenario touches three agents — APB, AXI master, and optionally an interrupt/DMA status agent.
Each agent has its own sequencer and driver. The scenario has a strict ordering constraint (program before start, start before memory check) and parallel phases (AXI reads and writes while DMA runs). Something must coordinate across agents — that coordinator is a virtual sequence.
[STIM] DMA transfer scenario — agent involvement
Step 1 [APB] Program DMA_SRC, DMA_DST, DMA_LEN registers
Step 2 [AXI] Write source buffer data to memory
Step 3 [APB] Write DMA_CTRL.START = 1
Step 4 [APB] Poll DMA_STATUS or wait for IRQ
Step 5 [AXI] Read destination buffer, compare to source
Agents: apb_agent axi_agent (irq_monitor for Step 4)
Sequencers: apb_sqr axi_sqrThe sprawl problem — test reaches into agents
Without virtual sequences, the test's run_phase directly starts sequences on each agent's sequencer. Scenario logic sprawls across the test file, cannot be reused in other tests, and breaks agent encapsulation — the test knows internal agent hierarchy details.
// ANTI-PATTERN: scenario logic in the test
task run_phase(uvm_phase phase);
prog_dma_seq prog = prog_dma_seq::type_id::create("prog");
axi_wr_seq wr = axi_wr_seq::type_id::create("wr");
axi_rd_seq rd = axi_rd_seq::type_id::create("rd");
phase.raise_objection(this);
prog.src = 32'h1000; prog.dst = 32'h2000; prog.len = 256;
prog.start(env.apb_agent.sqr); // test knows apb_agent
wr.addr = 32'h1000; wr.len = 256;
wr.start(env.axi_agent.sqr); // test knows axi_agent
// ... 50 more lines of coordination ...
phase.drop_objection(this);
endtask[VSEQ] sprawl vs encapsulation
WITHOUT virtual sequence:
TEST ──direct──► apb_agent.sqr
TEST ──direct──► axi_agent.sqr
TEST ──direct──► dma_agent.sqr
Scenario logic in test → not reusable, env coupling
WITH virtual sequence:
TEST ──► dma_xfer_vseq.start(env.v_sqr)
VSEQ ──► sub-sequences on p_sequencer.apb_sqr / .axi_sqr
Scenario in one reusable class → test stays thinScenario timeline — ordering and parallelism
The DMA scenario mixes sequential steps (program before start) with parallel traffic (AXI read and write streams during transfer). A virtual sequence expresses both with procedural SystemVerilog in body().
[VSEQ] dma_xfer_vseq — scenario timeline
TIME ─────────────────────────────────────────────────────────────►
APB: [prog SRC][prog DST][prog LEN]──────[START]──────[poll STATUS]
AXI: [wr stream src buf]───────────────────────────────
AXI: [rd stream dst buf]────────
DMA: ▲ engine active ──────────▲
Sequential: prog completes before START
Parallel: AXI wr during DMA; AXI rd after DMA done
Coordinator: virtual sequence body() — fork/join + ordered callsWhy agents cannot own this scenario
APB agent knows APB protocol — not AXI memory patterns or DMA flow.
Scenario spans agents — belongs at env/chip level, not inside one VIP.
Reuse: same dma_xfer_vseq in smoke test, stress test, and directed corner test.
[VSEQ] Virtual sequence is the scenario container; agents stay protocol-pure.
Virtual sequence as the answer
A dma_xfer_vseq encapsulates the entire scenario. The test sets knobs (src, dst, len), starts the vseq on the virtual sequencer, and drops objection when body() completes. All cross-agent ordering lives in one class.
// CLEAN pattern: thin test
task run_phase(uvm_phase phase);
dma_xfer_vseq vseq = dma_xfer_vseq::type_id::create("vseq");
vseq.randomize() with { len == 256; };
phase.raise_objection(this);
vseq.start(env.v_sqr);
phase.drop_objection(this);
endtaskKey takeaways
Chip scenarios span agents — need a coordinator above agent level.
Tests that reach into agent.sqr sprawl and break reuse.
Virtual sequence encapsulates cross-agent ordering and parallelism.
Common pitfalls
Putting DMA scenario in test run_phase — copy-paste across tests.
One mega-sequence inside AXI agent that calls APB — wrong ownership.
Assuming monitors coordinate stimulus — monitors observe; vseqs stimulate.