The raw XPLA3 bitstream is a three-dimensional array of bits. The bitstream is arranged into:
fb_rows * 52 + 2
rows
2 planes
bs_cols
columns
The fb_rows
and bs_cols
variables are per-device and can be obtained from the database.
The bitstream is roughly divided into areas as follows:
the last row is used to store the UES (user electronic signature)
the second to last row is used to store the READ_PROT
and ISP_DISABLE
bits, which should generally be programmed last in the sequence
all other rows are used to store (mostly) per-FB data, with 52 bitstream rows per FB row
each FB column has three ranges of columns, the start of each range is stored in the database:
IMUX bits (includes per-FB input multiplexers and the per-column ZIA_GCLK*_ENABLE
bits)
PT bits (includes product term bits and PLA sum term bits)
MC bits (includes per-MC config bits and misc per-FB config bits; also includes global bits configuring UCT muxes)
XPLA3 bitstreams are commonly stored in JED files. Bits in JED files are stored in a logical order completely unrelated to the physical structure of a bitstream. The order of bits in a JED file is as follows:
per-FB bits, for every FB i
in order:
IMUX bits, for every j < 40
:
every bit of FB[i].IM[j].MUX
in order
for every product term j < 48
, in order:
for every FB input k < 40
, in order:
FB[i].PT[i].IM[k].P
FB[i].PT[i].IM[k].N
for every feedback term k < 8
, in order:
for every product term j < 48
, in order:
for every macrocell k < 16
, in order:
misc per-FB bits, in order given below
for every macrocell with an IOB, in order (which macrocells have a IOB can be checked in the database io_mcs
field):
for every macrocell without an IOB, in order:
all global bits, in order given in the per-device database
Note that the UES bits and read protection bit are not included in the JED file, and must be provided out of band.
The size of every FB[i].IM[j].MUX
fuse set in the device is the same, and is given by the database imux_width
field. The position of bit k
of FB[i].IM[j].MUX
in the fuse array can be computed as follows:
row is:
if j < 20
: fb_row(i) * 52 + 2 + j
if j >= 20
: fb_row(i) * 52 + 2 + j + 8
plane is: (i & 1) ^ 1
column is fb_cols[fb_col(i)].imux_col + imux_width - 1 - k
The position of FB[i].PT[j].IM[k].P
and FB[i].PT[j].IM[k].N
can be computed as follows:
row is:
if k < 20
: fb_row(i) * 52 + 2 + k
if k >= 20
: fb_row(i) * 52 + 2 + k + 8
plane is 0
for .P
bit, 1
for .N
bit
column is:
if i
is even: fb_cols[fb_col(i)].pt_col + j
if i
is odd: fb_cols[fb_col(i)].pt_col + 95 - j
The position of FB[i].PT[j].FBN[k]
can be computed as follows:
row is fb_row(i) * 52 + dr
, where dr
is given in the table below
plane is given in the table below
column is:
if i
is even: fb_cols[fb_col(i)].pt_col + j
if i
is odd: fb_cols[fb_col(i)].pt_col + 95 - j
k
dr
plane
0 0 1
1 0 0
2 1 1
3 1 0
4 50 0
5 50 1
6 51 0
7 51 1
The position of FB[i].MC[j].SUM.PT[k]
can be computed as follows:
row is fb_row(i) * 52 + 22 + (j // 2)
plane is 1 - (j % 2)
column is:
if i
is even: fb_cols[fb_col(i)].pt_col + k
if i
is odd: fb_cols[fb_col(i)].pt_col + 95 - k
The per-MC bits are listed in the table below. The per-MC coordinates should be translated to global coordinates as follows:
row is:
if mc < 8
: fb_row(fb) * 52 + mc * 3 + table_row
if mc >= 8
: fb_row(fb) * 52 + 4 + mc * 3 + table_row
plane is: table_plane
column is:
if fb
is even: fb_cols[fb_col(fb)].mc_col + table_column
if fb
is odd: fb_cols[fb_col(fb)].mc_col + 9 - table_column
CLK_INV
1.1.4
REG_D_IREG
0.1.0
REG_D_SHIFT
0.1.3
non-inverted
[0]
CLK_MUX
1.1.2
1.1.1
1.1.0
FCLK0
0
0
0
FCLK1
0
0
1
PT
0
1
0
LCT4
0
1
1
LCT5
1
0
0
LCT6
1
0
1
LCT7
1
1
0
UCT3
1
1
1
IOB_SLEW
0.0.0
FAST
0
SLOW
1
IOB_ZIA_MUX
0.1.2
REG
0
IBUF
1
LUT
1.0.3
1.0.2
1.0.1
1.0.0
non-inverted
[3]
[2]
[1]
[0]
MC_IOB_MUX
1.0.4
MC_ZIA_MUX
0.2.3
REG
0
LUT
1
OE_MUX
0.0.3
0.0.2
0.0.1
GND
0
0
0
LCT0
0
0
1
LCT1
0
1
0
LCT2
0
1
1
LCT6
1
0
0
UCT0
1
0
1
VCC
1
1
0
PULLUP
1
1
1
REG_D_SHIFT_DIR
0.1.1
UP
0
DOWN
1
REG_MODE
1.2.4
1.2.3
DFF
0
0
TFF
0
1
LATCH
1
0
DFFCE
1
1
RST_MUX
1.2.2
1.2.1
1.2.0
LCT0
0
0
0
LCT1
0
0
1
LCT2
0
1
0
LCT3
0
1
1
LCT4
1
0
0
LCT5
1
0
1
UCT1
1
1
0
GND
1
1
1
SET_MUX
0.2.2
0.2.1
0.2.0
LCT0
0
0
0
LCT1
0
0
1
LCT2
0
1
0
LCT3
0
1
1
LCT4
1
0
0
LCT5
1
0
1
UCT2
1
1
0
GND
1
1
1
The per-FB bits are listed in the table below. The per-FB coordinates should be translated to global coordinates as follows:
row is: fb_row(fb) * 52 + 24 + table_row
plane is: table_plane
column is:
if fb
is even: fb_cols[fb_col(fb)].mc_col + table_column
if fb
is odd: fb_cols[fb_col(fb)].mc_col + 9 - table_column
FCLK_MUX
0.2.3
0.2.2
0.2.1
0.2.0
GCLK0_GCLK1
0
0
0
0
GCLK0_GCLK2
0
0
0
1
GCLK0_NONE
0
0
1
0
GCLK0_GCLK3
0
0
1
1
NONE_GCLK1
0
1
0
0
GCLK1_GCLK2
0
1
0
1
NONE
0
1
1
0
GCLK1_GCLK3
0
1
1
1
NONE_GCLK3
1
0
1
1
GCLK2_NONE
1
1
0
1
GCLK2_GCLK3
1
1
1
1
LCT0_INV
0.0.0
LCT1_INV
0.0.1
LCT2_INV
0.0.2
LCT3_INV
0.0.3
LCT4_INV
0.1.0
LCT5_INV
0.1.1
LCT6_INV
0.1.2
LCT7_INV
0.1.3
inverted
~[0]
The global bits are given by their raw position in the per-device database.