Skip to main content

veriforge

CI Changelog License

A Python library for parsing, analyzing, generating, and simulating Verilog/SystemVerilog designs, built on the Lark parser.

Features

  • Parse Verilog 2005 (with SystemVerilog extensions) into a semantic model
  • Preprocess source files (`define, `ifdef, `include, `timescale, etc.)
  • Multi-file project support — parse directories, link cross-module instances
  • Analyze designs — width inference, constant folding, clock/reset extraction, lint checks
  • Emit formatted Verilog from the model (round-trip, configurable style)
  • Python DSL — build hardware with operator-overloaded Python, emit to Verilog or simulate directly
  • Component library — FIFO, CDC, codec, AXI-Stream, AXI4-Lite, DSP, RAM, Xilinx inference
  • Auto-generate testbenches from any module
  • Convert parsed Verilog to DSL code (Verilog → Python translation)
  • Simulate — event-driven 4-state simulator (x and z share one representation — see known issues) with three engines (reference, bytecode VM, compiled Cython)
  • Fuzz — grammar-driven cross-engine + Icarus differential fuzzing tool (docs)
  • VCD output — IEEE 1364-2001 waveform dumps, cross-simulator validation
  • Inspect semantic models through lookup helpers and JSON serialization
  • Language Server — veriforge-lsp provides editor diagnostics, symbols, navigation, hover, and custom hierarchy/trace commands (install Verible for fast between-save diagnostics; the server falls back to the built-in Lark parser when Verible is absent)

Documentation

Quick Start

Parse a Verilog file

from veriforge.project import parse_file
from veriforge.codegen import emit_module

design = parse_file("rtl/counter.v", preprocess=True)
for mod in design.modules:
    print(emit_module(mod))

Build hardware with the Python DSL

Ports and registers are class attributes — a signal's name is never typed twice (see dsl_guide.md for the imperative builder alternative, used when the signal count isn't fixed at write-time):

from veriforge.dsl import ModuleSpec, In, OutReg, posedge
from veriforge.codegen import emit_module

class Counter(ModuleSpec):
    clk = In()
    rst = In()
    count = OutReg(8)

    def body(self, m):
        with m.always(posedge(self.clk)):
            with m.if_(self.rst):
                self.count <<= 0
            with m.else_():
                self.count <<= self.count + 1

print(emit_module(Counter().build()))

Simulate directly from Python

from veriforge.sim import Simulator, Clock

sim = Simulator(Counter().build())
sim.fork(Clock(sim.signal("clk"), period=10))

def test(s):
    s.drive("rst", 1)

sim.run(test, max_time=200)
print(sim.read("count"))

Analyze a project

from veriforge.project import parse_directory
from veriforge.analysis import analyze_design, lint_design

design = parse_directory("rtl/", preprocess=True)
analyze_design(design)
for w in lint_design(design):
    print(f"[{w.code.name}] {w.message}")

Installation

Prerequisites

Dependencies

  • Lark
  • Rich
  • treelib
  • pygls (LSP server)
  • intervaltree (LSP server)

PyPy Support (Optional — ~4x Simulation Speedup)

The full test suite passes under PyPy. Running the simulator under PyPy gives approximately 4x faster simulation compared to CPython thanks to JIT compilation, with zero code changes required.

  1. Install PyPy 3.10+ from https://www.pypy.org/download.html
  2. Install dependencies: pypy3 -m pip install lark rich treelib pygls intervaltree
  3. Run: pypy3 -m veriforge ...
git clone https://github.com/chiplukes/veriforge
cd veriforge
uv sync --extra test

Install with pip

git clone https://github.com/chiplukes/veriforge
cd veriforge
python -m venv .venv
# Activate:
#   Linux/macOS:       source .venv/bin/activate
#   Windows PowerShell: .venv\Scripts\activate
pip install -e .[test]

CLI Usage

The CLI is subcommand-based (legacy -f/-t/-r flags remain supported):

# Parse a file and print the syntax tree
uv run veriforge tree -f path/to/file.v

# Reconstruct Verilog text from the parsed tree
uv run veriforge reconstruct -f path/to/file.v

# Parse summaries (support --json for automation)
uv run veriforge parse-file -f rtl/top.v
uv run veriforge parse-directory rtl/

# Generate a Python testbench skeleton
uv run veriforge generate-python-testbench --file rtl/top.v

# Export a parsed project to Python DSL files
uv run veriforge export-dsl rtl/ out_dsl/

# Inspect hierarchy / wrapper candidates (--format text|dot|mermaid)
uv run veriforge hierarchy graph rtl/

# Grammar tree visualization
uv run python -m veriforge.lark_file.gen_tree --all --depth 5

See veriforge <command> --help for full flag listings and notes/cli_json_schema.md for the --json output contract.

Running Tests

