Part 3 · Factory & Configuration · Intermediate

vif Distribution Debug: Null Handle Triage

Systematic debug for null vif — path mismatch, type mismatch, timing errors, and multi-instance cross-wiring.

Debug workflow

A null vif at run_phase usually means get() failed silently in build_phase. Follow this order before touching driver logic:

  1. Print consumer get_full_name() — does set path match?

  2. Compare set path to expected: uvm_test_top.env.apb.drv

  3. Confirm type matches exactly — virtual apb_if on both set and get.

  4. Confirm set() ran before run_test() in top initial block.

  5. Run uvm_config_db::dump() — search for "vif" entries and scopes.

  6. For multi-instance: verify each agent path has its own set entry.

diagram
[HDL][CONFIG][UVM] null vif triage matrix

  symptom: uvm_fatal NOVIF at build_phase
     get returned 0: path, type, or timing

  symptom: null pointer dereference at run_phase
     get not checked, or vif get deferred to run_phase

  symptom: agt0 works, agt1 null
     missing set for agt1 path segment

  symptom: driver sees wrong bus
     both agents got same vif (over-broad path)

Diagnostic instrumentation

systemverilog
function void build_phase(uvm_phase phase);
  super.build_phase(phase);
  `uvm_info("VIF_DBG",
    $sformatf("inst=%s looking for vif", get_full_name()), UVM_LOW)

  if (!uvm_config_db#(virtual apb_if)::get(this, "", "vif", vif)) begin
    uvm_config_db::dump();
    `uvm_fatal("NOVIF",
      $sformatf("vif not set for %s — see dump above", get_full_name()))
  end
  `uvm_info("VIF_DBG", "vif get succeeded", UVM_LOW)
endfunction
systemverilog
// top.sv — confirm publish before run_test
initial begin
  `uvm_info("VIF_SET", "publishing apb_if to config_db", UVM_LOW)
  uvm_config_db#(virtual apb_if)::set(
    null, "uvm_test_top.env.apb.*", "vif", apb_if_i);
  run_test();
end

Timing mistakes

diagram
[HDL] correct vs wrong timing

  CORRECT:
    initial begin
      config_db.set(vif)    ← publish first
      run_test()            ← UVM build_phase runs, get succeeds
    end

  WRONG:
    initial begin
      run_test()            ← build_phase runs, get fails
      config_db.set(vif)    ← too late
    end

  WRONG:
    task run_phase
      get(vif)              ← deferred, no build-time check
      vif.psel <= 1         ← may dereference null
    endtask
  • Get vif in build_phase — fail fast with uvm_fatal.

  • Never use run_phase for first vif acquisition.

  • If using config object, validate cfg.vif in build_phase too.

Key takeaways

  • Null vif is almost always a config_db path/type/timing issue.

  • get_full_name() + dump() resolves most cases in minutes.

  • Multi-instance bugs show up as one agent working and another failing.

Common pitfalls

  • Debugging protocol logic before confirming vif is non-null.

  • Parameterized interface — param values differ, types look 'the same'.

  • Assuming wildcard set reached agent — print dump to verify scope.