Bitstream structure — XC9500XL/XV

The main differences from XC9500 are:

  1. The UIM wire-AND area is completely gone, only the main areas exist.
  2. The main area has 108 rows per FB instead of 72.
  3. Unprogrammed fuse state is 0, programmed fuse state is 1. Thus, the sense of every bitstream bit is inverted from the XC9500 version.
  4. While in XC9500 all areas are loaded sequentially, in XC9500XL/XV the areas are loaded in parallel. Thus, the JTAG unit is not a byte, but a word of size 8 * num_fbs. Likewise, the bytes for each FB are interleaved in the JED format.

On a high level, the whole bitstream is split into "areas". Each FB of the device corresponds to one area.

Each area is made of 108 "rows". Each row is made of 15 "columns". Each column is made of 6 or 8 bits: columns 0-8 are made of 8 bits, while columns 9-14 are made of 6 bits.

The low 6 bits of every column are used to store product term masks, and the high 2 bits of columns 0-8 are used to store everything else.

When programmed or read via JTAG, the bitstream is transmitted as words. Each word is 8 bits per FB. Each word of the bitstream has its address. Not all addresses are valid, and valid addresses are not contiguous. Address is 16 bits long, and is split to several fields:

  • bits 12-15: FB index (only used for JTAG FERASE operation, doesn't matter for reading and programming)
  • bits 5-11: row
  • bits 3-4: column / 5
  • bits 0-2: column % 5

The unprogrammed state of a bit on XC9500XL/XV is 0. The programmed state is 1. Thus, whenever a boolean fuse is mentioned in the documentation, the "true" value is actually represented as 1 in the bitstream.

JED format mapping

In the JED format, all fuses of the device are simply concatenated in order, skipping over invalid addresses. The bytes are not padded to 8 bits, but have their native size. Thus, converting from JED fuse index to device address involves some complex calculations::

row_bits = (8 * 9 + 6 * 6) * device.num_fbs
total_bits = row_bits * 108

def jed_to_jtag(fuse):
    row = fuse // row_bits
    fuse %= row_bits
    if fuse < 8 * 9 * device.num_fbs:
        column = fuse // (8 * device.num_fbs)
        fuse %= (8 * device.num_fbs)
        fb = fuse // 8
        bit = fuse % 8
    else:
        fuse -= 8 * 9 * device.num_fbs
        column = 9 + fuse // (6 * device.num_fbs)
        fuse %= (6 * device.num_fbs)
        fb = fuse // 6
        bit = fuse % 6
    return (
        row << 5 | 
        (column // 5) << 3 |
        (column % 5)
    ), (fb * 8 + bit)

def jtag_to_jed(addr, bit):
    fb = bit // 8
    bit %= 8
    row = addr >> 5 & 0x7f
    assert row < 108
    col_hi = addr >> 3 & 3
    assert col_hi < 3
    col_lo = addr & 7
    assert col_lo < 5
    column = col_hi * 5 + col_lo
    if column < 9:
        cfuse = column * 8 * device.num_fbs + fb * 8 + bit
    else:
        cfuse = 8 * 8 + (column - 9) * 6 * device.num_fbs + fb * 6 + bit
    return row * row_bits + cfuse

Fuses — product terms

The product term masks are stored in bits 0-5 of every column and every row of the main area. The formulas are as follows (unchanged from XC9500, but now with more rows):

  1. FB[i].MC[j].PT[k].IM[l].P is stored at:
    • row: l * 2 + 1
    • column: k + (j % 3) * 5
    • bit: j // 3
  2. FB[i].MC[j].PT[k].IM[l].N is stored at:
    • row: l * 2
    • column: k + (j % 3) * 5
    • bit: j // 3

Fuses — macrocells

Per-MC config fuses (that are not product term masks) are stored in bits 6-7 of columns 0-8 of rows 12-49 of the main area. The formulas are as follows:

  • row: corresponds to fuse function
  • column: mc_idx % 9
  • bit: 6 + mc_idx // 9
CE_MUX 0.37.0 0.36.0
NONE 0 0
PT2 0 1
PT3 1 0
CLK_INV 0.35.0
INV 0.22.0
IOB_GND 0.43.0
OE_INV 0.30.0
PT[0].HP 0.45.0
PT[1].HP 0.46.0
PT[2].HP 0.47.0
PT[3].HP 0.48.0
PT[4].HP 0.49.0
REG_INIT 0.42.0
SUM_HP 0.26.0
non-inverted [0]
CLK_MUX 0.34.0 0.33.0
FCLK1 0 0
FCLK2 0 1
FCLK0 1 0
PT 1 1
EXPORT_CHAIN_DIR 0.25.0
UP 0
DOWN 1
IMPORT_DOWN_ALLOC 0.24.0
IMPORT_UP_ALLOC 0.23.0
EXPORT 0
SUM 1
IOB_SLEW 0.44.0
SLOW 0
FAST 1
OE_MUX 0.29.0 0.28.0 0.27.0
PT 0 0 0
FOE0 0 0 1
FOE1 0 1 1
FOE2 1 0 1
FOE3 1 1 1
OUT_MUX 0.32.0
FF 0
COMB 1
PT[0].ALLOC 0.13.0 0.12.0
PT[1].ALLOC 0.15.0 0.14.0
PT[2].ALLOC 0.17.0 0.16.0
PT[3].ALLOC 0.19.0 0.18.0
PT[4].ALLOC 0.21.0 0.20.0
NONE 0 0
SUM 0 1
EXPORT 1 0
SPECIAL 1 1
REG_MODE 0.39.0
DFF 0
TFF 1
RST_MUX 0.40.0
SET_MUX 0.41.0
PT 0
FSR 1
CE_MUX 0.37.0 0.36.0
NONE 0 0
PT2 0 1
PT3 1 0
CLK_INV 0.35.0
INV 0.22.0
IOB_GND 0.43.0
OE_INV 0.30.0
PT[0].HP 0.45.0
PT[1].HP 0.46.0
PT[2].HP 0.47.0
PT[3].HP 0.48.0
PT[4].HP 0.49.0
REG_INIT 0.42.0
SUM_HP 0.26.0
non-inverted [0]
CLK_MUX 0.34.0 0.33.0
FCLK1 0 0
FCLK2 0 1
FCLK0 1 0
PT 1 1
EXPORT_CHAIN_DIR 0.25.0
UP 0
DOWN 1
IMPORT_DOWN_ALLOC 0.24.0
IMPORT_UP_ALLOC 0.23.0
EXPORT 0
SUM 1
IOB_SLEW 0.44.0
SLOW 0
FAST 1
OE_MUX 0.29.0 0.28.0 0.27.0
PT 0 0 0
FOE0 0 0 1
FOE1 0 1 1
FOE2 1 0 1
FOE3 1 1 1
OUT_MUX 0.32.0
FF 0
COMB 1
PT[0].ALLOC 0.13.0 0.12.0
PT[1].ALLOC 0.15.0 0.14.0
PT[2].ALLOC 0.17.0 0.16.0
PT[3].ALLOC 0.19.0 0.18.0
PT[4].ALLOC 0.21.0 0.20.0
NONE 0 0
SUM 0 1
EXPORT 1 0
SPECIAL 1 1
REG_MODE 0.39.0
DFF 0
TFF 1
RST_MUX 0.40.0
SET_MUX 0.41.0
PT 0
FSR 1

Fuses — FB inputs

The FB input mux configuraton is stored in rows 50-76, columns 0-8, bits 6-7. FB[i].IM[j].MUX has 9 bits and is stored at the following coordinates:

  • row: 50 + j % 27
  • column: mux fuse index (0-8)
  • bit: 6 if j < 27, 7 otherwise

The exact bit assignments are irregular and should be obtained from the database.

Fuses — per-FB bits and globals

Per-FB bits are stored in row 78, columns 0-8, bits 6-7. The bits are (row, bit, column):

xc9500xl fb bittile 0
FrameBit
0 1 2 3 4 5 6
0 - - - - - - -
1 - - - - - - -
2 - - - - - - -
3 - - - - - - -
4 - - - - - - -
5 - - - - - - -
6 - - - - - - -
7 - - - - - - -
8 - - - - - - -
9 - - - - - - -
10 - - - - - - -
11 WRITE_PROT - - READ_PROT - - -
12 - - - - - - -
13 - - - - - - -
14 - - - - - - -
15 - - - - - - -
16 - - - - - - -
17 - - - - - - -
18 - - - - - - -
19 - - - - - - -
20 - - - - - - -
21 - - - - - - -
22 - - - - - - -
23 - - - - - - -
24 - - - - - - -
25 - - - - - - -
26 - - - - - - -
27 - - - - - - -
28 - - - - - - -
29 - - - - - - -
30 - - - - - - -
31 - - - - - - -
32 - - - - - - -
33 - - - - - - -
34 - - - - - - -
35 - - - - - - -
36 - - - - - - -
37 - - - - - - -
38 - - - - - - -
39 - - - - - - -
40 - - - - - - -
41 - - - - - - -
42 - - - - - - -
43 - - - - - - -
44 - - - - - - -
45 - - - - - - -
46 - - - - - - -
47 - - - - - - -
48 - - - - - - -
49 - - - - - - -
50 - - - - - - -
51 - - - - - - -
52 - - - - - - -
53 - - - - - - -
54 - - - - - - -
55 - - - - - - -
56 - - - - - - -
57 - - - - - - -
58 - - - - - - -
59 - - - - - - -
60 - - - - - - -
61 - - - - - - -
62 - - - - - - -
63 - - - - - - -
64 - - - - - - -
65 - - - - - - -
66 - - - - - - -
67 - - - - - - -
68 - - - - - - -
69 - - - - - - -
70 - - - - - - -
71 - - - - - - -
72 - - - - - - -
73 - - - - - - -
74 - - - - - - -
75 - - - - - - -
76 - - - - - - -
77 - - - - - - -
78 ENABLE EXPORT_ENABLE - - - - PULLUP_DISABLE
ENABLE 0.78.0
EXPORT_ENABLE 0.78.1
PULLUP_DISABLE 0.78.6
READ_PROT 0.11.3
WRITE_PROT 0.11.0
non-inverted [0]
xc9500xv fb bittile 0
FrameBit
0 1 2 3 4 5 6
0 - - - - - - -
1 - - - - - - -
2 - - - - - - -
3 - - - - - - -
4 - - - - - - -
5 - - - - - - -
6 - - - - - - -
7 - - - - - - -
8 - - - - - - -
9 - - - - - - -
10 - - - - - - -
11 WRITE_PROT - - READ_PROT - - -
12 - - - - - - -
13 - - - - - - -
14 - - - - - - -
15 - - - - - - -
16 - - - - - - -
17 - - - - - - -
18 - - - - - - -
19 - - - - - - -
20 - - - - - - -
21 - - - - - - -
22 - - - - - - -
23 - - - - - - -
24 - - - - - - -
25 - - - - - - -
26 - - - - - - -
27 - - - - - - -
28 - - - - - - -
29 - - - - - - -
30 - - - - - - -
31 - - - - - - -
32 - - - - - - -
33 - - - - - - -
34 - - - - - - -
35 - - - - - - -
36 - - - - - - -
37 - - - - - - -
38 - - - - - - -
39 - - - - - - -
40 - - - - - - -
41 - - - - - - -
42 - - - - - - -
43 - - - - - - -
44 - - - - - - -
45 - - - - - - -
46 - - - - - - -
47 - - - - - - -
48 - - - - - - -
49 - - - - - - -
50 - - - - - - -
51 - - - - - - -
52 - - - - - - -
53 - - - - - - -
54 - - - - - - -
55 - - - - - - -
56 - - - - - - -
57 - - - - - - -
58 - - - - - - -
59 - - - - - - -
60 - - - - - - -
61 - - - - - - -
62 - - - - - - -
63 - - - - - - -
64 - - - - - - -
65 - - - - - - -
66 - - - - - - -
67 - - - - - - -
68 - - - - - - -
69 - - - - - - -
70 - - - - - - -
71 - - - - - - -
72 - - - - - - -
73 - - - - - - -
74 - - - - - - -
75 - - - - - - -
76 - - - - - - -
77 - - - - - - -
78 ENABLE EXPORT_ENABLE - - - - PULLUP_DISABLE
ENABLE 0.78.0
EXPORT_ENABLE 0.78.1
PULLUP_DISABLE 0.78.6
READ_PROT 0.11.3
WRITE_PROT 0.11.0
non-inverted [0]

Global bits are stored in rows (2, 6, 7), columns 0-8, bits 6-7 of FB 0. The bits are (fb, row, bit, column):

xc9500xl global bittile 0
FrameBit
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 - - - - - - - - - - - - - - - - -
1 - - - - - - - - - - - - - - - - -
2 FSR_INV FCLK0_ENABLE FCLK1_ENABLE FCLK2_ENABLE FOE0_ENABLE FOE1_ENABLE FOE2_ENABLE FOE3_ENABLE TERM_MODE[0] - - - - - - - -
3 - - - - - - - - - - - - - - - - -
4 - - - - - - - - - - - - - - - - -
5 - - - - - - - - - - - - - - - - -
6 USERCODE[30] USERCODE[28] USERCODE[26] USERCODE[24] USERCODE[22] USERCODE[20] USERCODE[18] USERCODE[16] - USERCODE[31] USERCODE[29] USERCODE[27] USERCODE[25] USERCODE[23] USERCODE[21] USERCODE[19] USERCODE[17]
7 USERCODE[14] USERCODE[12] USERCODE[10] USERCODE[8] USERCODE[6] USERCODE[4] USERCODE[2] USERCODE[0] - USERCODE[15] USERCODE[13] USERCODE[11] USERCODE[9] USERCODE[7] USERCODE[5] USERCODE[3] USERCODE[1]
FCLK0_ENABLE 0.2.1
FCLK1_ENABLE 0.2.2
FCLK2_ENABLE 0.2.3
FOE0_ENABLE 0.2.4
FOE1_ENABLE 0.2.5
FOE2_ENABLE 0.2.6
FOE3_ENABLE 0.2.7
FSR_INV 0.2.0
non-inverted [0]
TERM_MODE 0.2.8
KEEPER 0
FLOAT 1
USERCODE 0.6.9 0.6.0 0.6.10 0.6.1 0.6.11 0.6.2 0.6.12 0.6.3 0.6.13 0.6.4 0.6.14 0.6.5 0.6.15 0.6.6 0.6.16 0.6.7 0.7.9 0.7.0 0.7.10 0.7.1 0.7.11 0.7.2 0.7.12 0.7.3 0.7.13 0.7.4 0.7.14 0.7.5 0.7.15 0.7.6 0.7.16 0.7.7
non-inverted [31] [30] [29] [28] [27] [26] [25] [24] [23] [22] [21] [20] [19] [18] [17] [16] [15] [14] [13] [12] [11] [10] [9] [8] [7] [6] [5] [4] [3] [2] [1] [0]
xc9500xv global bittile 0
FrameBit
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 - - - - - - - - - - - - - - - - -
1 - - - - - - - - - - - - - - - - -
2 FSR_INV FCLK0_ENABLE FCLK1_ENABLE FCLK2_ENABLE FOE0_ENABLE FOE1_ENABLE FOE2_ENABLE FOE3_ENABLE TERM_MODE[0] - - - - - - - -
3 - - - - - - - - - - - - - - - - -
4 - - - - - - - - - - - - - - - - -
5 - - - - - - - - - - - - - - - - -
6 USERCODE[30] USERCODE[28] USERCODE[26] USERCODE[24] USERCODE[22] USERCODE[20] USERCODE[18] USERCODE[16] - USERCODE[31] USERCODE[29] USERCODE[27] USERCODE[25] USERCODE[23] USERCODE[21] USERCODE[19] USERCODE[17]
7 USERCODE[14] USERCODE[12] USERCODE[10] USERCODE[8] USERCODE[6] USERCODE[4] USERCODE[2] USERCODE[0] - USERCODE[15] USERCODE[13] USERCODE[11] USERCODE[9] USERCODE[7] USERCODE[5] USERCODE[3] USERCODE[1]
8 - - - - - - - - - - - - - - - - -
9 - - - - - - - - - - - - - - - - -
10 - - - - - - - - - - - - - - - - -
11 - - - - - - DONE - - - - - - - - - -
DONE 0.11.6
FCLK0_ENABLE 0.2.1
FCLK1_ENABLE 0.2.2
FCLK2_ENABLE 0.2.3
FOE0_ENABLE 0.2.4
FOE1_ENABLE 0.2.5
FOE2_ENABLE 0.2.6
FOE3_ENABLE 0.2.7
FSR_INV 0.2.0
non-inverted [0]
TERM_MODE 0.2.8
KEEPER 0
FLOAT 1
USERCODE 0.6.9 0.6.0 0.6.10 0.6.1 0.6.11 0.6.2 0.6.12 0.6.3 0.6.13 0.6.4 0.6.14 0.6.5 0.6.15 0.6.6 0.6.16 0.6.7 0.7.9 0.7.0 0.7.10 0.7.1 0.7.11 0.7.2 0.7.12 0.7.3 0.7.13 0.7.4 0.7.14 0.7.5 0.7.15 0.7.6 0.7.16 0.7.7
non-inverted [31] [30] [29] [28] [27] [26] [25] [24] [23] [22] [21] [20] [19] [18] [17] [16] [15] [14] [13] [12] [11] [10] [9] [8] [7] [6] [5] [4] [3] [2] [1] [0]

The DONE bit is only applicable to XC9500XV.