Part 11 · Senior Prep · Intermediate
Interview Q&A: Virtual Sequences
Model answers on virtual sequencers, p_sequencer, multi-agent fork/join, encapsulation rules, and chip-level scenario coordination.
Virtual sequence fundamentals
Q: Why virtual sequences?
[INT][SENIOR][UVM] MODEL ANSWER
Q: Why virtual sequences?
A:
MECHANISM: Sequence on uvm_virtual_sequencer holds handles to real sequencers;
starts sub-sequences on each without driving pins itself.
MOTIVATION: Chip scenarios span DMA + CPU + interrupt — agents stay encapsulated.
WHEN: Multi-agent coordinated tests at subsystem/chip level.
NOT WHEN: Single-agent block TB — virtual seq adds indirection for no gain.
PITFALL: Virtual seq reaches agt.drv or vif — breaks VIP boundary.
EXAMPLE: dma_fill_vseq: prog_dma_seq.start(apb_sqr); fork axi_rd/wr on axi_sqr.Q: What is a virtual sequencer?
[INT][SENIOR][UVM] MODEL ANSWER
Q: Virtual sequencer?
A:
MECHANISM: uvm_sequencer subclass with no driver — only holds sequencer handles
(apb_sqr, axi_sqr) assigned in env connect_phase.
MOTIVATION: Single start point for chip vseq; test does not hunt agent handles.
WHEN: env owns v_sqr; connect_phase: v_sqr.axi_sqr = axi_agt.sequencer.
PITFALL: Virtual sequencer with seq_item_port connected to driver — wrong.
EXAMPLE: soc_virtual_sequencer { apb_sqr, axi_sqr, pcie_sqr } — no driver child.Q: Explain uvm_declare_p_sequencer
[INT][SENIOR][UVM] MODEL ANSWER
Q: uvm_declare_p_sequencer?
A:
MECHANISM: Macro declares typed p_sequencer handle matching virtual sequencer class.
MOTIVATION: Type-safe access to apb_sqr, axi_sqr in vseq body without $cast.
WHEN: Every virtual sequence targeting a typed virtual sequencer.
PITFALL: Declaring p_sequencer as plain uvm_sequencer — loses typed handles.
EXAMPLE: uvm_declare_p_sequencer(soc_virtual_sequencer)
p_sequencer.apb_sqr — compile-time typed.[INT][SENIOR][UVM] virtual layer whiteboard
TEST.start(env.v_sqr, dma_vseq)
│
▼
[VSEQ] dma_vseq — NO start_item, NO driver
├─ prog_seq.start(p_sequencer.apb_sqr)
└─ fork
data_seq.start(p_sequencer.axi_sqr)
poll_seq.start(p_sequencer.apb_sqr)
joinKey takeaways
Virtual sequences orchestrate via start() — never drive pins.
Virtual sequencer = handle container, no driver connection.
p_sequencer gives typed multi-agent access in vseq body.
Common pitfalls
Virtual seq with start_item — only real sequencers have drivers below.
Test reaching into agt.sequencer — env should expose v_sqr.
Coordination patterns
Q: fork/join vs fork/join_any in virtual sequences?
[INT][SENIOR][UVM] MODEL ANSWER
Q: fork/join vs join_any in vseq?
A:
MECHANISM: join waits for all branches; join_any proceeds when first completes;
join_none detaches (dangerous without objection accounting).
MOTIVATION: Parallel traffic (AXI read + write); join_any for 'wait IRQ then stop bulk'.
WHEN: join for coordinated stress; join_any for event-triggered scenario phase.
PITFALL: join_none + immediate drop_objection — branches killed mid-sequence.
EXAMPLE: fork bulk_seq.start(axi_sqr); irq_wait_seq.start(apb_sqr); join_any
→ disable bulk when IRQ fires.Q: Where should virtual sequences live in the hierarchy?
[INT][SENIOR][UVM] MODEL ANSWER
Q: Vseq placement — env vs test?
A:
MECHANISM: Reusable scenario vseqs in env pkg or seq_lib; test starts chosen vseq.
MOTIVATION: Tests stay thin (objection + start); scenarios reusable across tests.
WHEN: dma_fill_vseq used by smoke, stress, and merge tests — lives in env seq_lib.
PITFALL: 200-line body() in test class — not reusable, not reviewable.
EXAMPLE: chip_stress_test.run_phase: vseq.start(env.v_sqr, chip_stress_vseq::type_id::get()).Q: How do virtual sequences interact with objections?
[INT][SENIOR][UVM] MODEL ANSWER
Q: Vseq and objections?
A:
MECHANISM: Test (or top-level vseq) raises objection before start(); drop after
vseq body completes — including all fork/join branches.
MOTIVATION: Objections track task-phase activity; vseq body is a task.
WHEN: Test raises/drops for simple cases; vseq raises for long multi-fork scenarios.
PITFALL: fork/join_none in vseq then test drops objection — parallel branches killed.
EXAMPLE: vseq body: raise_objection(this); fork ... join; drop_objection(this).Q: Block seq reuse at chip — what changes?
[INT][SENIOR][UVM] MODEL ANSWER
Q: Block sequences at chip level?
A:
MECHANISM: Same axi_burst_seq.start(axi_sqr) — only the sequencer handle comes from
v_sqr instead of test reaching into block agt.
MOTIVATION: Agent sequences unchanged; chip adds coordination layer only.
WHEN: Block sign-off seq_lib imported into chip env; vseq composes them.
PITFALL: Rewriting block sequences for chip — destroys reuse economics.
EXAMPLE: Block: test.start(agt.sqr, axi_rand_seq). Chip: vseq.start(p_sequencer.axi_sqr, same seq).Key takeaways
fork/join_any for event-driven phases; never drop objection before join.
Reusable vseqs in env pkg; tests select and start them.
Chip integration adds vseq layer — block agent seqs stay unchanged.
Common pitfalls
join_none without objection ownership plan — mid-scenario kill.
Rewriting agent sequences at chip instead of composing via vseq.