FPGA Live Reconfiguration (FLR) protocol specifications
, 2014.09.26, by Vincent Jordan.

Note: all literal values specified in this document are defined in the file "flr_protocol.h", found at the following address https://pikacode.com/vjp/fpgalivereprog/file/master/src/flr_protocol.h

Overview

Overview

The FGPA Live Reconfiguration (FLR) protocol was created to carry requests from a client to a server. The server contains a buffer on which most of the requests have a side-effect. The requests can be sorted in three main categories:
  1. Set server settings, which do not involve the FPGA target. Examples: test of the communication link, debug flags, ...
  2. Read/write the buffer from/to the FPGA target.
  3. Get/set specific FPGA settings in the working buffer.
The working buffer is actually a chunk of the native bitstream of the FPGA configuration. The protocol defines both lower-level requests, such as get- and set-buffer with raw data, as well as higher-level requests such as get- and set-LUT-equation, which is encoded in the bitstream.

Generic request and response overview

Each communication word (request or response) is 64-bit long. The request is composed of a request word followed by 0 or up to 0xFF request data words. The number of request data words following a request word is given by the request data length parameter in the request word.
The same pattern applies to the response: a response word followed by 0 or up to 0xFF response data words. The number of response data words is given by the response data length parameter in the response word.

The request (resp. response) data length is a 8-bit number, therefore the request (resp. response) data buffer is: 0xFF * sizeof(communication_word) = 2040 bytes.

Note: in the following request and response patterns, the fields in bold are mandatory, while the fields in italic are optional.

Request

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_length
service_id
service param byte 0
service param byte 1
service param byte 2
service param byte 3
service param byte 4
service param byte 5

Request data

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data byte 0
data byte 1
data byte 2
data byte 3
data byte 4
data byte 5
data byte 6
data byte 7
[...]
data byte 2032
data byte 2033
data byte 2034
data byte 2035
data byte 2036
data byte 2037
data byte 2038
data byte 2039

Response

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_length
service_resp_id + 0x80
return code
return byte 0
return byte 1
return byte 2
return byte 3
return byte 4

Response data

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data byte 0
data byte 1
data byte 2
data byte 3
data byte 4
data byte 5
data byte 6
data byte 7
[...]
data byte 2032
data byte 2033
data byte 2034
data byte 2035
data byte 2036
data byte 2037
data byte 2038
data byte 2039

FLR server operations

Note: values written in bold in the communication words are fixed values according to the described service, e.g., the service_id is not a variable field for a given service. Some services does not accept request data of variable length, hence the request data_length is also written in bold in such case.

0x00 FLR_SID_REPEAT_TEST

Sends back the data given with the request. This service is meant to be used for testing the communication link between the client and the server.

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len
service_id = 0x00






0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len
service_resp_id = 0x80







Request example

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
0x03
0x00






0x01
0x23
0x45
0x67
0x89
0xAB
0xCD
0xEF
0xEF
0x01
0x23
0x45
0x67
0x89
0xAB
0xCD
0xCD
0xEF
0x01
0x23
0x45
0x67
0x89
0xAB

Response example

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
0x03
0x80






0x01
0x23
0x45
0x67
0x89
0xAB
0xCD
0xEF
0xEF
0x01
0x23
0x45
0x67
0x89
0xAB
0xCD
0xCD
0xEF
0x01
0x23
0x45
0x67
0x89
0xAB

0x02 FLR_SID_READ_TARGET

Reads the FPGA target configuration, and copy it to the working buffer.

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = 0x00
service_id = 0x02
(A) row
(B) major
(C) minor
(D) length


0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = 0x00
service_resp_id = 0x82
return_code






Parameters

A
FLR_READ_TARGET_ROW
Row offset for read
1 byte
B
FLR_READ_TARGET_MAJ Major offset for read
1 byte
C
FLR_READ_TARGET_MIN
Minor offset for read
1 byte
D
FLR_READ_TARGET_LEN
Length of the read (in frames)
1 byte

0x03 FLR_SID_WRITE_TARGET

Writes the current buffer configuration to the FPGA target.

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = 0x00
service id = 0x03
(A) frame buffer offset
(B) write length



0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = 0x00
service resp. id = 0x83
return code






Parameters

A
FLR_WRITE_TARGET_OFF
Offset in the frame buffer (in frames)
2 bytes
B
FLR_WRITE_TARGET_LEN
Write length (in frames)
2 bytes

0x04 FLR_SID_GET_BUFFER

Get the current buffer content.
Hint: get buffer request with word count=0 can be used to get buffer length only.

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = 0x00
service_id = 0x04
(A) word offset
(B) word count



0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len
service resp. id = 0x84
return code
(C) buffer length



buffer word 1
buffer word 2
buffer word 3
buffer word 4
buffer word 5
... buffer word "word count"


Parameters

A
FLR_GET_BUFFER_WORD_OFF
Offset in the frame buffer (in buffer words)
2 bytes
B
FLR_GET_BUFFER_WORD_COUNT
Length (in buffer words)
2 bytes
C
FLR_GET_BUFFER_BUFFER_LEN
Maximum size of the working buffer (in buffer words)
2 bytes

