Xilinx MultiBoot module
This page describes the xil_multiboot module, a VHDL module for remote reprogramming a Xilinx FPGA. The module will be capable of writing bitstreams for Xilinx FPGAs only and will contain Xilinx IP modules.
Its main features are:
- software controls operation of the module:
- a finite-state machine (FSM) controls writing to the flash chip and sending the IPROG command to the FPGA
- modular, easily modifiable design
- flash chip is controlled by software, so virtually any 8-bit SPI flash chip is supported by writing software to send the various commands to the chip
- Wishbone interface can easily be replaced by some other interconnect (e.g., AXI) by implementing the multiboot_regs module
MultiBoot basics
Xilinx MultiBoot technology [1] allows reprogramming an FPGA by downloading a bitstream to a PROM chip external to the FPGA and then issuing an IPROG command to the configuration logic of the FPGA. This command triggers deleting the configuration of the FPGA and rewriting it with the new configuration written to the PROM.
Multiple bitstreams may exist in the PROM at the same time, as outlined in the figure below:
- Header bitstream - contains sync word, multiboot and golden bitstream addresses and the IPROG command
- MultiBoot bitstream - the bitstream that is normally loaded when the IPROG command is issued
- Golden bitstream - the bitstream loaded if the multiboot bitstream load fails
A strike count is used to select which bitstream gets loaded. In Xilinx FPGAs, two kinds of errors can exist when loading a bitstream:
- CRC error - the CRC at the end of the bitstream does not correspond to what is calculated by the programming logic
- Watchdog timer timeout - the Watchdog timer used to detect the configuration synchronization word [1] counts to its maximum value
The strike count increments on either of these two errors and bitstreams are selected based on this count as below:
- if it is 0..2, the MultiBoot bitstream gets loaded
- if it is 3..5, the golden bitstream gets loaded
- if it is 6..8, the header bitstream gets loaded, and multiboot and golden bitstreams are attempted three more times
- if it is 9, configuration is halted
Note that for this scheme to work, the flag -g reset_on_error must be set when running bitgen.
This strike count can only be reset by power-on reset or pulling low the special PROGRAM_B pin of the FPGA, so once the strike count hits three, one cannot go back into reprogramming the MultiBoot bitstream.
Workflow
In order to remotely reprogram a Xilinx FPGA using the xil_multiboot* module, the following workflow is employed [2]:
- Prepare a Xilinx FPGA bitstream
- Send the bitstream to the flash by writing to the FAR register
- Write the MultiBoot bitstream start address and flash chip read command op-code into the MBBAR register
- Write the Golden bitstream start address and flash chip read command op-code into the GBBAR register
- Unlock the IPROG bit in the FPGA by setting the CR.IPROG_UNL bit
- Issue a reprogramming command to the FPGA by setting the CR.IPROG bit
In order to check if reprogramming succeeded, a gateware version number should be implemented in a separate register and read via the Wishbone interface. This gateware number should be different from the Golden bitstream version number. By reading this gateware version number and making sure it is not that of the Golden bitstream address, MultiBoot can be validated.
Unfortunately, the BOOTSTS register in the Spartan-6 configuration logic [1] which should be used to detect if fallback has occured does not get set after an unsuccessful MultiBoot attempt and therefore cannot be used to detect fallback. The BOOTSTS register only gets set after a POR.
Generating bitstreams for Xilinx FPGA reprogramming
This section gives guidelines on how to generate bitstreams to be used in MultiBoot designs.
General guidelines
First and foremost, all bitstreams must have the -g reset_on_error flag set when generating the bitstream. Otherwise, in case of an error in the MultiBoot bitstream, the reconfiguration logic will not try to load the Golden bitstream.
Early in the design cycle, map your flash memory into three bitstreams:
-
the Header bitstream always starts from address 0 and is usually 68 bytes long*
-
the Golden bitstream usually starts from address 0x44 (68 in hex), if generated automatically (see below)
-
if generated and changed manually, it should be set on a sector boundary
-
the MultiBoot bitstream should be set after the Golden bitstream, on a sector boundary
As an example, using the M25P32 flash chip to store the three bitstreams for a Spartan-6 X6SLX45T. The M25P32 has 256-byte pages packed into 256-page sectors, and the X6SLX45T has a 1484472 bytes in the bitstream. Considering the size of the bitstream, 5799 pages of memory would be needed, or a total of 23 sectors
The following flash memory map can be used if the Golden bitstream is automatically generated:
* Address * | * Bitstream * |
---|---|
0x000000 | Header |
0x000044 | Golden |
0x170000 | MultiBoot |
On the other hand, should it be desired to manually change the Golden and Header bitstreams, the following address map can be selected:
* Address * | * Bitstream * |
---|---|
0x000000 | Header |
0x010000 | Golden |
0x180000 | MultiBoot |
Generating the Golden bitstream
Some bitgen flags need to be set in order to automatically generate the golden bitstream during design implementation:
- -g reset_on_err:Yes
- -g next_config_register_write:Enable
- -g next_config_reboot:Enable
- -g next_config_addr:<8-digit hex string> (two digits for Flash op-code and six digits for MultiBoot bitstream address)
- -g next_config_new_mode:Yes
- -g next_config_boot_mode:001 (to keep SPI master mode programming)
- -g golden_config_address:<8-digit hex string> (two digits for Flash op-code and six digits for Golden bitstream address)
All this can be done from the GUI of Xilinx ISE:
- Right-click Generate Programming File in the ISE processes pane and select Process Properties...
- In the General Options tab, tick -g reset_on_error
- In the Configuration Options tab:
- Tick Place MultiBoot Settings into Bitstream
- Set -g next_config_reboot to Enable
- Set -g next_config_addr to 8-digit hex string> (two digits for Flash op-code and six digits for Golden bitstream address)
- Tick -g next_config_new_mode
- Set -g next_config_boot_mode to 001
- Click OK
Note that some versions of ISE might not list all of the switches above, which were listed based on ISE 14.2. In this case, enable all available options and hope that ISE does the right settings.
Also note that on some versions of ISE, the software does not correctly insert the flash read command into the bitstream addresses. Consult Xilinx AR#42561 for workarounds.
Generating the MultiBoot bitstream
Apart from setting the -g reset_on_error switch, the -g next_config_register_write switch should also be set to Disable*, to keep the values of the GENERAL configuration registers intact between subsequent reprograms. This must be done, otherwise a corrupted multiboot image will not boot back to the Golden image and the card will require a power-on reset.
Adding the BitGen flags can be done in two ways:
- If running from command line, provide the flags to bitgen:
- -g reset_on_err:Enable
- -g next_config_register_write:Disable
- If running from the ISE GUI:
- Right-click Generate Programming File in the ISE processes pane and select Process Properties...
- In the General Options tab, tick -g reset_on_error
- In the Other Bitgen Command Line Options field of the General Options tab, write the following command: -g next_config_register_write:Disable
- In the Configuration Options tab, make sure Place MultiBoot Settings into Bitstream is unticked
- Click OK
Note that some versions of ISE might not list all of the switches above, which were listed based on ISE 14.2. In this case, enable all available options and hope that ISE does the right settings.
Also note that on some versions of ISE, the software does not correctly insert the flash read command into the bitstream addresses. Consult Xilinx AR#42561 for workarounds.
Architecture
A block diagram of the xil_multiboot module is shown below. It consists of the following blocks:
Block | Description |
---|---|
** multiboot_regs ** | Wishbone interface and registers |
** multiboot_fsm ** | Main FSM of the multiboot block |
** icap_spartan6 ** | Xilinx ICAP IP core |
** spi_master ** | SPI master from the bootloader design under the SVEC project |
Register map
Register | * Offset * | * Access * | Description |
---|---|---|---|
CR | 0x000 | R/W | Control Register |
SR | 0x004 | R/O | Configuration Image Register |
GBBAR | 0x008 | R/W | Golden Bitstream Base Address Register |
MBBAR | 0x00C | R/W | MultiBoot Bitstream Base Address Register |
FAR | 0x010 | R/W | Flash Access Register |
The GBBAR and MBBAR are images of the GENERAL1..4 configuration registers [1] in the Xilinx Spartan-6 FPGA.
CR
Offset: 0x00*
Bits | Field | * Default * | Description |
---|---|---|---|
31..18 | Reserved | X | Reserved bits read undefined; they should be written as '0' |
17 | IPROG | 0 | When 1, it triggers the FSM to send the IPROG command to the ICAP controller |
This bit needs to be unlocked by setting the IPROG_UNL bit in a previous cycle | |||
16 | IPROG_UNL | 0 | Unlock bit for the IPROG command. This bit needs to be set to 1 prior to writing the IPROG bit |
15..7 | Reserved | X | Reserved bits read undefined; they should be written as '0' |
6 | RDCFGREG | 0 | Initiate a read from the FPGA configuration register at address CFGREGADR |
5..0 | CFGREGADR | 0 | The address of the FPGA configuration register to read |
Notes on the control register:
- In order to read a configuration register, the following steps are
needed
- set the address of the configuration register in the CFGREGADR field (see the Configuration Registers section in [1] for configuration register descriptions)
- set the RDCFGREG bit to initiate the read
- the value of the configuration register can be found in the image register (SR), if the SR.IMGVALID bit is set
- In order to issue the IPROG command to the FPGA, the IPROG bit first needs to be unlocked by setting the IPROG_UNL bit
- After the IPROG command is issued, the FPGA will initiate the programming sequence
SR
Offset: 0x04*
Bits | Field | * Default * | Description |
---|---|---|---|
31..18 | Reserved | X | Reserved bits read undefined; they should be written as '0' |
17 | WDTO | 0 | When '1', a watchdog time-out has occured on the MultiBoot FSM |
This bit can be cleared by writing a '1' to it | |||
16 | IMGVALID | 0 | Indicates the CFGREGIMG contents are valid, i.e., a read from a configuration register has been performed |
15..0 | CFGREGIMG | 0 | Image of the FPGA configuration register |
Notes on the image register:
- the SR is only valid after read from the FPGA's configuration register has been performed, by setting bit 6 in CR
- the IMGVALID bit (bit 16) can be used to see if the current readout of the configuration register image is valid
- the IMGVALID bit is set by the FSM when a read from the configuration register has been performed via the ICAP and cleared on reprogramming
- bits 15..0 are an image of the configuration register (for details, see the Configuration Registers section in [1])
GBBAR
Offset: 0x08*
This register is an image of the GENERAL3,4 [1] configuration registers in Xilinx Spartan-6 FPGAs. Its contents are copied to the configuration registers as part of the configuration sequence of the FPGA.
Bits | Field | * Default * | Description |
---|---|---|---|
31..24 | OPCODE | 0x00 | Read op-code to be sent to Flash chip |
23..0 | GBA | 0x000000 | Golden bitstream start address in Flash memory |
Guidelines on selecting a GBBAR:*
- When generating the header image via Xilinx ISE, the address of GBBAR is (usually) automatically set by the software to 0x44
- If different than the default, the starting address of the golden bitstream should be set to a flash sector boundary (e.g., for the M25P flash series, an integer multiple of 0x10000)
MBBAR
Offset: 0x0C*
This register is an image of the GENERAL1,2 [1] configuration registers in Xilinx Spartan-6 FPGAs. Its contents are copied to the configuration registers as part of the configuration sequence of the FPGA.
Bits | Field | * Default * | Description |
---|---|---|---|
31..24 | OPCODE | 0x00 | Read op-code to be sent to Flash chip |
23..0 | MBA | 0x000000 | MultiBoot bitstream start address in Flash memory |
Guidelines on selecting an MBBAR:*
- The MultiBoot bitstream should start on a flash sector boundary (e.g., for the M25P flash series, an integer multiple of 0x10000)
FAR
Offset: 0x10*
This register should be used by software to access the Flash chip.
It contains the values of a maximum of three data bytes to send to the flash, as well as control bits for sending the data. The data in this register is in little-endian order.
Follow these steps to write to the flash (note that the steps can all be done at the same time via one write to the FAR):
- write the NBYTES field to select the number of data bytes to send
- write NBYTES+1 DATA fields with the data to send to the chip
- set CS to enable chip selection (leaving it cleared and setting XFER will lead to a "dummy" transfer, the equivalent of waiting for a full SPI cycle)
- set XFER to start the transfer; this bit clears itself automatically
- when the READY bit is high, NBYTES data fields have been sent (in the order DATA [0], DATA [1], DATA [2]), and the DATA fields contain NBYTES+1 bytes read from the flash chip.
Bits | Field | * Default * | Description |
---|---|---|---|
31..29 | Reserved | X | Reserved bits read undefined; they should be written as '0' |
28 | READY | 1 | 1: SPI transfer is ready (NBYTES sent and received) |
0: SPI transfer in progress | |||
27 | CS | 0 | Chip select bit. Inverted with respect to SPI chip select, which is normally active low. |
1: Selects the Flash chip (CS pin = 0) | |||
0: Flash chip not selected (CS pin = 1) | |||
26 | XFER | 0 | 1: Start sending NBYTES over SPI |
0: No effect | |||
This bit clears itself automatically | |||
25..24 | NBYTES | 0 | Number of bytes to send during one transfer |
0: send DATA [0] | |||
1: send DATA [0], DATA [1] | |||
2: send DATA [0], DATA [1], DATA [2] | |||
3: Reserved | |||
23..16 | DATA [2] | 0x00 | Write this register with the value of data byte 2 |
After an SPI transfer, this register contains the value of data byte 2 read from the flash | |||
15..8 | DATA [1] | 0x00 | Write this register with the value of data byte 1 |
After an SPI transfer, this register contains the value of data byte 1 read from the flash | |||
7..0 | DATA [0] | 0x00 | Write this register with the value of data byte 0 |
After an SPI transfer, this register contains the value of data byte 0 read from the flash |
The example below shows the setting of the FAR register for different number of data bytes sent to the chip.
Sending bytes 0xAA 0xBB (in that order) to the flash chip:
DATA[0] = 0xAA
DATA[1] = 0xBB
DATA[2] = unimportant
NBYTES = 0x1
XFER = 1
CS = 1
FAR = 0x0D00BBAA
Sending bytes 0x11 0x22 0x33 (in that order) to the flash chip:
DATA[0] = 0x11
DATA[1] = 0x22
DATA[2] = 0x33
NBYTES = 0x2
XFER = 1
CS = 1
FAR = 0x0E332211
Finite-state machine
A simplified block diagram of the MultiBoot FSM is shown below. In VHDL, the FSM is comprised of several states that lead to the phase being completed, but most of these states have been omitted for ease of understanding.
The following table describes these phases. More involved descriptions on each phase are given below.
Phase | Description |
---|---|
IDLE | Wait for one of the following control bits to be set: |
CR.RDCFGREG | |
CR.IPROG (after CR.IPROG_UNL) | |
FAR.XFER | |
SPI transfer | Shift out NBYTES of the three DATA fields in the FAR register, and simultaneously shift in data received from the flash |
When NBYTES have been sent, FAR.READY is written high and the FSM returns to IDLE | |
IPROG | IPROG sequence (Table 7-1, p.130 [1]) |
Read status register | Configuration register readout sequence (Table 6-1, p.113 [1]) |
On reset and when not performing any work, the FSM is in the IDLE state. It waits in this state until one (and only one) of these control signals from multiboot_regs are set:
- CR.RDCFGREG
- CR.IPROG
- FAR.XFER
Depending on which of these three bits are set, the FSM goes into one of the three possible states.
In the SPI transfer phase, the FSM transfers up to three bytes to the SPI flash chip. The FSM sends one byte at a time to the spi_master* module and sets the appropriate control signals of this module. The spi_master then handles shifting out each bit in the byte and simultaneously shifting in a byte from the flash. When a byte has been shifted out from the FPGA and in from the flash, the spi_master* module signals the FSM. The FSM then stores the received byte in the FAR.DATA [0] field and proceeds to shift out the next byte, if NBYTES > 0. When the spi_master sends and receives the second byte from the flash, this second byte received is stored in the FAR.DATA [1] field. Up to three bytes can be sent in this manner, depending on the value of the NBYTES field. After NBYTES bytes have been sent out, the FSM goes back into the IDLE state, setting the FAR.READY signal. The value of the DATA fields in the FAR now contain valid data, in the case of a read.
In the IPROG phase, the FSM performs the steps listed in Table 7-1, p.130 of [1], to initiate the IPROG command. It sends the values listed in this table to the ICAP component to initiate the IPROG command. Note that after the IPROG command has been initiated, the FPGA starts reconfiguring itself with the data in the flash chip and no further user control is possible on the FPGA until it has been reconfigured.
In the Read status register stage, the FSM performs the steps listed in Table 6-1, p.113 of [1]. If the CR.RDCFGREG bit is set, the FSM will perform this sequence to read the configuration register at the address specified in CR.CFGREGADR. After this sequence is complete, the IMGVALID bit of the status register (SR.IMGVALID) is set and the value of the configuration register is present in the lower half of the image register (SR.CFGREGIMG).
The FSM also contains a watchdog that resets the FSM if it stays too long outside the IDLE state. The watchdog gets reset by the FSM while it is in the IDLE state; when the FSM is triggered, it goes out of the IDLE state and the watchdog starts counting. Should the FSM stall for more than 512 cycles, the watchdog times out and it resets the FSM. At the same time, the WDTO bit in the SR is set.
The timeout value for the watchdog was selected based on the longest time the FSM is expected to stay outside the IDLE state. This time is spent while in the SPI transfer phase and it corresponds to the time to send three 8-bit bytes at an SPI clock cycle eight times slower than the FSM input clock cycle. This according to simulation results in a total of 218 clock cycles spent outside the IDLE state. The value 512 was selected to account for longer delays that can occur in hardware.
SPI master interface
The spi_master module in the xil_multiboot module implements an eight-bit SPI master interface with the following settings:
- CPOL = 0
- CPHA = 0
Thus, the idle state of SCK is low ('0') and bits are shifted out on the MOSI line on the falling edge of SCK, and shifted in on the MISO line on the rising edge of SCK.
References
[1] Xilinx UG380: Spartan-6 FPGA Configuration, User
Guide
[2] Xilinx SP605 MultiBoot
Design
Theodor-Adrian Stana, Oct. 2013