Part 10 · Advanced Topics · Intermediate

Logging and Seed Replay

Capture reproducibility metadata and convert any failing run into an exact replay command.

What to log for deterministic replay

A seed alone is not always enough. Deterministic replay usually requires the tuple (test, seed, build hash, plusargs, simulator version). Missing one field can create false non-reproducible behavior.

diagram
[REG] replay metadata checklist

  Required:
    test_name
    seed
    simulator + version
    compiled image hash or git sha
    key plusargs (timeouts, mode knobs, protocol switches)

  Useful:
    hostname / OS
    randomization knobs from env vars
    failure signature id
    first error timestamp

Emit metadata at UVM_NONE

systemverilog
function void start_of_simulation_phase(uvm_phase phase);
  super.start_of_simulation_phase(phase);
  `uvm_info(
    "RUN_META",
    $sformatf(
      "test=%s seed=%0d sim=%s build=%s args=%s",
      get_type_name(),
      $get_initial_random_seed(),
      `SIM_NAME,
      `GIT_SHA,
      `PLUSARG_SUMMARY
    ),
    UVM_NONE
  )
endfunction
  • Use UVM_NONE so line always appears even in quiet farm mode.

  • Prefer machine-parseable key=value shape for ingestion scripts.

  • Avoid multiline metadata lines when possible.


Replay command generation

Best practice is to generate replay commands automatically after each run and attach them to result metadata. Engineers should not need to reconstruct long command lines manually.

bash
# Sample generated replay line
simv +UVM_TESTNAME=axi_random_test +ntb_random_seed=821734 \
     +CFG_AXI_MAX_OUTSTANDING=16 +UVM_VERBOSITY=UVM_LOW \
     -l out/logs/axi_random_test_seed821734.log
python
def replay_cmd(row: dict) -> str:
    sim = row["sim"]
    test = row["test_name"]
    seed = row["seed"]
    args = " ".join(row.get("plusargs", []))
    if sim == "vcs":
        return f"simv +UVM_TESTNAME={test} +ntb_random_seed={seed} {args}"
    if sim == "xrun":
        return f"xrun -R -uvm -svseed {seed} +UVM_TESTNAME={test} {args}"
    raise ValueError(f"unsupported sim {sim}")

Manifest row shape

json
{
  "run_id": "2026-06-10T113022Z_axi_random_test_821734",
  "test_name": "axi_random_test",
  "seed": 821734,
  "sim": "vcs",
  "sim_version": "VCS-2026.03",
  "build_sha": "abc1234",
  "plusargs": ["+CFG_AXI_MAX_OUTSTANDING=16", "+UVM_VERBOSITY=UVM_LOW"],
  "status": "FAIL",
  "signature": "SCB_MISMATCH@axi_scb.sv:198",
  "replay_cmd": "simv +UVM_TESTNAME=axi_random_test +ntb_random_seed=821734 +CFG_AXI_MAX_OUTSTANDING=16 +UVM_VERBOSITY=UVM_LOW"
}

Log parsing pipeline

diagram
[REG] replay pipeline

  simulator log --> parser --> manifest row --> dashboard row --> replay button
       |             |              |                 |
       |             |              |                 +--> copy exact cmd
       |             |              +--> signature bucket
       |             +--> extract RUN_META + first fatal
       +--> source of truth

Keep parsing strict and explicit. Regexes should match stable tag IDs like RUN_META, SCB_MISMATCH, and TEST_DONE. Avoid brittle parsing of freeform prose.

bash
# Quick local extract for one failing log
rg "RUN_META|UVM_(ERROR|FATAL)|TEST_DONE" out/logs/axi_random_test_seed821734.log

Key takeaways

  • Record full replay tuple, not seed only.

  • Auto-generate replay commands from manifest rows.

  • Use stable machine tags in logs for robust parsing.

  • Surface replay command directly in triage UI/workflow.

Common pitfalls

  • Only storing console output and losing launch context.

  • Manual replay reconstruction that drops important plusargs.

  • Parsing human prose instead of tagged structured lines.