The MicroBlaze™ CPU is a family of drop-in, modifiable preset 32-bit/64-bit RISC microprocessor configurations.
The MicroBlaze processor meets the requirements of many diverse applications including Industrial, Medical, Automotive, Consumer, and Communications markets. The MicroBlaze uses a Harvard architecture, and typically this is via a dual LMB BRAM in the PL. However, In this Blog we will discuss how we can execute a MicroBlaze Application from the PSU DDR on the Zynq UltraScale ZCU104 board.
Upon exiting reset, the MicroBlaze will fetch its instructions from the memory address specified in the C_BASE_VECTORS parameter in the MicroBlaze Configuration. In our case, this C_BASE_VECTORS will be set to a region in the PSU DDR.
However, this poses a potential problem as depending on the boot flow employed, the PSU DDR might not be configured before the PL. This can cause the MicroBlaze to hang. To prevent this, we can use the Reset Mode signal on the MicroBlaze.
In the table above, we can see the various configurations for the reset_mode. The configurations that best suits our use case is "01", where the MicroBlaze is held in reset until we are ready. We will use the GPIO via the EMIO on the PSU to bring the MicroBlaze out of reset.
Creating the Hardware:
The Vivado IP Integrator Block Design can be seen below:
Users can customize their design as they see fit.
The key components configurations are discussed below.
Use the Block Automation tool in Vivado IP Integrator to Initially configure the MicroBlaze as shown below. Here, I have removed the local memory, and used 64K of cache:
To enable the reset_mode and wakeup pins, users need to enable the Discrete Ports in the MicroBlaze configuration:
In the Zynq UltraScale PS configurations, I have enabled two slave ports; one for memory, one for the peripherals:
I have enabled the GPIO via the EMIO so that I can control the MicroBlaze wakeup:
We can also access all of the Zynq UltraScale IP that are enabled from our MicroBlaze. To do this, enable the Address Fragmentation:
We discussed the reset mode above. We will hold the MicroBlaze in reset until we are ready.
To hold the MicroBlaze in reset, we can use the Constant IP from the IP catalog:
Finally, connect the GPIO and the Constant IP:
The MicroBlaze Address map is shown below:
Users can right click on an address segment, and either add or exclude from the address map.
That is it for the hardware configuration. We can Generate the Output Products, Create the HDL wrapper, and Generate the Bitstream then export the Hardware.
This will generate the XSA to be used in Vitis to generate our Software.
Creating the Software:
The Vitis IDE can be used to generate the MicroBlaze application. Vitis will also create the boot images including the FSBL and the PMUFW automatically.
However, because we want to control the GPIO EMIO from the FSBL, we will opt to not have the tools generate the boot images:
Generate the MicroBlaze Hello World application:
We can add new project applications as shown below. For example, for the Zynq FSBL:
Note: the FSBL does not support 64 bit to 32 bit handoff. So, because the MicroBlaze is 32 bits, we should also have the FSBL set to 32 bits:
Repeat for the PMUFW:
You should see all of the application projects as shown below:
Because we added the PS UART to the MicroBlaze address map, we can use this for the STDIN/OUT in the BSP:
We can see the MicroBlaze Hello World Linker here:
This is placed at the base address of the DDR (0x00000000). Users need to keep this in mind when creating a boot image so that applications do not overlap.
Programming via the SD Card
First update the FSBL.
We can use the Xil_Out32 API to toggle the GPIO.
Add the xil_io header file to the xfsbl_handoff.c file: