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
@hansfbaier, this is the first run of the parity gate we discussed: your himbaechel tree and nextpnr-xilinx 0.9.3, same netlists, same XDC, same prjxray-db, same yosys, same fasm2frames/xc7frames2bit, on our build server. Numbers first, reading after. @jrrk2 in copy because half of it answers questions from your handover doc.
Setup (one factor: the P&R binary)
himbaechel: openXC7/nextpnr branch himbaechel-xilinx-porting at 2212c004 (current tip), submodule meta a4af910c. Built with your demos.yml recipe (-DARCH=himbaechel -DHIMBAECHEL_UARCH=xilinx -DHIMBAECHEL_XILINX_DEVICES='xc7a50t;xc7s50'): 89 s, 1.8 GB peak RSS, zero errors, zero local patches.archcheck (--test) green on both dies.
nextpnr-xilinx: the released 0.9.3 package (68aeeb39, apio release 2026-08-20), binary taken from inside the tarball.
prjxray-db ab1fc60 (the package's copy; both arms read the same directory — verified by inode), yosys 0.63+173, --router router2 in both arms (himbaechel's default is default, so it is passed explicitly).
Our regression suite (22 designs: fabric property tests, congestion pair, BRAM/DSP/LUTRAM/SRL/PLL/tristate, four board demos) runs on himbaechel without changing a line: a 40-line shim translates --chipdb F → --chipdb F --device <part>-1, --xdc/--fasm → -o xdc=/-o fasm=, and --post-route → --report (upstream's report carries the same fmax/utilisation fields). Happy to send the shim; it is almost identical to your .github/scripts/nextpnr-xilinx-shim.sh plus that last translation.
Chipdb
0.9.3 (per package footprint)
himbaechel (per die)
the 6 footprints on the xc7a50t die (a35t ×4, a50t ×2)
6 bins, 558.0 MB
1 bin, 29.6 MB (18.9×)
xc7s50csga324
92.4 MB
28.9 MB
generation (xilinx_gen.py + bbasm)
—
32 s, 1.8 GB RSS, byte-reproducible
Suite, xc7a35tcsg324, tier ≤2 (22 designs)
19 of 20 comparable designs reach a bitstream on himbaechel (fasm2frames accepted every emitted feature, 0 warnings; xc7frames2bit produced 19 .bit). The other two: demo-basys3 fails in both arms (our runner forces --part, its XDC is for cpg236 — artefact), demo-genesys2 is expected-fail in both (kintex7 not packaged).
LUT/FF utilisation identical to 0.9.3 in 19 of 20; the one delta is carry-const-di (20 → 22 LUTs). BRAM and DSP identical everywhere.
The only himbaechel-specific failure is bram, and it is policy, not coverage (next section).
Fmax: median −6.7 %, 14 of 17 within ±15 %, but see "fmax is not comparable" below.
Runtime: himbaechel 3-4× faster on the small designs (1.1-1.8 s vs 3.7-4.6 s), slower on the two congestion designs (29.7 vs 22.3 s; 56.5 vs 31.9 s).
Spartan-7 (xc7s50csga324, carry/SRL tests): 5/5 complete in both arms, same utilisation.
LiteX DDR (litex-ddr-arty-s7, xc7s50, main and deep-hierarchy variants)
Both complete on himbaechel with the full DDR3 PHY — 45 OSERDESE2, 16 ISERDESE2, 16 IDELAYE2, IDELAYCTRL, PLLE2_ADV, 38 RAMB18E1 + 3 RAMB36E1, 4 DSP48E1, 260 CARRY4, 138 SELMUX2_1 in the deep variant — with the same utilisation as 0.9.3 (FF 3590/3590, LUT 7373 vs 7349), and fasm2frames + xc7frames2bit produce a bitstream. Jonathan's layer-1 blockers did not fire on these parts (no GT, no HP-bank pins in these designs), and the SELMUX2_1 placement that exploded on an empty vx485t places without incident here.
himbaechel also derives the clock constraints through the PLL natively (Derived VCO frequency 1600.0 MHz, 100/200/400 MHz outputs) — the thing our #156 just added to nextpnr-xilinx — so #156 does not need porting.
Control leg, one factor (no create_clock in either arm, --freq 100 in both, no derived constraints in either): critical clock main_crg_clkout_buf0 66.9 MHz (0.9.3) vs 97.3 MHz (himbaechel); deep variant sys_clk 73.0 vs 93.5 MHz. Read with the caveat below.
The one blocker: hold violations are fatal
himbaechel runs hold analysis with the chipdb's single DEFAULT speed grade and combinational-only cell timing, and treats every violation as an error: bram and both LiteX builds exit 1 (ERROR: Hold/min time violation …) after writing the FASM. With --timing-allow-fail the FASM is byte-identical and the bitstream is produced. 0.9.3 does not analyse hold at all. This is a product decision more than a port bug: as long as the hold model is the fiction Jonathan describes for parts without their own timing, a fatal hold check rejects designs that are fine. Question for you: should the xilinx uarch default to warning here until the model deserves to be trusted?
Where the two trees actually differ (FASM dialect, litex-main as the richest design)
No FASM is identical between arms (0 of 25) — expected, placements differ. But separating site-configuration features from routing pips and folding tile types to their family, the configuration vocabulary agrees at ~95 % (287 common names, 16 only-0.9.3, 15 only-himbaechel in litex-main). The delta is four nameable things:
BRAM configuration bits himbaechel does not emit: RAMB18.READ_WIDTH_{A,B}_1, WRITE_WIDTH_{A,B}_1, RSTREG_PRIORITY_{A,B}_RSTREG — 179 features in litex-main (e.g. RSTREG_PRIORITY_* 88 → 0, WRITE_WIDTH_B_1 44 → 5, READ_WIDTH_B_1 40 → 7). This is your WP2.3 ("SDP BRAM opposite-port width + 36-wide marker + ZINV_REGCLK*"), which 05-porting-plan.md lists as not done — the plan is accurate. It is the most concrete bitstream-parity item and the one I would fix first.
5FF packing: himbaechel uses the 5FF slot and O5 heavily (*5FFMUX.IN_A 0 → 731, OUTMUX.O5 ~1200) where 0.9.3 uses the main flop and OUTMUX.CY/F7. Placement choice, not a dialect gap; it explains most of the "only-himbaechel" lines.
ILOGIC defaults: 0.9.3 emits IOI3.ILOGIC.IDELMUXE3.P1 (3, litex) and ISERDES.MODE.MASTER / NUM_CE.N1 (suite); himbaechel leaves them unwritten. With 16 IDELAYE2 in use in LiteX this is the delta most worth checking at bit level.
fmax is not comparable between the trees (yet)
constant — one LUT, one FF, identical utilisation, same netlist and router — reports 2865 MHz on 0.9.3 and 1044 MHz on himbaechel. That is not placement; it is two delay models measuring the same circuit. So across trees only rc, utilisation, feature counts and FASM are comparable; fmax is meaningful only against each tree's own baseline. Any QoR claim between the two needs a board or a common analyser. We will record per-tree baselines for the gate.
What we have NOT verified
Nobody has programmed a board with a himbaechel bitstream yet. Whether the missing BRAM/ILOGIC bits are harmless silicon defaults or break the design is unknown; next on our side is a bit2fasm round trip on a himbaechel bitstream, and a board test (Jonathan offered an Artix-50 board; we will send a .bit + design once we know the exact part/board).
Jonathan's Virtex-7 numbers (78/754 MB, 14.65 GB, the four layer-1 blockers) are quoted, not reproduced; they are a different family.
Offer
The gate is running: your binary, our suite, one overlay, ~8 minutes per arm for the whole table, plus LiteX. I can wire it as a nightly on our server and post the table here (or wherever you prefer) on every push to the branch, and record per-tree baselines so metric drift on either side is visible. Three questions to point it right: the hold default above; whether WP2.3 is where you want us to look next (we can bring the missing BRAM features with the litex-main measurements as the test); and whether #161 (LUT route-through) should target this tree — it already has the is_pseudo arcs data in the db, the question is what the uarch does with them.
Everything here is reproducible from ~/data/openxc7/himba/README-0013.md on our server; scripts and the raw reports are available on request.
@hansfbaier, this is the first run of the parity gate we discussed: your himbaechel tree and nextpnr-xilinx 0.9.3, same netlists, same XDC, same prjxray-db, same yosys, same
fasm2frames/xc7frames2bit, on our build server. Numbers first, reading after. @jrrk2 in copy because half of it answers questions from your handover doc.Setup (one factor: the P&R binary)
openXC7/nextpnrbranchhimbaechel-xilinx-portingat2212c004(current tip), submodule metaa4af910c. Built with yourdemos.ymlrecipe (-DARCH=himbaechel -DHIMBAECHEL_UARCH=xilinx -DHIMBAECHEL_XILINX_DEVICES='xc7a50t;xc7s50'): 89 s, 1.8 GB peak RSS, zero errors, zero local patches.archcheck(--test) green on both dies.68aeeb39, apio release 2026-08-20), binary taken from inside the tarball.ab1fc60(the package's copy; both arms read the same directory — verified by inode), yosys 0.63+173,--router router2in both arms (himbaechel's default isdefault, so it is passed explicitly).--chipdb F→--chipdb F --device <part>-1,--xdc/--fasm→-o xdc=/-o fasm=, and--post-route→--report(upstream's report carries the same fmax/utilisation fields). Happy to send the shim; it is almost identical to your.github/scripts/nextpnr-xilinx-shim.shplus that last translation.Chipdb
xilinx_gen.py+bbasm)Suite, xc7a35tcsg324, tier ≤2 (22 designs)
fasm2framesaccepted every emitted feature, 0 warnings;xc7frames2bitproduced 19.bit). The other two:demo-basys3fails in both arms (our runner forces--part, its XDC is for cpg236 — artefact),demo-genesys2is expected-fail in both (kintex7 not packaged).carry-const-di(20 → 22 LUTs). BRAM and DSP identical everywhere.bram, and it is policy, not coverage (next section).Spartan-7 (xc7s50csga324, carry/SRL tests): 5/5 complete in both arms, same utilisation.
LiteX DDR (litex-ddr-arty-s7, xc7s50, main and deep-hierarchy variants)
Both complete on himbaechel with the full DDR3 PHY — 45 OSERDESE2, 16 ISERDESE2, 16 IDELAYE2, IDELAYCTRL, PLLE2_ADV, 38 RAMB18E1 + 3 RAMB36E1, 4 DSP48E1, 260 CARRY4, 138 SELMUX2_1 in the deep variant — with the same utilisation as 0.9.3 (FF 3590/3590, LUT 7373 vs 7349), and
fasm2frames+xc7frames2bitproduce a bitstream. Jonathan's layer-1 blockers did not fire on these parts (no GT, no HP-bank pins in these designs), and theSELMUX2_1placement that exploded on an empty vx485t places without incident here.himbaechel also derives the clock constraints through the PLL natively (
Derived VCO frequency 1600.0 MHz, 100/200/400 MHz outputs) — the thing our #156 just added to nextpnr-xilinx — so #156 does not need porting.Control leg, one factor (no
create_clockin either arm,--freq 100in both, no derived constraints in either): critical clockmain_crg_clkout_buf066.9 MHz (0.9.3) vs 97.3 MHz (himbaechel); deep variantsys_clk73.0 vs 93.5 MHz. Read with the caveat below.The one blocker: hold violations are fatal
himbaechel runs hold analysis with the chipdb's single
DEFAULTspeed grade and combinational-only cell timing, and treats every violation as an error:bramand both LiteX builds exit 1 (ERROR: Hold/min time violation …) after writing the FASM. With--timing-allow-failthe FASM is byte-identical and the bitstream is produced. 0.9.3 does not analyse hold at all. This is a product decision more than a port bug: as long as the hold model is the fiction Jonathan describes for parts without their own timing, a fatal hold check rejects designs that are fine. Question for you: should the xilinx uarch default to warning here until the model deserves to be trusted?Where the two trees actually differ (FASM dialect, litex-main as the richest design)
No FASM is identical between arms (0 of 25) — expected, placements differ. But separating site-configuration features from routing pips and folding tile types to their family, the configuration vocabulary agrees at ~95 % (287 common names, 16 only-0.9.3, 15 only-himbaechel in litex-main). The delta is four nameable things:
RAMB18.READ_WIDTH_{A,B}_1,WRITE_WIDTH_{A,B}_1,RSTREG_PRIORITY_{A,B}_RSTREG— 179 features in litex-main (e.g.RSTREG_PRIORITY_*88 → 0,WRITE_WIDTH_B_144 → 5,READ_WIDTH_B_140 → 7). This is your WP2.3 ("SDP BRAM opposite-port width + 36-wide marker + ZINV_REGCLK*"), which05-porting-plan.mdlists as not done — the plan is accurate. It is the most concrete bitstream-parity item and the one I would fix first.PRECYINIT.C0/C1(88 in litex-main), himbaechel feeds the constant throughPRECYINIT.AX(131). Both legal; different packing choice. (Related: the only utilisation delta,carry-const-di20 → 22 LUTs, is this class — see Carry-O relocation leaves chain-root bit unrelocatable when CIN is a constant #163 / xc7: relocate CARRY4 O fabric fanout at chain root with constant CIN #164 for what the fork does at the chain root.)*5FFMUX.IN_A0 → 731,OUTMUX.O5~1200) where 0.9.3 uses the main flop andOUTMUX.CY/F7. Placement choice, not a dialect gap; it explains most of the "only-himbaechel" lines.IOI3.ILOGIC.IDELMUXE3.P1(3, litex) andISERDES.MODE.MASTER/NUM_CE.N1(suite); himbaechel leaves them unwritten. With 16 IDELAYE2 in use in LiteX this is the delta most worth checking at bit level.fmax is not comparable between the trees (yet)
constant— one LUT, one FF, identical utilisation, same netlist and router — reports 2865 MHz on 0.9.3 and 1044 MHz on himbaechel. That is not placement; it is two delay models measuring the same circuit. So across trees only rc, utilisation, feature counts and FASM are comparable; fmax is meaningful only against each tree's own baseline. Any QoR claim between the two needs a board or a common analyser. We will record per-tree baselines for the gate.What we have NOT verified
bit2fasmround trip on a himbaechel bitstream, and a board test (Jonathan offered an Artix-50 board; we will send a.bit+ design once we know the exact part/board).Offer
The gate is running: your binary, our suite, one overlay, ~8 minutes per arm for the whole table, plus LiteX. I can wire it as a nightly on our server and post the table here (or wherever you prefer) on every push to the branch, and record per-tree baselines so metric drift on either side is visible. Three questions to point it right: the hold default above; whether WP2.3 is where you want us to look next (we can bring the missing BRAM features with the litex-main measurements as the test); and whether #161 (LUT route-through) should target this tree — it already has the
is_pseudoarcs data in the db, the question is what the uarch does with them.Everything here is reproducible from
~/data/openxc7/himba/README-0013.mdon our server; scripts and the raw reports are available on request.