FPGA Horizons Journal Issue 1

(This article is from Issue 1 of the FPGA Horizons Journal. If you’d like to read more FPGA-related articles, you can download a PDF of the issue right now.)

Embedded processing in FPGAs

Adam Taylor, Publisher & Founder/Principal Consultant, Adiuvo Engineering & Training

Over the 25 years that I have been a practicing FPGA engineer, one thing that has become apparent is that FPGA solutions are increasingly software-defined.

Depending upon the application we might use a System-on-Chip (SoC) device which has hard processors integrated within a defined processing system. These devices are used where applications demand high performance and the use of operating systems such as Embedded Linux, Zephyr or other real-time systems.

Alternatively, we could use a softcore microcontroller implemented within the programmable logic resources. These processors are more often used for configuring the processing pipelines and IP contained within the FPGA, and implementing simple sequential control and communication processes.

I find that most of my FPGAs do contain a small softcore microcontroller, implemented to perform this configuration of the IP cores within the design, and to perform the necessary housekeeping. I also work with a wide range of FPGAs from all vendors, but how do we instantiate and use the softcore processors they provide?

This article is the first in a series exploring the processor architecture, its customization options and the tools we use to develop both the processor and its application. The objective for each will be the same: create a simple hello_world program which communicates over a UART and flashes an LED.  I find that understanding how to create a simple implementation provides us with the necessary starting point to build the more complex applications necessary for our applications.

I am focusing here on the AMD MicroBlaze V as I spend most of my time developing AMD-based solutions. Let’s start by examining the architecture of the processor itself and the different configurations we are able to instantiate. The MicroBlaze V is exceptionally configurable, which offers significant benefits at this stage.

Architecture

As you might guess from its name, the MicroBlaze V is based around the increasingly popular RISC-V Instruction Set Architecture (ISA). The base configuration is the RV32I integer instruction set which provides 32-bit general purpose registers, an ALU, barrel shifter and a single-issue pipeline. However, being a softcore processor, it can be configured for a range of different configurations including:

  • M – Multiplication and Division
  • A – Atomic Instructions
  • F – Floating Point Instructions
  • C – Code Compression
  • Zba, Zbb, Zbc, Zbs – Bit manipulation
  • 64-bit RV64I base integer instruction set

A full list of the configuration options can be found in the MicroBlaze V Processor Reference Guide (UG1629), which addresses how the MicroBlaze V can be configured, optimized and deployed.

Of course, options for interfacing and performance enhancement include instruction caches and data caches, Arm Coherency Extensions interfaces, along with AXI4 and AX14-Stream interfacing. If we are considering use within a high-reliability application, we can also deploy multiple MicroBlaze V instances in lock-step operation, eg, for Triple Modular Redundancy.

As the configuration of the processor has multiple options, AMD provides several different baseline configurations which can be used to select the most appropriate starting point.

These preset configurations currently include:

  • Microcontroller – The smallest configuration for a MicroBlaze V-based microcontroller
  • Real-time microcontroller – Configuration of the MicroBlaze V for real-time applications

There is also, as I understand it, an application version in development which will configure the MicroBlaze V for running Embedded Linux.

Within these configurations it is possible to further optimize the configuration for either performance, area, frequency, or throughput, depending on the needs of the implementation.

Development tools

Developing a MicroBlaze V solution requires two elements, the first being the programmable logic definition. This is the configuration and instantiation of the processor within the programmable logic. To create the MicroBlaze V, we use AMD Vivado Design Suite and its IP Integrator tool to capture the MicroBlaze system. This IP Integrator design can be expanded to contain the remainder of the design of which the MicroBlaze is an element. Or the auto-generated IP integrator wrapper can be used and instantiated within an RTL design using Verilog or VHDL.

The output from Vivado is an archive file (XSA) which contains the bitstream, along with all of the necessary driver and address space information needed to create a software platform once the design has been implemented.

The application software is created within the Vitis Unified Integrated Development Environment (IDE). It is within Vitis that we can write the application software and create the Board Support Package (BSP), which abstracts away the hardware peripherals, providing us easy API access. Within Vitis we can also create boot loader applications if required.

Vitis additionally provides several libraries to help work with AMD device features such as security (XilSecure) and a range of other libraries including lightweight IP (LwIP) for implementing Ethernet stacks with UDP and TCP/IP support, along with libraries for working with flash memory and file systems.

Development flow

The development flow for a MicroBlaze V processor is straightforward and can be seen in the flowchart below.

Development Flow Chart

Application execution and boot

The application we develop for the MicroBlaze can reside locally in Block RAMs (BRAMs), normally connected via the Local Memory Bus to ensure a low latency path between the processor and memory. Alternatively, it can be stored within BRAM connected over an AXI interface if desired.

Of course, BRAM size is limited and some larger applications including, for example, Embedded Linux require more memory. In this instance, the MicroBlaze is capable of executing its application from external memory such as LPDDR 3/4/5. This enables much larger applications to be executed.

