himbaechel/xilinx: fix MMCM loop filter programming

The MMCM fasm writer put the 10-bit BANDWIDTH loop-filter word into
FILTREG1_RESERVED[11:0] and wrote a hardcoded 0x3d4 into TABLE[9:0].
prjxray's TABLE[9:0] is the loop-filter table word; with the filter
word misplaced the MMCM analog loop is misconfigured and never
asserts LOCKED on hardware (clock outputs stay dead).

Swap them: TABLE[9:0] gets filter_lookup[CLKFBOUT_MULT-1],
FILTREG1_RESERVED[11:0] gets the constant 0x8, matching Vivado
bitstreams for the same configurations.

Hardware-validated on xc7a100t (QMTech Wukong): MMCM-derived clocks
lock and run; the same designs never asserted LOCKED before this
change.

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
Joris van Zwieten
2026-10-01 14:43:02 +02:00
committed by myrtle
co-authored by Claude Fable 5
parent 408022fe22
commit 0c71b06aa3
+3 -2
View File
@@ -1691,14 +1691,15 @@ struct FasmBackend
filter_lookup = Xc7MMCM::filter_lookup_high;
else
filter_lookup = Xc7MMCM::filter_lookup_optimized;
write_int_vector("FILTREG1_RESERVED[11:0]", filter_lookup[clkfbout_mult - 1], 12);
// TABLE holds the loop-filter word; FILTREG1_RESERVED is a constant 0x8 (matches Vivado)
write_int_vector("FILTREG1_RESERVED[11:0]", 0x8, 12);
// 0x9900 enables fractional counters
// only int counters would be 0x1 << 8
// 0xffff enables everything, I suppose, this is what is used in xap888
write_int_vector("POWER_REG_POWER_REG_POWER_REG[15:0]", 0xffff, 16);
write_bit("LOCKREG3_RESERVED[0]");
write_int_vector("TABLE[9:0]", 0x3d4, 10);
write_int_vector("TABLE[9:0]", filter_lookup[clkfbout_mult - 1], 10);
pop(2);
}
void write_dsp_cell(CellInfo *ci)