Skip to content

a fundamental Python package for digital circuit waveform analysis

License

Notifications You must be signed in to change notification settings

cxzzzz/wavekit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

wavekit

PyPI version Python Versions License

Wavekit is a fundamental Python library for digital waveform analysis. By seamlessly converting VCD and FSDB data into Numpy arrays, it empowers engineers to perform high-performance signal processing, protocol analysis, and automated verification with ease.

✨ Features

  • High Performance: Cython-optimized parsers and Numpy-backed storage deliver exceptional speed and memory efficiency for large waveform files.
  • Flexible Extraction: Effortlessly batch-extract signals using glob patterns or regular expressions.
  • Rich Analysis Tools: Comprehensive toolkit for bit-precise manipulation, temporal analysis, and signal transformation, streamlining complex analysis tasks with succinct, Numpy-like APIs.

📦 Installation

Using pip (For Users)

You can install the library using pip:

pip install wavekit

Note: To read FSDB files, ensure the VERDI_HOME environment variable is set before installation.

From Source (For Developers)

This project uses Poetry for dependency management.

  1. Clone the repository:

    git clone https://github.com/cxzzzz/wavekit.git
    cd wavekit
  2. Install dependencies:

    poetry install

🚀 Quick Start

Batch Signal Extraction

Wavekit simplifies extracting multiple signals using brace expansion or regular expressions.

1. Using Brace Expansion Use brace patterns (e.g., {state,next} or {0..7}) to load related signals in one go.

from wavekit import VcdReader

with VcdReader("jtag.vcd") as f:
    # Load both J_state and J_next signals
    # Returns: { ('state',): Waveform(...), ('next',): Waveform(...) }
    waves = f.load_matched_waveforms(
        "tb.u0.J_{state,next}[3:0]",
        clock="tb.tck"
    )

    for (suffix,), wave in waves.items():
        print(f"Signal J_{suffix}: width={wave.width}")

2. Using Regular Expressions Prefix the pattern with @ to enable regex matching. Capture groups (...) become the dictionary keys.

with VcdReader("jtag.vcd") as f:
    # Use '@' prefix for regex mode
    # Match signals like J_state[3:0] and J_next[3:0]
    # Capture the suffix (state/next)
    regex_pattern = r"tb.u0.@J_([a-z]+)"

    # Returns: { ('state',): Waveform(...), ('next',): Waveform(...) }
    waves = f.load_matched_waveforms(regex_pattern, clock="tb.tck")

    for (name_part,), wave in waves.items():
        print(f"Matched: {name_part}")

Basic: FIFO Occupancy Analysis

Here is a simple example demonstrating how to read a VCD file and calculate the average occupancy level of a FIFO:

import numpy as np
from wavekit import VcdReader

with VcdReader("fifo_tb.vcd") as f:
    clock = "fifo_tb.s_fifo.clk"
    depth = 8

    # Load signals with clock synchronization
    w_ptr = f.load_waveform("fifo_tb.s_fifo.w_ptr[2:0]", clock=clock)
    r_ptr = f.load_waveform("fifo_tb.s_fifo.r_ptr[2:0]", clock=clock)

    # Perform vectorized arithmetic operations directly on waveforms
    fifo_water_level = (w_ptr + depth - r_ptr) % depth

    # Calculate average occupancy using Numpy
    average_level = np.mean(fifo_water_level.value)
    print(f"Average FIFO occupancy: {average_level:.2f}")

Advanced: Data Validity Filtering

Use the powerful masking capabilities to filter data based on valid signals:

from wavekit import VcdReader

with VcdReader("bus_tb.vcd") as f:
    clock = "top.clk"

    # Load data and valid signals
    data = f.load_waveform("top.bus_data[31:0]", clock=clock)
    valid = f.load_waveform("top.bus_valid", clock=clock)

    # Filter data where valid is high (1)
    # The mask() method accepts a boolean waveform or numpy array
    valid_data = data.mask(valid == 1)

    # Analyze the valid transactions
    print(f"Total valid transactions: {len(valid_data.value)}")
    print(f"First valid data: {hex(valid_data.value[0])}")

🛠️ Development

This project adheres to strict code quality standards using modern Python tooling:

  • Linting & Formatting: Ruff
  • Type Checking: Mypy

Ensure all checks pass before submitting a Pull Request:

# Run linting and formatting checks
poetry run ruff check .
poetry run ruff format --check .

# Run type checks
poetry run mypy .

📄 License

This project is licensed under the MIT License. See the LICENSE file for details.

About

a fundamental Python package for digital circuit waveform analysis

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published