pyCircuit turns a small Python hardware description into C++ and Verilog through one compiler flow. This complete counter is the smallest stateful example:
# ruff: noqa: F823 -- Module state captured by Rules is compiler-owned.
from pycircuit import bits, log, rule, system
@system
def HelloCounter(): # noqa: N802
count: bits[8] = 0
@rule
def increment() -> None:
log("info", "count", count)
count = count + 1count is persistent eight-bit storage. Its rule logs the current value and
proposes an increment modulo 256. Clock/reset and storage write enables are
compiler-owned, and @system selects a closed executable simulation.
After installing pyCircuit, the checked-in example runs with:
pycircuit run examples/hello_counter --cycles 5
pycircuit run examples/hello_counter --target verilog --cycles 5The two commands generate their own simulation harnesses. No C++ driver, RTL testbench or runtime configuration needs to be authored.
After installing pyCircuit, save the source as
hello_counter.py and run:
mkdir -p .pycircuit_out/hello_counter/units
pycircuit compile -c hello_counter.py --source-root . \
--package-prefix hello -o .pycircuit_out/hello_counter/units/hello_counter
pycircuit link .pycircuit_out/hello_counter/units/hello_counter \
--top hello.hello_counter.HelloCounter \
-o .pycircuit_out/hello_counter/hello_counter.ac
pycircuit emit .pycircuit_out/hello_counter/hello_counter.ac \
--target cpp -o .pycircuit_out/hello_counter/cpp
pycircuit emit .pycircuit_out/hello_counter/hello_counter.ac \
--target verilog -o .pycircuit_out/hello_counter/verilogCompilation publishes one independently reusable source unit. Linking verifies
the complete design, and both emit commands consume that same verified artifact.
Generated files stay in .pycircuit_out.
For the complete generated C++ and RTL run, continue with the hello counter tutorial.