Welcome to this comprehensive tutorial on controlling the PMOD IO on the KV260 carrier board using Petalinux 2023.1 and developing IP for it using VitisHLS. The PMOD IO is a versatile input/output interface that allows for the easy integration of a wide range of peripheral modules with FPGA-based systems. This tutorial will walk you through the step-by-step process of configuring the KV260 carrier board running Petalinux 2023.1 to interface with the PMOD IO, enabling you to control LEDs connected to the IO pins of the PMOD connector. Additionally, we will explore the development of IP (Intellectual Property) using VitisHLS, a high-level synthesis tool that simplifies the creation of custom accelerators for FPGA designs. By the end of this tutorial, you will have a solid understanding of how to manipulate the connected LEDs and Vitis HLS to create efficient and robust FPGA-based solutions. Let's get started!
Create IP in Vitis HLS- Launch Vitis HLS and create a new project:
In this step, we have to add the design's source file to our project.
C++ code#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
typedef unsigned short int u16;
u16 pmod_io(u16 io_ctrl, u16 io_num, u16& pmod) {
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE s_axilite port=io_ctrl
#pragma HLS INTERFACE s_axilite port=io_num
#pragma HLS INTERFACE s_axilite port=pmod
u16 pmod_mask;
if (io_ctrl == 0xf){
pmod_mask = 0;
} else if (io_ctrl == 0xa) {
pmod_mask = (1 << io_num);
} else if (io_ctrl == 0x5) {
pmod_mask = (0 << io_num);
} else if (io_ctrl == 0x1) {
pmod_mask = io_num;
} else {
pmod_mask = pmod_mask;
}
pmod = pmod_mask;
return pmod_mask;
}
- Save it as gpio.cpp in the project path.
This function takes three parameters: io_ctrl, io_num, and pmod. io_ctrl is used to specify the control value to determine the action on the PMOD IO. io_num represents the specific PMOD I/O pin number, and pmod is the reference to a variable that will store the result of the function.
The function then checks the value of io_ctrl using conditional statements. Depending on the value of io_ctrl, it sets pmod_mask accordingly. The control values 0xf, 0xa, 0x5, and 0x1 represent different actions: clearing all pins, setting a specific pin to 1, setting a specific pin to 0, and setting pmod_mask directly to io_num, respectively.
The function updates the pmod reference with the calculated pmod_mask and returns the result.
- Add the
gpio.cpp
file to the project - Select the TOP function by clicking browse.
- Testbench is out of the scope of this project.
- Next, select the target FPGA chip for the project. Search for Kria KV260
- Click Finish, and HLS will load the new project:
AXI4-Lite Interface:
In an FPGA design, the AXI (Advanced eXtensible Interface) is a widely used standard for communication between different modules and the processing system (CPU) on the FPGA.
AXI4-Lite is a subset of the AXI4 protocol, optimized for simple, low-bandwidth communication with the CPU. It is commonly used for control registers and configuration interfaces.
The pragmas used in the top-level function, such as #pragma HLS INTERFACE s_axilite port=io_ctrl
, #pragma HLS INTERFACE s_axilite port=io_num
, and #pragma HLS INTERFACE s_axilite port=pmod
, indicate that these variables (io_ctrl, io_num, and pmod) will be accessible through the AXI4-Lite interface.
Control Register Creation:
When an AXI4-Lite interface is specified for a variable, the HLS tool will create a control register for each of these variables in the IP core.
Control registers are memory-mapped registers that provide a way for the CPU to read from and write to the corresponding variables in the IP core.
These registers act as an interface between the CPU and the IP core, allowing the CPU to configure or control the IP core's behavior during runtime.
C Synthesis:
C Synthesis is the process of converting high-level C/C++ code into hardware description languages (HDL) like VHDL or Verilog. It's a step in the HLS flow where the code is transformed into a hardware design suitable for FPGA implementation.
- Select C Synthesis from the drop-down of the green play button icon in the toolbar.
- Click OK in the C Synthesis-Active Solution dialog box.
- If you get the below error during synthesis
ERROR: [HLS 200-1023] Part 'xck26sfvc784-2LV-c' is not installed.
- Select Solution Settings from the Solution menu.
- The Solution Settings (pmod_led) dialog opens. Change the Part by clicking on the part selection button.
- Select as shown below and select xck26sfvc784-2LV-c
- Re-Run the C Synthesis.
- Upon successful completion, a C synthesis summary report will pop up:
- Make a note of the Offset values of the control registers. It is helpful in application development.
- Log
Starting C synthesis ...
D:/Xilinx/Vitis_HLS/2022.1/bin/vitis_hls.bat D:/SampleProjects/Vitis_HLS/GPIO/LED/pmod_led/csynth.tcl
INFO: [HLS 200-10] Running 'D:/Xilinx/Vitis_HLS/2022.1/bin/unwrapped/win64.o/vitis_hls.exe'
INFO: [HLS 200-10] For user 'nrshr' on host 'desktop-4r1j52h' (Windows NT_amd64 version 6.2) on Mon Jul 17 23:21:25 -0700 2023
INFO: [HLS 200-10] In directory 'D:/SampleProjects/Vitis_HLS/GPIO'
Sourcing Tcl script 'D:/SampleProjects/Vitis_HLS/GPIO/LED/pmod_led/csynth.tcl'
INFO: [HLS 200-1510] Running: source D:/SampleProjects/Vitis_HLS/GPIO/LED/pmod_led/csynth.tcl
INFO: [HLS 200-1510] Running: open_project LED
INFO: [HLS 200-10] Opening project 'D:/SampleProjects/Vitis_HLS/GPIO/LED'.
INFO: [HLS 200-1510] Running: set_top pmod_io
INFO: [HLS 200-1510] Running: add_files gpio.cpp
INFO: [HLS 200-10] Adding design file 'gpio.cpp' to the project
INFO: [HLS 200-1510] Running: open_solution pmod_led -flow_target vivado
INFO: [HLS 200-10] Opening solution 'D:/SampleProjects/Vitis_HLS/GPIO/LED/pmod_led'.
INFO: [SYN 201-201] Setting up clock 'default' with a period of 10ns.
INFO: [HLS 200-1611] Setting target device to 'xck26-sfvc784-2LV-c'
INFO: [HLS 200-1505] Using flow_target 'vivado'
Resolution: For help on HLS 200-1505 see www.xilinx.com/cgi-bin/docs/rdoc?v=2022.1;t=hls+guidance;d=200-1505.html
INFO: [HLS 200-1510] Running: set_part xck26-sfvc784-2LV-c
INFO: [HLS 200-1510] Running: create_clock -period 10 -name default
INFO: [SYN 201-201] Setting up clock 'default' with a period of 10ns.
INFO: [HLS 200-1510] Running: csynth_design
INFO: [HLS 200-111] Finished File checks and directory preparation: CPU user time: 0 seconds. CPU system time: 0 seconds. Elapsed time: 0.057 seconds; current allocated memory: 1.431 GB.
INFO: [HLS 200-10] Analyzing design file 'gpio.cpp' ...
INFO: [HLS 200-111] Finished Source Code Analysis and Preprocessing: CPU user time: 0 seconds. CPU system time: 0 seconds. Elapsed time: 3.555 seconds; current allocated memory: 1.431 GB.
INFO: [HLS 200-777] Using interface defaults for 'Vivado' flow target.
INFO: [HLS 200-111] Finished Compiling Optimization and Transform: CPU user time: 0 seconds. CPU system time: 0 seconds. Elapsed time: 8.802 seconds; current allocated memory: 1.431 GB.
INFO: [HLS 200-111] Finished Checking Pragmas: CPU user time: 0 seconds. CPU system time: 0 seconds. Elapsed time: 0.002 seconds; current allocated memory: 1.431 GB.
INFO: [HLS 200-10] Starting code transformations ...
INFO: [HLS 200-111] Finished Standard Transforms: CPU user time: 0 seconds. CPU system time: 0 seconds. Elapsed time: 0.194 seconds; current allocated memory: 1.431 GB.
INFO: [HLS 200-10] Checking synthesizability ...
INFO: [HLS 200-111] Finished Checking Synthesizability: CPU user time: 0 seconds. CPU system time: 0 seconds. Elapsed time: 0.093 seconds; current allocated memory: 1.431 GB.
INFO: [XFORM 203-401] Performing if-conversion on hyperblock to (gpio.cpp:30:2) in function 'pmod_io'... converting 4 basic blocks.
INFO: [HLS 200-111] Finished Loop, function and other optimizations: CPU user time: 1 seconds. CPU system time: 0 seconds. Elapsed time: 0.113 seconds; current allocated memory: 1.431 GB.
INFO: [HLS 200-111] Finished Architecture Synthesis: CPU user time: 0 seconds. CPU system time: 0 seconds. Elapsed time: 0.076 seconds; current allocated memory: 1.431 GB.
INFO: [HLS 200-10] Starting hardware synthesis ...
INFO: [HLS 200-10] Synthesizing 'pmod_io' ...
INFO: [HLS 200-10] ----------------------------------------------------------------
INFO: [HLS 200-42] -- Implementing module 'pmod_io'
INFO: [HLS 200-10] ----------------------------------------------------------------
INFO: [SCHED 204-11] Starting scheduling ...
INFO: [SCHED 204-11] Finished scheduling.
INFO: [HLS 200-111] Finished Scheduling: CPU user time: 0 seconds. CPU system time: 0 seconds. Elapsed time: 0.37 seconds; current allocated memory: 1.431 GB.
INFO: [BIND 205-100] Starting micro-architecture generation ...
INFO: [BIND 205-101] Performing variable lifetime analysis.
INFO: [BIND 205-101] Exploring resource sharing.
INFO: [BIND 205-101] Binding ...
INFO: [BIND 205-100] Finished micro-architecture generation.
INFO: [HLS 200-111] Finished Binding: CPU user time: 0 seconds. CPU system time: 0 seconds. Elapsed time: 0.132 seconds; current allocated memory: 1.431 GB.
INFO: [HLS 200-10] ----------------------------------------------------------------
INFO: [HLS 200-10] -- Generating RTL for module 'pmod_io'
INFO: [HLS 200-10] ----------------------------------------------------------------
WARNING: [RTGEN 206-101] Design contains AXI ports. Reset is fixed to synchronous and active low.
INFO: [RTGEN 206-500] Setting interface mode on port 'pmod_io/io_ctrl' to 's_axilite & ap_none'.
INFO: [RTGEN 206-500] Setting interface mode on port 'pmod_io/io_num' to 's_axilite & ap_none'.
INFO: [RTGEN 206-500] Setting interface mode on port 'pmod_io/pmod' to 's_axilite & ap_vld'.
INFO: [RTGEN 206-500] Setting interface mode on function 'pmod_io' to 'ap_ctrl_none'.
INFO: [RTGEN 206-100] Bundling port 'io_ctrl', 'io_num' and 'pmod' to AXI-Lite port control.
INFO: [RTGEN 206-100] Finished creating RTL model for 'pmod_io'.
INFO: [HLS 200-111] Finished Creating RTL model: CPU user time: 0 seconds. CPU system time: 0 seconds. Elapsed time: 0.258 seconds; current allocated memory: 1.431 GB.
INFO: [HLS 200-111] Finished Generating all RTL models: CPU user time: 0 seconds. CPU system time: 0 seconds. Elapsed time: 0.672 seconds; current allocated memory: 1.431 GB.
INFO: [HLS 200-111] Finished Updating report files: CPU user time: 1 seconds. CPU system time: 1 seconds. Elapsed time: 0.715 seconds; current allocated memory: 1.431 GB.
INFO: [VHDL 208-304] Generating VHDL RTL for pmod_io.
INFO: [VLOG 209-307] Generating Verilog RTL for pmod_io.
INFO: [HLS 200-789] **** Estimated Fmax: 249.63 MHz
INFO: [HLS 200-111] Finished Command csynth_design CPU user time: 2 seconds. CPU system time: 1 seconds. Elapsed time: 15.213 seconds; current allocated memory: 0.000 MB.
INFO: [HLS 200-112] Total CPU user time: 10 seconds. Total CPU system time: 3 seconds. Total elapsed time: 21.36 seconds; peak allocated memory: 1.431 GB.
Finished C synthesis.
Export RTL from HLS- Select Export RTL from the drop-down for the green play button icon in the toolbar.
- Log
Starting Export RTL/Implementation ...
D:/Xilinx/Vitis_HLS/2022.1/bin/vitis_hls.bat D:/SampleProjects/Vitis_HLS/GPIO/LED/pmod_led/export.tcl
INFO: [HLS 200-10] Running 'D:/Xilinx/Vitis_HLS/2022.1/bin/unwrapped/win64.o/vitis_hls.exe'
INFO: [HLS 200-10] For user 'nrshr' on host 'desktop-4r1j52h' (Windows NT_amd64 version 6.2) on Mon Jul 17 23:43:25 -0700 2023
INFO: [HLS 200-10] In directory 'D:/SampleProjects/Vitis_HLS/GPIO'
Sourcing Tcl script 'D:/SampleProjects/Vitis_HLS/GPIO/LED/pmod_led/export.tcl'
INFO: [HLS 200-1510] Running: source D:/SampleProjects/Vitis_HLS/GPIO/LED/pmod_led/export.tcl
INFO: [HLS 200-1510] Running: open_project LED
INFO: [HLS 200-10] Opening project 'D:/SampleProjects/Vitis_HLS/GPIO/LED'.
INFO: [HLS 200-1510] Running: set_top pmod_io
INFO: [HLS 200-1510] Running: add_files gpio.cpp
INFO: [HLS 200-10] Adding design file 'gpio.cpp' to the project
INFO: [HLS 200-1510] Running: open_solution pmod_led -flow_target vivado
INFO: [HLS 200-10] Opening solution 'D:/SampleProjects/Vitis_HLS/GPIO/LED/pmod_led'.
INFO: [SYN 201-201] Setting up clock 'default' with a period of 10ns.
INFO: [HLS 200-1611] Setting target device to 'xck26-sfvc784-2LV-c'
INFO: [HLS 200-1505] Using flow_target 'vivado'
Resolution: For help on HLS 200-1505 see www.xilinx.com/cgi-bin/docs/rdoc?v=2022.1;t=hls+guidance;d=200-1505.html
INFO: [HLS 200-1464] Running solution command: config_export -description {gpio interface}
INFO: [HLS 200-1464] Running solution command: config_export -display_name=PMOD_IO
INFO: [HLS 200-1464] Running solution command: config_export -output=D:/SampleProjects/Vitis_HLS/GPIO
INFO: [HLS 200-1464] Running solution command: config_export -vendor=shreyas
INFO: [HLS 200-1464] Running solution command: config_export -version=1.0.1
INFO: [HLS 200-1510] Running: set_part xck26-sfvc784-2LV-c
INFO: [HLS 200-1510] Running: create_clock -period 10 -name default
INFO: [SYN 201-201] Setting up clock 'default' with a period of 10ns.
INFO: [HLS 200-1510] Running: config_export -description gpio interface -display_name PMOD_IO -output D:/SampleProjects/Vitis_HLS/GPIO -vendor shreyas -version 1.0.1
INFO: [HLS 200-1510] Running: export_design -rtl verilog -format ip_catalog -output D:/SampleProjects/Vitis_HLS/GPIO
INFO: [IMPL 213-8] Exporting RTL as a Vivado IP.
****** Vivado v2022.1 (64-bit)
**** SW Build 3526262 on Mon Apr 18 15:48:16 MDT 2022
**** IP Build 3524634 on Mon Apr 18 20:55:01 MDT 2022
** Copyright 1986-2022 Xilinx, Inc. All Rights Reserved.
source run_ippack.tcl -notrace
ipx::create_core: Time (s): cpu = 00:00:06 ; elapsed = 00:00:07 . Memory (MB): peak = 1637.129 ; gain = 0.000
INFO: [IP_Flow 19-234] Refreshing IP repositories
INFO: [IP_Flow 19-1704] No user IP repositories specified
INFO: [IP_Flow 19-2313] Loaded Vivado IP repository 'D:/Xilinx/Vivado/2022.1/data/ip'.
INFO: [Common 17-206] Exiting Vivado at Mon Jul 17 23:43:56 2023...
INFO: [HLS 200-802] Generated output file export.zip
INFO: [HLS 200-111] Finished Command export_design CPU user time: 2 seconds. CPU system time: 0 seconds. Elapsed time: 27.326 seconds; current allocated memory: 0.000 MB.
INFO: [HLS 200-112] Total CPU user time: 9 seconds. Total CPU system time: 2 seconds. Total elapsed time: 32.765 seconds; peak allocated memory: 1.442 GB.
Finished Export RTL/Implementation.
Vivado Project- Launch Vivado and create a new project:
- Block Design
- Add AXI GPIO, system reset block
- Select the IP catalog in the Flow Navigator, Right click, and select Add Repository, navigate to the
export.zip
from the Vitis HLS.
- Add the PMOD_IO IP block.
- Click on Run Connection Automation, and select all the blocks.
- Create an output port for the PMOD_IO block. Right Click, select Create Port,
- Since only the lower 8 bits of the 16-bit output from the PMOD_IO HLS IP are being used, add a Slice IP block and configure it for the lower 8 bits:
- Connect PMOD_IO output to the slice IN, Slice Out to the output port pmod.
- Run Connection Automation.
- Final Block Design
- Go to Platform Setup and enable the default clock and AXI master port.
- Validate the block design - Save the design; right click on kria_kv260_pmod_bd and select validate design.
- Create HDL Wrapper
- create a new constraints file for the PMOD pins.
(Flow Navigator > Add Sources > Add or create constraints) and copy the following constraints
set_property PACKAGE_PIN H12 [get_ports pmod[0]] ;# PMOD pin 1 - som240_1_a17
set_property PACKAGE_PIN B10 [get_ports pmod[1]] ;# PMOD pin 2 - som240_1_b20
set_property PACKAGE_PIN E10 [get_ports pmod[2]] ;# PMOD pin 3 - som240_1_d20
set_property PACKAGE_PIN E12 [get_ports pmod[3]] ;# PMOD pin 4 - som240_1_b21
set_property PACKAGE_PIN D10 [get_ports pmod[4]] ;# PMOD pin 5 - som240_1_d21
set_property PACKAGE_PIN D11 [get_ports pmod[5]] ;# PMOD pin 6 - som240_1_b22
set_property PACKAGE_PIN C11 [get_ports pmod[6]] ;# PMOD pin 7 - som240_1_d22
set_property PACKAGE_PIN B11 [get_ports pmod[7]] ;# PMOD pin 8 - som240_1_c22
set_property IOSTANDARD LVCMOS33 [get_ports pmod*];
set_property SLEW SLOW [get_ports pmod*];
set_property DRIVE 4 [get_ports pmod*];
- Generate Block Design(Select Synthesis Options to Global.)
- Run Synthesis, Implementation, and generate bitstream with bin file.
- Export the hardware using File > Export > Export Hardware, and then select the Fixed Platform option.
- Create a petalinux project with 2022.2 bsp for KV260.
$ petalinux-create -t project -s ../inputs/xilinx-kv260-starterkit-v2022.2-10141622.bsp --name pmodgpioOS
- Import the hardware platform to the petalinux project
ramesh@notos:~/petalinuxProjects/pmodIO/pmodgpioOS$ petalinux-config --get-hw-description=/mnt/beegfs/home/ramesh/petalinuxProjects/pmodIO/LED/
- Continue with Step 2 from this project
Do the following in rootfs configuration
petalinux-config -c rootfs
Under Filesystem Packages > misc > python3, enable
Under Filesystem Packages > base > i2c-tools, enable
i2c-tools
i2c-tools-dev
Device Tree Overlay- Refer to Step 3 from this project
- Refer to Step 3 from this project
wget https://bootstrap.pypa.io/get-pip.py
python3 get-pip.py
Install SMBUS packagepip3 install smbus2
Testxilinx-kv260-starterkit-20221:~$ sudo xmutil listapps
Password:
Accelerator Accel_type Base Base_type #slots(PL+AIE) Active_slot
k26-starter-kits XRT_FLAT k26-starter-kits XRT_FLAT (0+0) 0,
myApp_i2c XRT_FLAT myApp_i2c XRT_FLAT (0+0) -1
xilinx-kv260-starterkit-20221:~$ sudo xmutil unloadapp
Accelerator successfully removed.
xilinx-kv260-starterkit-20221:~$ sudo xmutil loadapp myApp_i2c
Accelerator loaded to slot 0
xilinx-kv260-starterkit-20221:~$ i2cdetect -l
i2c-1 unknown Cadence I2C at ff030000 N/A
i2c-2 unknown ZynqMP DP AUX N/A
i2c-3 unknown xiic-i2c N/A
xilinx-kv260-starterkit-20221:~$
Note: You may want to add permissionsudo chmod a+rw /dev/i2c-3
Comments
Please log in or sign up to comment.