Stage 4 Research Report: VCD Tracer vs Industry Landscape
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, andTraceWrapperclasses. 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
- ASCII text, no compression: VCD files are enormous. Moderately complex simulations produce gigabytes.
- No random access: Must be read sequentially from the beginning. FST solves this with block-based structure.
- No memory/array support: Only individual scalar signals and vectors. A fundamental limitation of the IEEE 1364 spec.
- 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.
- No streaming/incremental guarantee: Not designed for viewing during capture. LXT2 was specifically designed for this.
- No metadata or event annotations: Only value changes. CTF, Perfetto, and OpenTelemetry support rich event metadata and hierarchical spans.
- 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.