Summary
openXC7 emits a wrong bitstream from a correct netlist for SRL16E. This is
the same defect class as the already-recorded live-operand DSP48E1 failure
(tri-net#381). Both pass the wrong-part → ours Done 0 → done 1 acceptance
criterion while computing the wrong answer, and every tool upstream reports
success.
Status: [измерено] — reproduced on three QMTech XC7A200T-FGG676 dice.
Symptom
A design whose only unusual feature is a long shift register returns wrong values
from the fabric. Nothing upstream complains:
- yosys elaborates and maps without error;
- nextpnr places and routes and reports a valid Fmax;
fasm2frames and xc7frames2bit produce a bitstream of the correct size;
- the die accepts it — a wrong-part bitstream drives
Done to 0 and ours returns
it to 1, so the acceptance criterion passes;
- the JTAG readback register works and returns the design's magic word.
Only the computed values are wrong.
Reproduction
Design: a 593-bit shift register loaded 31 bits per BSCANE2 UPDATE, with 16
combinational truth tables reading scattered bits of it and reporting through
CAPTURE. The Verilog source is byte-identical between the two runs; only the
yosys flag differs.
| synthesis |
cells |
rows agreeing with the reference model |
synth_xilinx -family xc7 -nodsp |
44 SRL16E + 58 FDRE |
0 / 6 |
synth_xilinx -family xc7 -nodsp -nosrl |
0 SRL16E + 362 FDRE |
24 / 24 |
The reference model was independently confirmed against the emitted Verilog
under Icarus Verilog 13.0: 64 of 64 vectors exact. So the netlist is right and
the bitstream is not.
Toolchain: yosys 0.63, nextpnr-xilinx (openXC7 fork), prjxray-db artix7,
part xc7a200tfbg676-1, host macOS 25.3.0 / arm64.
How it was localised, for whoever hits this next
- Simulate the emitted Verilog against the model. If it passes, the defect
is below the netlist. This step alone would have saved three waves.
- Build a small bitstream that reports the suspect register's own contents.
Ours was 33 LUT and exonerated the transport in one pass.
- Read the cell list, not the LUT count.
SRL16E was visible in the stat
output for a whole wave before anyone looked past the first line.
Mitigation, already in the tree
synth_xilinx -nodsp -nosrl is now mandatory for this toolchain, and
t27c yostat exits 2 when SRL16E, SRLC32E or DSP48E1 appears in a
synthesis log, naming the flag to add:
!! KNOWN-BAD PRIMITIVES FOR openXC7 !!
44 shift-register LUT(s). The bitstream is wrong while the netlist is right.
Re-synthesise with `synth_xilinx -nosrl`.
A bitstream built from this netlist will load, pass the 0->1 acceptance
criterion, and compute the wrong answer.
Full write-up: docs/reports/OPENXC7-SRL16E-DEFECT.md.
What is NOT claimed
The root cause inside openXC7 is not identified — only that the defect is
reproducible, primitive-specific, and removed by suppressing inference of that
primitive. Whether it lies in nextpnr's SRL placement, in the fasm emission, or
in prjxray's database for SLICEM shift registers is not measured.
Wider lesson recorded
Done 0 → done 1 proves a bitstream was accepted by the configuration
engine, never that it implements the netlist. Pair it always with a
design-specific readback that a wrong build cannot produce.
Summary
openXC7 emits a wrong bitstream from a correct netlist for
SRL16E. This isthe same defect class as the already-recorded live-operand
DSP48E1failure(tri-net#381). Both pass the wrong-part → ours
Done 0 → done 1acceptancecriterion while computing the wrong answer, and every tool upstream reports
success.
Status: [измерено] — reproduced on three QMTech XC7A200T-FGG676 dice.
Symptom
A design whose only unusual feature is a long shift register returns wrong values
from the fabric. Nothing upstream complains:
fasm2framesandxc7frames2bitproduce a bitstream of the correct size;Doneto 0 and ours returnsit to 1, so the acceptance criterion passes;
Only the computed values are wrong.
Reproduction
Design: a 593-bit shift register loaded 31 bits per
BSCANE2UPDATE, with 16combinational truth tables reading scattered bits of it and reporting through
CAPTURE. The Verilog source is byte-identical between the two runs; only theyosys flag differs.
synth_xilinx -family xc7 -nodspsynth_xilinx -family xc7 -nodsp -nosrlThe reference model was independently confirmed against the emitted Verilog
under Icarus Verilog 13.0: 64 of 64 vectors exact. So the netlist is right and
the bitstream is not.
Toolchain: yosys 0.63, nextpnr-xilinx (openXC7 fork), prjxray-db
artix7,part
xc7a200tfbg676-1, host macOS 25.3.0 / arm64.How it was localised, for whoever hits this next
is below the netlist. This step alone would have saved three waves.
Ours was 33 LUT and exonerated the transport in one pass.
SRL16Ewas visible in thestatoutput for a whole wave before anyone looked past the first line.
Mitigation, already in the tree
synth_xilinx -nodsp -nosrlis now mandatory for this toolchain, andt27c yostatexits 2 whenSRL16E,SRLC32EorDSP48E1appears in asynthesis log, naming the flag to add:
Full write-up:
docs/reports/OPENXC7-SRL16E-DEFECT.md.What is NOT claimed
The root cause inside openXC7 is not identified — only that the defect is
reproducible, primitive-specific, and removed by suppressing inference of that
primitive. Whether it lies in nextpnr's SRL placement, in the fasm emission, or
in prjxray's database for SLICEM shift registers is not measured.
Wider lesson recorded
Done 0 → done 1proves a bitstream was accepted by the configurationengine, never that it implements the netlist. Pair it always with a
design-specific readback that a wrong build cannot produce.