Skip to content
PTO-ISAPublic

About

Python-first hardware construction toolkit with MLIR compilation, C++ simulation, and Verilog generation.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

31 stars

Watchers

0 watching

Forks

Latest commit

 

History

913 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

pyCircuit

pyCircuit

Describe hardware in Python. Compile once. Simulate in C++ or Verilog.

CI Release Latest release BSD 3-Clause license Python 3.11 or later LLVM and MLIR 22.1.8

Get started · Language reference · Examples · Repository map · Contribute

pyCircuit is a hardware programming language and compiler built on Python syntax and MLIR. Typed modules, persistent state and stateless rules describe the design. The compiler checks types, dependencies and effects, then emits C++ simulation models and Verilog from the same verified hardware IR.

Use it to build reusable hardware modules, compose stateful designs, and run closed simulation systems with compiler-generated drivers. Python supplies the authoring syntax; capture parses the source without executing the design.

What you get

  • Hardware semantics in familiar syntax. Fixed-width values, records, Tables, rules and module composition, with explicit admission and diagnostics.
  • Two backends, one verified design. GFSIM C++ models and Verilog consume the same final artifact, with source ownership preserved across compilation units.
  • Executable systems. A closed @system describes the DUT, stimulus and checks. The compiler generates native and Verilator simulation harnesses.
  • Atomic simulation steps. Rules read the old state. Whole-system checks precede commit; a failed epoch commits neither state nor clock history and publishes no source observations.
  • A separate Runtime package. Generated C++ consumers use the Runtime CMake component without installing LLVM or the compiler development package.

The checkout identifies itself as pyCircuit 6.1. The language is under active development: general parameter-dependent elaboration, broader clock scheduling, wide/four-state observation transport and some collection forms remain limited. The language reference defines supported constructs; known limitations records the boundaries.

A complete counter

from pycircuit import bits, log, rule, system


@rule
def increment(count):
    log("info", "count", count)
    count = count + 1


@system
def HelloCounter():
    count: bits[8] = 0
    increment(count)

count is eight-bit persistent storage. The rule observes its current value and proposes an increment modulo 256. The compiler infers storage, clock/reset connections and write enables, and generates the simulation harness.

From a checkout with an installed toolchain:

pycircuit run examples/hello_counter --target cpp --cycles 5
pycircuit run examples/hello_counter --target verilog --cycles 5

Each cycle contains low and high sampling epochs, so both runs log 0, 0, 1, 1, 2, 2, 3, 3, 4, 4. Generated files and simulator builds stay under .pycircuit_out/run/hello_counter/. Verilog execution requires Verilator. Use --toolchain /absolute/path/to/install when selecting an external toolchain.

See the quickstart for explicit compile/link/ emit commands and the tutorial for inspecting and running the generated artifacts.

Build from source

Task Requirements
Build the compiler Python 3.11+, CMake 3.25+, Ninja, a C++20 compiler, LLVM and MLIR 22.1.8
Run generated C++ C++20 toolchain, CMake/Ninja and pyCircuit Runtime
Run generated Verilog systems Installed pyCircuit compiler, Verilator, CMake/Ninja and a C++20 toolchain

Install LLVM/MLIR first. The build helper discovers llvm-config-22 or a matching llvm-config; alternatively set LLVM_CONFIG, or both LLVM_DIR and MLIR_DIR, to that installation. Installing the Python package alone does not install the native compiler.

git clone https://github.com/PTO-ISA/pyCircuit.git
cd pyCircuit
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e .
PYC_BUILD_TESTING=OFF bash tools/pyc build

export PYC_TOOLCHAIN_ROOT="$PWD/.pycircuit_out/toolchain/install"
export PATH="$PYC_TOOLCHAIN_ROOT/bin:$PATH"
pycircuit run examples/hello_counter --target cpp --cycles 5

These commands use a POSIX shell. The installation guide covers CMake build options, Runtime-only installations and package consumers. For prebuilt wheels, check the assets and platform support of the specific release.

One compiler flow

Python modules and systems
          │ syntax capture
          ▼
MLIR type, dependency and effect analysis
          │ hardware lowering and verification
          ▼
Independent source units ── explicit link closure ── verified final IR
                                                        │
                                               ┌────────┴────────┐
                                               ▼                 ▼
                                          GFSIM C++           Verilog
Command Purpose
pycircuit compile Compile one source and publish its body, interface and dependencies.
pycircuit link Check the complete explicit source-unit closure and select the design root.
pycircuit emit Emit C++ or Verilog from the verified final artifact.
pycircuit run Build and execute a closed system through those same public stages.

@module defines reusable hardware, @rule defines stateless computations, and @system defines a closed simulation composition. The current system path owns its generated clock/reset scaffolding; ordinary module drivers can provide explicit physical inputs. See system execution for sampling, reset, observation and failure semantics.

Explore and contribute

Start with For
Repository map Folder responsibilities, source boundaries and the right place for a change.
Example catalog Counters, pipelines, queues, tables and larger designs, with their verification owners.
Python language Types, source constructs, composition and rejection boundaries.
Compiler architecture Capture, MLIR analyses, source publication and code generation.
Build and test workflow Bounded gates, native tests and nightly coverage.
Contribution guide Scope, contracts, review and reproducible changes.

For compiler development, enable PYC_BUILD_TESTING=ON and install the native test dependencies, including GoogleTest and lit. With that testing build installed, run the bounded checks from the repository root:

bash tools/run_api_tests.sh --tier gate
bash tools/run_examples.sh --tier gate

For a nondefault build, set PYC_BUILD_DIR and PYC_TOOLCHAIN_ROOT as described in the testing guide. PR CI checks Python, publication, repository hygiene and documentation; native, example and release evidence have their own documented entrypoints. A green CI badge does not imply full backend or platform coverage.

Unfinished historical example migration and full-catalog validation are tracked in issue #272. A catalog entry or a removed example is not a claim of completed verification. Retired frontends and compiler aliases are not compatibility paths.

License

pyCircuit is licensed under BSD-3-Clause.

About

Python-first hardware construction toolkit with MLIR compilation, C++ simulation, and Verilog generation.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

31 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages