Part 5 · Sequences · Intermediate

Verbosity Tracing & Plusargs: uvm_set_verbosity

Targeted uvm_set_verbosity plusargs, strategic uvm_info placement, and localizing stalls without log flood.

Tracing without flooding

Turning UVM_FULL on the entire testbench produces gigabyte logs that hide the one line you need. Effective sequence debug uses scoped verbosity — raise level on one sequencer, one driver, or the uvm_sequence reporter id — and strategic uvm_info at handshake boundaries.

diagram
[UVM] verbosity strategy

  BAD:  +uvm_set_verbosity=*,_ALL_,UVM_FULL,time      unreadable log

  GOOD: +uvm_set_verbosity=env.axi_agent.drv,_ALL_,UVM_HIGH,time
        +uvm_set_verbosity=env.axi_agent.sqr,_ALL_,UVM_HIGH,time
        grep "waiting get_next_item|start_item|finish_item"

uvm_set_verbosity plusargs

bash
# Trace one sequencer component from time 0
+uvm_set_verbosity=env.apb_agent.sqr,_ALL_,UVM_HIGH,time

# Trace all sequences globally by reporter id (still verbose — use for short repro)
+uvm_set_verbosity=*,uvm_sequence,UVM_FULL,time

# Print every item at medium during run_phase only
+uvm_set_verbosity=*,_ALL_,UVM_MEDIUM,run

# Trace driver and sequencer together
+uvm_set_verbosity=env.axi_agent.drv,DRV,UVM_HIGH,time \
+uvm_set_verbosity=env.axi_agent.sqr,_ALL_,UVM_HIGH,time
  • time vs run — time starts at 0ns; run limits to run_phase window only.

  • Component path must match get_full_name() — typo = no extra messages.

  • Reporter id filter (e.g. DRV) limits to uvm_info with that id string.


Strategic uvm_info placement

Place four log points per beat and you can localize any stall to one handshake phase without UVM_FULL:

systemverilog
// Sequence — log at handshake boundaries
task automatic send_beat(axi_item req);
  `uvm_info(get_type_name(), "pre start_item", UVM_HIGH)
  start_item(req);
  `uvm_info(get_type_name(), "post start_item, pre randomize", UVM_HIGH)
  assert(req.randomize());
  `uvm_info(get_type_name(), req.sprint(), UVM_MEDIUM)
  `uvm_info(get_type_name(), "pre finish_item", UVM_HIGH)
  finish_item(req);
  `uvm_info(get_type_name(), "post finish_item", UVM_HIGH)
endtask

// Driver — mirror the four boundaries
task run_phase(uvm_phase phase);
  forever begin
    `uvm_info("DRV", "pre get_next_item", UVM_HIGH)
    seq_item_port.get_next_item(req);
    `uvm_info("DRV", $sformatf("post get_next_item: %s", req.sprint()), UVM_MEDIUM)
    drive(req);
    `uvm_info("DRV", "pre item_done", UVM_HIGH)
    seq_item_port.item_done();
    `uvm_info("DRV", "post item_done", UVM_HIGH)
  end
endtask

Walkthrough — reading a stall from log grep

diagram
Legend: [SEQ] [DRV]

  LAST LOG LINES:
    axi_burst_seq: pre finish_item
    DRV: post get_next_item: { addr:'h1000 ... }
    (nothing after)

  INTERPRETATION:
    sequence waiting at finish_item
    driver got item, has NOT called item_done
    stall inside drive() — NOT sequencer, NOT randomize

  NEXT STEP:
    add uvm_info inside drive() channels
    check for early return path skipping item_done

Debug playbook — ordered grep commands

bash
# 1. Did driver start?
grep "run_phase started" sim.log

# 2. Is driver waiting for items?
grep "get_next_item" sim.log | tail -5

# 3. Did sequence reach handshake?
grep "start_item\|finish_item" sim.log | tail -10

# 4. Any randomize failures?
grep "RAND\|randomize" sim.log

# 5. Lock activity?
grep -i "lock\|grab\|unlock" sim.log
  • Run short repro (micro-second) with UVM_HIGH on drv+sqr only.

  • Compare last seq message vs last drv message — gap reveals stall side.

  • Add one log line per hypothesis — remove after fix to keep regression log lean.

Key takeaways

  • Scope verbosity to drv + sqr — never UVM_FULL on whole bench for seq debug.

  • Four boundary logs per beat localize stall to start_item, drive, or finish_item.

  • grep playbook faster than wave debug for handshake stalls.

Common pitfalls

  • UVM_FULL on * — sim slows, log rotates, you lose the stall line.

  • uvm_info in tight loop at UVM_LOW — floods log even without UVM_FULL.

  • Verbosity plusarg typo in path — silent, you think tracing is on but it is not.

  • Removing all debug uvm_info after fix — leave UVM_HIGH boundaries for next debug.