You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ci(fpga): seed searches hide nextpnr's log when every seed fails #856
38 of the 39 AX7203 workflows that search nextpnr seeds write each attempt to /tmp/np_*.log. When no seed routes cleanly they print only:
##[error]no clean seed
and exit 1. The upload step is skipped on failure, so nothing in the run says why routing failed: not the unrouted arc, not the placer error, not a timeout.
Seen today on ax7203-gf10-sub.yml, both on main (run 37198621522) and on the #852 branch (runs 37197232296 and 37198736545). All three fail with that one line, after 8 seeds in 92–106 s. The last success on main was 2026-07-14, and regymm/openxc7:latest has moved since (image 591b377b7a59… now). Without the logs we cannot tell whether it is the DSP48E1 $PACKER_GND_NET route failure that -nodsp fixed in format-cost and build-timing, or something else.
Reference
ax7203-format-cost.yml already tails the logs before exiting (lines 129–133). The other 38 should do the same.
Fix
Insert tail -n 15 /tmp/np_*.log; between the echo and the exit 1. One line per file.
Coverage
before
after
seed searches that show nextpnr output on failure
1 / 39
39 / 39
openxc7-build-timing.yml mentions "no clean seed" only in a comment and has no seed search. It is not counted.
With #857's change, ax7203-gf10-sub was dispatched on ci/seed-search-show-log (run 37200092267). The seed search now prints each seed's log, and they say:
seeds
where nextpnr stops
1, 2, 3, 5, 6, 7, 8
ERROR: post-placement validity check failed for Bel 'SLICE_X…Y…/A5FF' (no cell), then Placing design failed. A different slice each time, always A5FF.
4
placement passes; Failed to find a route for arc 6 of net $PACKER_VCC_NET, then Routing design failed
So the bare "no clean seed" was a placement-validity failure, not a timing or routing shortfall.
What changed since the last green run. That run is 29338858369 (2026-07-14), and the workflow has not run between then and today. Comparing its log with today's:
2026-07-14, green
2026-10-04, red
regymm/openxc7:latest digest
sha256:eced1cdd…
sha256:35c91073… (tag pushed 2026-10-01)
Yosys
0.62 (git 7326bb7d6, g++ 9.4)
0.68 (git 38e001a6f, g++ 13.3)
the three input files (gf_adder_param.v, gf10_sub_ax7203.v, gf16_clean_ax7203.xdc)
at 69ed10d34
identical: git diff 69ed10d34 origin/main on them is empty
Yosys command line
same
same
cells after synth_xilinx
351
352
LUT2 / LUT3 / LUT4 / LUT6
99 / 66 / 54 / 67
103 / 60 / 44 / 79
MUXF7 / MUXF8
3 / 1
5 / 2
FDCE / FDPE
107 / 31
107 / 31
The netlist nextpnr receives is different, and nextpnr itself may be too. The nextpnr version is not in either log. Both changed at once, so this does not yet say which one breaks placement.
A/B running now. Branch exp/gf10-image-ab, workflow exp-gf10-image-ab.yml, run 37206223497. It runs the same commit as four jobs: the old or new image for Yosys, crossed with the old or new image for nextpnr. Every job runs all 8 seeds and reports how many are clean, and also prints the nextpnr, prjxray-db and prjxray commits inside each image. The old digest is still pullable (registry returns 200 for it).
Not concluded yet:
Whether the extra MUXF7/F8 have anything to do with A5FF. It is a plausible guess, because the F7 mux select and the 5FF bypass share a slice's AX input, but nothing here shows it.
Whether pinning the old digest is the right fix, or a workaround for a nextpnr or Yosys regression worth reporting upstream.
The A/B (run 37206223497) is finished. Four jobs, the same commit and the same Yosys and nextpnr command lines throughout. Each job runs all 8 seeds:
Yosys (synth image)
nextpnr (pnr image)
clean seeds
0.62, git 7326bb7d6 (old)
45a986b (old)
2/8 (seeds 1, 6)
0.62 (old)
1743d0f4, 0.8.2-81 (new)
2/8 (seeds 1, 6)
0.68, git 38e001a6f (new)
45a986b (old)
0/8
0.68 (new)
1743d0f4 (new)
0/8
The regression is in Yosys, not nextpnr. Given the same netlist, the two nextpnr builds fail on the same seeds at the same Bel. For example, old-Yosys seed 2 fails at SLICE_X112Y141/A5FF under both. New-Yosys seed 1 fails at SLICE_X22Y183/A5FF under both. Each job's stat table reproduces the netlist it was meant to reproduce (old: 67 LUT6, 3 MUXF7, 1 MUXF8; new: 79, 5, 2).
The design was already marginal before the image moved. With Yosys 0.62, 6 of 8 seeds fail the same A5FF way. July's run passed because the seed search stops at the first clean seed, and seed 1 was clean (its log says seed=1). So "the last green run" was 2 clean seeds out of 8, not a margin.
The error is nextpnr rejecting a placement that its own placer produced. That makes it look like a placer problem that some netlists expose, not an illegal design. That is a reading of the message, not something tested.
Round two is running on the same branch (commit e0a29e1ff):
new Yosys, seeds 9 to 40: does any seed place at all;
new Yosys with -nowidelut: no MUXF7/MUXF8 built from wide LUTs; does A5FF go away;
old Yosys with -nowidelut: the control.
The flag is -nowidelut, not -nomux. synth_xilinx has no -nomux, and with -widemux left at 0 the MUXF7/F8 here can only come from the wide-LUT mapping.
Noticed in passing, and not related to this failure: the new image ships prjxray-db 381966a (2025-06-05), while the old one had 6c02fde (2026-04-23, "Kintex 7 PCIe segbits/tilegrid and GTX bit fixes"). So the newer image carries an older database. Its /prjxray is newer (9553f1ad, 2026-09-23, against 132342f7).
Round two (run 37208602651) is finished, and it corrects my previous comment.
synth image
flags
seeds
clean
new (Yosys 0.68)
default
9-40
11 of 32 (11 12 20 21 30 31 32 35 37 39 40)
new
-nowidelut
1-8
2 (seeds 1, 2)
old (Yosys 0.62)
-nowidelut
1-8
0
Correction. I wrote "the regression is in Yosys, not nextpnr". The second half holds: given the same netlist, the two nextpnr builds fail the same seed at the same Bel. The first half is not supported:
With seeds 1-40 together, the new Yosys places this design on 11 of 40 seeds. The old Yosys placed it on 2 of 8. The old figure rests on 8 attempts, so the two rates cannot be told apart.
What the image change did was move which seeds win. On the old netlist the first clean seed was 1. On the new one seeds 1 to 10 all fail and seed 11 is the first clean one. An 8-seed search never gets that far.
So the job went red for a deterministic reason, but the design did not get harder to place.
The wide-mux hypothesis is refuted. With -nowidelut there are no MUXF7/MUXF8 cells at all, and A5FF still fails: the new Yosys places 2 of 8 that way, the old one 0 of 8. Any change to the netlist reshuffles the winning seeds. I found nothing that made the failure go away.
Failure modes across the 32 new-default attempts:
failure
seeds
time
post-placement validity check at SLICE_…/A5FF
18
~7 s each
nextpnr assertion valid_wires_for_net.count(w) at common/router1.cc:331
2 (seeds 18, 19)
37-56 s
Failed to find a route for arc 21 of net $PACKER_VCC_NET
1 (seed 24)
~40 s
clean
11
36-113 s
The assertion is a nextpnr crash, not a placement the tool rejects. Reproducing it needs the image digest, this design and --seed 18. I have not reported it upstream.
Fix: #861. It widens the search from 8 seeds to 32, and the search still stops at the first clean seed. If the outcome is deterministic for a fixed image and seed, it should print seed=11 and pay about ten 7-second failures first. Run 37210095288 checks that prediction.
Pinning the old digest was the other option. It would buy back one lucky seed (seed 1) rather than a margin, so I did not take it.
Not measured: whether other ax7203 workflows are in the same lottery, and the clean rate with the old image beyond seed 8.
The cause. The A5FF signature in this issue is openXC7/nextpnr-xilinx#162: post-placement validity check failed for Bel 'SLICE_…/A5FF' (no cell). That issue diagnoses it as an SA-placer bug on xc7.
--placer sa can leave a tile with its OUTMUX claimed twice, by O5 and by a 5FF's Q.
The final sweep reports the first Bel of that tile, often an empty A5FF.
HeAP refuses the pairing at the tile level.
cavearr closed #162 on 2026-09-24 because that nextpnr line is archived. I should have searched for the error text before the first experiment, not after two rounds.
Round three (run 37210944365) used the same Verilog, xdc and command line as before and only changed --placer sa to --placer heap:
synth image
placer
seeds
clean
time per seed
Fmax (50 MHz constraint)
new, sha256:35c91073 (Yosys 0.68)
heap
1-16
16/16
5-7 s
65.4-71.6 MHz
old, sha256:eced1cdd (Yosys 0.62)
heap
1-8
8/8
4-7 s
64.9-69.9 MHz
new
sa (round two)
1-40
11/40
failures ~7 s, clean 36-113 s
—
What this changes in #861. The PR now switches this workflow to --placer heap and keeps the 8-seed search as a margin. The 32-seed SA search it first proposed did work (run 37210095288 printed seed=11, as predicted), but it treated the bug as a lottery.
What it does not change. 32 of the 61 nextpnr workflows on main pass --placer sa. Some of them are measurements, where the placer is part of the recorded configuration; commits 5f571f9, d6e6978 and 30a230b show the placer/router pair moving Fmax by up to 4.3x. Those cannot be switched by a sweep, and the audit gets its own issue.
Not measured.
Whether HeAP is clean on seeds above 16.
Whether the router1.cc:331 assertion from seeds 18 and 19 can happen under HeAP; it did not in these 24 runs.
Activity
ci(fpga): A/B the openxc7 image for gf10-sub (experiment for #856)
gHashTag commentedon Oct 4, 2026
With #857's change,
ax7203-gf10-subwas dispatched onci/seed-search-show-log(run 37200092267). The seed search now prints each seed's log, and they say:ERROR: post-placement validity check failed for Bel 'SLICE_X…Y…/A5FF' (no cell), thenPlacing design failed. A different slice each time, alwaysA5FF.Failed to find a route for arc 6 of net $PACKER_VCC_NET, thenRouting design failedSo the bare "no clean seed" was a placement-validity failure, not a timing or routing shortfall.
What changed since the last green run. That run is 29338858369 (2026-07-14), and the workflow has not run between then and today. Comparing its log with today's:
regymm/openxc7:latestdigestsha256:eced1cdd…sha256:35c91073…(tag pushed 2026-10-01)gf_adder_param.v,gf10_sub_ax7203.v,gf16_clean_ax7203.xdc)69ed10d34git diff 69ed10d34 origin/mainon them is emptysynth_xilinxThe netlist nextpnr receives is different, and nextpnr itself may be too. The nextpnr version is not in either log. Both changed at once, so this does not yet say which one breaks placement.
A/B running now. Branch
exp/gf10-image-ab, workflowexp-gf10-image-ab.yml, run 37206223497. It runs the same commit as four jobs: the old or new image for Yosys, crossed with the old or new image for nextpnr. Every job runs all 8 seeds and reports how many are clean, and also prints the nextpnr, prjxray-db and prjxray commits inside each image. The old digest is still pullable (registry returns 200 for it).Not concluded yet:
A5FF. It is a plausible guess, because the F7 mux select and the 5FF bypass share a slice'sAXinput, but nothing here shows it.ci(fpga): gf10-sub experiment round two, -nowidelut and seeds 9-40 (#856
gHashTag commentedon Oct 4, 2026
The A/B (run 37206223497) is finished. Four jobs, the same commit and the same Yosys and nextpnr command lines throughout. Each job runs all 8 seeds:
45a986b(old)1743d0f4, 0.8.2-81 (new)45a986b(old)1743d0f4(new)The regression is in Yosys, not nextpnr. Given the same netlist, the two nextpnr builds fail on the same seeds at the same Bel. For example, old-Yosys seed 2 fails at
SLICE_X112Y141/A5FFunder both. New-Yosys seed 1 fails atSLICE_X22Y183/A5FFunder both. Each job's stat table reproduces the netlist it was meant to reproduce (old: 67 LUT6, 3 MUXF7, 1 MUXF8; new: 79, 5, 2).The design was already marginal before the image moved. With Yosys 0.62, 6 of 8 seeds fail the same
A5FFway. July's run passed because the seed search stops at the first clean seed, and seed 1 was clean (its log saysseed=1). So "the last green run" was 2 clean seeds out of 8, not a margin.The error is nextpnr rejecting a placement that its own placer produced. That makes it look like a placer problem that some netlists expose, not an illegal design. That is a reading of the message, not something tested.
Round two is running on the same branch (commit
e0a29e1ff):-nowidelut: no MUXF7/MUXF8 built from wide LUTs; doesA5FFgo away;-nowidelut: the control.The flag is
-nowidelut, not-nomux.synth_xilinxhas no-nomux, and with-widemuxleft at 0 the MUXF7/F8 here can only come from the wide-LUT mapping.Noticed in passing, and not related to this failure: the new image ships prjxray-db
381966a(2025-06-05), while the old one had6c02fde(2026-04-23, "Kintex 7 PCIe segbits/tilegrid and GTX bit fixes"). So the newer image carries an older database. Its/prjxrayis newer (9553f1ad, 2026-09-23, against132342f7).gHashTag commentedon Oct 4, 2026
Round two (run 37208602651) is finished, and it corrects my previous comment.
-nowidelut-nowidelutCorrection. I wrote "the regression is in Yosys, not nextpnr". The second half holds: given the same netlist, the two nextpnr builds fail the same seed at the same Bel. The first half is not supported:
The wide-mux hypothesis is refuted. With
-nowidelutthere are no MUXF7/MUXF8 cells at all, andA5FFstill fails: the new Yosys places 2 of 8 that way, the old one 0 of 8. Any change to the netlist reshuffles the winning seeds. I found nothing that made the failure go away.Failure modes across the 32 new-default attempts:
SLICE_…/A5FFvalid_wires_for_net.count(w)atcommon/router1.cc:331Failed to find a route for arc 21 of net $PACKER_VCC_NETThe assertion is a nextpnr crash, not a placement the tool rejects. Reproducing it needs the image digest, this design and
--seed 18. I have not reported it upstream.Fix: #861. It widens the search from 8 seeds to 32, and the search still stops at the first clean seed. If the outcome is deterministic for a fixed image and seed, it should print
seed=11and pay about ten 7-second failures first. Run 37210095288 checks that prediction.Pinning the old digest was the other option. It would buy back one lucky seed (seed 1) rather than a margin, so I did not take it.
Not measured: whether other ax7203 workflows are in the same lottery, and the clean rate with the old image beyond seed 8.
ci(fpga): gf10-sub experiment round three, --placer heap (#856)
ci(fpga): place gf10-sub with HeAP instead of searching SA seeds
gHashTag commentedon Oct 4, 2026
Round three: the placer, not the synth image
The cause. The A5FF signature in this issue is openXC7/nextpnr-xilinx#162:
post-placement validity check failed for Bel 'SLICE_…/A5FF' (no cell). That issue diagnoses it as an SA-placer bug on xc7.--placer sacan leave a tile with its OUTMUX claimed twice, by O5 and by a 5FF's Q.cavearr closed #162 on 2026-09-24 because that nextpnr line is archived. I should have searched for the error text before the first experiment, not after two rounds.
Round three (run 37210944365) used the same Verilog, xdc and command line as before and only changed
--placer sato--placer heap:sha256:35c91073(Yosys 0.68)sha256:eced1cdd(Yosys 0.62)What this changes in #861. The PR now switches this workflow to
--placer heapand keeps the 8-seed search as a margin. The 32-seed SA search it first proposed did work (run 37210095288 printedseed=11, as predicted), but it treated the bug as a lottery.What it does not change. 32 of the 61 nextpnr workflows on main pass
--placer sa. Some of them are measurements, where the placer is part of the recorded configuration; commits 5f571f9, d6e6978 and 30a230b show the placer/router pair moving Fmax by up to 4.3x. Those cannot be switched by a sweep, and the audit gets its own issue.Not measured.
router1.cc:331assertion from seeds 18 and 19 can happen under HeAP; it did not in these 24 runs.ci(fpga): A/B the openxc7 image for gf10-sub (experiment for #856)
ci(fpga): gf10-sub experiment round two, -nowidelut and seeds 9-40 (#856
ci(fpga): gf10-sub experiment round three, --placer heap (#856)