9.6 KiB
Segbit fixes carried in this database
Substantive corrections this virtex7 DB carries over a stock prjxray fuzz. These are what make the fully-open VC707 flow produce correct bitstreams. (Commit hashes refer to the prjxray fuzzer-code repo that produced them.)
CLB OUTMUX.O5 duplicate → incomplete encoding (6fd1d26)
The "telegraph bug." Duplicate OUTMUX.O5 segbit definitions; last-wins
picked the incomplete one (missing the shared xMUX-enable bit) → output muxes
encoded as 0x55. Fix: dedupe keeping the complete definition. This was
the root cause of long-chased open-flow output corruption.
IOB18 OLOGIC SING-row segbits (afb49cc, fuzzer 036-iob18-ologic-sing)
SING-row IOB18 sites had no OLOGIC segbits. Added via a dedicated sub-fuzzer.
LIOI / RIOI OLOGIC inversion segbits (local fuzz, superset)
segbits_lioi*.db / segbits_rioi_sing.db gained the OLOGIC_Y*.IS_*_INVERTED
features (IS_CLKDIV_INVERTED, IS_D1..D4_INVERTED, etc.) — +88 lines per
file over the last release (216 vs 128). Plus mask_lioi*.db and
tileconn.json. This is why the build-area copy is a strict superset of the
released DB.
LIOB18 / RIOB18 IOB_Y1 IN_ONLY (09588f3)
Dropped spurious bits !38_32 !38_34 from the Y1 (slave-site) input-only
encoding, fixing left-HP single-ended LVCMOS inputs.
Tilegrid SING propagation for HP-only LIOB18 / LIOI columns (1c63972, 1574e9c)
Propagated SING-row bits and added the iob18_sing sub-fuzzer so HP-only
columns get correct SING-row geometry.
Top-SING tile alias start_offset (OLOGIC/IOB "invalid word address")
tilegrid.json: the top SING-row tiles (LIOI_SING/RIOI_SING/LIOB18_SING/
RIOB18_SING at bits.CLB_IO_CLK.offset == 99) had alias start_offset: 0,
but it must be 2 (matching the bottom SING tiles at offset 0). With
start_offset 0 the aliased regular OLOGIC_Y0 / IOB features (regular words
2–3) mapped to absolute frame words 101–102, which don't exist — fasm2frames
emitted invalid word address and silently dropped them (e.g. VC707 counter
LED on LIOI_SING_X82Y51.OLOGIC_Y0.OMUX.D1). With start_offset 2 the
effective offset becomes 99-2=97, so regular word 3 → abs 100, word 2 → abs
99 — landing in the tile's real 2-word window.
Confirmed empirically: fuzzer 036-iob18-ologic-sing (re-run at N=50) places
OLOGIC_Y0.OMUX.D1 at abs word 100, exactly what start_offset 2 produces.
28 tiles fixed (7 each of LIOI/RIOI/LIOB18/RIOB18_SING). (The dedicated
segbits_*_sing.db are NOT consulted for aliased tiles, so this is a tilegrid
fix, not a segbits one.) Follow-up: fix the generator (fuzzers/005-tilegrid)
so a regenerated tilegrid doesn't reintroduce start_offset 0.
Known remaining gap (worked around downstream, not yet fixed in DB)
LVCMOS18 single-ended input on certain HP-bank sites (e.g. AU33) is missing
segbit bit_0042101c_063_18 and sets a spurious IBUF_HP_BANK_GLUE — the
rx-distortion bug. Currently patched at the frame level in the demo
(uartram/patch_rx_iob.py); a proper fix belongs here as a segbit correction.
2026-06-10: SING-tile OLOGIC route-thru features are bit-free (ppips)
ppips_{l,r}ioi_sing.db: added *IOI_SING.OLOGIC_Y{0,1}.{OQUSED, OMUX.D1, OSERDES.DATA_RATE_TQ.BUF} always. The SING tilegrid entries alias into the
regular LIOI/RIOI segbits with start_offset 2, so these route-thru features
resolved to WRONG physical bits and poisoned the pad output path (HW symptom:
led[4]/AR35 = IO_0_VRN_13 on LIOI_SING_X82Y51 stuck high in every open-flow
VC707 build, confirmed in both picosoc and johnson). Raw-frame diff against
a HW-working Vivado golden shows Vivado sets NO OLOGIC config bits in the
SING window — the D1->OQ pass-through is bit-free there — while on regular
LIOI tiles it sets the same OQUSED/OMUX.D1 bits we do. Declaring the
features as pseudo-pips makes fasm2frames emit no bits for them
(TileSegbitsAlias.feature_to_bits short-circuits on the tile's own ppips).
RIOI_SING entries added by symmetry (same alias structure), not HW-verified.
Suspected same misalias issue for SING ILOGIC input features (not yet seen).
2026-06-11: targeted solve of 3 HCLK_CMT_L CK_IN <- MUX_CLK segbits
Added to segbits_hclk_cmt_l.db (3 bits each):
CK_IN1 <- MUX_CLK_8: 28_183 29_152 29_155
CK_IN0 <- MUX_CLK_7: 26_152 26_154 29_182
CK_IN10 <- MUX_CLK_5: 29_181 29_203 29_206
Method: one Vivado specimen per pip (pipsolve/ in v7-johnson-demo) with
FIXED_ROUTE forced through the pip; residual = raw window bits minus the
bit2fasm->fasm2frames re-encoding. KEY: these "MUX_CLK_" wires are the
GT MGT clock spine (node of HCLK_CMT_L_X305Y26/MUX_CLK_8 is
GTX_COMMON_X394Y23/GTXE2_COMMON_MGT_CLK4; MUX_CLK_7=MGT_CLK3<-TXOUTCLK_1,
MUX_CLK_5=MGT_CLK1<-RXOUTCLK_1) - which is why the 045 fuzzer (no GT in
specimens) could never solve them. Each entry's 3rd bit (~_181..183) looks
like a per-lane spine-tap enable shared with other consumers of the same
MUX_CLK lane; included in the pip entry since lanes are single-consumer in
practice. Remaining family members (other CK_IN x MUX_CLK combos) still
unsolved - a proper fuzz needs GT-driven specimens.
2026-06-11: BRAM_L_X114Y0 tilegrid entry was empty
xc7vx485t/tilegrid.json: BRAM_L_X114Y0 had bits: {} (tilegrid fuzzer
gap at the column bottom), silently dropping every feature for any BRAM
placed there. Filled from the column pattern (same baseaddrs as
BRAM_L_X114Y5/Y10, offset 0): BLOCK_RAM 0x00C20500/128f/10w,
CLB_IO_CLK 0x00423900/28f/10w. Found by the dcp2fasm bit-equivalence
campaign (ethsoc Vivado DCP -> fasm -> frames vs golden bit).
2026-06-11: SING IOB tiles - prefer own segbits db over broken alias
prjxray/grid.py get_tile_segbits_at_tilename(): tiles whose tilegrid
bits carry an alias (LIOB18_SING etc.) were ALWAYS resolved through
TileSegbitsAlias, but the virtex7 SING alias metadata is wrong (sites
map names IOB33_* on an IOB18 part; start_offset arithmetic places the
LIOB18-db Y1 bits 2 words below the SING window) -- features for e.g.
led[4]'s LIOB18_SING_X81Y51 silently CORRUPTED the neighbouring
LIOB18_X81Y49 frames (6 stray bits, found by the bit-equivalence
ledger). Fix: when the tile type has its own segbits db
(segbits_liob18_sing.db exists), use it directly; alias only as
fallback. Applied to deps/prjxray and $HOME/prjxray.
2026-06-17: kintex7 transplant removal — IOI ILOGIC + ISERDES re-fuzzed
The LIOI/RIOI segbits carried features whose origin_info recorded fuzzers
that CANNOT run on this HP-only part (IOB33/HR-targeted), i.e. kintex7
transplants. Audited via the per-bit origin: provenance; retired so far:
035-iob-ilogic(114 bits): replaced by new fuzzer fuzzers/035-iob18-ilogic (IOB18 sites, L+R, tag-grouped enums). Real ILOGIC/IFF config measured on both sides. IMPORTANT:ILOGIC_Y{0,1}.ZINV_Dhas NO virtex7 frame bit (exhaustive frame search = zero correlation; kintex7/artix7 don't carry it as a bit either) — the transplant was wrong, not just incomplete. Now declared bit-free via<tile>.ILOGIC_Y{0,1}.ZINV_D alwaysin the IOI ppips.035b-iob-iserdes(156 bits): replaced by fuzzers/035b-iob18-iserdes (IOB18 ISERDESE2, L+R). Real ISERDES taxonomy (MEMORY/NETWORKING/OVERSAMPLE x rate x width, MODE, DYN_*, IN_USE).
Method: utils/strip_transplant.py drops bits by origin from both the .db and
.origin_info.db, then the new fuzzer's make pushdb merges real L+R data
(segmaker's IOI. prefix -> mergedb rewrites per side). Validated by rebuilding
the open-flow picosoc: ILOGIC/ISERDES warnings gone, bit configures on VC707.
Still transplanted (to do): f4pga (768 bits, lioi left-side IOI pips — needs
037-iob18-pips driven to cover the left column) and hand-copied-from-LIOB18
(5 bits, LIOB18_SING IOB_Y1 DRIVE/SLEW/PULLTYPE/STEPDOWN + OBUF_HP_BANK_GLUE).
2026-06-18: SING IOB18 — hand-copied transplant replaced by validated mirror
LIOB18_SING / RIOB18_SING IOB18 carried 5 hand-copied (origin hand-copied-from-LIOB18), partly mis-addressed entries. Built fuzzers/030-iob18-sing (OBUF/IBUF/unused mix on the ~28 SING IOB18 sites) and confirmed by real measurement that the SING IOB18 DRIVE/SLEW/PULLTYPE/IN bits are BIT-IDENTICAL to the regular LIOB18 (e.g. Y1 DRIVE 38_32/38_34/39_23/39_55).
Finding: nextpnr emits the regular LIOB18 feature names for SING tiles, and the ~28 rare SING sites cannot make segmatch resolve the multi-bit DRIVE enum (OUT stays at any N). So the SING IOB db must mirror LIOB18's names exactly; it cannot be independently fuzzed into a nextpnr-consumable form. Resolution: replaced the hand-copy with a COMPLETE, correct mirror of every LIOB18/RIOB18 IOB_Y0/Y1 feature (origin liob18-arch-mirror), excluding STEPDOWN whose !00_127 (frame 0) bit overflows the SING tilegrid word window (word 102) and corrupts neighbours -- left as a tolerated "not found" rather than the corrupting "invalid word address". picosoc now builds with only that one benign STEPDOWN warning. This is a same-part architectural mirror, NOT a kintex7 transplant.
SLICEM DOUTMUX.MC31 spurious A5FFMUX bit (2026-07-02)
CLBLM_{L,R}.SLICEM_X0.DOUTMUX.MC31 carried a spurious 30_10 — that bit is
A5FFMUX.IN_B (fuzzer-specimen contamination). A real Vivado SRL cascade
(SRLC32E chain crossing a slice: A-LUT MC31 -> DMUX -> fabric -> next slice's
DI pin) sets only {30_52, 30_57} in the DOUTMUX group, so bit2fasm decoded NO
DOUTMUX feature and the cascade link was silently dropped. Fix: remove 30_10;
the remaining !30_51 30_52 !30_56 30_57 is distinct from every other DOUTMUX
leg. Found via the bit2verilog srl differential test (160-deep SRL, d3 diverged
at cycle 129 = the first value needing the cross-slice hop).