Return codes

OK
No error
DATA_BUF_LEN
The data buffer is too small
OUT_OF_RANGE
word offset and/or word count are too large according ot the working buffer size.

0x05 FLR_SID_SET_BUFFER

Set the current buffer content with provided data.

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len
service_id = 0x05
(A) word offset
(B) word count


buffer word 1 buffer word 2
buffer word 3
buffer word 4
buffer word 5
...
buffer word "word count"



0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = 0x00 service_resp_id = 0x85
return code





Parameters

A
FLR_SET_BUFFER_OFF
Offset in the frame buffer (in buffer words)
2 bytes
B
FLR_SET_BUFFER_WORD_COUNT
Length (in buffer words)
2 bytes

Return codes

OK
No error
OUT_OF_RANGE
word offset and/or word count are too large according ot the working buffer size.

0x06 FLR_SID_GET_CONFIG

Get the current configuration 64-bit bitfield.

Request example

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = 0x00
service_id = 0x06







Response

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = 0x01
service_resp_id = 0x86
return code





64-bit config bitfield


bit index
description (0=disabled, 1=enabled)
63
Enable debug text output on second serial port, of request information
62
Enable debug text output on second serial port, of read/write target dump

0x07 FLR_SID_SET_CONFIG

Set the current configuration 64-bit bitfield.

Request example

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = 0x01
service_id = 0x07






64-bit config bitfield
The data word is the new config bitfield to be set.
See FLR_SID_GET_CONFIG for the meaning of each bit.

Response

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = 0x00
service_resp_id = 0x87
return_code






0x08 FLR_SID_READ_RAW

0x09 FLR_SID_WRITE_RAW

Write directly to the target (no buffer) what is given as input. If JTAG is used, the command is CFG_IN.
Note: this is a special command which does not use the "data_len" field, in order to write more than 0xFF words.


0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = 0x00
service id = 0x09
(A) raw data length





0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = 0x00
service resp. id = 0x89
return code






Parameters

A
FLR_WRITE_RAW_LEN
Write length (in bytes)
2 bytes

Logic operations

0x20 FLR_SID_GET_LUT_EQU

Get the LUT equation in the current buffer.

0x21 FLR_SID_SET_LUT_EQU

Set the LUT equation in the current buffer.

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = 0x01
service_id = 0x21
(A) row
(B) maj (C) idx (D) LUT


64-bit LUT equation

Parameters

A
FLR_SET_LUT_EQU_ROW
"Row" coordinate in the bitstream
1 byte
B
FLR_SET_LUT_EQU_MAJ
"Major" coordinate in the bitstream 1 byte
C
FLR_SET_LUT_EQU_IDX Index in the major
1 byte
D
FLR_SET_LUT_EQU_LUT LUT type
1 byte

LUT type

FRP_LUT_A_XM 0x00
FRP_LUT_B_XM 0x01
FRP_LUT_C_XM 0x02
FRP_LUT_D_XM 0x03
FRP_LUT_A_MM 0x04
FRP_LUT_B_MM 0x05
FRP_LUT_C_MM 0x06
FRP_LUT_D_MM 0x07
FRP_LUT_A_XL 0x08
FRP_LUT_B_XL 0x09
FRP_LUT_C_XL 0x0A
FRP_LUT_D_XL 0x0B
FRP_LUT_A_LL 0x0C
FRP_LUT_B_LL 0x0D
FRP_LUT_C_LL 0x0E
FRP_LUT_D_LL 0x0F

LUT equation

A6
A5
A4
A3
A2
A1
O
0
0
0
0
0
0
X (LSB)
0
0
0
0
0
1
X
...
1
1
1
1
1
0
X
1
1
1
1
1
1
X (MSB)

Some examples:
            MSB .........LSB
O = 0 -> 0x0000000000000000
O = 1 -> 0xFFFFFFFFFFFFFFFF
O = A1 -> 0xAAAAAAAAAAAAAAAA
O = A2 -> 0xCCCCCCCCCCCCCCCC
O = A3 -> 0xF0F0F0F0F0F0F0F0
O = A4 -> 0xFF00FF00FF00FF00
O = A5 -> 0xFFFF0000FFFF0000
O = A6 -> 0xFFFFFFFF00000000

0x23 FLR_SID_GET_LOGIC_CONF

Get the configuration of a logic bloc in the working buffer.
Xilinx Spartan-6 only: Slice_M configuration

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = 0x02
service_id = 0x23
(A) row
(B) maj (C) idx (D) type


Global logic block config bitfield
Flip-Flop SR initialization
Multiplexer input selection

Parameters

A
FLR_GET_LOGIC_CONF_ROW
"Row" coordinate in the bitstream
1 byte
B
FLR_GET_LOGIC_CONF_MAJ
"Major" coordinate in the bitstream 1 byte
C
FLR_GET_LOGIC_CONF_IDX Index in the major
1 byte
D
FLR_GET_LOGIC_CONF_TYP
Logic block type
1 byte

Logic block type

0x00
Reserved

0x01
FLR_LOGIC_M
M type
0x02
FLR_LOGIC_L L type
0x03 ~ 0xFF
Reserved

