Skip to content

mrg_build: YoWASP WASM toolchain backend (Docker-free local synth/PnR, #8) - #9

Open
santolucito wants to merge 3 commits into
mainfrom
yowasp-wasm-backend
Open

mrg_build: YoWASP WASM toolchain backend (Docker-free local synth/PnR, #8)#9
santolucito wants to merge 3 commits into
mainfrom
yowasp-wasm-backend

Conversation

@santolucito

Copy link
Copy Markdown
Contributor

Implements the mrg_build half of #8: a toolchain-abstraction layer that resolves each tool to either a native binary on $PATH (oss-cad-suite / the sandbox image) or a YoWASP WASM entry point (yowasp-yosys, yowasp-nextpnr-ecp5) — so local synth/PnR reports work in Docker-less environments with nothing but pip wheels.

What's in this PR

  • toolchain.backend() — picks native (tools on PATH, preferred) or wasm (YoWASP wheels importable) once per run, so a report is never a native/wasm hybrid. Forceable via MRG_TOOLCHAIN_BACKEND=native|wasm for parity testing.
  • WASM execution via subprocess shim — YoWASP entry points (yowasp_yosys.run_yosys(...)) are invoked in a sys.executable -c subprocess, so cwd, env, and output capture behave identically to the native tools. All call sites (synth, pnr, pnr_soc — including the LiteX build-script lines) route through one _cmd() resolver.
  • BuildReport.backend — every report now records which backend produced it (native / wasm; the SDK's Docker path can set docker), alongside the existing toolchain version string (Proposal: [local] extra — Docker-free local synth/PnR via YoWASP #8 acceptance criterion).
  • Error messages — a missing toolchain now suggests pip install 'manhattan-reasoning-gym[local]' before oss-cad-suite (Proposal: [local] extra — Docker-free local synth/PnR via YoWASP #8 acceptance criterion).
  • Teststest_toolchain.py is parametrized over both backends, each skipping independently when its backend isn't installed, plus unit tests for backend selection and the error message. Also fixed a vacuous pass in the determinism test (None == None when both runs fail).
  • README — documents the two backends under sandbox/.

Verified

On this host (macOS, arm64), with yowasp-yosys==0.66.0.0.post1165 and yowasp-nextpnr-ecp5==0.10.0.0.post753:

  • wasm synth on tests/fixtures/mac.v: ok, exactly 1 MULT18X18D, backend/toolchain recorded (Yosys 0.66 / nextpnr-0.10, backend: "wasm").
  • wasm PnR: fits, Fmax 339 MHz, timing_met at 65 MHz, DSP 1/156, deterministic across runs with the same seed.
  • Absolute host paths resolve fine through YoWASP's wasmtime runtime (no cwd-only restriction).
  • pytest tests/ — all wasm-backend and backend-selection tests pass; ruff check clean.

Note: the three [native] test failures on my host are pre-existing (also fail on main): the local ~/oss-cad-suite bundle is a stale yosys 0.47 that misparses the quoted tee -o filename, vs the repo's 0.62 pin. The image's native path is unaffected — argv construction for the native backend is byte-identical to before.

Out of scope (tracked in #8)

  • The SDK-side fallback order in _local_build.py (native → wasm → Docker → error) and the [local] extra in pyproject.toml with pinned wheel versions — those live in the SDK repo.
  • Shipping the pre-elaborated base SoC for full-SoC pnr without LiteX installed.
  • Version pinning of the YoWASP wheels to the sandbox image's yosys/nextpnr builds (the wheels used here are current releases, newer than the image pin).

Closes nothing on its own; part of #8.

🤖 Generated with Claude Code

santolucito and others added 3 commits July 7, 2026 23:20
The mrg_build half of #8: tools now resolve through one of two backends,
picked once per run so a report is never a native/wasm hybrid:

- native: yosys/nextpnr-ecp5 on PATH (the image / oss-cad-suite) — preferred
- wasm: the yowasp-yosys / yowasp-nextpnr-ecp5 pip wheels, run via wasmtime
  in a subprocess so cwd/env/output capture match the native tools

MRG_TOOLCHAIN_BACKEND=native|wasm forces a backend (parity tests). Missing-
toolchain errors now suggest `pip install manhattan-reasoning-gym[local]`
first. BuildReport grows a `backend` field so local numbers are attributable.

Toolchain tests are parametrized over both backends, each skipping when its
backend isn't installed; verified the full synth + pnr flow end-to-end on the
wasm backend (mac.v: 1 DSP, fits, deterministic Fmax across runs).

The SDK-side fallback order in _local_build.py and the pinned [local] extra
land separately.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The wasm-backend variants of the toolchain tests (added in this PR) were
self-skipping in CI since only oss-cad-suite (native) was installed --
CI was only ever proving the backend-selection logic and the native path,
never that synth/PnR actually work through YoWASP. Installing the wheels
lets the parametrized tests run for real on both backends.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant