Part 5 · Sequences · Intermediate

Layered Sequences & uvm_sequence_library

Hub — reusable stimulus stacks from beat to virtual scenario, base sequence helpers, start() delegation, uvm_sequence_library registration, and factory overrides.

Overview

Flat tests that duplicate randomize() loops in every scenario become unmaintainable within a single project week. Layered sequences solve this by assigning one concern per level: atomic beats at the bottom, protocol bursts in the middle, multi-agent flows at the top. Higher layers call lower layers with start() or shared base helpers — they do not re-implement the same start_item/finish_item block five times.

This topic breaks layering and libraries into five focused lessons. Each lesson answers a different how question: how to map the beat→burst→flow→vseq stack, how base classes centralize helpers, how start() delegates sub-sequences, how uvm_sequence_library diversifies regressions, and how factory overrides swap library entries without editing the library source.

Lessons in this topic

  1. Layering Stack Overview — beat→burst→flow→vseq diagram and abstraction boundaries.

  2. Base Sequence Helpers — axi_base_seq send_beat() and shared knobs.

  3. Starting Sub-Sequences — axi_four_beat_seq and start() semantics.

  4. Sequence Library Registration — uvm_sequence_library and selection modes.

  5. Factory Library Overrides — set_type_override_by_type for regression variants.

The layering stack

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

┌─────────────────────────────────────────────────────────────────────────┐
│  LAYERING STACK — one concern per level                                   │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                           │
│  TEST [STIM]          chip_stress_test.start_vseq()                       │
│       │                                                                   │
│       ▼                                                                   │
│  VSEQ [SEQ]           chip_stress_vseq  (fork dma + pcie + axi)           │
│       │                                                                   │
│       ▼                                                                   │
│  FLOW [SEQ]           axi_burst_flow_seq  (N bursts, gaps, backpressure)│
│       │                                                                   │
│       ▼                                                                   │
│  BURST [SEQ]          axi_burst_seq  (one burst: len, addr, data[])       │
│       │                                                                   │
│       ▼                                                                   │
│  BEAT [SEQ]           axi_single_seq  (one beat: start_item/finish_item)│
│       │                                                                   │
│       ▼                                                                   │
│  ITEM [UVM]           axi_item  (rand addr, data, burst_len)              │
│       │                                                                   │
│       ▼                                                                   │
│  SEQUENCER [UVM]    DRIVER [DRV]    DUT pins                            │
│                                                                           │
└─────────────────────────────────────────────────────────────────────────┘

Keep this diagram as your map. Every sub-lesson expands one box or arrow — never all five at once.

diagram
[STIM] layering vs monolithic — maintenance cost

  MONOLITHIC (one 500-line body)
    every test copies randomize loops
    bug fix in burst logic  edit 40 tests
    regression diversity = write 40 new tests

  LAYERED (beat  burst  flow  vseq)
    fix send_beat once in axi_base_seq
    tests start chip_stress_vseq only
    uvm_sequence_library randomizes burst mix

Key takeaways

  • Layer: beat → burst → flow → virtual scenario → test — one abstraction per level.

  • Base sequences centralize send_beat and knobs; derived sequences override body().

  • start() delegates whole sub-sequences; inline start_item for atomic beats only.

  • uvm_sequence_library + factory overrides diversify regressions without new tests.

Common pitfalls

  • Mega-sequence that skips layers — zero reuse, copy-paste across tests.

  • Sub-sequence started on wrong sequencer — p_sequencer type mismatch.

  • Library with one sequence type — use a plain sequence instead.

  • Deep inheritance without base helpers — duplicated start_item blocks everywhere.