Post

AXIDMA Loopback Test - ZCU102

Using DMA in ZCU102 to exchange data from and to betwenn memory and IP block.

AXIDMA Loopback Test - ZCU102

In this post, we will walk through the bring-up and testing of the AXIDMA using vitis bare-metal examples and the petalinux axidmatest driver. The hardware configuration for this demonstration is based on the setup described at fpgadeveloper.com, you can also refer the youtube video; however, I have provided the full .tcl script for the vivado project to simplify the setup.

This project was developed using vivado 2022.2. To ensure compatibility, you must use the corresponding versions of petalinux and vitis.

1
2
3
4
5
6
7
8
# Open Vivado and use tcl console
# Navigate to home directory and verify path
cd [file normalize ~]
puts "Current working directory: [pwd]"

# Create and navigate to the working directory
file mkdir "[file normalize ~]/axidma-vivado"
cd "[file normalize ~]/axidma-vivado"

Downlaod this .tcl script axi-dma.tcl and save it inside ~/axidma-vivado.

1
2
3
4
5
6
# make sure to save the downloaded tcl script inside this folder ~/axidma-vivado
# source the .tcl file in vivado tcl console
# this also automatically opens the project folder ~/axidma-vivado/axi-dma
source "[file normalize ~]/axidma-vivado/axi-dma.tcl"
# Open the block design
open_bd_design "[file normalize ~]/axidma-vivado/axi-dma/axi-dma.srcs/sources_1/bd/design_1/design_1.bd"

The block diagram would look similar to this;

BD

1
2
3
4
5
6
7
8
9
10
11
12
13
# Run synthesis
launch_runs synth_1 -jobs 2
wait_on_run synth_1
# Run implementation
launch_runs impl_1 -jobs 2
wait_on_run impl_1
# Generate bitstream
launch_runs impl_1 -to_step write_bitstream -jobs 2
wait_on_run impl_1

# Export the Hardware Platform (XSA)
write_hw_platform -fixed -include_bit -force -file "[file normalize ~]/axidma-vivado/axi-dma/design_1_wrapper.xsa"

ZCU102 Petalinux Build

We need few pre-requisites for petalinux build to test the axidma, which includes downloading the offline files of petalinux downloads, sstate-cache for aarch64 and petalinux toolchain. Follow the steps explained in petalinux-starter-guide.

1
2
3
4
5
6
7
8
9
10
11
12
# open ubuntu bash terminal
cd $HOME
# Source petalinux tool chain
source $HOME/petalinux_downloads_sstate_shared/tools/petalinux/2022.2/settings.sh

# create zcu102 petalinux project
petalinux-create -t project --template zynqMP -n zcu102_axi_dma
cd zcu102_axi_dma

petalinux-config --get-hw-description=$HOME/axidma-vivado/axi-dma/design_1_wrapper.xsa
# this opens a blue menuconfig window and change the following config variables

Configuration OptionValueDescription / Purpose 
CONFIG_SUBSYSTEM_BOOTARGS_AUTOyAutomatically generates kernel boot arguments 
CONFIG_SUBSYSTEM_BOOTARGS_EARLYPRINTKyEnables early printk in boot arguments 
CONFIG_SUBSYSTEM_EXTRA_BOOTARGScma=1024MAppends custom extra arguments (e.g., CMA memory allocation) 
CONFIG_SUBSYSTEM_ROOTFS_EXT4yConfigures the root filesystem type as EXT4 
SUBSYSTEM_SDROOT_DEV/dev/sda1Specifies the SD/storage root device partition 
CONFIG_SUBSYSTEM_HOSTNAMEzcu102_axi_dmaSets the target board hostname 
CONFIG_TMP_DIR_LOCATION${PROOT}/build/tmpDefines the Yocto temporary build directory 
CONFIG_PRE_MIRROR_URLfile:///home/user/petalinux_downloads_sstate_shared/downloadsPoints to local source downloads mirror 
CONFIG_YOCTO_LOCAL_SSTATE_FEEDS_URL/home/user/petalinux_downloads_sstate_shared/aarch64Specifies the local shared sstate feed path 
CONFIG_YOCTO_NETWORK_SSTATE_FEEDSnDisables network-based sstate feeds 
CONFIG_YOCTO_BB_NO_NETWORKyForces offline BitBake builds without internet access**

After setting above configs, CONFIG_SUBSYSTEM_USER_CMDLINE will contain final kernel bootargs, which will look like earlycon console=ttyPS0,115200 clk_ignore_unused root=/dev/sda1 rw rootwait cma=1024M


Kernel Configs

1
2
# set the kernel configuration options using 
petalinux-config -c kernel
Kernel Configuration OptionValueDescription / Purpose
CONFIG_DMATESTmEnables the generic DMA test client as a loadable module
CONFIG_XILINX_ZYNQMP_DMAyEnables the Xilinx ZynqMP DMA driver
CONFIG_XILINX_DMATESTmEnables the Xilinx DMA test client as a loadable module
CONFIG_XILINX_VDMATESTmEnables the Xilinx Video DMA test client as a loadable module
CONFIG_CMA_SIZE_MBYTES1024Sets the Contiguous Memory Allocator (CMA) size to 1024 MB
CONFIG_XILINX_DMAyEnables the core Xilinx DMA engine driver
CONFIG_ARM64_4K_PAGES4KBConfigures the ARM64 kernel page size to 4KB
CONFIG_CMAyEnables the Contiguous Memory Allocator subsystem
CONFIG_PARTITION_ADVANCEDyEnables advanced partition table types support
CONFIG_EFI_PARTITIONyEnables GPT (EFI) partition table support
CONFIG_USB_DWC3yEnables DesignWare USB3 DRD controller driver
CONFIG_USB_DWC3_DUAL_ROLEySets USB DWC3 controller to dual-role (Host/Device) mode
CONFIG_USB_SUPPORTyEnables core USB support in the kernel
CONFIG_USB_COMMONyEnables common USB framework files
CONFIG_USB_ARCH_HAS_HCDyIndicates architecture has USB Host Controller Driver support
CONFIG_USByEnables support for USB
CONFIG_USB_XHCI_HCDyEnables xHCI USB controller support (USB 3.0)
CONFIG_USB_XHCI_PLATFORMyEnables generic platform xHCI controller driver