When using external memory the access time can be considerable, so it is highly recommended that to improve performance both instruction and data caches are used. Their use has a significant impact on the performance of the system.

The choice of location for the application also determines the complexity of the boot sequence required to bring up the MicroBlaze V when the device is powered on.

Starting with the simplest solution, if the program is contained within the BRAM of the FPGA, the ELF file created by Vitis can be merged by Vivado into the bitstream. This is possible because with SRAM FPGA we are able to define the contents of BRAM within the programming bitstream.

This means that following configuration of the FPGA, the MicroBlaze V will be released from reset and the processor will start executing the application stored within the BRAM.

For many small applications this is the best solution, as the software flow is simplest and no additional external resources are required. If the application is too large for internal memory and external memory is used, the boot process becomes a little more complex. In this instance, a first-stage boot loader (FSBL) needs to be created which then cross loads the application from the configuration memory into the external memory for execution.

Rather helpfully, AMD provides template FSBLs which can be used to cross load the memory. In this instance the FSBL ELF is the file which is merged with the bitstream such that when the FPGA is configured and the MicroBlaze released from reset the bootloader can start executing. The bootloader is then able to cross load from the configuration memory to the external memory.

Processor creation

Let’s take a look at the steps required to create a new processor using Vivado and Vitis. The first thing we need to do is create a new Vivado project and, for this project, I will be using Vivado 2025.1. We can target a MicroBlaze V to any AMD device, either SoC- or FPGA-based, and here I will target a cost-optimized Spartan-7 on an Arty S7 board.

Creating a block design with Vivado IP Integrator

Fig 1. Creating a block design with Vivado IP Integrator

Once the project is created, the next step is to create a new IP integrator block diagram. Using Vivado IP Integrator we can quickly assemble the processor and its peripherals using a block design methodology (see Figure 1). The nice thing about the IP integrator is that the design assistance and automation help accelerate the design process.

Once the IP integrator block design is created, we can then start creating the MicroBlaze V system. The first step is to add the MicroBlaze V from the IP catalog which will instantiate a MicroBlaze V core. However, it will not yet have a configuration applied and we can do this either manually or by leveraging the design automation. In this instance I will use the design automation to help connect and configure the MicroBlaze V.

This configures the MicroBlaze V as a microcontroller with 32 KB of local memory, along with a debug port to allow me to debug the application, and an AXI peripheral port to connect to AXI-based peripherals like a UART and GPIO.

This will generate a diagram like the one below (Figure 2), which includes the processor, local-memory clocks and resets, AXI interconnects and the interrupt controller.

IP Integrated block diagram created using Vivado IP Integrator

Fig 2. IP Integrated block diagram created using Vivado IP Integrator

To this diagram from the IP catalogue we can add a UART and GPIO, allowing the connection automation to connect them into the AXI network. This provides us with the ability to control the LEDs on the board and send messages over the UART. These are the basic building blocks of an embedded processor in an FPGA and can be scaled for future use.

With the design completed the final stage is to create an RTL wrapper and generate the bitstream, ready for it to be exported into Vitis.

Software development 

Within Vitis we need to firstly create the platform which contains the BSP, and then create the application. Creating the platform is straightforward, and we simply point the platform creation wizard to the exported XSA and select the desired options. In most cases for a simple microcontroller there is only one option to choose.

With the platform created the next step is to compile the platform so that it becomes visible to the application creation wizard. The application creation process is, again, straightforward and we can select the hello_world application example and walk through the creation wizard with a few simple clicks.

Once the wizard is completed we have a simple hello_world project that we can explore, build, and deploy on the board. This is shown under the source directory and full instructions and a video of the build are available on the FPGA Horizons Git Repository at https://github.com/FPGA-Horizons. Running the application on the target hardware will show the hello_world being run across the terminal and the LEDS flashing: 

Hello Message

Within the software environment, the build flow and configuration are all CMake-based and we can change compiler settings, library search paths, etc, using the dialogs available within Vitis. Ultimately these are saved in CMake files.

To ensure repeatability, both Vivado and Vitis flows can and should be scripted, and you can see similar scripted flows in the Git Repository.

Wrap up

This is the first processor example in the series, and probably the most commonly used of all the softcore processors we will examine. To help you get started with the MicroBlaze V, the Git Repository provides all of the necessary files to rebuild the application, should you wish to try, while the video provides the detailed step-by-step process.

The ability to use embedded processors is a key skill every engineer should understand. It can make what would be a complex control Finite State Machine (FSM) much simpler, easier, and more maintainable.

FPGA Horizons Journal issue 1

This article is from Issue 1 of the FPGA Horizons Journal. If you’d like to read more FPGA-related articles written by FPGA engineers for FPGA engineers, why not go ahead and download a PDF of the issue right now?

Download the pdf

More articles in this issue: