Skip to main content
Glama

Waveform MCP — AI-Friendly VCD/FSDB Waveform Debugger

A Model Context Protocol (MCP) server that gives AI agents the ability to read, analyze, and debug VCD/FSDB waveform files from digital circuit simulations.

Parse a waveform once, then query signals, find AXI transactions, render ASCII waveforms, and validate protocol compliance — all through structured JSON-RPC tools.

Features

  • Stateful session: Parse once, query many times. Large files cached in memory.

  • VCD + FSDB support: Native VCD parsing; FSDB via Verdi's fsdb2vcd auto-conversion.

  • 32 structured tools: Signal search, snapshot, edge detection, transaction analysis, AXI write/read channel correlation, burst aggregation, bus-level protocol checks, clock analysis, signal activity stats, dual-waveform diff, value diff between times, ASCII rendering, multi-session comparison, signal aliases, and more.

  • Smart signal search: Ranked relevance matching (exact > base name > suffix > component > substring), with support for bit-select suffixes like wdata[31:0].

  • AXI transaction analysis: Automatically extract valid-ready transactions from all 5 AXI channels (AW/W/B/AR/R) with captured data values. One-call analyze_axi_channel auto-detects signals, aggregates W beats into bursts by wlast, and reports throughput/gap/duration statistics. analyze_axi_write/analyze_axi_read correlate address+data+response channels into complete transfers with latency breakdown.

  • Bus-level protocol checks: Detect AXI protocol violations including data instability while VALID=1/READY=0, BVALID before WLAST, and zero-width valid pulses.

  • Clock & activity analysis: Auto-detect clock signals and report period, frequency, duty cycle, jitter, and gating. Find dead signals (never toggle) and rank signals by change activity.

  • Dual-waveform diff: Compare two loaded waveforms signal-by-signal, report first mismatch time and value for each differing signal. Matches signals by base name across hierarchies.

  • Multi-session support: Load multiple waveforms simultaneously (e.g. golden vs actual) under different session IDs, switch between them, or pass session_id to any tool for cross-waveform comparison.

  • Signal aliases: Define short aliases for long hierarchical paths (e.g. tb.dut.u_memory.wdata[31:0]wdata), usable anywhere a signal name is expected.

  • Flexible time inputs: All time parameters accept integers (picoseconds) or human-readable strings like "100ns", "1.5us", "500ps".

  • ASCII waveform rendering: View timing diagrams directly in the conversation without a waveform viewer. Linear-scan rendering with collision-free time scale and right-boundary labeling.

  • Protocol compliance checking: Detect valid-ready handshake violations.

  • Pickle cache: Large files reload in seconds instead of minutes.

  • CLI fallback: Human-friendly command-line interface for manual debugging.

Related MCP server: EDA Tools MCP Server

Architecture

src/waveform_mcp/core.py    (core library, pure stdlib, no MCP dependency)
   ├── src/waveform_mcp/server.py  (MCP Server — 32 tools over stdio JSON-RPC)
   └── src/waveform_mcp/cli.py     (CLI — backward-compatible, human-friendly)

The core library (core.py) contains all parsing and analysis logic. It can be used standalone in Python scripts, or exposed via MCP or CLI. The package uses a standard src/ layout and is installable via pip install -e ..

Installation

Requirements

  • Python >= 3.10

  • mcp >= 2.0 (for MCP Server; CLI and core library don't need it)

  • Verdi with fsdb2vcd in PATH (only for FSDB files; VCD files don't need it)

Install (package mode, optional)

pip install -e ".[mcp]"     # installs core + MCP SDK
pip install -e .             # core only (zero dependencies, for CLI/scripts)

Install MCP dependency (manual mode)

pip install "mcp[cli]"

Clone / copy the project

# All files are self-contained in this directory
cd D:\workspace\waveform_mcp

No build step required. The project is pure Python.

MCP Server Deployment

Claude Desktop

Edit claude_desktop_config.json (location varies by OS):

Windows: %APPDATA%\Claude\claude_desktop_config.json

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

Linux: ~/.config/Claude/claude_desktop_config.json

{

  "mcpServers": {

    "waveform-debugger": {

      "command": "python",

      "args": \["D:\\\workspace\\\waveform\_mcp\\\waveform\_mcp.py"]

    }

  }

}

Restart Claude Desktop. The server will appear in the MCP status indicator with 17 tools.

Cursor

Create or edit .cursor/mcp.json in your project root:

{

  "mcpServers": {

    "waveform-debugger": {

      "command": "python",

      "args": \["D:\\\workspace\\\waveform\_mcp\\\waveform\_mcp.py"]

    }

  }

}

Restart Cursor. Enable the server in Settings > MCP.

Other MCP-compatible clients

Any MCP 2.x-compatible client (Cline, Continue, custom agents) can connect via stdio:

{

  "command": "python",

  "args": \["D:\\\workspace\\\waveform\_mcp\\\waveform\_mcp.py"]

}

Verify the server is working

\# List registered tools (should show 17)

python -c "import asyncio, sys; sys.path.insert(0,'.'); from waveform\_mcp import server; print(asyncio.run(server.list\_tools()).\_\_len\_\_())"

\# Run full MCP communication test

python test\_mcp\_server.py

Tool Reference

Session Management

Tool

Description

load_waveform(path, use_cache=true, session_id?)

Load a VCD/FSDB file and parse into memory. Must be called first. session_id for multi-waveform comparison.

get_waveform_info(session_id?)

Get signal count, module count, max time, timescale, module list.

unload_waveform()

Unload all sessions and free memory.

list_sessions()

List all loaded sessions and the active session ID.

switch_session(session_id)

Switch the active session.

close_session(session_id?)

Close a specific session and free its memory.

Signal Aliases

Tool

Description

set_alias(alias, signal_name, session_id?)

Define a short alias for a long hierarchical signal path. Usable anywhere a signal name is expected.

list_aliases(session_id?)

List all user-defined aliases.

remove_alias(alias, session_id?)

Remove a user-defined alias.

Tool

Description

list_modules()

List all module hierarchy paths.

list_signals(module?, pattern?)

List signals, optionally filtered by module or name pattern.

search_signals(pattern, match_mode="auto", exclude_constants=false)

Search signals by name. auto mode ranks by relevance. Supports [31:0] suffixes.

Match modes:

  • auto — ranked relevance (recommended)

  • exact — exact full path match

  • suffix — base name ends with pattern (supports bit-select suffixes)

  • contains — case-insensitive substring

  • regex — regular expression

Time Queries

Tool

Description

snapshot(time, signals, session_id?)

Get signal values at a specific time (bin/hex/dec). time accepts int (ps) or "100ns"/"1.5us".

watch_signals(signals, trigger?, time_window?, max_events=10, trigger_on="first", session_id?)

Track values over time. trigger_on="any" reports when ANY signal changes; each event includes triggered_by.

next_edge(signal, from_time, edge="rising", session_id?)

Find next rising/falling edge after a time.

prev_edge(signal, from_time, edge="rising", session_id?)

Find previous rising/falling edge before a time.

find_edges(signal, edge="both", max_n=100, session_id?)

Find all edges of a signal.

Transaction Analysis

Tool

Description

find_transactions(valid_signal, data_signals, ready_signal?, max_n=10, session_id?)

Find valid-ready transactions and capture data values at each start. Registered-ready handshake time is correct (end = ready assertion, not valid fall).

analyze_axi_channel(channel_prefix, max_n=100, session_id?)

One-call AXI channel analysis: auto-detect signals, extract transactions, aggregate W beats into bursts by wlast, report throughput/gap/duration stats. Channel: aw/w/b/ar/r.

get_transaction_stats(valid_signal, data_signals, ready_signal?, max_n=100, bytes_field?, session_id?)

Extract transactions and compute cross-transaction stats: count, duration min/avg/max, gap min/avg/max, total bytes, throughput Mbps.

compare_transaction_fields(transactions, expected_field, actual_field)

Compare two fields across all transactions, find mismatches.

analyze_axi_write(max_n=100, session_id?)

Correlate AW+W+B channels into complete write transfers with latency breakdown (AW->W, W-burst, WLAST->B, total). Time-proximity matching handles unequal channel counts.

analyze_axi_read(max_n=100, session_id?)

Correlate AR+R channels into complete read transfers with latency breakdown (AR->R-first, R-burst, total).

Protocol, Clock & Activity Analysis

Tool

Description

check_axi_protocol(channel="write", session_id?)

AXI bus-level protocol checks: data stability while VALID=1/READY=0, BVALID before WLAST, zero-width valid pulses.

analyze_clock(clock_signal?, session_id?)

Auto-detect clock and report period, frequency, duty cycle, jitter, and gating periods.

signal_activity_stats(module?, top_n=20, session_id?)

Rank signals by change count, find dead signals (never toggle), report average changes per signal.

Value Diff & Comparison

Tool

Description

value_diff_between_times(t1, t2, signals?, session_id?)

Find all signals whose value changed between two time points. Useful for "what changed after reset?".

compare_waveforms(session_a, session_b, signals?, time_window?)

Compare two loaded waveforms signal-by-signal, report first mismatch time and value for each differing signal.

Visualization

Tool

Description

render_ascii_waveform(signals, time_start, time_end, width=80, session_id?)

Render ASCII timing diagram with collision-free time scale and right-boundary label. Linear-scan for performance.

Validation & Checking

Tool

Description

check_signal_value(signal, expected_value, at_time, session_id?)

Check if signal equals expected value (bin/hex/dec).

find_signal_mismatch(signal_a, signal_b, time_window?, session_id?)

Find times when two signals differ.

check_valid_ready_protocol(valid_signal, ready_signal, session_id?)

Detect valid-ready handshake violations.

Example Workflow (Agent Debugging AXI2MEM)

Here's how an agent would use the tools to debug a waveform:

1\. load\_waveform(path="/path/to/axi2mem\_tb.vcd")

   → 671 signals, 66 modules, 475us max time

2\. search\_signals(pattern="awvalid", exclude\_constants=true)

   → \["axi2mem\_tb.awvalid", ...]

3\. find\_transactions(

     valid\_signal="awvalid",

     data\_signals=\["awaddr", "awlen", "awsize", "awburst"],

     ready\_signal="awready",

     max\_n=5

   )

   → 5 write address transactions with addresses and lengths

4\. find\_transactions(

     valid\_signal="wvalid",

     data\_signals=\["wdata", "wstrb", "wlast"],

     ready\_signal="wready",

     max\_n=5

   )

   → 5 write data transactions:

     \[0] 115ns wdata=0xDEADBEEF wstrb=0xF wlast=1

     \[1] 385ns wdata=0xA0000000 wstrb=0xF wlast=0

     ...

5\. render\_ascii\_waveform(

     signals=\["clk", "awvalid", "awready", "wvalid", "wready"],

     time\_start=90000, time\_end=110000, width=80

   )

   → ASCII timing diagram showing handshake timing

6\. check\_valid\_ready\_protocol(valid\_signal="wvalid", ready\_signal="wready")

   → 0 violations (clean protocol)

CLI Usage

The CLI (src/waveform_mcp/cli.py) provides a human-friendly interface for manual debugging. It is backward-compatible with the original script.

List signals

python debug\_waveform.py --vcd waveform.vcd --list-signals

python debug\_waveform.py --vcd waveform.vcd --list-signals --pattern valid

Snapshot at a time

python debug\_waveform.py --vcd waveform.vcd --watch result mode --time 95000

python debug\_waveform.py --vcd waveform.vcd --watch result mode --time 95000 --json

Time-series with trigger

python debug\_waveform.py --vcd waveform.vcd --watch result mode --trigger valid -n 20

Time window trace

python debug\_waveform.py --vcd waveform.vcd --watch valid result --time 95000-97500

Transaction analysis (new)

python debug\_waveform.py --vcd waveform.vcd \\

  \--transactions valid\_out \\

  \--data result mode overflow \\

  \--ready ready\_in \\

  -n 5

ASCII waveform (new)

python debug\_waveform.py --vcd waveform.vcd \\

  \--ascii clk valid\_out ready\_in result \\

  \--time 90000-110000 \\

  \--width 100

FSDB support

python debug\_waveform.py --vcd waveform.fsdb --watch result --time 95000

Requires fsdb2vcd from Verdi in PATH.

Cache (new)

python debug\_waveform.py --vcd huge.vcd --cache --watch result --time 95000

First load parses and saves cache; subsequent loads are ~5x faster.

Python API Usage

Use the core library directly in scripts:

from waveform\_core import WaveformSession

\# Load waveform

session = WaveformSession("/path/to/waveform.vcd", use\_cache=True)

\# Search signals

valid\_signals = session.search\_signals("valid", exclude\_constants=True)

\# Snapshot

snap = session.snapshot(95000, \["result", "mode"])

print(snap\["signals"]\["result"]\["hex"])

\# Find AXI transactions

txs = session.find\_transactions(

    "awvalid", \["awaddr", "awlen"],

    ready\_signal="awready", max\_n=10

)

for tx in txs:

    print(f"  addr={tx\['data']\['awaddr']\['hex']} len={tx\['data']\['awlen']\['hex']}")

\# ASCII waveform

wave = session.render\_ascii(\["clk", "valid", "ready"], 90000, 110000, width=80)

print(wave)

\# Protocol check

violations = session.check\_valid\_ready\_protocol("valid", "ready")

session.unload()

FSDB Support

FSDB (Fast Signal Database) is Synopsys Verdi's proprietary format. Since it's not open, this project uses Verdi's fsdb2vcd command-line tool for conversion:

  1. When you load a .fsdb file, the server automatically calls fsdb2vcd to convert it to a temporary VCD.

  2. The converted VCD is then parsed normally.

  3. The temporary file is cleaned up on unload.

Requirements:

  • Verdi installed with fsdb2vcd in PATH, or

  • Set VERDI_HOME environment variable, or

  • Pass fsdb2vcd_path explicitly in Python API

Limitations:

  • Conversion adds overhead (proportional to file size).

  • FSDB-specific features (like signal hierarchy browsing in Verdi) are not available.

  • For very large FSDB files, consider converting to VCD manually first.

Testing

Core library tests (synthetic VCD)

python test\_waveform\_core.py

12 tests covering: load/parse, search, snapshot, transactions, edges, ASCII rendering, protocol check, cache, watch signals, mismatch detection, module listing.

MCP communication tests

python test\_mcp\_server.py

8 tests covering the full stdio JSON-RPC lifecycle: initialize, tools/list, load_waveform, search, snapshot, transactions, ASCII rendering, unload.

End-to-end agent workflow test

python test\_e2e\_mcp.py                          # auto-detects real VCD, falls back to synthetic

python test\_e2e\_mcp.py /path/to/your/waveform.vcd

15-step simulation of a full agent debugging session over real stdio JSON-RPC: initialize → tools/list → load → search (7 patterns) → list_modules → snapshot → find_transactions (all AXI channels) → render_ascii → find_edges/next_edge → protocol_check → watch_signals (trigger) → check_signal_value → unload. Uses real AXI2MEM VCD when available.

Real VCD tests

python test\_real\_vcd.py /path/to/your/waveform.vcd

10 tests against a real waveform: load performance, module/signal inventory, search patterns, snapshot at multiple times, edge detection, watch with trigger, AXI transaction analysis (5 channels), ASCII rendering, protocol check, cache performance.

Generate a test VCD

python generate\_test\_vcd.py

Creates test_waveform.vcd with a simple valid-ready pipeline for quick testing.

File Structure

waveform\_mcp/

├── AGENTS.md                    # Agent rules file (project context, run commands, conventions)

├── README.md                    # This file

├── WAVEFORM\_MCP\_DESIGN.md      # Detailed design document (architecture, API, roadmap)

├── waveform\_core.py             # Core library: parsing, querying, analysis (no MCP dep)

├── waveform\_mcp.py              # MCP Server: 17 tools over stdio JSON-RPC

├── debug\_waveform.py            # CLI: human-friendly command-line interface

├── generate\_test\_vcd.py         # Test VCD generator

├── test\_waveform\_core.py        # Core library test suite (12 tests)

├── test\_mcp\_server.py           # MCP communication test suite (8 tests)

├── test\_e2e\_mcp.py              # End-to-end agent workflow test (15 steps, real VCD support)

├── test\_real\_vcd.py             # Real VCD test suite (10 tests)

└── test\_waveform.vcd            # Generated test VCD (small, synthetic)

Performance

Measured on a 22MB VCD (671 signals, 475us simulation):

Operation

Time

Initial parse

2.0s

Cache load (2nd time)

0.75s

Snapshot query

0.1-0.6ms

Transaction analysis (5 tx)

0.2ms

ASCII render (80 chars)

0.3ms

Protocol check

0.3ms

For files >100MB, use --cache or use_cache=True to avoid re-parsing.

Troubleshooting

"No module named 'mcp'"

Install the MCP SDK:

pip install "mcp\[cli]"

"fsdb2vcd not found"

  • Ensure Verdi is installed and fsdb2vcd is in PATH.

  • Or set the VERDI_HOME environment variable.

  • Or convert FSDB to VCD manually: fsdb2vcd -i input.fsdb -o output.vcd

MCP server not showing up in client

  • Check the path in the config is correct (use absolute paths).

  • Check Python is in PATH (use full path to python.exe if needed).

  • Run python src/waveform_mcp/server.py directly — it should start and wait for input (no errors).

  • Check client logs for connection errors.

Signal search returns too many results

  • Use exclude_constants=true to filter out parameters and constants.

  • Use more specific patterns (e.g., awvalid instead of valid).

  • Use match_mode="suffix" for exact base-name suffix matching.

ASCII waveform looks wrong

  • Ensure the time window is correct (in picoseconds).

  • For multi-bit signals, values are shown as hex labels at change points.

  • Increase width for more detail.

Design Document

See docs/DESIGN.md for the full design document, including:

  • Detailed architecture and design principles

  • Complete API specification

  • Tool-by-tool parameter reference

  • FSDB support design (two approaches)

  • Deployment configuration for all clients

  • Extension roadmap (v1.1, v1.2, v2.0)

  • Verification checklist

License

Internal use.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables analysis of RTL waveform files (VCD, FST) through WAL (Waveform Analysis Language). Supports signal inspection, transition extraction, and advanced waveform queries for hardware design verification.
    14
    BSD 3-Clause
  • F
    license
    Not graded
    quality
    B
    maintenance
    An MCP server that provides AI assistants with a persistent, sandboxed Python environment for waveform analysis, enabling loading and manipulation of VCD/FST/FSDB files and temporal pattern matching.
    9
  • A
    license
    Not graded
    quality
    C
    maintenance
    An MCP server for reading and querying FSDB waveform files, enabling AI assistants to browse hierarchy, search signals, and extract waveform data with value changes.
    13
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/schalkiii/waveform-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server