MicroZed Chronicles: FPGA MultiBoot

Last week, we explored how we could update the design Zynq designs in the field and use MultiBoot to ensure there was a golden image should the update fail.

This week, we are going to examine how we can do the same when we use a standard FPGA. For this example, we are going to use a Artix-A7 100T device running a MicroBlaze design. The program executed by the MicroBlaze will be different depending upon the image.

Again, we will be creating two images — one gold image that can be fallen back to, and another which can be overwritten and updated if required in the field.

The inclusion of the gold image means that if the update goes wrong, we will not brick the system. However, to ensure this operates correctly, we need to correctly configure the design and especially the constraints.

So how does it work? In normal operation (no MultiBot), the bitstream located at address 0x0 in the configuration memory is loaded. In a MultiBoot approach, there are two images in the configuration memory device. The first is located at 0x0 and is the gold image, while the normally loaded image is stored at an offset in the configuration memory.

Crucially the gold image contains the address offset where the normal / update image resides. The address of this normal / update image is read from the gold image and stored in the gold image Warm Boot Start Address (WBSTAR). The configuration block in the FPGA can then jump to this memory address using the IPROG or internally generate pulse which initiates the jump to the specified address.

Should a configuration error be detected in the normal / update bitstream, the FPGA will fall back to using the gold image.

The two images I am creating for this demonstration will print out different ‘hello world’ messages depending upon if the gold or update image is loaded.

Multiboot configuration (Source — XAPP1247)

Besides the difference in the contents of the MicroBlaze program, the main difference between projects in the MultiBoot configuration is in the constraints files.

Within the constraints file for the gold image, we need to enable the fallback option. We also need to provide the location of the update image, which should be attempted to be loaded first.

I have also enabled compression on the image and set the SPI bus width to 1.

Gold image constraint file

While for the update image, its constraint file should be as below enabling the configuration fallback but without the config address specified.

Update image constraint file

Once we have both images (gold and update), we can then generate a combined MCS file which contains both images — with the gold image at address 0 and the update image at the specified offset. Note: in the field update would require the FPGA to contain a configuration method to write a bin or hex file to the configuration memory at the update address.

To create the MCS file, we use the command below:

write_cfgmem -format mcs -interface SPIX1 -size 16 -loadbit “up 0 golden.bit up 0x0400000 update.bit” image.mcs

After the MCS file is created, you will see a report generated that shows the content of the generated MCS file.

Once we have the MCS file, we are ready to program the QSPI memory, which we can do using Vivado’s hardware manager.

After programming the QSPI is completed, power cycle the board and you will see the updated image load from the QSPI memory. This is the image we want to be seeing in normal operation:

However, we also want to test that the fallback to the gold image will work if a update to the update image goes wrong.

To test this, we are going to create a new MCS file and include a corrupted update image.

We are going to corrupt the update image by opening the file in a hex editor and modifying a value. This will cause the CRC to fail and the device to fall back to the gold image.

With the corrupted bit file ready, we can then create an updated MCS file and flash it in to QSPI device.

When we try and load the update image from the flash, we will see the image gold image loaded in place of the update image due to the CRC error.

To confirm this has occurred for the reasons stated above we can, connect using Vivado’s hardware manager over JTAG and check the boot status register.

Looking at the boot status register you will see the CRC error reported for bit stream 1 and that the fallback image 0 has been loaded. Exactly as we want it to work!

You can obtain the project I created for this on my GitHub page.

See My FPGA / SoC Projects: Adam Taylor on Hackster.io

Get the Code: ATaylorCEngFIET (Adam Taylor)

Access the MicroZed Chronicles Archives with over 280 articles on the Zynq / Zynq MpSoC updated weekly at MicroZed Chronicles.

MicroZed Chronicles: FPGA MultiBoot was originally published in Hackster Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.

Original article: MicroZed Chronicles: FPGA MultiBoot
Author: Adam Taylor