pyCircuit 6
Python-first hardware construction and architecture modeling, backed by MLIR, deterministic C++ simulation, and Verilog generation.
pyCircuit provides two complementary Python frontends in one versioned toolchain:
pycircuitconstructs cycle-aware, synthesizable hardware from signals, state, hierarchy, memories, and explicit logical cycles.agentic_circuitmodels architecture-level processes, queues, resources, scheduling, and committed state through ACPy and ACIR.
Both paths converge on verified PYC MLIR when generating hardware. C++ and Verilog therefore share one semantic contract, rather than separate handwritten implementations.
Highlights
- Cycle-aware by construction. Signal provenance tracks logical cycles, and automatic pipeline balancing lowers to explicit PYC MLIR (Decision 0148).
- One verified contract. Structural and cycle-aware authoring reach the same verified PYC representation; semantics live in the dialect, passes, and verifiers rather than in one backend.
- Deterministic output. Preserved module hierarchy and deterministic generated artifacts.
- Rich data model. Exact-width values, typed structures, queues, tables, and memories.
- Multiple backends. C++ cycle simulation, gfsim architecture simulation, and Verilog generation from one design.
- Reviewable change control. Focused pull-request gates plus a reproducible release closure.
Choose a frontend
| You want to describe | Install | Import | Primary flow |
|---|---|---|---|
| Ports, signals, registers, memories, pipelines, and synthesizable hardware | pycircuit-hisi |
pycircuit |
Python → PYC → pycc → C++ / Verilog |
| Processes, queues, resources, scheduling, and architecture state | pycircuit-hisi |
agentic_circuit |
Python → acc.py → verified ACIR → acc → C++ / bundle / Verilog |
Read Choose a Frontend for the supported authoring boundaries and examples.
Quick start
The integrated development setup requires Python 3.11 or later, CMake, Ninja, and LLVM/MLIR 22.1.8. pyCircuit-only frontend use supports Python 3.10 or later.
git clone https://github.com/PTO-ISA/pyCircuit.git
cd pyCircuit
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e "python/semantic-core"
python -m pip install -e ".[dev,docs]"
bash flows/scripts/pyc build
export PYC_TOOLCHAIN_ROOT="$PWD/.pycircuit_out/toolchain/install"
Build the counter example with the C++ and Verilog backends:
PYTHONPATH=python/pycircuit/src \
python -m pycircuit.cli build \
examples/pycircuit/basics/counter/tb_counter.py \
--out-dir .pycircuit_out/quickstart/counter \
--target both \
--jobs 8
Add the architecture-modeling frontend when needed:
python -m pip install -e "python/agentic-circuit[test]"
agentic-circuit --help
Continue with the Quickstart or the complete installation guide.
Write your first circuit
Each frontend has one authoring entry point, and both lower to verified PYC before any backend runs.
Cycle-aware hardware with pycircuit
CycleAwareSignal is the primary authoring model. Compute the next value in the
current logical cycle, call domain.next(), then commit the assignment; the
frontend inserts delay registers wherever cycles must be balanced.
from pycircuit import (
CycleAwareCircuit,
CycleAwareDomain,
build_cycle_aware,
cas,
mux,
wire_of,
)
def build(m: CycleAwareCircuit, domain: CycleAwareDomain, width: int = 8) -> None:
enable = cas(domain, m.input("enable", width=1), cycle=0)
count = domain.signal(width=width, reset_value=0, name="count")
m.output("count", wire_of(count))
# Compute next at cycle 0, then commit after domain.next().
count_next = mux(enable, count + 1, count)
domain.next()
count <<= count_next
build.__pycircuit_name__ = "counter"
print(build_cycle_aware(build, name="counter", width=8).emit_mlir())
The full design, testbench, and parameters live in
examples/pycircuit/basics/counter, and the
pyCircuit 6 Tutorial covers testbenches,
hierarchy, memories, and multi-cycle pipelines.
Transactional architecture with agentic_circuit
Use Agentic Circuit when a design is better described as typed data moving through queues and atomic rules. Availability, backpressure, reservations, arbitration, and commit are compiler responsibilities, so the Python describes intent rather than hand-built handshakes.
import agentic_circuit as ac
@ac.struct
class Entry:
index: ac.u2
value: ac.u8
def increment(entry: Entry) -> Entry:
return entry.with_fields(value=entry.value + 1)
@ac.rule
def install(entries, incoming):
old = entries[incoming.index]
entries[incoming.index] = increment(incoming)
return old
@ac.system
def transaction_pipeline(incoming: Entry) -> Entry:
entries = ac.table[4, Entry](init=0)
outgoing = install(entries, incoming)
return outgoing
Every @ac.rule is one schedulable atomic transition. Here the Table
replacement and the Queue transfers in install prepare together and publish at
the same tick edge, so backpressure or a state conflict leaves the committed
image unchanged; no reservation, check, or prepare/publish step appears in the
Python.
Runnable state examples, including explicit ac.source() and ac.sink()
capture forms, multi-rule ROB scheduling, and slot ownership, live in
examples/agentic-circuit/state. The
Agentic Circuit and ACIR documentation covers ACPy,
verified ACIR, ACC, QueueGraph, and gfsim, and the
Agent Frontend Guide states the
authoring rules this example follows.
How the toolchain fits together
agentic_circuit frontend -> acc.py -> verified ACIR -> acc
|-> gfsim C++ / bundle
`-> PYC -> pycc -> Verilog
pycircuit frontend -> Cycle-Aware Signal -> PYC -> pycc -> pyc6 C++ / Verilog
ACIR remains an architecture-level dialect; PYC remains the shared hardware
contract. The pycircuit and agentic_circuit Python namespaces are separate
and are not compatibility aliases.
Documentation
| Start here | Purpose |
|---|---|
| Getting Started | Install the toolchain and run the first design |
| Choose a Frontend | Select between pycircuit and agentic_circuit |
| pyCircuit 6 Tutorial | Learn cycle-aware authoring and testbenches |
| Language and API Reference | Look up syntax, APIs, diagnostics, primitives, and PYC IR |
| Architecture | Understand frontends, compiler stages, runtimes, and backends |
| Agentic Circuit and ACIR | Learn ACPy, verified ACIR, ACC, QueueGraph, and gfsim |
| Development Guide | Build, test, contribute, and prepare pull requests |
| Agent Frontend Guide | Choose and apply a Pythonic authoring model for complex circuits |
Repository layout
The tree is organized by responsibility:
python/ Python distributions and shared semantics
compiler/ PYC and ACIR dialects, passes, ACC, and generators
library/ Stable pyCircuit C++ runtime and Verilog implementations
simulator/ gfsim architecture-modeling runtime
docs/ User, architecture, reference, and contributor documentation
examples/ Small supported examples
benchmarks/ Performance-only workloads and harnesses
tests/ Unit, system, integration, MLIR, C++, Verilog, and golden tests
tools/ User-facing and product-maintenance utilities
flows/ Build, CI, gate, and release orchestration
schemas/ Machine-readable contracts, inventories, and registries
packaging/ SDK, archive, and wheel assembly
toolchains/ Pinned compiler and dependency identities
See Repository Layout for the complete
ownership map, including .github/, cmake/, and third_party/. Complete CPU,
NPU, accelerator, SoC, board, ISA, and product-specific testbench sources live
in their owning consumer repositories.
Validate a change
Run the lightweight repository checks first:
pre-commit run --all-files
pytest tests/unit -m unit
python tools/agentic-circuit/check-contracts.py
mkdocs build --strict
Native compiler or runtime changes also require the narrowest affected MLIR, C++, simulation, or backend test. The full release matrix runs through the release workflow rather than every pull request.
See Testing and Gates for the exact change-to-gate mapping.
Project status
PTO-ISA/pyCircuit is the canonical
source, issue tracker, and release authority. The latest published release is
available from GitHub Releases.
The distribution name is pycircuit-hisi; the Python import remains
pycircuit.
The former standalone Agentic Circuit repository is archived provenance. Its consolidation record is preserved in the historical repository record, not as an active development or compatibility path.
Contributing and security
- Contributing guide
- Development workflow
- Review and merge requirements
- Security policy
- Code of conduct
License
pyCircuit and the integrated Agentic Circuit sources are licensed under the BSD 3-Clause License.
Metadata
Release files for pycircuit-hisi 6.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pycircuit_hisi-6.1.0-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| pycircuit_hisi-6.1.0-py3-none-macosx_15_0_arm64.whl | Python 3 | none | macOS 15.0+ ARM64 | Details |
Total release size: 127.9 MB
Release files / pycircuit_hisi-6.1.0-py3-none-win_amd64.whl
| Download URL | pycircuit_hisi-6.1.0-py3-none-win_amd64.whl |
|---|---|
| Size | 44.4 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
13e1ed259e83665d88722cc9b1d081be47bfc3edd0747109e7e7e6fd0c57d0a7
|
|
BLAKE2b-256 checksum How to use checksums |
a2345567f9062e5a870176edcabe865990d961a207fde62a75e35852c23aa50f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / pycircuit_hisi-6.1.0-py3-none-macosx_15_0_arm64.whl
| Download URL | pycircuit_hisi-6.1.0-py3-none-macosx_15_0_arm64.whl |
|---|---|
| Size | 83.5 MB |
| Tags | Python 3 macOS 15.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
b0863ab87172002c80f99b48486a996b0d9981fac1972728f150fe89c59e74c4
|
|
BLAKE2b-256 checksum How to use checksums |
2e85138fdc3efc2f71aa7c2509f474dd3bb49f8cc29c49d9121c6d05627e6df1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|