Document under review: _posts/2022-08-06-vcd-tracer.md Date: 2026-02-24

A. Existing C++ VCD Tracing Libraries

Simulation-framework tracing (VCD as side-effect)

  • SystemC (sc_trace / sc_create_vcd_trace_file): The reference implementation for VCD in C++. Part of IEEE 1666. Signals must be registered before simulation starts; only SystemC types can be traced. Tightly coupled to the SystemC simulation kernel.
    • https://github.com/accellera-official/systemc
    • https://learnsystemc.com/basic/trace
  • Verilator (VerilatedVcdC / VerilatedFstC): Generates VCD or FST from Verilated C++ models. Supports multithreaded FST tracing (up to 2 offload threads). Uses CRTP to share logic between VCD and FST backends.
    • https://veripool.org/guide/latest/faq.html
  • GVSoC (PULP Platform): RISC-V virtual platform simulator. Dumps VCD/FST traces of processor state (PC, registers, DMA, instruction disassembly). Defaults to FST because it is “much faster and smaller than VCD.”
    • https://github.com/pulp-platform/gvsoc

Standalone C++ VCD generation libraries

  • cpp-vcd-tracer (the reviewed library): C++17. Dependency injection design decouples module hierarchy from traced variables. Templated vcd_tracer::value<> for fundamental types with configurable bit widths. Framework-agnostic.
    • https://github.com/nakane1chome/cpp-vcd-tracer
  • cpptracer (Galfurian): MIT-licensed (2016-2025). Traditional OOP API with Tracer, Trace, and TraceWrapper classes. Supports hierarchical scoping, optional compression, customisable timescales. The closest comparable standalone library.
    • https://github.com/Galfurian/cpptracer
  • RTEdbg: Embedded-systems data logging/tracing toolkit. Not a VCD library per se, but its decoder can export to VCD files. Targets bare-metal and RTOS environments.
    • https://github.com/RTEdbg/RTEdbg

VCD parsers (reading, not writing)

  • libvcdparse (C++): https://github.com/kmurray/libvcdparse
  • verilog-vcd-parser (C++): https://github.com/ben-marshall/verilog-vcd-parser
  • wavedrom/vcd (C/WASM): https://github.com/wavedrom/vcd

B. Alternatives to VCD

Format Type Size vs VCD Random access Tooling
FST (Fast Signal Trace) Binary, block-based, compressed 10-100x smaller Yes (block-level) GTKWave, Surfer, Verilator
LXT2 Binary, block-based Smaller Yes (block-level) GTKWave
VZT (Verilog Zipped Trace) Binary, compressed Often smallest Yes GTKWave
GHW (GHDL Waveform) Binary Smaller Yes GTKWave, Surfer
CTF (Common Trace Format) Binary, high-performance Much smaller Yes LTTng, barectf, Babeltrace 2, Trace Compass
Perfetto Protobuf Binary protobuf Much smaller Yes Perfetto UI
Chrome Trace JSON JSON text Comparable (verbose) No Perfetto UI, chrome://tracing

FST is the most direct VCD replacement — same data model (signals over time), same tooling (GTKWave), dramatically better efficiency. Developed by GTKWave’s author.

Sources:

  • https://blog.timhutt.co.uk/fst_spec/
  • https://gtkwave.github.io/gtkwave/intro/formats.html
  • https://barectf.org/docs/barectf/3.1/index.html
  • https://perfetto.dev/docs/

C. VCD Outside Traditional Hardware Simulation

VCD has spread beyond its Verilog origins:

  • RISC-V software execution tracing: A modified Spike ISA simulator generates VCD files showing program counter, register values, CSR changes, and interrupt timing during bare-metal execution. “This sort of error is hard to see using a debugger, but clear on a waveform trace.”
    • https://five-embeddev.com/toolchain/2022/09/02/spike-fork/
  • Embedded firmware tracing: RTEdbg exports timing data from embedded systems to VCD files for visualisation in GTKWave.

  • Virtual platform simulation: GVSoC traces full-platform RISC-V SoC behaviour at the software level, not just RTL signals.

  • Logic analyser software: sigrok/PulseView uses VCD as both input and output for real hardware logic analysers, bridging simulation and physical measurements.
    • https://sigrok.org/wiki/Main_Page
  • General C++ software tracing: cpp-vcd-tracer and cpptracer explicitly target tracing arbitrary C++ software variables over time.

