Skip to main content

Generate cycle-accurate SystemVerilog testbenches from VCD waveforms

Project description

wave2tb-generator

CI

Generate a cycle-based SystemVerilog testbench from a captured VCD waveform and DUT RTL.

Why This Project Matters

  • Small design team using Chisel can keep their verification written in svsim.
  • Outsourced backend/PD teams usually need plain, static SV testbenches for GLS handoff.
  • This tool bridges both worlds by converting captured VCD behavior into deterministic, standalone SV TB code (no Chisel runtime dependency).
  • It reduces manual TB rewrite effort and lowers handoff risk between frontend and backend flows.

Workflow

  1. Parse DUT ports from RTL in Python (tree-sitter-verilog).
  2. Read VCD waveform and auto-match one DUT scope.
  3. Build a JSON IR containing per-cycle input stimulus and expected outputs.
  4. Emit a standalone SystemVerilog testbench that:
    • drives the same per-cycle stimulus (only emits changed input assignments),
    • steps the DUT clock,
    • checks expected outputs every cycle.

Install

uv sync

After uv sync, run CLI commands with uv run (recommended), for example:

uv run wave2tb --help

If you prefer not to use uv run each time, activate the venv first:

source .venv/bin/activate
wave2tb --help

CLI

Generate testbench in one step from VCD + RTL:

uv run wave2tb vcd-to-tb \
  --vcd test/out/reference.vcd \
  --rtl test/data/sample_dut.sv \
  --top-module sample_dut \
  --clock clk \
  --tb-out test/out/generated_tb.sv \
  --ir-out test/out/generated.ir.json

Generate IR and testbench (legacy two-output command):

uv run wave2tb from-vcd \
  --vcd test/out/reference.vcd \
  --rtl test/data/sample_dut.sv \
  --top-module sample_dut \
  --clock clk \
  --ir-out test/out/generated.ir.json \
  --tb-out test/out/generated_tb.sv

Generate testbench from an existing IR:

uv run wave2tb ir-to-tb \
  --ir test/out/generated.ir.json \
  --tb-out test/out/generated_tb.sv

Optional external equivalence verification:

uv run wave2tb vcd-to-tb \
  --vcd test/out/reference.vcd \
  --rtl test/data/sample_dut.sv \
  --top-module sample_dut \
  --clock clk \
  --tb-out test/out/generated_tb.sv \
  --verify-with-verilator

End-to-End Test

Run:

bash test/run_e2e.sh

Note: the optional --verify-with-verilator flow and test/run_e2e.sh require external Verilator.

Generated Output Examples

generated.ir.json (delta IR)

generated.ir.json uses encoding: "delta" and is the intermediate format consumed by the toolchain. Core rules:

  • Top-level metadata includes schema_version, encoding, top_module, scope, timescale, clock_name, and clock_edge.
  • The ports array stores the DUT port list; each item has direction, name, and width.
  • The cycles array is time-ordered; each entry has index, time, inputs, and outputs.
  • inputs / outputs only store signals that changed relative to the previous cycle; an empty object means no changes in that direction for this cycle.
  • When loading IR, the tool performs carry-forward expansion to reconstruct full per-cycle vectors before TB generation.

generated_tb.sv (generated SystemVerilog TB)

Below is the key excerpt copied from the real test artifact test/out/generated_tb.sv: the statements inside initial begin ... end.

clk = CLK_IDLE;
rst_n = '0;
clear = '0;
en = '0;
din = '0;
mode = '0;

// cycle 0, source_time=5 (1ps)
step_to_edge();
`CHECK_EQ(accum, 6'b000000, 0, "accum");
`CHECK_EQ(dout, 4'b0000, 0, "dout");
`CHECK_EQ(valid, 1'b0, 0, "valid");
`CHECK_EQ(parity, 1'b0, 0, "parity");
step_to_idle();

// cycle 1, source_time=15 (1ps)
rst_n = 1'b1;
en = 1'b1;
din = 4'b0011;
step_to_edge();
`CHECK_EQ(accum, 6'b000011, 1, "accum");
`CHECK_EQ(dout, 4'b0011, 1, "dout");
`CHECK_EQ(valid, 1'b1, 1, "valid");
`CHECK_EQ(parity, 1'b1, 1, "parity");
step_to_idle();

$display("PASS: %0d cycles checked for sample_dut from scope reference_wave_tb.u_dut", NUM_CYCLES);
$finish;

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wave2tb_generator-0.1.0.tar.gz (17.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wave2tb_generator-0.1.0-py3-none-any.whl (18.5 kB view details)

Uploaded Python 3

File details

Details for the file wave2tb_generator-0.1.0.tar.gz.

File metadata

  • Download URL: wave2tb_generator-0.1.0.tar.gz
  • Upload date:
  • Size: 17.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.25 {"installer":{"name":"uv","version":"0.9.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for wave2tb_generator-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f563ea156924d653e510aef2ba60ded15c19746330803b4aa1b9648088ceb60f
MD5 f813a769972ddcf1a6c1631ccf3df547
BLAKE2b-256 e6d261848f2ccee7c6d43aa0818d9b73017152b230ef24ad4b67ee5b1ee71665

See more details on using hashes here.

File details

Details for the file wave2tb_generator-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: wave2tb_generator-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 18.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.25 {"installer":{"name":"uv","version":"0.9.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for wave2tb_generator-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0e23a6c49b3908aafafc385ea454bc9b56d78128f3ef7e738fd25bcdf9492d8d
MD5 767be9ddfb80c52cecf83d59828aef2c
BLAKE2b-256 dacd717b069aeb18517aa2a85f146d0fae09ba5796f72433c48e38ef995139f0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page