cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to leverage Versal CIPS IP from MicroBlaze

stephenm
Xilinx Employee
Xilinx Employee
8 0 1,253

There are a host of IP cores available on the Versal™ Control, Interfaces and Processing System (CIPS) that users can access from the APU or RPU on the CIPS.

However, in this blog we will instead discuss how we can leverage these IP cores from a Soft Processor in the Programmable Logic. In this blog the Soft Processor will be the MicroBlaze. I will show how you how to execute from the PS DDR and how to leverage the UART on the CIPS.

 

The Hardware Design:

Launch Vivado, target the VCK190 board and create a Block Design (BD):

CIPS.PNG

You can make use of the Run Block Automation utility:

run_block_auto.PNG

In the resulting page on the GUI, select the DDR and then enable the PL Clock and Reset:

block_config.PNG

This will add the CIPS and the NoC (The NoC provides a path from the DDR to the CIPS):

cips_and_noc.PNG

Note: you can remove the sys_clk0 and the CH0_DDR4_0 pin/port and all nets between the CIPS and the NoC here as we will be using the board connections here.

Next, we need to configure the CIPS. Double click on the CIPS BD cell in the IP Integrator canvas to open the config GUI.

As we are targeting the VCK190 board, you can pick the preset config settings.

Click OK:

cips_fixed_io.PNG

If you are on a custom board, you can manually enable the MIO settings based on your needs.

Select PC-PMC -> NoC and configure as shown below:

cips_noc_config.PNG

Select PC-PMC -> PS-PL Interfaces and configure as shown below:

lpd.PNG

Next, Double click on the NoC from the IP Integrator canvas, and configure as shown below:

noc_ddr.PNG

noc_inputs.PNG

noc_connetivity.PNG

Then connect as shown here:

cips_noc_nets.PNG

Then run the Run Connection Automation utility:

cips_noc_auto.PNG

Note: this is a good starting point for most users to evaluate Versal in Vitis.

However in this case, we will be adding the MicroBlaze.

So let's do that.

Add the MicroBlaze from the IP catalog:

add_microblaze.PNG

Again, we can make use of the Run Block Automation utility:

mb_config.PNG

I have chosen to omit the LMB BRAM here, as I will show how we can use the DDR via the NoC as executable memory to save BRAM resources:

mb_setup.PNG

This will result in a system similar to the following. 

mb_cache.PNG

The MicroBlaze will be connected to the DDR via the NoC. To do this, we need to add another slave port and clock on the NoC.

Double click on the NoC BD cell in the IP Integrator canvas and configure as shown below:

noc_increase.PNG

noc_increase_con.PNG

Add a new AXI SmartConnect (call it axi_smc_memory), and use this to connect the MicroBlaze to the DDR (via the axi_noc_0):

axi_smc_memory.PNG

We need to enable the debug port on the CIPS:

cips_debug.PNG

We also need to enable the bscan port on the MDM:

bscan.PNG

Then connect as shown:

connect_bscan.PNG

We shall be clocking and resetting the clocking wizard from the CIPS.

So we need to configure the input clock and reset as shown below:

single_end.PNG

active_low.PNG

Then connect as shown:

clk_wiz.PNG

Because we are executing from DDR, we need to hold the MicroBlaze in Reset until the DDR is calibrated. To ensure this, we can use the discrete ports on the MicroBlaze, and set the MicroBlaze in a reset mode until it is awoken. We can control the wakeup by using a GPIO on the CIPS.

Firstly, double click on the MicroBlaze BD cell in the IP Integrator canvas and enable the Discrete ports as shown below:

discrete_ports.PNG

Use a constant IP set to 01 to drive the reset_mode on the MicroBlaze:

constant.PNG

reset_mode.PNG

Next, we can add a GPIO on the CIPS to control the wake-up:

gpio.PNG

wakeup.PNG

Connect the Proc reset pin to the PL reset pin:

reset.PNG

Next, we can add another AXI SmartConnect (called axi_smc_periph), and connect from the MicroBlaze data port to the CIPS LPD.

Configure this AXI SmartConnect as shown below:

axi_smc_periph.PNG

Then connect the MicroBlaze data port to the CIPS LPD:

mb_lpd.PNG

Note: All of the clk pins are connected to the clock wiz clk_out1 and the reset to the respective pin on the proc reset IP.

Validate the Design:

validate.PNG

The assign the slaves in the Address Editor:

address_editor.PNG

Make sure that the address map covers all of the IP cores:

address_map.PNG

We are now ready to implement the design and export to Vitis™:

  • Generate the Block Design
  • Create the HDL wrapper
  • Generate the Device Image

Modifying the PDI file:

The MicroBlaze is held in reset, until woken by the wakeup pin. The wakeup pin is controlled by the GPIO. To toggle the GPIO, we can create a custom CDO file.

Note: See the blog here for more information on the Versal boot files.

First create a .txt file with the following contents:

 

 

 

 

version 2.0
mask_write 0xff0b0018 0x1 0x1
mask_write 0xff0b02c4 0x1 0x1
mask_write 0xff0b02c8 0x1 0x1
mask_write 0xff0b004c 0x1 0x1

 

 

 

 

Then use the command below to convert this into a CDO file:

cdoutil -output-binary-be -output-file microblaze_reset.cdo microblaze_reset.txt

Next, navigate to the .runs_0/impl_1 folder in the Vivado project directory and open the BIF file and append the content below (inside the last }):

 

 

 

 

 image
  {
   name = mb_bootloder
   id = 0xdeadbee
   partition
   {
    id = 0x11
    type = cdo
    file = gen_files/mb_bootloop_le.elf
   }
 }
 image
 {
  name = mb_reset
  id = 0x1234567
  partition
  {
   id = 0x12
   type = cdo
   file = gen_files/microblaze_reset.cdo
  }
 }

 

 

 

 

I have also copied the MicroBlaze bootloader ELF from the Vivado install here too. This is to prevent the MicroBlaze from stalling once it comes out of reset:

bootloader.PNG

Once you are finished debugging the MicroBlaze app in Vitis, then the bootloader ELF can be replaced by the user application ELF.

Then use the command below to regenerate the PDI file:

bootgen -arch versal -image design_1_wrapper.bif -w -o design_1_wrapper.pdi
  • Select File -> Export Hardware (Include Device Image)
  • Select Tools -> Launch Vitis IDE

Creating the software design:

Once Vitis Launches, create a new application:

create_app.PNG

Select the "Create a new platform from Hardware (XSA)" tab, and import the XSA created in the previous section:

create_plat.PNG

add_xsa.PNG

Create a new system, and allow the tools to automatically create the Domain:

hello_world.PNG

mb_domain.PNG

Finally, select the Hello World template:

hello_world_template.PNG

Exploring the Domain:

By default, the UART on the CIPS will be used as the STDIN and STDOUT when creating the domain.

However, we can double check here:

bsp_settings.PNG

 

modify_bsp.PNG

Here we can see the STDIN and STDOUT:

stdin_out.PNG

Place the application sections into the DDR.

Also by default all sections will be placed in the DDR in the linker.

However, if we want to investigate this we can follow the steps below:

generate_linker.PNG

linker_ddr.PNG

Select the hammer icon to build the project:

build.PNG

Debugging the Hello World Application in Vitis:

To debug, user can right click on the app and select Debug As -> Debug Configurations:

debug_config.PNG

Then double click on the Single Application Debug:

single_app_debug.PNG

Then Apply and Debug. This will launch the debug perspective where you can debug as you normally would:

debug_view.PNG