Skip to content

images: add pnr-xilinx (openXC7 for Xilinx 7-series) + refresh all pins - #6

Merged
soronpo merged 4 commits into
mainfrom
images/pnr-xilinx-openxc7
Sep 8, 2026
Merged

soronpo merged 4 commits into
mainfrom
images/pnr-xilinx-openxc7

Conversation

@soronpo

@soronpo soronpo commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Adds the toolchain DFHDL needs for build -t foss on Xilinx/AMD 7-series, and
refreshes every other pin to its current upstream release.

1. pnr-xilinx

A new image carrying nextpnr-xilinx, bbasm, prjxray (xc7frames2bit, xc7patch,
bitread, fasm2frames) and the prjxray bit database.

Deliberately separate from pnr: openXC7 is a fork of nextpnr
(openXC7/nextpnr-xilinx, -DARCH=xilinx), not an arch of the YosysHQ tree, and it
carries a ~500 MB bit database that ECP5/Gowin users should not pay for. Keeping them
apart also means a Trellis or Apicula pin bump never rebuilds this image, and vice versa.
The database is pruned to the families nextpnr-xilinx-meta also ships (artix7, spartan7,
zynq7), since without site metadata the bba exporter cannot build a chipdb for the rest
anyway. 100 MB sif from an 894 MB prefix.

