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.

This tcl script uses HP port, so this port doesn’t suppport hardware cache coherency (cci-400).

The script with cci-400 will be explained in next blog.

1
2
3
4
5
6
7
8
# 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"
# regenerate block design layout
regenerate_bd_layout

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

Petalinux Config Variables (15 lines)
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
Petalinux Kernel Config Variales (22 lines)
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
Petalinux Rootfs Config Variables (9 lines)
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 (46 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 (49 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
43
44
45
/* 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
    // this driver has to be manually probed by user
    // there is no modprobe.d rule for this official axidmatest driver from the kernel source
    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";
    };

    /* To use the changed PL clock in vivado zynq configuration menu,
     * specify that clock in DT to make the changes effective in the petalinux build.
     */
    fclk0 {
        status = "okay";
        assigned-clocks = <&zynqmp_clk PL0_REF>;
        assigned-clock-rates = <100000000>; // 100MHz
    };
};

/* Override the second channel's device-id to 1 so they are unique; 
 * Some driver expect the channel id to be 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
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 October 22, 2026