Introduction

chia_openpiton is a CHIA adapter for OpenPiton, Princeton’s manycore RTL platform. It wraps OpenPiton’s sims tool as CHIA nodes, so an agentic loop can configure, build, simulate, and collect results from an OpenPiton manycore through one interface. MACE drives OpenPiton through it. The adapter supports three native cores, Ariane, OpenSPARC T1, and PicoRV32, and RV32 cores on the Generic Tile (core generic).

What the adapter exposes

Module

Contents

state_def.py

PitonConfig, the result dataclasses (PitonBuildArtifact, PitonRunResult, PitonRegressResult, PitonCollectResult), DiagEntry, the literal types PitonCore, SimType, NetworkConfig, and Verdict, and the constants COVERAGE_LINE_FLAG, ARIANE_WAY_RULE, and SIM_TYPES

openpiton_workspace.py

OpenPitonWorkspaceNode, with the members configure, build, run, regress, put_file, apply_edits, revert_edits, collect, clean, and the sims escape hatch

parse.py

Transcript parsers: pure functions over sim.log, status.log, and sims output

tools.py

PitonToolServer, the MCP tool server an LLM agent calls

state_def and parse have no dependencies, so the config types and parsers work without Ray or MCP. import chia_openpiton exports PitonConfig, the result dataclasses, the literal types, DEFAULT_CACHES, and MAX_TILES_PER_AXIS, and adds OpenPitonWorkspaceNode when Ray and CHIA are installed. Each OpenPiton checkout is prepared once with scripts/patch_openpiton.sh (see Environment Patches).

The CHIA adapter pattern

The adapter follows CHIA’s ESP adapter, chia.esp.esp_workspace.EspWorkspaceNode, and CHIA’s gem5 tool server, chia.simulators.gem5.Gem5ToolServer.

  • Colocated node. OpenPitonWorkspaceNode subclasses CHIA’s ColocatedNode. sims keeps its state on disk: a model directory under $PITON_ROOT/build/ with the run directories inside it. Later calls read what earlier calls wrote, so configure, build, and run must reach the same worker. By default the node reserves a placement group with one bundle, {"CPU": 1, "openpiton": 1}, and pins every member call to it.

  • Resource-tagged remote functions. Each member is a static method decorated with @ChiaFunction(resources={"openpiton": 1}), with the checkout root as its first argument. A node instance binds the root, so node.build.chia_remote(cfg) omits it and runs on the node’s bundle. The class attribute, OpenPitonWorkspaceNode.build.chia_remote(root, cfg), takes the root and is not pinned.

  • Tool server over the same functions. PitonToolServer exposes these members to an LLM agent, so the agent and the Python API share one implementation.

The openpiton resource

openpiton is a custom Ray resource. One unit is one OpenPiton checkout, and one machine can host several. OpenPiton’s template preprocessor (pyHP) writes generated .tmp.v files back into the source tree on every build, so two concurrent builds with different tile counts in one checkout corrupt each other. A worker that advertises {"openpiton": 2} must host two separate checkouts, each with its own node instance. MACE’s parallel integrator opens one node per checkout for the same reason (see Integrator).

When no worker advertises enough openpiton units, the placement-group reservation waits instead of failing, unless pg_ready_timeout_s is set.

Isolation from mace

chia_openpiton imports nothing from mace, so it can move into an upstream CHIA checkout as chia/openpiton/ unchanged.

The tier0 job in .github/workflows/ci.yml checks the rule on every push and pull request. It installs CHIA’s v1.0.1 release, imports the package, and fails if any mace module was loaded:

python -c "
import chia_openpiton, sys
leaked = sorted(m for m in sys.modules if m.startswith('mace'))
assert not leaked, f'chia_openpiton pulled in {leaked}'
print('isolation OK')
"

That check sees only the modules that importing the package loads. The lint job in the same workflow also fails on any line in chia_openpiton/ that imports mace, such as an import inside a function.

The tier0 job then runs the tier-0 tests, which start no Ray instance and need no OpenPiton checkout. To run the adapter’s tier-0 tests alone:

pytest chia_openpiton/test -q --ignore=chia_openpiton/test/cluster

chia_openpiton/test/cluster/openpiton_e2e_test.py holds tier 1 and tier 2. Tier 1 starts a local Ray instance and checks that a node reserves and releases its placement group. Tier 2 builds and runs diags on an OpenPiton checkout when OPENPITON_TEST_REAL=1 and OPENPITON_ROOT are set. The tier1 job in ci.yml runs tier 1 on every push. The RTL smoke workflow, .github/workflows/rtl.yml, runs tier 2’s first acceptance test on a 1x1 PicoRV32 tile: it patches OpenPiton at the pinned commit, builds the tile with the flake’s Verilator, and runs addi.S, once with MACE installed by pip and once inside nix develop. It runs every week and when the adapter, the patch script, or the flake changes. chia_openpiton/README.md keeps the upstreaming checklist.