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 firmware version number should be implemented in a separate register and read via the Wishbone interface. This firmware number should be different from the Golden bitstream version number. By reading this firmware 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, as outlined in this Xilinx answer record.
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
- 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 the MultiBoot 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
- 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
- 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 |
IMGR | 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 (IMGR), if the IMGR.VALID 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
IMGR
Offset: 0x04*
Bits | Field | * Default * | Description |
31..17 | Reserved | X | Reserved bits read undefined; they should be written as '0' |
16 | VALID | 0 | Indicates the SR 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 IMGR is only valid after read from the FPGA's configuration register has been performed, by setting bit 6 in CR
- the VALID bit (bit 16) can be used to see if the current readout of the IMGR is valid
- the VALID 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.130 [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.130 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 valid bit of the image register (IMGR.VALID) is set and the value of the configuration register is present in the lower half of the image register (IMGR.CFGREGIMG).
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 high 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