Part 5 · Sequences · Intermediate
Driver Running Checklist: Objections, Active Agent, vif
Confirm the driver entered run_phase, agent is active, virtual interface is set, and get_next_item is reachable.
Checklist 1 — Is the driver running?
Before debugging sequence code, confirm the driver execution path is alive. A sequence can call start_item perfectly; if the driver never enters its run_phase loop, the sequencer FIFO fills and the sequence blocks forever at the first start_item.
run_phase objection raised before seq.start()? Driver only runs during run_phase.
Active agent? Passive agents have no driver — sequences on their sequencer never complete.
Driver build_phase got virtual interface? Null vif → driver may hang or skip get_next_item.
Driver run_phase has forever loop with get_next_item? Missing loop = one transaction only.
Instrumented driver — what to grep for
class axi_driver extends uvm_driver #(axi_item);
virtual axi_if vif;
function void build_phase(uvm_phase phase);
super.build_phase(phase);
if (!uvm_config_db#(virtual axi_if)::get(this, "", "vif", vif))
`uvm_fatal("NOVIF", "virtual axi_if not set on driver")
`uvm_info("DRV", $sformatf("build_phase: vif=%s", vif == null ? "NULL" : "OK"), UVM_LOW)
endfunction
task run_phase(uvm_phase phase);
`uvm_info("DRV", "run_phase started", UVM_LOW)
forever begin
`uvm_info("DRV", "waiting get_next_item", UVM_HIGH)
seq_item_port.get_next_item(req);
`uvm_info("DRV", $sformatf("got item: %s", req.sprint()), UVM_MEDIUM)
drive(req);
seq_item_port.item_done();
`uvm_info("DRV", "item_done sent", UVM_HIGH)
end
endtask
endclassIf you never see waiting get_next_item, the driver never started. If you see it once then silence, the driver exited run_phase or hung inside
drive() before item_done. If you see get_next_item but never got item, no sequence called start_item on this sequencer.
Objection timing — the quiet pass trap
UVM ends run_phase when all objections drop. If the test drops the objection before the sequence runs, the driver may never service pending items — or the sequence starts after run_phase ended.
// WRONG — seq starts after run_phase effectively ended
task run_phase(uvm_phase phase);
phase.raise_objection(this);
#100ns;
phase.drop_objection(this); // driver may stop here
axi_seq seq = axi_seq::type_id::create("seq");
seq.start(env.axi_agent.sqr); // too late — quiet pass or hang
endtask
// RIGHT — sequence completes before objection drops
task run_phase(uvm_phase phase);
axi_seq seq = axi_seq::type_id::create("seq");
phase.raise_objection(this);
seq.start(env.axi_agent.sqr);
phase.drop_objection(this);
endtaskWalkthrough — objection and driver timeline
Legend: [STIM] [DRV] [UVM]
T0 test: phase.raise_objection
T1 [UVM] run_phase begins for all components
T2 [DRV] driver: "run_phase started"
T3 [DRV] driver: "waiting get_next_item" (blocked)
T4 [STIM] test: seq.start(axi_sqr)
T5 [SEQ] sequence: start_item → item enters FIFO
T6 [DRV] driver: "got item" — unblocked
T7 [DRV] drive(req); item_done()
T8 [SEQ] finish_item returns
T9 [STIM] test: phase.drop_objection
T10 [UVM] run_phase ends — driver loop must not be needed after thisActive vs passive agent
[UVM] is_active determines driver existence
UVM_ACTIVE
agent builds: sequencer + driver + monitor
connect_phase: drv.seq_item_port.connect(sqr.seq_item_export)
sequences on sqr complete normally
UVM_PASSIVE
agent builds: monitor only (no driver, no sequencer export path)
sequences on sqr block forever at start_item
use case: monitor-only observation agent — NOT for stimulus// Agent build — confirm active when driving stimulus
function void build_phase(uvm_phase phase);
if (is_active == UVM_ACTIVE) begin
sqr = axi_sequencer::type_id::create("sqr", this);
drv = axi_driver::type_id::create("drv", this);
end
mon = axi_monitor::type_id::create("mon", this);
endfunctionKey takeaways
Grep for driver run_phase started and waiting get_next_item before debugging seq.
raise_objection before seq.start; drop only after sequence completes.
UVM_PASSIVE agent cannot execute sequences — verify is_active.
Common pitfalls
seq.start in fork without join — objection drops while seq still running.
Null vif not fatal in build_phase — drive() hangs on null pointer access.
Driver without forever loop — processes one item then exits run_phase.
Setting is_active in test after agent already built — too late, rebuild required.