See Xilinx UG384 "Spartan-6 FPGA CLB User Guide" for a description of each type.

Global logic block config bitfield

bit index
Mnemonic
description (0=disabled, 1=enabled)
0
CLK_INV

1
SYNC_ATTR

2
ALL_LATCH

3
SR_ENABLE

4
CE_ENABLE

5
PRECY_INIT

6
Reserved

7
Reserved

8
CY0_A

9
CY0_B

10
CY0_C

11
CY0_D

12 ~ 63
Reserved


Flip-Flop SR initialization

From bit 0 to 3 is from LUT A to D.

bit index
Mnemonic
Description
0 ~ 3
FLR_LOGIC_CONF_FF__ML_{A, B, C, D}

4 ~ 7
FLR_LOGIC_CONF_FF5_ML_{A, B, C, D}
8 ~ 11
FLR_LOGIC_CONF_FF__X__{A, B, C, D}
12 ~ 15
FLR_LOGIC_CONF_FF5_X__{A, B, C, D}
16 ~ 31
Reserved


Multiplexer config array

Applies to M and L slice types only.

bit index
Mnemonic
Description
32 ~ 35
FLR_LOGIC_CONF_OUTMUX_A

36 ~ 39
FLR_LOGIC_CONF_OUTMUX_B

40 ~ 43
FLR_LOGIC_CONF_OUTMUX_C

44 ~ 47
FLR_LOGIC_CONF_OUTMUX_D

48 ~ 51
FLR_LOGIC_CONF_FFMUX__A

52 ~ 55
FLR_LOGIC_CONF_FFMUX__B

56 ~ 59
FLR_LOGIC_CONF_FFMUX__C

60 ~ 63
FLR_LOGIC_CONF_FFMUX__D


Multiplexer settings

Each multiplexer has 6 inputs, but their connections depends on the corresponding LUT (i.e., A, B, C, or D).

Code
Mnemonic
OUTMUX
FFMUX
0x0
FLR_LOGIC_MUX_SEL0
5Q
MC31 (D) or F7 (A and C) or F8 (B)
0x1
FLR_LOGIC_MUX_SEL1 MC31 (D) or F7 (A and C) or F8 (B) CY
0x2
FLR_LOGIC_MUX_SEL2 CY
XOR
0x3
FLR_LOGIC_MUX_SEL3 XOR
X
0x4
FLR_LOGIC_MUX_SEL4 O5
O5
0x5
FLR_LOGIC_MUX_SEL5 O6
O6
0x6 ~ 0xF
Reserved
Reserved
Reserved

0x24 FLR_SID_SET_LOGIC_CONF

Set the configuration of a logic bloc in the working buffer.

Switch operations

0x30 FLR_SID_GET_SWITCH

Get the switch status (0x0000=disabled, 0x0001=enabled) in the current buffer.

Request

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = req_len
service_id = 0x30
(A) row
(B) maj (C) idx (D) switch count


0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Switch id 1 Switch id 2
Switch id 3
Switch id 4
Switch id 5
...
Switch id "switch count"




Response

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = req_len
service id = 0xB0
return_code




0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Switch id 1 status
Switch id 2 status
Switch id 3 status
Switch id 4 status
Switch id 5 status
...
Switch id sw_n status





Parameters

A
FLR_GET_SWITCH_ROW
"Row" coordinate in the bitstream
1 byte
B
FLR_GET_SWITCH_MAJ
"Major" coordinate in the bitstream 1 byte
C
FLR_GET_SWITCH_IDX Index in the major
1 byte
D
FLR_GET_SWITCH_LEN Number of requested switch status
2 bytes

Switch id

Switch id list for Xilinx Spartan-6

0x31 FLR_SID_SET_SWITCH

Set the routing switch in the current buffer.

Test operations

The test operations enables to create simple automated tests by setting output pins and readind input pins.

0x40 FLR_SID_GET_TEST_IO

Get the current bit value at the test input pins.

Request

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = 0x00
service_id = 0x40







Response

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = 0x00
service id = 0xC0
return_code (A) bit values




0x41 FLR_SID_SET_TEST_IO

Set the current bit value at the test input pins.

Request

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = 0x00
service_id = 0x41

(A) bit values




Response

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_len = 0x00
service id = 0xC1
return_code




Examples

Those examples are based on the Xilinx Spartan6 LX9 (XC6SLX9).

Upload a new FPGA configuration

Sequence:
  1. Get work buffer length with FLR_SID_GET_BUFFER, and word_count=0
  2. Fill the current working buffer with FLR_SID_SET_BUFFER commands (several commands required, since the working buffer is larger than the request maximum data length)
  3. FLR_SID_WRITE_TARGET
  4. Repeat step 2 and 3, if the working buffer is smaller than the target configuration.

Update a LUT equation

Sequence:
  1. FLR_SID_READ_TARGET
  2. FLR_SID_GET_LUT_EQU
  3. update the 64-bit equation on client side
  4. FLR_SID_SET_LUT_EQU
  5. FLR_SID_WRITE_TARGET
The LUT now has the updated equation.