Part 5 · Sequences · Intermediate
Randomize Failures & Arbitration Locks
Constraint conflicts, unchecked randomize, lock/grab without unlock, and background sequence starvation.
Randomize failures — silent or loud
If randomize() fails and you do not check the return value, behavior depends on your code path: you may call finish_item with stale defaults, skip the beat entirely, or hit an assert. Constraint conflicts are common when layering adds inline constraints on top of item constraints.
if (!req.randomize() with { addr[1:0] == 2'b00; len inside {[1:8]}; }) begin
`uvm_error("RAND", "constraint conflict — printing item state")
req.print();
// do NOT call finish_item with illegal item unless testing error path
return;
endConflicting inline + with constraints and item constraints — solver returns 0.
rand_mode(0) on fields you forgot to assign manually before finish_item.
constraint_mode(0) on legal_addr — randomize produces addresses driver rejects.
Hard constraint added in send_beat conflicts with test soft override — solver fail.
Diagnosing constraint conflicts
Raise solver visibility with UVM_FULL verbosity on the sequence or item class, or run with the standard plusarg:
# Full solver trace (verbose — use narrow scope when possible)
+UVM_VERBOSITY=UVM_FULL
# Or per-component after sim starts
+uvm_set_verbosity=env.axi_agent.sqr,_ALL_,UVM_FULL,timeWalkthrough — conflicting burst constraints
[SEQ] constraint conflict example
axi_item constraint: burst_len inside {0, 1, 3, 7}
send_beat inline: burst_len inside {[4:15]}
solver: empty solution set → randomize() == 0
LOG: UVM_ERROR RAND constraint conflict
FIX: align inline with item constraints OR disable item constraint for this seq// Temporary debug — see which constraints clash
req.rand_mode(1);
req.constraint_mode(1);
assert(req.randomize() with { burst_len == 7; }); // narrow to one legal valueArbitration lock and grab
When a sequence calls lock() or grab() on the sequencer, it holds exclusive access. Other sequences block at start_item until unlock() or ungrab(). A forgotten unlock is one of the most common long-hang root causes in multi-sequence environments.
Legend: [SEQ] [UVM]
bg_config_seq.body()
p_sequencer.lock(this)
// ... long config sequence ...
// BUG: forgot unlock — holds lock forever
test_seq.body()
start_item(req) ◄── BLOCKS forever waiting for lock releaseSearch codebase for lock( and grab( — every call needs matching unlock/ungrab.
Background seq started in env run_phase before test seq — may hold lock.
uvm_do_with macros inside locked region — nested start_item still obeys lock.
kill() on locked sequence — verify unlock in cleanup or pre_abort hook.
Starvation patterns
// Safe lock pattern — unlock in all paths
task body();
p_sequencer.lock(this);
begin
// config traffic — limited beats
repeat (10) send_beat(req);
end
p_sequencer.unlock(this); // mandatory
endtask
// Background seq that never finishes — starves others without lock
task body();
forever begin
send_beat(req); // hogs arbitration fairly but never yields scenario
end
endtaskWalkthrough — lock hang timeline
[STIM] lock starvation timeline
T0 env run_phase: bg_config_seq.start(sqr) — calls lock()
T1 bg_config_seq: slow register programming via APB beats
T2 test run_phase: stress_seq.start(sqr)
T3 stress_seq: start_item(req) — BLOCKED (lock held)
T4 sim runs forever — no error, no bus activity on AXI
T5 grep "lock" in log — see bg_config_seq locked, no unlock message
FIX: add unlock after config OR do not start bg seq before test seq
OR use grab with timeout policy (custom sequencer subclass)Key takeaways
Always check randomize() return; print item on failure.
lock/grab without unlock/ungrab blocks all other sequences at start_item.
Background forever-seq starves scenario seq even without explicit lock.
Common pitfalls
assert(req.randomize()) without message — hard to trace which constraint failed.
unlock in forked thread racing with parent's next start_item.
Assuming hang is finish_item when log shows hang at start_item — check lock first.
Killing sim without identifying which sequence holds lock — bug reproduces next run.