Part 7 · Environment & Tests · Intermediate

Global Timeout Kill: Fail-Fast Guardrail for Hangs

Use global timeout as a hard kill-switch for stuck objections, deadlocked handshakes, and runaway tests while preserving actionable diagnostics.

Timeout role in closure architecture

A global timeout is not the normal end-of-test mechanism; it is the last-resort kill-switch that prevents infinite farm resource burn when objections or protocol threads hang.

diagram
[UVM][ENV] closure priority

Primary end:
  objection drop + readiness checks + drain

Secondary guard:
  global timeout

timeout firing should be rare and actionable
diagram
[TEST] hang classes timeout catches

- missing drop_objection path
- deadlocked sequence/driver handshake
- DUT never returns ready/response
- thread waiting forever on event that never triggers
  • Treat timeout as safety net, not success path.

  • Tune per environment scale and performance profile.

  • Always gather diagnostics before the timeout fatal if possible.


Configuration patterns

systemverilog
class base_test extends uvm_test;
  `uvm_component_utils(base_test)
  int unsigned timeout_ns = 2_000_000;

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    uvm_top.set_timeout(timeout_ns * 1ns, 1);
  endfunction
endclass
bash
simv +UVM_TESTNAME=stress_test +UVM_TIMEOUT=5000000,YES
systemverilog
function void build_phase(uvm_phase phase);
  super.build_phase(phase);
  uvm_cmdline_processor clp = uvm_cmdline_processor::get_inst();
  string vals[$];
  if (clp.get_arg_values("+EOT_TIMEOUT_NS=", vals) > 0)
    timeout_ns = vals[0].atoi();

  // Keep global built-in plusarg override enabled.
  uvm_top.set_timeout(timeout_ns * 1ns, 1);
endfunction
diagram
[UVM] timeout policy matrix

smoke:
  low timeout for fast failure

stress:
  higher timeout with same fail-fast principle

nightly random:
  measured value + margin, not unbounded
  • Provide a stable base timeout plus explicit override knobs.

  • Prefer one documented timeout source in base_test.

  • Keep timeout values aligned with expected worst-case sequence runtime.


Diagnostics and post-timeout triage

Pre-timeout breadcrumbs

systemverilog
task heartbeat_thread();
  forever begin
    #10000ns;
    `uvm_info("HEARTBEAT",
      $sformatf("time=%0t issued=%0d done=%0d mon=%0d sb=%0d",
        $time,
        env.drv.issued_cnt,
        env.drv.done_cnt,
        env.mon.publish_cnt,
        env.sb.compare_cnt),
      UVM_LOW)
  end
endtask
systemverilog
function void report_phase(uvm_phase phase);
  super.report_phase(phase);
  `uvm_info("EOT_SUMMARY",
    $sformatf("timeout_ns=%0d final_objections=%0d",
      timeout_ns,
      uvm_run_phase::get().get_objection().get_objection_total()),
    UVM_LOW)
endfunction
diagram
[UVM][ENV] timeout triage order

1) objection trace: who still holds?
2) sequence-driver handshake counters
3) monitor publish activity
4) scoreboard queue growth or starvation
5) DUT ready/response waveform evidence

Key takeaways

  • Global timeout is essential regression hygiene for hung runs.

  • Configure timeout in base_test and permit controlled overrides.

  • Always pair timeout with periodic diagnostics for actionable failures.

  • Timeout events should trigger root-cause fixing, not routine acceptance.

Common pitfalls

  • Setting timeout so high that hangs waste hours before failure.

  • Setting timeout so low that legitimate long tests fail spuriously.

  • No heartbeat metrics, leaving timeout failures opaque.

  • Treating timeout as an expected normal test exit path.