NEXTPNR_XILINX_REV must stay at or after 6680df93 (openXC7 PR #156). Below it
create_clock does not propagate past the input BUFG, so every build silently reports
PASS at 12.00 MHz whatever the real constraint. Pinned at 3ad30f57, 24 commits after
the fix.

2. Chip databases as release assets

The per-part databases nextpnr places against cannot live in the image (90-670 MB each,
7.8 GB for the full set) and should not be built on a user's machine. scripts/chipdb.sc
generates them from inside a freshly built sif and publishes each as its own immutable,
content-addressed asset under a new chipdbs section of dftools.lock.json.

Generating from the image is what makes them valid: nextpnr asserts that a chipdb's
interned IdString table matches its own constids.inc. For the same reason the workflow
runs that job exactly when pnr-xilinx is rebuilt -- carrying a previous lockfile's
chipdbs past a NEXTPNR_XILINX_REV or PRJXRAY_DB_REV bump would publish databases the
new binary refuses.

Measured, not estimated (plain CPython inside the image):

part bbaexport bbasm .bba chipdb
xc7a35tcpg236 43 s 3 s 268 MB 93.0 MB
xc7a100tcsg324 71 s 5 s 466 MB 159.6 MB

Well under upstream's "1-3 h per family, 5-30 GB scratch", which must describe the full
34-part set and the large zynq/virtex footprints. No pypy3 needed.

3. Pin refresh

from to
ghdl master (synth-vhdl) ea079441cff0 1391e71fabb8
ghdl-yosys-plugin a45a8fbf1982 50420290404d
nextpnr (pnr) nextpnr-0.10 nextpnr-0.11.1
apycula 0.32 0.33
verilator dde6aa34cebb f8c296ce2edb
xezim + xezim-core 0.9.8 0.10.3
wavecrux (+ sha256) 0.6.0 0.8.0

Already current and untouched: yosys/eqy v0.68, prjtrellis 1.4, ghdl v6.0.0, nvc
r1.22.1, iverilog v13_0, surfer v0.7.0, gtkwave v3.3.116, openFPGALoader v1.1.1,
fpga-isv v0.2.0.

nextpnr 0.11 moved the himbaechel and Trellis cmake options into subdirectory CMakeLists
files, but HIMBAECHEL_UARCH, HIMBAECHEL_GOWIN_DEVICES (still special-casing all) and
TRELLIS_INSTALL_PREFIX all still exist with the same meaning at the 0.11.1 tag, so the
pnr configure line is unchanged. The wavecrux sha256 was computed from the downloaded
AppImage and matches the checksum in upstream's own update feed.

Also drops the sim-xezim linux-arm64 exclude, which was marked TEMPORARY pending
aionhw/xezim#105. That issue is closed and its fix commit is an ancestor of 0.10.3 and
not of 0.9.8, which is the condition the comment set. CI is what proves the arm64
build actually goes through
-- that is the one claim here I could not check locally.

Validation

Done locally on this branch:

  • the pnr-xilinx image builds clean and every test.sc probe passes
  • the full flow (yosys JSON -> nextpnr-xilinx -> fasm2frames -> xc7frames2bit)
    produces a valid 3,825,899 byte Nexys A7 bitstream from DFHDL's generated output,
    at the design's real 100 MHz constraint (PASS at 100.00 MHz)
  • both chipdbs generated from the image and verified against real place-and-route;
    xc7a100tcsg324 comes out byte-identical to the FPGAwars prebuilt, which
    independently confirms chipdb validity tracks constids.inc rather than the revision
  • lockfile.sc's new chipdbs section smoke-tested end to end

Left to CI: every other image at its new pin, and the arm64 sim-xezim build. Note the
diff touches scripts/ and .github/workflows/, so affected-images.sh correctly forces
a full 11-image rebuild rather than an incremental one -- a long run, but it means
every image is validated at its new pin.

The DFHDL side (YosysNextPNR.Xilinx7, DFToolsChipdb, the pnr XDC dialect) is a separate
change; until this is released it drives the flow through
-Ddfhdl.dftools.sif.pnr-xilinx and -Ddfhdl.chipdb.<part> overrides.

The two commits are independent if you would rather land the pin refresh separately.

🤖 Generated with Claude Code

Oron Port and others added 4 commits September 8, 2026 22:59
Adds the toolchain DFHDL needs for `build -t foss` on Xilinx/AMD 7-series parts:
nextpnr-xilinx, bbasm, prjxray (xc7frames2bit, xc7patch, bitread, fasm2frames)
and the prjxray bit database.

A separate image, not an extension of `pnr`: openXC7 is a fork of nextpnr
(openXC7/nextpnr-xilinx, -DARCH=xilinx) rather than an arch of the YosysHQ tree,
and it carries a ~500 MB bit database that ECP5/Gowin users should not pay for.
Keeping them apart also means a Trellis or Apicula pin bump never rebuilds this
image, and vice versa. The database is pruned to the families nextpnr-xilinx-meta
also ships (artix7, spartan7, zynq7), since without site metadata the bba exporter
cannot build a chipdb for the rest anyway. Built size: 100 MB sif from an 894 MB
prefix.

NEXTPNR_XILINX_REV must stay at or after 6680df93 (openXC7 PR #156). Below it
create_clock does not propagate past the input BUFG, so every build silently
reports "PASS at 12.00 MHz" whatever the real constraint. Pinned at 3ad30f57,
24 commits after the fix.

The per-part chip databases nextpnr places against cannot live in the image
(90-670 MB each, 7.8 GB for the full set) and should not be built on a user's
machine, so scripts/chipdb.sc generates them from inside a freshly built sif and
publishes each as its own immutable, content-addressed asset in a new `chipdbs`
section of dftools.lock.json. Generating from the image is what makes them valid:
nextpnr asserts a chipdb's interned IdString table matches its own constids.inc.
The release workflow runs that job exactly when pnr-xilinx is rebuilt, since
carrying a previous lockfile's chipdbs past a nextpnr-xilinx or prjxray-db bump
would publish databases the new binary refuses.

Validated locally: the image builds clean, all probes pass, and the full flow
(yosys JSON -> nextpnr-xilinx -> fasm2frames -> xc7frames2bit) produces a valid
3,825,899 byte Nexys A7 bitstream from DFHDL's generated output at the design's
real 100 MHz constraint. Both published chipdbs were generated from the image and
verified against real place-and-route; xc7a100tcsg324 comes out byte-identical to
the FPGAwars prebuilt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Bumps each pin that had moved, leaving those already current (yosys/eqy v0.68,
prjtrellis 1.4, ghdl v6.0.0, nvc r1.22.1, iverilog v13_0, surfer v0.7.0,
gtkwave v3.3.116, openFPGALoader v1.1.1, fpga-isv v0.2.0, and the openXC7 trio).

  synth-vhdl     ghdl master  ea079441cff0 -> 1391e71fabb8
                 ghdl-yosys-plugin a45a8fbf1982 -> 50420290404d
  pnr            nextpnr  nextpnr-0.10 -> nextpnr-0.11.1
                 apycula  0.32 -> 0.33
  sim-verilator  verilator master  dde6aa34cebb -> f8c296ce2edb
  sim-xezim      xezim + xezim-core  0.9.8 -> 0.10.3
  wavegen        wavecrux  0.6.0 -> 0.8.0 (+ sha256)

The two ghdl pins move together because the plugin tracks ghdl master and uses
libghdl synth APIs that are not in a release; likewise xezim and xezim-core,
which upstream tags in lockstep, and the wavecrux version and its digest. The
wavecrux sha256 was computed from the downloaded AppImage and matches the
checksum in upstream's own update feed.

nextpnr 0.11 moved the himbaechel and Trellis cmake options into subdirectory
CMakeLists files, but HIMBAECHEL_UARCH, HIMBAECHEL_GOWIN_DEVICES (still special
casing "all") and TRELLIS_INSTALL_PREFIX all still exist with the same meaning at
the 0.11.1 tag, so the pnr configure line is unchanged.

Also drops the sim-xezim linux-arm64 exclude from the release matrix, which was
marked TEMPORARY pending aionhw/xezim#105. That issue is closed and its fix
commit ("fix: aarch64 build (c_char) and severity exit status") is an ancestor of
0.10.3 and not of 0.9.8, which is the condition the comment set for removing it.
CI is what proves the arm64 build actually goes through.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The chipdb job used `actions/upload-artifact@v8`, which does not exist: upload-
artifact and download-artifact are versioned independently, and upload is still on
v7 (as build-test already had it) while download is on v8. The job failed in "Set
up job", before any step ran, with "unable to find version `v8`".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
  scalapptainer  0.2.1  -> 0.5.4   (build.sc, chipdb.sc, test.sc)
  os-lib         0.11.4 -> 0.11.8  (all four scripts)

upickle stays at 4.4.3, already the newest release. The Scala version stays at
3.8.4, matching what DFHDL builds with: these scripts drive that build, and 3.9.0
buys them nothing.

os-lib 0.11.9 is a milestone series, so this takes the last stable.

The scalapptainer jump crosses three minors, so the API surface these scripts use
was checked rather than assumed: `bind(source, dest)`, `pwd`, `withOptions`,
`exec`, `execInteractive`, `image` and `build` all keep their signatures, and
`ExecOptions.toArgs` still renders `--bind <src>:<dest>` and `--pwd <path>`
identically, so the container invocations are unchanged. All four scripts compile,
and lockfile.sc was re-run end to end against the new versions.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@soronpo
soronpo merged commit 2c26dfd into main Sep 8, 2026
27 checks passed
@soronpo
soronpo deleted the images/pnr-xilinx-openxc7 branch September 8, 2026 22:07
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