Back to Learn

Closure & enterprise workflow

Waveform Intelligence: A Heuristic Digest of VCD Traces

A megabyte-scale VCD is hard to navigate by hand. Waveform intelligence walks the trace after the simulator returns and builds a digest — likely clocks and resets, signal groups, transaction markers, and advisory warnings — so you can find what to look at. It is a map of the trace, not a graded list of bugs: it does not score anomalies or claim a formal bus decode.

The problem with reading waveforms by hand

A nightly regression on a medium SoC produces VCDs in the tens to hundreds of megabytes. Even one block-level run on a UART controller is a few megabytes once you start dumping internal signals. The trace is rich — it contains every observable state in the design, sample by sample — but reading it by hand is a bad use of an engineer’s time. The relevant information is sparse: ninety-nine percent of the toggles are uninteresting, and the bug you are looking for is a few cycles in one signal somewhere. GTKWave is fine for confirming a hypothesis; it is the wrong tool for finding one.

Waveform intelligence flips the workflow. Instead of an engineer scrolling through cursors, the trace is consumed by a small collection of structural and statistical heuristics that build a navigable digest — likely clocks and resets, signal groups, transaction markers, and a few advisory warnings. It is a map of the trace, not a graded list of bugs.

What the summary surfaces

A few heuristic categories cover most of the value you can extract from a single run without modeling the design. These are candidates and hints, not scored findings — the engineer reads them and decides what is interesting:

  • Clock candidates. Signals whose toggle pattern and name look like a clock, with an estimated period. Useful for orienting yourself in an unfamiliar trace.
  • Reset candidates. Signals that look like resets (by name and activity), flagged with likely active level so you can find reset release in the trace.
  • Signal groups. Related signals grouped by scope and inferred role, so a wide bus of hundreds of signals collapses into a handful of navigable groups.
  • Transaction markers. Heuristic hints about where bus-like activity happens, so you can jump to the interesting cycles. These are hints, not a formal bus decode, and nothing is graded pass/fail.
  • Warnings. Plain advisory notes about the trace itself — for example an empty or truncated VCD, or a long quiet tail. Informational only.

The heuristics

The summary is deliberately simple. It is not a full LRM-conformant property checker and not a formal tool — if it were, you would feed it SVA. It also does not score glitches, X-propagation, or protocol violations as failures. The point is to extract a fast, cheap map of the trace.

  • Toggle-rate activity. For each signal, count value changes across the trace. A signal with a regular high toggle rate and a clock-like name is a clock candidate; a quiet signal is grouped but not flagged as a bug.
  • Clock and reset heuristics. Combine activity with name matching (rst/reset/rst_n/aresetn and friends) to propose clock and reset candidates with an estimated period and likely active level.
  • Scope-based grouping. Group signals by their hierarchical scope and an inferred role so the digest stays navigable on wide traces.
  • Transaction-marker hints. Look for bus-like activity and emit a bounded list of markers (capped) plus protocol hints. These are pointers into the trace, not a validated protocol decode.

Each heuristic runs in a single pass over the VCD’s value-change records. On a 200 MB trace, the full pass takes a few seconds on commodity hardware.

A worked example

A trimmed VCD from a UART top-level testbench:

$timescale 1 ns $end
$scope module top $end
$var wire 1  ! clk           $end
$var wire 1  " rst_n         $end
$var wire 8  # data_in [7:0] $end
$var wire 8  $ data_out [7:0] $end
$var wire 1  % req           $end
$var wire 1  & ack           $end
$upscope $end
$enddefinitions $end

#0
0!
0"
b00000000 #
b00000000 $
0%
0&
#5
1!
#10
0!
1"
#15
1!
b00000001 #
1%
#20
0!
b00000001 $
#25
1!
b00000010 #
b00000010 $
1%

The summary endpoint returns a digest of the trace — candidate clocks and resets, signal groups, transaction markers, and any advisory warnings:

// GET /api/projects/{id}/waveform/intelligence
{
  "timescale":         "1 ns",
  "timescale_unit_ps": 1000,
  "duration":          120000,
  "signal_count":      842,
  "transition_count":  53120,
  "clock_candidates": [
    { "id": "!", "name": "clk", "scope_name": "top", "period": 10 }
  ],
  "reset_candidates": [
    { "id": "\"", "name": "rst_n", "scope_name": "top", "active_low": true }
  ],
  "signal_groups": [
    { "scope_name": "top.uart_rx", "role": "data", "signals": ["data_out", "valid"] }
  ],
  "transaction_markers": [
    { "t": 18400, "scope_name": "top.uart_tx", "label": "tx_busy rising" }
  ],
  "protocol_decodes": [],
  "warnings": [
    "trace covers 120000 time units; no top-level activity after t=95000"
  ]
}

From this an engineer can immediately see which signal is the clock and its period, that rst_n is the active-low reset, how the data signals group, and where the last bus activity occurred. The warning about a long quiet tail is a prompt to go look — it is not graded as a failure, and the summary does not claim the design hung. Confirming whether that quiet tail is a real deadlock is the engineer’s call, typically in a waveform viewer or with an assertion.

What it actually reports

Waveform intelligence is a heuristic summary, not a scorer. It does not assign info/warn/fail severities, does not classify glitches, X-propagation, or protocol violations as failures, and does not feed a closure score. The response is a structured digest of the trace:

  • clock_candidates and reset_candidates — signals whose activity and naming look like clocks or resets, surfaced as likely candidates rather than confirmed roles.
  • signal_groups — related signals grouped by scope and inferred role so a wide trace is navigable.
  • transaction_markers and protocol_decodes — heuristic hints about where bus activity occurs, explicitly not a formal bus decode.
  • warnings — plain advisory notes about the trace (for example an empty or truncated VCD). These are informational; nothing here is graded pass/fail.

When to look at it

The summary is computed on demand from the latest simulation’s VCD, regardless of whether the run passed or failed. The two cases where it earns its keep:

  • Sim PASS, anomalies present. This is the common case and the most valuable. The testbench agrees the design did not violate any assertion, but the trace shows a stuck flag, an unreset register, or a hung region. These are the bugs that escape the test plan.
  • Sim FAIL, anomalies localized. The simulator reported a failing assertion at a specific cycle. The analyzer’s findings around that cycle are usually the shortest path to root cause — the X-region that propagated into the assertion path is upstream of the failure.

Limitations

  • VCD-only, latest run only. The analyzer reads the most recent trace produced by the project’s simulator. If sim never ran, there is nothing to analyze. FST and FSDB are not yet first-class.
  • Not a property checker, not a scorer. The summary is signal- and structure-shaped, and it does not grade the trace. If the bug requires understanding the algorithm the design implements, you still need SVA, formal, or scoreboard-driven testbenches.
  • Candidates are heuristic. Clock/reset detection and grouping are best-effort guesses from activity and naming. They orient you in the trace; they are not authoritative role assignments.
  • Markers are name-driven hints. Transaction-marker and protocol hints lean on naming conventions (AXI signals like awvalid, awready). If your project renames bus signals, fewer hints will surface — and either way they are not a validated protocol decode.

How it pairs with simulation

Waveform intelligence is not a replacement for Verilator or any other simulator — it is a consumer of the trace the simulator produces. The simulator is responsible for executing the design against stimulus and reporting any assertion failures. The analyzer is responsible for telling you what the testbench did not ask. The two tools answer different questions:

  • Simulator: Did the design violate the properties I was watching for?
  • Summary: What does this trace contain — what are the clocks, resets, groups, and where is the activity — so I can find what to look at?

A clean tapeout flow runs both. The waveform summary helps you navigate the trace and decide where to point a viewer, an assertion, or a waiver discussion — but the summary itself does not feed a closure score or gate anything.

Related reading

  • Verilator simulation — the engine that produces the VCDs the analyzer reads.
  • Verification plan — where the closure objectives a person tracks live (the waveform summary informs them; it does not auto-populate them).
  • Clock domain crossing — CDC bugs often manifest as glitches and X regions the analyzer flags.

Try it on your project

Paste a GitHub URL at chipverify.ai/tinytapeout (free) for a one-shot scan, or sign in at chipverify.ai/dashboard to wire waveform intelligence into your CI alongside lint, sim, and synthesis.

Get a heuristic digest of your trace

Sign in and ChipVerify AI digests your VCD into likely clocks, resets, signal groups, and advisory warnings so you know where to look — a heuristic map, not a formal bus decode or a foundry signoff.