PyXL - Python Directly in Hardware

PyXL runs Python directly in hardware — no VM, no OS, no JIT.
Admin
Python directly in hardware

What is PyXL?

PyXL is a custom hardware processor that executes Python directly — no interpreter, no JIT, and no tricks. It takes regular Python code and runs it in silicon.

A custom toolchain compiles a .py file into CPython ByteCode, translates it to a custom assembly, and produces a binary that runs on a pipelined processor built from scratch.

It's a real processor for Python, built for determinism and speed.

Where does it run?

PyXL runs on a Zynq-7000 FPGA (Arty-Z7-20 dev board). The PyXL core runs at 100MHz. The ARM CPU on the board handles setup and memory, but the Python code itself is executed entirely in hardware.

The toolchain is written in Python and runs on a standard development machine using unmodified CPython.

What is a GPIO?

GPIO stands for General Purpose Input/Output. It’s a simple hardware pin that software can read from or write to — a way to control the outside world: LEDs, buttons, sensors, motors, and more.

In MicroPython (like on the PyBoard), your Python code interacts with C functions that handle hardware registers underneath. It’s reasonably fast, but still goes through a Python VM and a software stack before reaching the pin.

PyXL skips all of that. The Python bytecode is executed directly in hardware, and GPIO access is physically wired to the processor — no interpreter, no function call, just native hardware execution.

The program

from compiler.intrinsics import *


def main():
    pyxl_write_gpio_pin1(0)              # Reset output pin

    c1 = pyxl_get_cycle_counter()        # Cycle counter (100 MHz)

    pyxl_write_gpio_pin1(1)              # Set output pin
    while pyxl_read_gpio_pin2() == 0:    # Wait until input pin is set to 1
        continue

    c2 = pyxl_get_cycle_counter()        # Cycle counter (100 MHz)

    return (c2 - c1) * 10                # Return result in nano seconds (each cycle is 10 ns)

As you can see, this is a regular Python program, but it also has some unfamiliar function calls. These functions originate from compiler.intrinsics module.

pyxl_get_cycle_counter()

Gets the current cycle counter from the PyXL CPU. This counter advances by 1 on every tick

pyxl_write_gpio_pin1()

Writes a value (0/1) to a GPIO pin. These are low-level intrinsics exposed by the compiler — currently hardcoded for this test, but will evolve into a more general pyxl_gpio_write(pin, value) API.

pyxl_read_gpio_pin2()

Reads the value from Pin2. The same API comment is true here as well.

How does it work?

As described above, the program is compiled using a CPython Bytecode and then recompiled using PyXL assembly. It is then linked together, and a binary is generated.

This binary is sent via network to the Arty board, where an ARM CPU gets the application, copies it to a shared memory with the PyXL HW, and starts running it.

A typical Python runtime (CPython or MicroPython in case of the PyBoard or Python for embedded in general) has a big overhead caused by running the ByteCode on a software-based VM. In PyXL, there's no VM; the HW does everything.

As for reading and writing the GPIO, the GPIO headers are directly mapped to FPGA pins, and physically wired into PyXL's core top-level module. Think of it as the main function of the HW.

In this test, all code and data reside in predictable, low-latency memory, ensuring deterministic behavior (real-time behavior). This means that for the same input, it'll take the exact same time to run.

PyXL