AXI DMA介绍
本篇博文讲述AXI DMA的一些使用总结,硬件IP子系统搭建与SDK C代码封装参考米联客ZYNQ教程。若想让ZYNQ的PS与PL两部分高速数据传输,需要利用PS的HP(高性能)接口通过AXI_DMA完成数据搬移,这正符合PG021 AXI DMA v7.1 LogiCORE IP Product Guide中介绍的AXI DMA的应用场景:The AXI DMA provides high-speed data movement between system memory and an AXI4-Stream-based target IP such as AXI Ethernet.
如图,AXI DMA主要包括Memory Map和 Stream两部分接口,前者连接PS子系统,后者则连接带有流接口的PL IP核。

其最简单的事直接寄存器模式(Simple DMA),这里需要注意地址对齐的问题:当没有使能地址重对齐的情况下,如果AXI Memory Map数据位宽是32bit,则搬移数据所在地址必须在0x0,0x4,0x8等起始地址上。接下来关注DMA IP核配置界面主要参数:

重点查看以下几个参数:
1 Width of Buffer Length Register:
在直接寄存器模式下,它指定在MM2S_LENGTH和S2MM_LENGTH寄存器的有效比特数。MM2S_LENGTH寄存器指定了MM2S通道传输数据字节数,当CPU写入非零值时开始进行PS到PL的数据搬移,而S2MM_LENGTH对应另一个数据流方向。比特数直接与对应寄存器可写入的最大数直接相关,传输最大字节数= 2^(Width of Buffer Length Register)。此处保持默认14bit,也就是说启动DMA传输的最大数据量是16384byte。
2 Memory Map Data Width:
该参数指定了Memory Map侧数据接口宽度,选定32bit后搬移数据所在内存地址必须与4对齐。
3 Max Burst Size:
之前在讲解PS子系统内部的DMA时介绍过DMA的Burst概念,即分批次传输数据块。此处没有完全看明白手册的介绍,猜想是每次传输的最大数据个数。
二、AXI DMA Loop IP子系统
在利用ZYNQ搭建系统时,经常需要利用各种IP核做所谓的“计算加速”,将重复性高 计算量大 占用较大CPU资源的底层处理交给各个IP核完成。这时PS ->DMA ->PL -> DMA -> PS的环路架构非常适用。这里使用AXI Stream Data FIFO代替自定义IP核作为演示,硬件IP子系统如下:

三、SDK 官方demo解析
首先分析下官方的demo。
xaxidma_example_simple_intr.c主函数中依次完成了:DMA初始化,建立中断系统,使能DMA中断,初始化标志位及发送数据,启动DMA传输以及数据检测。中断部分的内容与PS DMA非常相近,传输完成后进入的中断函数中仅置位了发送或接收完成标志位:
intrHandler DMA启动传输部分如下,调用库函数XAxiDma_SimpleTransfer。以第一个为例,是将RxBufferPtr为数据首地址,MAX_PKT_LEN为字节数,XAXIDMA_DEVICE_TO_DMA为传输方向启动DMA传输数据。MAX_PKT_LEN不能超过之前IP核配置参数指定的16384byte,XAXIDMA_DEVICE_TO_DMA和XAXIDMA_DMA_TO_DEVICE依次指PL-> DMA ->PS以及PS->DMA -> PL方向,也就是PL就是其中的DEVICE。DMA启动函数只有一个地址,这是与PS端DMA最大的区别,因为数据搬移的另一侧是带有无地址的流接口的IP核,该侧“地址”由硬件连接决定。
再来看看搬移数据内存首地址RxBufferPtr和TxBufferPtr.从下边的定义可见MEM_BASE_ADDR是DDR_BASE_ADDR加上一段偏移量的结果,DDR基地址数值从xparameters.h中查看。



四、函数重用封装
官方的代码比较乱,都写在main函数里,米联客教程init_intr_sys()函数完成整个中断系统的建立,将官方demo中main函数DMA测试之前关于中断部分的代码全部封装其中,包括DMA中断初始化,中断控制器初始化,使能中断异常,连接DMA发送与接收中断,DMA中断使能五个过程。

五、AXI总线信号ILA波形分析
AXI Stream主要接口:
tdata:数据 tkeep:字节有效指示 tlast:帧尾指示 tready:准备就绪 tvalid:数据有效指示
一帧数据有64个,每个数据32bit(4byte),一共正好为C代码中MAX_PKT_LEN数值,即256byte。

在PL->DMA->PS方向上,检测tvalid上升沿拉高则触发ILA抓取信号波形。观察到一个奇怪的现象,发现DMA在接收几个数据后拉低ready信号停止接收数据,一段时间后再次拉高继续接收。暂时还不清楚原因,希望知道的朋友指点一二。