D. VCD’s Known Limitations

  1. ASCII text, no compression: VCD files are enormous. Moderately complex simulations produce gigabytes.
  2. No random access: Must be read sequentially from the beginning. FST solves this with block-based structure.
  3. No memory/array support: Only individual scalar signals and vectors. A fundamental limitation of the IEEE 1364 spec.
  4. Timescale rigidity: Must be 1/10/100 of a time unit (s, ms, us, ns, ps, fs). Can cause spurious samples when the data source uses different granularity.
  5. No streaming/incremental guarantee: Not designed for viewing during capture. LXT2 was specifically designed for this.
  6. No metadata or event annotations: Only value changes. CTF, Perfetto, and OpenTelemetry support rich event metadata and hierarchical spans.
  7. No native analog support: Staircase artifacts for analog signals.

Sources:

  • https://sigrok.org/wiki/File_format:Vcd
  • https://en.wikipedia.org/wiki/Value_change_dump

E. Waveform Viewers

Viewer Language Formats Notes
GTKWave C VCD, FST, LXT2, VZT, GHW The standard. Mature, stable, UI showing its age.
Surfer Rust VCD, FST, GHW Modern, extensible, VSCode extension, web target. Presented at CAV 2025. Most actively developed open-source viewer.
Vaporview TypeScript VCD, FST, GHW VSCode extension. RTL linking, in-editor debugging, remote waveform viewing.
Dinotrace C VCD Older Motif-based viewer from Verilator team. Historical.

Sources:

  • https://gtkwave.sourceforge.net/
  • https://surfer-project.org/
  • https://github.com/Lramseyer/vaporview

F. The Two Tracing Paradigms

The library’s concurrent/distributed use case sits at the boundary between two tracing traditions:

Aspect Waveform viewers (VCD/FST) Timeline viewers (Perfetto/OTel)
Data model Named signals with continuous value histories Discrete events/spans with start/end times
Hierarchy Module/signal tree (static) Process/thread/span tree (dynamic)
Time resolution Cycle-accurate, sub-nanosecond Microsecond typical, configurable
Strength Correlating many signals at exact same instant Showing causal chains across services
Weakness No event metadata, no causal linking No signal-level value tracking

Where VCD-for-software makes sense: When software behaviour resembles hardware — many parallel signals changing simultaneously with cycle-level timing relationships. Instruction set simulators, concurrent state machines, real-time embedded systems, protocol-level interactions. The waveform view excels at “what was the state of everything at this exact moment?”

Where it does not: Distributed microservices, request-response patterns, performance profiling. The spans/traces model (OpenTelemetry, Perfetto) is strictly superior here. VCD’s lack of causal metadata and file-size problems at scale make it a poor fit.

C++ tracing libraries in the Perfetto/Chrome Trace ecosystem:

  • minitrace: https://github.com/hrydgard/minitrace (minimal C/C++ library producing Chrome Trace JSON)
  • Perfetto C++ SDK: https://github.com/google/perfetto (production-grade C++17)
  • OpenTelemetry C++ SDK: https://opentelemetry.io/docs/languages/cpp/

G. Comparison: Reviewed Library vs Landscape

Strengths

Feature cpp-vcd-tracer SystemC Verilator cpptracer
Framework-agnostic Yes No (SystemC only) No (Verilator only) Yes
Dependency injection Yes No No No (traditional OOP)
Configurable bit width Yes Limited No Yes
C++ standard C++17 C++11/14 C++14 C++14
Dual use case (sim + concurrent) Yes Simulation only Simulation only Simulation focus

Gaps

  • No FST output: The most impactful gap. FST is 10-100x more efficient than VCD with the same tooling support. Adding an FST backend would dramatically improve the library’s utility for large traces.
  • No compression: VCD is inherently uncompressed. For the distributed tracing use case (trace on server A and B, merge), file sizes will be a practical problem.
  • No streaming support: For long-running concurrent software, the ability to view traces during execution (as LXT2 supports) would be valuable.

Summary

The library occupies a genuine gap in the ecosystem: a standalone, framework-agnostic C++ VCD tracer with dependency injection design. The closest comparable library (cpptracer) uses a traditional OOP API. The dual use case (simulation + concurrent software) is validated by the RISC-V ecosystem’s adoption of VCD for software-level tracing. The main gap is the absence of FST support, which is the standard efficiency alternative to VCD and would address the file-size limitation the post already acknowledges.