Rootfs Configs

1
2
# set the rootfs configuration options 
petalinux-config -c rootfs
RootFS Configuration Option / RecipeValueDescription / Purpose
CONFIG_libmali-xlnxyEnables the Xilinx Mali GPU user-space library
CONFIG_mali-backend-waylandyConfigures the Mali graphics backend for Wayland
CONFIG_packagegroup-petalinux-westonyIncludes the PetaLinux Weston (Wayland compositor) package group
CONFIG_axidma-driveryEnables the custom AXI DMA driver recipe in the rootfs
CONFIG_auto-loginyEnables automatic console login for the root user

Device tree Overlay

1
2
3
# Build the device tree yocto task to updat the DTSI files
# This will get us system-user.dtsi and pl.dtsi
petalinux-build -c device-tree

Using this command the DMA IP block parameters are succesfully translated to devicetree node, it captures the memory mapped address, scatter gather settings, buffer length, read and write channel properties.

pl.dtsi (45 lines)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/* file: ./components/plnx_workspace/device-tree/device-tree/pl.dtsi
 * CAUTION: This file is automatically generated by Xilinx.
 * Version: XSCT
 */

/ {
	amba_pl: amba_pl@0 {
		#address-cells = <2>;
		#size-cells = <2>;
		compatible = "simple-bus";
		ranges ;
		axi_dma_0: dma@a0000000 {
			#dma-cells = <1>;
			clock-names = "s_axi_lite_aclk", "m_axi_sg_aclk", "m_axi_mm2s_aclk", "m_axi_s2mm_aclk";
			clocks = <&zynqmp_clk 71>, <&zynqmp_clk 71>, <&zynqmp_clk 71>, <&zynqmp_clk 71>;
			compatible = "xlnx,axi-dma-7.1", "xlnx,axi-dma-1.00.a";
			interrupt-names = "mm2s_introut", "s2mm_introut";
			interrupt-parent = <&gic>;
			interrupts = <0 89 4 0 90 4>;
			reg = <0x0 0xa0000000 0x0 0x10000>;
			xlnx,addrwidth = <0x20>;
			xlnx,include-sg ;
			xlnx,sg-length-width = <0xe>;
			dma-channel@a0000000 {
				compatible = "xlnx,axi-dma-mm2s-channel";
				dma-channels = <0x1>;
				interrupts = <0 89 4>;
				xlnx,datawidth = <0x20>;
				xlnx,device-id = <0x0>;
			};
			dma-channel@a0000030 {
				compatible = "xlnx,axi-dma-s2mm-channel";
				dma-channels = <0x1>;
				interrupts = <0 90 4>;
				xlnx,datawidth = <0x20>;
				xlnx,device-id = <0x0>;
			};
		};
	};
};


1
2
# edit the system-user.dtsi to enable usb host mode and axidmatest node
nano project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi
system-user.dtsi (36 lines)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/* the same overlay will be used by both kernel and uboot
 * file: project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi
*/

/include/ "system-conf.dtsi"
/ {

    // this node is needed to test axidma using axidmatest kernel module
    dmatest_0: dmatest@0 {
        compatible = "xlnx,axi-dma-test-1.00.a";
        dmas = <&axi_dma_0 0 &axi_dma_0 1>;
        dma-names = "axidma0", "axidma1";
    };
};

/* Override the second channel's device-id to 1 so they are unique */
&axi_dma_0 {
    dma-channel@a0000030 {
        xlnx,device-id = <0x1>;
    };
};

// usb enable
&usb0 {
    status = "okay";
};

// usb as host mode to boot from flash drive
&dwc3_0 {
    status = "okay";
    dr_mode = "host";
};

Build and Flash

Follow the same exact steps we discussed in

Once you are in u-boot hush shell, will boot kernel from usb flash drive manually

1
2
3
4
5
ext4ls usb 0:1 /boot/
ext4load usb 0:1 0x00200000 /boot/Image
ext4load usb 0:1 0x00100000 /boot/system.dtb
setenv bootargs "console=ttyPS0,115200 root=/dev/sda1 rw rootwait cma=1024M"
booti 0x00200000 - 0x00100000

Once booted will probe the axidmatest kernel module to verify the vivado hardware loopback design.

1
2
3
4
5
6
7
8
9
modprobe axidmatest

# will get following kernel logs which proves the successful integration of DMA and AXIS Data FIFO in loopback
# [  207.251636] dmatest: Started 1 threads using dma0chan0 dma0chan1
# [  207.273131] dma0chan0-dma0c: terminating after 5 tests, 0 failures 2162 iops 182958 KB/s (status 0)

#  you can also try multiple iterations also
modprobe axidmatest iterations=100

This post is licensed under MIT by the author.

© - Sanjaybyranna. All rights reserved

Personal blog post

Last updated on August 27, 2026