Firmware

SPEC7 Golden Architecture

This design was build to provide PCIe enumeration within 100ms

_images/spec7_golden.png

SPEC7 Reference design with XDMA for Remote Upgrade

This design was built on SPEC7 Reference Design with addititonal BAR 4 for PCIe to upload new firmware to PS-DDR via AXI DMA and PCIe core with addon Virtual UART provided through AXI Uartlite Core to direct PS to load firmware in PL

_images/spec7_ref_dma.png
  1. Script Build.sh in sw/scripts/boot intiates build for FSBL and Uboot It also creates spec7.bif file which consists of path for all output obtained i.e bitstream, elf files located in output directory

./Build.sh  --t <specify Tandem Design>  --r <reference design> --o <offset>
  1. The above step will create BOOT.bin in output directory which can be flashed directly to flash memory

program_flash -f BOOT.bin -fsbl </path/to/fsbl>/zynq_fsbl.elf  -flash_type qspi-x8-dual_parallel  -blank_check -url tcp:localhost:3121
  1. To automate loading of second design, it’s possible in two ways

Create environment variable in U-boot in Runtime

SPEC7> sf probe 0 0 0
SPEC7> sf erase 0x2000000 0x1000000

SPEC7> sf write ${loadbit_addr} 0x2000000 ${filesize}

SPEC7> fpga loadb 0 ${loadbit_addr} ${filesize}

The above commands are for test, where 0x2000000 specifies the offset defined in BOOT.bin

Automatic gateware update from QSPI

In order to allow for automatic loading of the gateware from QSPI using the UBoot, first we define the following environment variables:

SPEC7> setenv bootdelay "0"
SPEC7> setenv gateware_size 0x1000000
SPEC7> setenv qspi_gateware_offset 0x2000000

The meaning for each of these variables are: - bootdelay: this contains the maximum value of the countdown that UBoot perform before executing the bootcmd. By setting it to zero, we save a precious time at startup. - gateware_size: we define this auxiliary variable that specify the size of the slot containing the gateware that we want to move from QSPI to DDR. We set the value to 16 MiB, i.e. the full size of the slot. - qspi_gateware_offset: we define this auxiliary variable containing the QSPI offset of the slot containing the gateware we want to load. In this case, we are pointing to the Slot 2, but we can easily modify the slot to be used by editing this variable.

Now, we create the boot command to read the gateware from the desired QSPI slot to DDR, then from DDR to FPGA, and finally go back to the U-boot prompt:

SPEC7> editenv bootcmd_gateware
edit: sf probe 0 0 0 && sf read ${loadbit_addr} ${qspi_gateware_offset} ${gateware_size} && fpga loadb 0 ${loadbit_addr} 0x1

Note: because we are using bitstream in bit format, the fpga loadb command doesn’t require the exact size of the bitstream, just a non zero value, as the size is already encoded in the bitstream header.

In order to boot execute this command at start-up, we must assign the bootcmd variable and save the environment:

SPEC7> setenv bootcmd "run bootcmd_gateware"
SPEC7> saveenv

Adding the above environment during building U-boot using make menuconfig or adding in config

#define CONFIG_EXTRA_ENV_SETTINGS \
      "bootdelay = 0"\
      "gateware_size =0x1000000" \
      "qspi_gateware_offse= 0x2000000" \
      " bootcmd_gateware = sf probe 0 0 0 && sf read ${loadbit_addr} ${qspi_gateware_offset} ${gateware_size} && fpga loadb 0 ${loadbit_addr} 0x1" \
      "bootcmd = run bootcmd_gateware"