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

systemverilog
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
endclass

If 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.

systemverilog
// 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);
endtask

Walkthrough — objection and driver timeline

diagram
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 this

Active vs passive agent

diagram
[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
systemverilog
// 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);
endfunction

Key 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.