Before start, please review this tutorial.
In the DUNE experiment, the DAPHNE photon detection system has undergone an evolution, reaching the use of SoM (System on Modules), aiming for increased compactness in hardware and software task implementation. This transition is also expected to provide better system control and operational security. Given the context of the DUNE experiment, where the system will be located 1 km underground in Fermilab's caverns, with limited accessibility for subsequent system servicing, a high level of security and robustness in system implementation is required. This is where the KRIA KR260 takes center stage as the chosen SoM to manage the photon detection system's operation.
In this tutorial, I'll demonstrate the necessary steps to include the AXI UARTLite peripheral in the PL. This peripheral connects to the PS through the AXI port, receives an assigned address in the Petalinux memory map, and simultaneously, a driver managed by the Device Tree will be mounted. This will make the hardware visible in the device list at /dev.
Once the project is configured in Vivado 2022.2, synthesis and implementation are completed, the bitstream is generated, and the platform is exported. This will be sent, creating the Device Tree Overlay for the KRIA KR260. The embedded hardware will be implemented, and control will be given to the peripherals through the AXI port from Petalinux 2022.2.
Also, please visit the following link containing important information:UartLite Peripheral implementation
- Configuration of UARTLite in Linux
To integrate the UART as an IP Core in the PL side and utilize it within the KRIA KR260 using Petalinux, we need to incorporate the AXI UartLite IP. We'll locate the IP within the IP Catalog
and add it to the block design.
We can configure the IP Core by double-clicking on the block. In this example, we'll modify the Baud Rate to 115200
. You can make any additional changes you deem necessary for your specific project.
After this, proceed with the connections for the IP. You can utilize the Automatic connection tool located in the upper part of the block design window, which will establish the connection for the AXI Interface. Additionally, ensure to connect the Interrupt to the PS side in the ZYNQ UltraScale+.
- To establish this connection, use the
Concat
block and link it to the AXI Interrupt Controller IP. - Furthermore, right-click on the
UART
port in the AXI UartLite IP and selectMake External
. Assign an appropriate name, for example,kria_uart
.
We're following the block design created in this tutorial.
For this purpose, we will employ two additional IPCORE blocks. Initially, theConcat
block will be utilized to consolidate all potential interrupts into a unified bus. The output from the Concat IP block will connect to the Utility Reduced Logic IP block, configured as anOR
gate. The output of this block will link to the AXI Interrupt Controller, which subsequently connects to the PS (Processing System).
The block design should resemble the following:
In this example, we will use the PMOD1 connector to connect the UART
peripheral to the exterior of the KRIA.
Create the constrains file comm_uart.xdc
using the following pinout:
##################### PMOD 1 Upper ###################################
set_property PACKAGE_PIN H12 [get_ports {kria_uart_rxd}]
set_property IOSTANDARD LVCMOS33 [get_ports {kria_uart_rxd}]
#set_property PACKAGE_PIN E10 [get_ports {pmod1_io_tri_io[1]}]
#set_property IOSTANDARD LVCMOS33 [get_ports {pmod1_io_tri_io[1]}]
#set_property PACKAGE_PIN D10 [get_ports {pmod1_io_tri_io[2]}]
#set_property IOSTANDARD LVCMOS33 [get_ports {pmod1_io_tri_io[2]}]
#set_property PACKAGE_PIN C11 [get_ports {pmod1_io_tri_io[3]}]
#set_property IOSTANDARD LVCMOS33 [get_ports {pmod1_io_tri_io[3]}]
##################### PMOD 1 Lower ###################################
set_property PACKAGE_PIN B10 [get_ports {kria_uart_txd}]
set_property IOSTANDARD LVCMOS33 [get_ports {kria_uart_txd}]
#set_property PACKAGE_PIN E12 [get_ports {pmod1_io_tri_io[5]}]
#set_property IOSTANDARD LVCMOS33 [get_ports {pmod1_io_tri_io[5]}]
#set_property PACKAGE_PIN D11 [get_ports {pmod1_io_tri_io[6]}]
#set_property IOSTANDARD LVCMOS33 [get_ports {pmod1_io_tri_io[6]}]
#set_property PACKAGE_PIN B11 [get_ports {pmod1_io_tri_io[7]}]
#set_property IOSTANDARD LVCMOS33 [get_ports {pmod1_io_tri_io[7]}]
Once at this point, we can perform the synthesis, implementation, and bitstream generation which will be loaded onto the PL side. This process generates an address map for the AXI interface. This address interface can be accessed from the PS side using the devmem
command in Linux.
For this step, visit this tutorial in the section Generate the Device Tree Overlay from the PL Design.
The device tree blob containing the overlay nodes must be compiled for the design, which can be easily achieved using the Xilinx Software Command Line Tools (XSCT):
source /tools/Xilinx/Vitis/2022.2/settings64.sh ~/Kria_KR260$
xsct
Open the exported XSA from Vivado and utilize the createdts
command to generate the device tree source files for the PL design:
xsct% hsi::open_hw_design kria_base.xsa
xsct% createdts -hw kria_base.xsa -zocl -platform-name kria_kr260 -git-branch xlnx_rel_v2022.2 -overlay -compile -out ./dtg_kr260_v0
xsct% exit
Upon exiting XSCT, utilize the standard Linux device tree compiler (dtc
) to compile the source files into the necessary device tree blob:
dtc -@ -O dtb -o ./dtg_kr260_v0/dtg_kr260_v0/kria_kr260/psu_cortexa53_0/device_tree_domain/bsp/pl.dtbo ./dtg_kr260_v0/dtg_kr260_v0/kria_kr260/psu_cortexa53_0/device_tree_domain/bsp/pl.dtsi
Transferring the PL Design Files to KR260I prefer creating a folder to collect all necessary design files that need to be uploaded to the KR260 for an accelerated application or PL design (note: the Kria_KR260 directory is the top-level directory of the Vivado project).
mkdir -p comm_file_transfer
cd ./comm_file_transfer/
Here, I'll create the description file, shell.json
, for the design:
nano shell.json
Then, copy and paste the following content into shell.json
:
{
"shell_type": "XRT_FLAT",
"num_slots": "1"
}
Next, copy the generated device tree blob and .bin file into the folder:
cp../dtg_kr260_v0/dtg_kr260_v0/kria_kr260/psu_cortexa53_0/device_tree_domain/bsp/pl.dtbo ./
cp ../Kria_KR260.runs/impl_1/kria_bd_wrapper.bin ./
Rename the device tree blob and .bin file to the same name, with the only difference being their respective file extensions (also change the .bin
extension to .bit.bin
):
mv kria_bd_wrapper.bin kr260_comm.bit.bin
mv pl.dtbo kr260_comm.dtbo
Then, with the KR260 powered on and running the Petalinux, connected to the local network, transfer the new PL design files to it:
scp kr260_comm.dtbo kr260_comm.bit.bin shell.json petalinux@<KR260’s IP address>:/home/petalinux
Run PL Design on KR260This part of the tutorial is execute in the KRIA KR260, you need to connect to it through SSH using the follow command and your access password:
ssh petalinux@xilinx-kr260-starterkit-20222
After successfully transferring the files to the KR260, create a directory in the /lib/firmware/xilinx
directory using the same name given to the device tree blob and .bin file, and then copy these files into it:
sudo mkdir /lib/firmware/xilinx/kr260_comm
sudo mv kr260_comm.dtbo kr260_comm.bit.bin shell.json /lib/firmware/xilinx/kr260_comm
At this stage, the PL design will appear just like an accelerated application would using the xmutil
commands:
sudo xmutil listapps
Unload the default application and then load the PL design, which flashes the PL design’s bitstream into the PL and loads its device tree overlay:
sudo xmutil unloadapp
sudo xmutil loadapp kr260_comm
Once here, you can verify the serial port added on the PS side using the following command:
dmesg | grep serial
You should receive the following output in the console:
[ 4.217686] ff010000.serial: ttyPS1 at MMIO 0xff010000 (irq = 60, base_baud = 6249999) is a xuartps
[ 11.179198] systemd[1]: Created slice Slice /system/serial-getty.
[ 6683.166373] 80010000.serial: ttyUL0 at MMIO 0x80010000 (irq = 74, base_baud = 0) is a uartlite
Where ttyUL0
corresponds to the peripheral with 0x80010000
address, as indicated in the AXI address map. This refers to the AXI UartLite IP.
Additionally, you'll need to modify the permissions for the device using the following command:
sudo chmod 777 /dev/ttyUL0
Testing UartLiteTo conduct this test, establish a loopback connection between the txd
(transmit) and rxd
(receive) pins. This configuration enables the verification of both write and read operations simultaneously through the communication channel.
Also, you can use the following Python code, which utilizes the pyserial library. To install the library, execute the following command:
python -m pip install pyserial
Python CodeCreate a file named Serial_test.py
and paste the following script:
# Testing Uartlite with petalinux and python using KRIA
import serial
# configuration of serial port
ser = serial.Serial()
ser.port = "/dev/ttyUL0"
ser.baudrate = 115200
# open the port and begin the test
ser.open() # open the port
ser.flush() # clean the buffer
# Send data to Uartlite
n = ser.write('Hi, this is a KRIA test'.encode())
dato = ser.read(n).decode() # read data from serial
print(dato)
ser.close() # close the serial port
To execute the script, use python Serial_test.py
. You should receive the following output:
Hi, this is a KRIA test
This is the first in a series of three tutorials where we will demonstrate how to configure the UART
, I2C
, and SPI
interfaces from the PL and utilize them with the PS.
Comments