This document will first help you to create a hardware design using a custom AXI IP for LED control with Vivado 2023.2. Then it will help you to create an application to control the LED using this design with Vitis Unified 2023.2. We will be using the Kria KD240 Drives Starter Kit.
First create a project in Vivado. Enter the project name, choose a project location and select the create project subdirectory option.
Then for the project type leave the default option RTL Project selected. Also check option under RTL project : Do not specify sources at this time and un-check (disable) Project is an extensible Vitis platform.
In the Default Part part go to the Boards tab and search for KD240. Then select the KRIA KD240 Drives Starter Kit SOM. Click on "Connections" under the board name to manage the board connections. Link Connector 1 on K24 SOM (SOM240_1) to Drives Starter Kit carrier(SOM240_1) and Connector 2 on K24 SOM (SOM40_2) to Drives Starter Kit carrier(SOM40_2) :
Then check the new project summary and click on Finish to create the project.
Block designCreate a new block design (choose a name for it and click OK). Click on the + button in the newly created empty block design (Diagram tab) to add an IP. Choose the Zynq UltraScale+ MPSoC. A message with a green background will appear, click on Run Block Automation. A window will open. The Apply Board Preset needs to be checked, then click OK.
Add a Processor System Reset IP. Run Block Automation again. It will link slowest_sync_clk (of the Processor System Reset block) to pl_clk0 (of the Zynq UltraScale+ MPSoC block) and ext_reset_in (of the Processor System Reset block) to pl_resetn0 (of the Zynq UltraScale+ MPSoC block).
We will be using an already packaged custom AXI IP to control the LED. You can directly download the repository of the custom IP we will be using (ip_repo.zip) at the attachment of this tutorial (footer section).
If you want to learn how to create a custom IP you can have a look at this : https://github.com/xupgit/Embedded-System-Design-Flow-on-Zynq/blob/2018.1/lab3.md
To add the custom IP to the project, we first need to add the repository where the custom IP is located. In the Flow Navigator pane open the Settings. Go to IP > Repository, click on the plus button, browse to your repository location, select the repository (ip_repo) and click select. Click Apply and then OK.
Then in the block design click on the plus button to add an IP and choose led_ip_v1.0. The custom IP is added to the block design. In the block configuration properties (double click on the led IP block) the Led Width property should be 1, as we want to control one LED.
Run Connection Automation. The custom IP will be automatically connected to the AXI Interconnect (automatically created). Click on the Regenerate Layout button.
Run Connection Automation again. It will connect the M_AXI_HPM1_FPD port of the Zynq UltraScale+ MPSoC block to the S01_AXI port of the AXI Interconnect (automatically created).
Then, on the led_ip block, right-click on the LED port and make it external. Click on the newly created external LED_0 port and rename it LED.
Go to the Address editor tab. An address must have been assigned to the LED control IP led_ip.
Regenerate Layout (circle arrow button) and validate the design (button with a check sign in a square).
Our block design looks like this :
Right click on the block design in the Sources window (the.bd file) and select Generate output products. You can also click on Generate Block Design from the Flow Navigator, it will open the same Generate Output Products window. Click on generate (leave the default options). It will run out-of-context modules.
We have a green check for each completed synthesis run. If any modification is made to an IP, its synthesis will need to be done again.
HDL WrapperRight click on the block design and select Create HDL Wrapper. Select Let Vivado manage wrapper and auto-update and click OK.
ConstraintsIn the flow navigator pane, click on Add sources and select Add or create constraints. Create a new file named Constraint.xdc with this content :
set_property PACKAGE_PIN D9 [get_ports {LED[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[0]}]This post explains how to get the constraints (for a different board but the principle is the same with our board) : https://adaptivesupport.amd.com/s/question/0D54U00008qiXeHSAU/-info-post-getting-constraint-of-kria-boards-from-its-schematic-and-som-xdc-file?language=en_US
For the KD240 board we use, you can download the schematics on the bottom of this page : https://www.amd.com/en/products/system-on-modules/kria/k24/kd240-drives-starter-kit.html
You can find the raw pinout constraint file for KD24 SoM here : https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/1641152513/Kria+SOMs+Starter+Kits#SOM-XDC-Files
We will connect our LED to the Pmod pin number 2 on the board. As we can see on the Kria kd240 schematic, it's connected to PMOD HDA15. As we can see on the SoM xdc file, PMOD HDA15 is linked to the pin D9 of the SoM. We need 3.3V to power the LED. That's why we use those constraints.
Run synthesis, run implementation and generate bitstreamClick on run synthesis from the flow navigator. Leave the defaults settings and click OK.
When completed, a window will open. Select Run Implementation and click OK. Then leave the default settings and click OK.
When completed, a new window will open. Select Generate Bitstream and click OK. Leave the default settings and click OK.
When completed, don't open the implemented design, just click cancel.
Export hardwareGo to File > Export and click on Export Hardware. Check the Include bitstream option.
It will generate a.XSA file that you will use in Vitis to create the application to control the LED.
The hardware design part is now done. To switch to vitis and do the software design click on Tools > Launch Vitis IDE.
2 - Software in Vitis Unified 2023.2Create a new workspaceClick on Open Workspace in the Vitis Component tab. Create an empty directory and click OK.
Create platform componentIn the Vitis component window, click on Create Platform Component. Choose a name, then choose the previously exported XSA file. It takes Vitis some time to read the XSA. In the Select Operating System and Processor part, select standalone for the Operating system and psu_cortexa53_0 for the Processor. Select the Generate Boot artifacts and Generate PMU Firmware options. Then finish the platform component creation.
After it is generated, build the platform component using the flow tab in the vitis component window. The build of the application we will create after doesn't re-build the platform component so if you modify it you will have to re-build it.
Update UART portsWe need to change the configuration in KD240 BSP. Open vitis-comp.json file in the Setting folder of the platform component. In psu_cortexa53_0 > standalone_psu_cortexa53_0 > Board Support Package > standalone and in psu_cortexa53_0 > zynqmp_fsbl > Board Support Package > standalone change standalone_stdin and standalone_stdout to psu_uart_1, go to Board Support Package and click on Regenerate BSP (for both).
Build the platform component again.
Create application componentIn the welcome tab click on Examples. Select the "Hello World" application and click on Create Application Component from Template. You can leave the component name as it is and click next. In the Select Platform part, choose the platform component previously created, click next. In the select domain part there should be only the standalone_psu_cortexa53_0 choice. Click Next and then finish.
Build the application to check for errors.
With Vitis Unified, the custom IP driver can't be used like a VIVADO based AXI Slave IP driver. On the Board Support tab where drivers are listed, a non-custom AXI GPIO IP driver would be shown but the LED custom IP is not listed.
Additional reference on how to access custom AXISlave IP in Vitis Application (2023.2 or later) -Vitis 2024.1 - Custom RTL IP (AXI IP) driver - How to generate and use ?
That's why to control the LED we will include xil_io.h and use this function :
#include "xil_io.h"
Xil_in32(addr, val);The address for the custom IP used to control the LED can be found in the file xparameters.h (located in the includes of the application component under project_location/platform_name/export/platform_name/sw/standalone_psu_cortexa53_0/include). Open this file and find this address by searching for the IP name LED_IP in the file. We will use the definition of the address (XPAR_LED_IP_0_BASEADDR) in the Xil_in32 function.
In the hello world.c file generated with the Hello World example (located in the sources files of the application), add more includes and modify the main function. The file will be like this :
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xil_io.h"
UINTPTR LED_ptr;
int main()
{
init_platform();
LED_ptr = XPAR_LED_IP_0_BASEADDR;
xil_printf("Turning LED on...\n\r");
Xil_Out32(LED_ptr, 1);
for (int i=0; i<100; i++){
xil_printf("LED on...\n\r");
};
xil_printf("Turning LED off...\n\r");
Xil_Out32(LED_ptr, 0);
xil_printf("Successfully ran LED control application");
cleanup_platform();
return 0;
}Then build the application.
Debug/run the application on the boardTo be able to debug the application on the Kria board, you need to do the Jumper Setup for JTAG.
Just use a cable to connect together the two pins where it is written JTAG MODE on the board (you can see a black cable doing that on the picture at the beginning of the tutorial). If you want more details check this : https://adaptivesupport.amd.com/s/article/000036959?language=en_US
Connect the LED, then connect the Kria kd240 and debug the application to be able to execute the program step by step. You can use a serial port terminal, for example gtkterm, to view the printed messages.
The LED will turn on and then off, and you will be able to see the UART communications in the serial port terminal :
Congratulations !
Kudos to Cédric Le Beaudour (FPGA & Embedded Design - Intern at LogicTronix) for creating this quick tutorial on custom AXI IP design and test with Vitis Unified 2023.2 for the KD240 Kria drives kit.






Comments