go-vcd-parser: a tested VCD parser and toolkit in Go
go-vcd-parser reads Value Change Dump (VCD) files, the waveform format that simulators such as Verilator, Icarus Verilog and nvc write. The format is defined in IEEE 1800. The parser handles the 4-value format and the pragmatic extensions that real simulators produce.
Why another VCD parser
Most open source VCD parsers are written in Python, Perl or C++, and most ship with few tests or none. Some throw an exception on the first realistic file. go-vcd-parser is written in Go, compiles to a static binary, and a test suite guards its behavior: unit tests for individual VCD stanzas, unit tests for odd snippets found in the wild, and integration tests over complete files sampled from actual simulator runs.
What you get
The repository builds a Go library and two command-line tools.
vcdcvtparses a VCD file and converts it to JSON or to a SQLite signals database. The SQLite form turns waveform questions into SQL queries: signal names become rows, value changes become tuples, andsqlite3becomes your waveform inspector.sqlite2drawtimingreads that SQLite database and writes drawtiming input for the signals you select, so a timing diagram for documentation is two commands away from a simulation dump.
Prebuilt static binaries for Linux and macOS, on x86_64 and arm64, are on
the releases page. Download, chmod +x, done:
curl -LO https://github.com/filmil/go-vcd-parser/releases/latest/download/vcdcvt-linux-amd64
chmod +x vcdcvt-linux-amd64
A two-minute tour
# Convert a simulation dump to a SQLite database.
vcdcvt -in dump.vcd -format sqlite -out signals.db
# Ask it questions.
sqlite3 signals.db 'SELECT * FROM signals LIMIT 10;'
# Produce a timing diagram description for two signals.
sqlite2drawtiming -in signals.db -signal clk -signal reset > timing.dt
To build from source instead, install bazel with the bazelisk
method and run bazel test //... in a checkout. The build brings
its own toolchains; the release binaries are cross-compiled the same way.
Limits worth knowing
The parser is not streaming: it builds an in-memory representation of the whole file before writing anything out. VCD files from long simulations get very large, and a file that exceeds your memory will not parse. If you hit a file the parser mishandles, file a bug and attach a minimal example if you can.
Prior art
A survey of existing parsers is in the project README, with links to the Python, Perl, C++ and Rust alternatives that were considered before writing this one.