In all of our previous MicroBlaze soft processor examples, we have used JTAG to download and execute the application code via SDK. You can’t do that in the real world. To deploy a real system, we need the MicroBlaze processor to load and boot its application code from non-volatile memory without our intervention. I thought that showing you how to do this would make for a pretty interesting blog. So using the $99 Digilent Arty A7 board, which is based on a Xilinx Artix-7 FPGA, I am going to demonstrate the steps you need to take using the Arty’s on-board QSPI Flash memory. We will store both the bitstream configuration file and the application software in the QSPI flash.
The QSPI therefore has two roles:
Configure the Artix FPGA
Store the application software
For the first role, we do not need to include a QSPI interface in our Vivado design. All we need to do is update the Vivado configuration settings to QSPI, provided the QSPI flash memory is connected to the FPGA’s configuration pins. However, we need to include a QSPI interface in our design to interface with the QSPI Flash memory once the FPGA is configured and the MicroBlaze soft processor is instantiated. This addition allows a bootloader to copy the application software from the QSPI Flash memory to the Arty’s DDR SDRAM where it actually executes.
Of course, this raises the question:
Where does the MicroBlaze bootloader come from?
The process flowchart for developing the bootloader looks like this:
Development Flow Chart
Our objective is to create a single MCS image containing both the FPGA bitstream and the application software that we can burn into the QSPI Flash memory. To so this we need to perform the following steps in Vivado and SDK:
Include a QSPI Interface within the existing Vivado MicroBlaze design
Edit the device settings in Vivado to configure the device using Master SPI_4 and to compress the bit file, then to build and export the application to SDK
In SDK, create a new application project based on the exported hardware design. During the project-creation dialog, select the SREC SPI Bootloader template. This selection creates an SREC bootloader application that will load the main application code from QSPI Flash memory. Before we build the bootloader ELF, we first need to define the address offset from the base address of the QSPI to the location of the application software. In this case it is 0x600000. We define this offset within blconfig.h. We also need to update the SREC Bootloader BSP to identify the correct serial Flash memory device family. To do this, reconfigure the BSP. The family identification number to use is defined within xilisf.h, available under BSP libsrc. For this application, we select type 5 because the Arty board uses a Micron QSPI device, which is type 5.
Now create a second application project In SDK. This is the application we are going to load using the bootloader. For this application, I created a simple “hello world” application, ensuring in the linker file that this program will run from DDR SDRAM. To create the single MCS file, we need the application software to be in the S-record format. This format stores binary information in an ASCII format. (This format is now 40 years old and was originally developed for the 8-bit Motorola 6800 microprocessor.) We can use SDK to convert the generated ELF into S-record format. To generate the S-record file in SDK, open a bash shell and enter the following command in the directory that contains the application ELF:
cmd /c mb-objcopy -O srec <app>.elf <app>.srec
With the bootloader ELF created, we now need to merge the bitstream with the bootloader ELF in Vivado. This step allows the bootloader to be loaded into and run from the MicroBlaze processor’s local memory following configuration. Because this memory is small, the bootloader application must also be small. If you are experiencing problems reducing the size of the software application, consider using a compiler optimisation before increasing the local memory size.
With the merged bit file created and the S-record file available, use Vivado’s hardware manager to add the configuration memory:
The final step is to generate the unified MCS file containing the merged bitstream and the application software. When generating this file, we need to remember to load the application software using the same offset used in the SREC bootloader.
Once the file is built and burned into the QSPI memory, we can test to see that the MCS file works by connecting the Arty board to a terminal and pressing the board’s reset button. After a few seconds you should see the Arty board’s “done” LED illuminate and then you should see the results of the SREC bootloader appear in the terminal window. This report should show that the S records have loaded from QSPI memory into to DDR SDRAM before the program executes.
We now have a working MicroBlaze system that we can deploy in our designs.