# Same representative fast slice used by push/PR CI
uv run --extra test pytest tests/test_verilog_parser/test_all.py tests/test_model/test_module.py tests/test_model/test_instances.py tests/test_model/test_roundtrip.py tests/test_model/test_tree_to_model_characterization.py tests/test_analysis/test_width_inference.py tests/test_analysis/test_const_fold.py tests/test_preprocessor/test_preprocessor.py tests/test_formatter/test_formatter.py --tb=no -q

# Full local suite
uv run --extra test pytest tests/ --tb=no -q

For long-running grammar-driven fuzz testing across all engines (including Icarus cross-check), see the standalone fuzzer at notes/fuzzer.md:

uv run -m veriforge.fuzz --max 100 --no-icarus

Examples

Runnable examples are in the examples/ directory. See examples/README.md for prerequisites and category guidance.

  • examples/basics/ — counter, shift register, FSM, ALU, testbench
  • examples/library/ — FIFO, CDC, codec, DSP, Xilinx components
  • examples/axi/ — AXI-Stream and AXI4-Lite usage
  • examples/composability/ — pipeline generators, design exploration, register banks
  • examples/darkriscv/ — real-world RISC-V SoC integration target
  • examples/femtorv/ — compact RISC-V processor integration target
  • examples/picorv32/ — PicoRV32 processor integration target
  • examples/serv/ — SERV bit-serial RISC-V processor integration target
  • examples/ibex/ — Ibex-related validation assets
  • examples/pulp/ — imported validation targets based on pulp-platform designs

Current Limitations

veriforge targets RTL-level behavioral simulation and analysis. Before using it, it is worth knowing where the current boundaries are:

Simulation scope

  • This is a behavioral RTL simulator, not a replacement for Icarus Verilog, Verilator, or commercial tools for full-chip verification. It is well-suited for unit-level testbenches, design exploration, and cross-validating specific behaviors.
  • X/Z propagation is modeled but corner cases in complex expressions may not match the IEEE spec in all situations. For designs where X-propagation correctness is critical, cross-validate with IcarusCosim.
  • Specify blocks (timing annotations) and gate-level / UDP primitives are parsed and emitted but not executed.
  • The compiled Cython engine falls back to reference coroutines for #delay / @(posedge) inside initial/always blocks; a warnings.warn is emitted when this happens. The workaround is to move timing control into the Python testbench layer.

SystemVerilog subset

  • The SystemVerilog verification layer is out of scope: classes, SVA assertions, covergroups, randomize/constraints, dynamic arrays, queues, bind, and program blocks are not simulated.
  • Packed structs, interfaces, and parameterized interfaces work for common RTL patterns but may require flat wrapper modules for complex cases. The support matrix has the per-construct breakdown.
  • Functions and tasks cover the common RTL patterns used by the validation examples; unusual calling conventions or recursive functions may fail.

Verilog-to-DSL conversion

  • The converter (export-dsl) is intentionally conservative. Control-flow-heavy constructs, complex always blocks, and module-level generate blocks often require manual rewriting. See notes/dsl/dsl_conversion_coverage.md for the detailed gap list.

Hierarchy refactor tooling

  • Structural, behavioral, parameterized, and generate-containing wrappers are detected and classified but collapse is intentionally blocked pending safer transforms. Extract and boundary-move operations cover common direct-wiring cases; complex connectivity patterns fail closed with a diagnostic. See notes/roadmap.md for the backlog.

Performance

  • Even with the compiled Cython engine, throughput is lower than C-based simulators. For simple sequential testbenches on medium-sized designs, performance is practical. For very large designs or workloads requiring millions of cycles, prefer a dedicated simulator and use veriforge for the analysis and testbench-generation layers.

License

MIT

Metadata

Release files for veriforge 0.1.7

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for veriforge 0.1.7
File Size Uploaded
veriforge-0.1.7.tar.gz 865.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for veriforge 0.1.7
File Interpreter ABI Platform
veriforge-0.1.7-py3-none-any.whl Python 3 none any Details

Total release size: 1.8 MB

Release files / veriforge-0.1.7.tar.gz

Download URL veriforge-0.1.7.tar.gz
Size 865.0 kB
Tags Source
SHA-256 checksum
How to use checksums
c73bab500b6416440898de3e7c71c2ff7e3ea2dd877b370ae3109b1c10be967c
BLAKE2b-256 checksum
How to use checksums
8cfb6c30712165470c8f256eac969098549bbb688333dd6d591348d52af47fb4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 31, 2026.

Transparency log

Release files / veriforge-0.1.7-py3-none-any.whl

Download URL veriforge-0.1.7-py3-none-any.whl
Size 944.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4e69f07b682d3be62e4062232d6a48af85a459a2d91595467f2122a8470b2f14
BLAKE2b-256 checksum
How to use checksums
97bb03186a90f454e910586aa809bfe3dae6b32cf07cfc973769b5c119b35de7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 31, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.9

2 release files

0.1.8

2 release files

This release

0.1.7 This release

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page