Bitstream structure

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)

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):
    • 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.

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
    • 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

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
    • 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
kdrplane
001
100
211
310
4500
5501
6510
7511

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

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 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
CE_MUX 1.1.3
LCT4 0
PT 1
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

JED mapping — macrocells with IOB

JED mapping — macrocells without IOB

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
    • 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]

JED mapping

Fuses — global bits

The global bits are given by their raw position in the per-device database.