Part 5 · Sequences · Intermediate
Sequence Items: Fields, Constraints, and Randomization
Hub — uvm_sequence_item as the transaction contract, field macros, constraints, layering, and copy/clone for scoreboards.
Overview
A uvm_sequence_item is the payload object that flows from sequence through sequencer to driver. It answers what to send — address, data, opcode, burst length — but never how to wiggle pins. That boundary is the foundation of reusable UVM agents: the same item class works in block tests, chip tests, and directed regressions because pin timing stays in the driver.
This topic breaks sequence items into five focused lessons. Each lesson answers a different why question: why items must not contain driver logic, why field macros matter for debug and scoreboards, why constraints define legal space vs directed corners, why derived items layer protocol rules, and why clone before queue prevents silent scoreboard corruption.
Lessons in this topic
Item vs Driver Boundary — what belongs in items, what must stay in the driver.
Field Macros & Automation — uvm_field_*, print, compare, copy, pack/unpack.
Constraints & randomize() with — inline blocks, with blocks, failure handling.
Layered & Derived Items — extend items, constraint layering, wr-only variants.
Copy, Clone & Scoreboard — type_id::create, clone before queue, unregistered fields.
Item flow in the stimulus stack
Legend: [STIM] [SEQ] [DRV] [ITEM] [UVM]
[STIM] TEST
│ seq.start(sqr)
▼
[SEQ] SEQUENCE.body()
│ start_item(req)
│ req.randomize() ← [ITEM] fields filled here
│ finish_item(req)
▼
[SEQ] SEQUENCER ──► [DRV] DRIVER.drive_apb(req)
│
▼ paddr, pwdata on vif
DUT pins
[ITEM] apb_item { addr, data, write } — data contract only
[DRV] drive_apb() { @(pclk); wait pready; } — timing policyEvery sub-lesson below expands one aspect of the [ITEM] box — how to define it, randomize it, extend it, and safely copy it for checking.
[ITEM] hub — ownership rules
IN the item: addr, data, write, burst_len, id, user fields
OUT of the item: virtual interface handles, #delays, clock waits
OUT of the item: pready/pvalid handshake loops, drive state machines
WHY: items cross sequence/driver boundary as pure data.
Driver owns HOW; item owns WHAT.Key takeaways
sequence_item is the data contract between sequence and driver.
Field macros give print, compare, and copy for free — register every payload member.
Constraints define legal space; randomize() with blocks add per-call directed corners.
Clone before queue — never store handles the monitor or driver still mutates.
Common pitfalls
Putting virtual interface handles inside items — breaks agent reuse across hierarchies.
Forgetting to check randomize() return value — silent constraint conflicts stall debug.
Using new() instead of type_id::create() — factory overrides on item types ignored.