Bitstream structure
The raw XPLA3 bitstream is a three-dimensional array of bits. The bitstream is arranged into:
fb_rows * 52 + 2
rows2 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
andISP_DISABLE
bits, which should generally be programmed last in the sequenceall 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)
JED structure
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:FB[i].PT[i].FBN[k]
for every product term
j < 48
, in order:for every macrocell
k < 16
, in order:FB[i].MC[k].SUM.PT[j]
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):misc per-MC bits, in order given below
for every macrocell without an IOB, in order:
misc per-MC bits, in order given below
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.
Fuses — IMUX bits
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
- ifj >= 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
Fuses — product and sum terms
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
- ifk >= 20
:fb_row(i) * 52 + 2 + k + 8
plane is
0
for.P
bit,1
for.N
bitcolumn is: - if
i
is even:fb_cols[fb_col(i)].pt_col + j
- ifi
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
, wheredr
is given in the table belowplane is given in the table below
column is: - if
i
is even:fb_cols[fb_col(i)].pt_col + j
- ifi
is odd:fb_cols[fb_col(i)].pt_col + 95 - j
|
|
|
---|---|---|
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
- ifi
is odd:fb_cols[fb_col(i)].pt_col + 95 - k
Fuses — macrocells
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
ifmc >= 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
- iffb
is odd:fb_cols[fb_col(fb)].mc_col + 9 - table_column
Row | Plane | Column | ||||
---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | ||
0 | 0 | X | X | X | X | - |
0 | 1 | X | X | X | X | X |
1 | 0 | X | X | X | X | - |
1 | 1 | X | X | X | X | X |
2 | 0 | X | X | X | X | - |
2 | 1 | X | X | X | X | X |
IOB_SLEW | [0, 0, 0] |
---|---|
FAST | 0 |
SLOW | 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 |
LUT | [0, 1, 3] | [0, 1, 2] | [0, 1, 1] | [0, 1, 0] |
---|---|---|---|---|
Non-inverted | [3] | [2] | [1] | [0] |
MC_IOB_MUX | [0, 1, 4] |
---|---|
REG | 0 |
LUT | 1 |
REG_D_IREG | [1, 0, 0] |
---|---|
Non-inverted | [0] |
REG_D_SHIFT_DIR | [1, 0, 1] |
---|---|
UP | 0 |
DOWN | 1 |
IOB_ZIA_MUX | [1, 0, 2] |
---|---|
REG | 0 |
IBUF | 1 |
REG_D_SHIFT | [1, 0, 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 |
CE_MUX | [1, 1, 3] |
---|---|
LCT4 | 0 |
PT | 1 |
CLK_INV | [1, 1, 4] |
---|---|
Non-inverted | [0] |
SET_MUX | [2, 0, 2] | [2, 0, 1] | [2, 0, 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 |
MC_ZIA_MUX | [2, 0, 3] |
---|---|
REG | 0 |
LUT | 1 |
RST_MUX | [2, 1, 2] | [2, 1, 1] | [2, 1, 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 |
REG_MODE | [2, 1, 4] | [2, 1, 3] |
---|---|---|
DFF | 0 | 0 |
TFF | 0 | 1 |
LATCH | 1 | 0 |
DFFCE | 1 | 1 |
JED mapping — macrocells with IOB
JED offset | Bit |
---|---|
0 | MC_IOB_MUX |
1 | LUT[0] |
2 | LUT[1] |
3 | LUT[2] |
4 | LUT[3] |
5 | IOB_SLEW |
6 | OE_MUX[0] |
7 | OE_MUX[1] |
8 | OE_MUX[2] |
9 | CE_MUX |
10 | CLK_INV |
11 | CLK_MUX[0] |
12 | CLK_MUX[1] |
13 | CLK_MUX[2] |
14 | REG_D_IREG |
15 | REG_D_SHIFT_DIR |
16 | REG_D_SHIFT |
17 | IOB_ZIA_MUX |
18 | RST_MUX[0] |
19 | RST_MUX[1] |
20 | RST_MUX[2] |
21 | SET_MUX[0] |
22 | SET_MUX[1] |
23 | SET_MUX[2] |
24 | REG_MODE[0] |
25 | REG_MODE[1] |
26 | MC_ZIA_MUX |
JED mapping — macrocells without IOB
JED offset | Bit |
---|---|
0 | LUT[0] |
1 | LUT[1] |
2 | LUT[2] |
3 | LUT[3] |
4 | CE_MUX |
5 | CLK_INV |
6 | CLK_MUX[0] |
7 | CLK_MUX[1] |
8 | CLK_MUX[2] |
9 | REG_D_IREG |
10 | REG_D_SHIFT_DIR |
11 | REG_D_SHIFT |
12 | RST_MUX[0] |
13 | RST_MUX[1] |
14 | RST_MUX[2] |
15 | SET_MUX[0] |
16 | SET_MUX[1] |
17 | SET_MUX[2] |
18 | REG_MODE[0] |
19 | REG_MODE[1] |
20 | MC_ZIA_MUX |
Fuses — FBs
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
- iffb
is odd:fb_cols[fb_col(fb)].mc_col + 9 - table_column
Row | Plane | Column | |||
---|---|---|---|---|---|
0 | 1 | 2 | 3 | ||
0 | 0 | X | X | X | X |
1 | 0 | X | X | X | X |
2 | 0 | X | X | X | X |
LCT0_INV | [0, 0, 0] |
---|---|
Inverted | ~[0] |
LCT1_INV | [0, 0, 1] |
---|---|
Inverted | ~[0] |
LCT2_INV | [0, 0, 2] |
---|---|
Inverted | ~[0] |
LCT3_INV | [0, 0, 3] |
---|---|
Inverted | ~[0] |
LCT4_INV | [1, 0, 0] |
---|---|
Inverted | ~[0] |
LCT5_INV | [1, 0, 1] |
---|---|
Inverted | ~[0] |
LCT6_INV | [1, 0, 2] |
---|---|
Inverted | ~[0] |
LCT7_INV | [1, 0, 3] |
---|---|
Inverted | ~[0] |
FCLK_MUX | [2, 0, 3] | [2, 0, 2] | [2, 0, 1] | [2, 0, 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 |
JED mapping
JED offset | Bit |
---|---|
0 | FCLK_MUX[0] |
1 | FCLK_MUX[1] |
2 | FCLK_MUX[2] |
3 | FCLK_MUX[3] |
4 | LCT0_INV |
5 | LCT1_INV |
6 | LCT2_INV |
7 | LCT3_INV |
8 | LCT4_INV |
9 | LCT5_INV |
10 | LCT6_INV |
11 | LCT7_INV |
Fuses — global bits
The global bits are given by their raw position in the per-device database.