Home

Awesome

The NEORV32 XIP Bootloader

Introduction

The XIP Bootloader allows you to write a binary file to flash, read data from flash, erase sectors, check the status byte and execute your program from flash using the XIP (eXecute In Place) component of the NEORV32. The XIP module uses an SPI interface to interface with the flash memory. It is still possible to use the NEORV32's SPI interface for other purposes, as both interfaces are independent from each other.

The XIP Bootloader consists of two files, bootloader_xip.c and neorv_sh.py.

bootloader_xip.c is the source code for the bootloader running inside the NEORV32 processor, inside the bootloader memory space.

neorv_sh.py is a command line interface which lets you interact with the bootloader.

The commands between the CLI and the bootloader use the UART0 interface.

It is highly recommended to implement the i-cache in the FPGA fabric, otherwise the program may run awfully low!

Usage

Compiling the bootloader

Running

make bootloader

will generate the XIP bootloader VHDL file in /rtl/neorv32_bootloader_image.vhd. You'll have to re-build your VHDL project.

The default settings for the XIP bootloader are based on a DE0-Nano Cyclone IV dev board:

The values above can be updated in the bootloader_xip.c file:

/** SPI flash boot base address */
#ifndef SPI_FLASH_BASE_ADDR
  #define SPI_FLASH_BASE_ADDR 0x00400000
#endif
/**@}*/
/** SPI flash address width (in numbers of bytes; 2,3,4) */
#ifndef SPI_FLASH_ADDR_BYTES
  #define SPI_FLASH_ADDR_BYTES 3 // default = 3 address bytes = 24-bit
#endif
/** XIP Page Base */
#ifndef XIP_PAGE_BASE
  #define XIP_PAGE_BASE 0x20000000
#endif

The timeout for the bootloader is 8 seconds. If the bootloader times out, it starts execution from the flash address at SPI_FLASH_BASE_ADDR.

Compiling a firmware application

For a compiled application to run, the linker script located in sw/common/neorv32.ld needs to be updated. The line which defines the ROM address must have the new base address:

  rom   (rx) : ORIGIN = DEFINED(make_bootloader) ? 0xFFFF0000 : 0x20400000, LENGTH = DEFINED(make_bootloader) ? 32K : 4M

Running the command line interface, neorv_sh.py

The command line interface (CLI) requires Python 3.x to run, as it uses the CMD module. It is based on a simple request - response communication mode. The CLI sends a 1-byte command requesting a write or a read, waits for the response, and either sends the rest of the data or processes the information received.

Run the script using python neorv_sh.py.

At bootloader start, you have 8 seconds to poke the bootloader and prevent it from jumping to the application. There are two ways of doing this:

The implemented commands are:

FPGA implementations

Cyclone IV DE0 Nano

The de0_nano folder contains all files and configurations necessary to open a Quartus Project. This has been created with Quartus 21.1.