Vivado AXI-DMA开发
0. 参考资料
1. AXI DMA概述
AXI DMA即利用AXI接口的Direct Memory Access(直接内存访问),为内存和AXI-Stream流的外设之间提供高带宽内存访问。其功能框图如下图所示:
其中有两类访存数据的接口:Memory Map和Stream。Memory Map(存储映射)的接口是负责读取存储空间(如DDR)的数据(本质是AXI4-Full接口),经过DataMover之后转换成AXI Stream数据(或主或从)。AXI4 Control Strea、AXI4 Memory Map Write/Read 和 AXI4 Stream是Scatter/Gather功能下的接口。AXI-Lite为AXI总线的配置接口。
2. AXI DMA时钟接口介绍
本IP Core共有四个时钟输入:
Signal Ports | Description |
---|---|
m_axi_mm2s_aclk |
用于MM2S接口 |
m_axi_s2mm_aclk |
用于S2MM接口 |
s_axi_lite_aclk |
用于AXI-Lite控制接口 |
m_axi_sg_aclk |
用于Scatter/Gather接口 |
时钟逻辑有同步和异步两种,在同步时钟逻辑下,所有逻辑跑在同一频率下。m_axi_sg_aclk
、m_axi_mm2s_aclk
、m_axi_s2mm_aclk
三个时钟信号需要绑定在同一个时钟源下。s_axi_lite_aclk
可以给一个频率低一点的时钟。在异步时钟逻辑下,只需保证s_aci_lite_aclk
频率小于等于m_axi_sg_aclk
小于等于m_axi_mm2s_aclk
、m_axi_s2mm_clk
中较小的那个。
3. 编程顺序(即想使用AXI-DMA我需要从何开始)
3.1. Direct Register Mode 直接寄存器模式 (Simple DMA, 简单DMA)
在简单DMA模式下,Scatter/Gather功能是用不到的(Disabled),数据传输通过对DMACR(DMA Control Register)、源地址、目的地址和长度寄存器的访问初始化发起传输。传输完成后,如果使能了中断输出,那么DMASR(Status Register).IOC_lrq会有效,生成一个中断输出。MM2S和S2MM均可使用。
DMA的MM2S(存储器映射到Stream通道)的配置:
- MM2S_DMACR.RS = 1 (Run/Stop 比特置1,启动通道运行);DMASR.Halted = 0 (暂停位置低,表示MM2S通道正在运行);
- (可选,推荐,用于中断信号产生)MM2S_DMACR.IOC_IrqEn = 1; MM2S_DMACR.Err_IrqEn = 1;
- MM2S_SA寄存器中写一个有效的源地址。注意源地址需对齐。
(补:何为地址对齐(Data Alignment),假如存储映射区的数据位宽为32b,一个寄存器存储8b的数据,所以32b需要4个寄存器,数据地址应以4进行偏移:0x0, 0x4, 0x8, 0xC. 如果使能数据重对齐(Data-realignment enable, DRE),则AXI Stream的数据只要小于128b,源地址的偏移量可以是任意的) - MM2S_LENGTH寄存其中写要传输的数据的字节数。且该寄存器是必须最后一个配置,其他寄存器配置可以是任意顺序的。
S2MM的操作和上面一模一样…
3.2. IPCore的使用(Vivado平台)
下图为VIvado 2019.2平台中的AXI-DMA IP核(v7.1)的配置界面
大部分的配置接口都在上面有提到,详细的可以参考PG021手册。下面我们用一个简单的例子来演示怎么用AXI DMA。
3.2.1 创建 ZYNQ7000 Block design
加入Zynq7 Processing System IP,并作如下配置:
①: 找到PS-PL Configuration,在HP Slave AXI Interface中找到S AXI HP0 Interface并勾选启用
②: 依然在PS-PL Configuration界面中,在General->Enable Clock Resets勾选FCLK_RESET0_N
③: 在AXI Non Secure Enablement->GP Master AXI Interface中勾选M AXI GP0 Interface
④: 找到Clock Configuration界面,在PL Fabric Clocks中勾选FCLK_CLK0并更改时钟频率为100MHz。
⑤: 设置中断:找到Interrupts,勾选Fabric Interrupts并在下拉菜单PL-PS Interrupt Ports中勾选IRQ_F2P[15:0]
⑥: 点击OK
3.2.2 添加AXI DMA IP核
①: 在IP库中搜索AXI DMA并添加到当前的Block Design中。(详细步骤见图)
②: 取消勾选Enable Scatter Gather Engine
③: 点击OK
3.2.3 添加AXI4 Stream Data FIFO IP核
在IP库中搜索AXI4 Stream FIFO并添加到当前的Block Design中。(详细步骤见图),保持默认设置即可。
3.2.4 将AXI DMA的中断信号与PS端互联
AXI DMA的两个中断输出信号mm2s_introut和s2mm_introut均为一位,我们想将他们合并成一个两位的数据输入PS端。这时候需要一个COncat IP核进行合路。
①: 在IP库搜索Concat并添加到当前Block Design中。
3.2.5 连线
①: 点击工程上方的Run Connection Automation
②: 在弹出窗口中勾选所有接口,点击OK。
现在的工程不出意外应该长这个样子:
但还有两个模块没有连,我们继续点击Run Connection Automation,点击OK.
目前的工程长这个样子,至此软件能帮我们自动连线的部分就是这么多了。
③: 手动连接以下接口:
接口1 | 接口2 |
---|---|
AXI4 Stream Data FIFO, M_AXIS | AXI Direct Memory Access, S_AXIS_S2MM |
AXI4 Stream Data FIFO, S_AXIS | AXI Direct Memory Access, M_AXIS_MM2S |
AXI Direct Memory Access, mm2s_introut | Concat, In0[0:0] |
AXI Direct Memory Access, s2mm_introut | Concat, In1[0:0] |
Concat, dout[1:0] | Zynq7 Processing System, I2Q_F2P[0:0] |
④: 又出现Run Connection Automation, 因为我们还没有配置FIFO的时钟复位等接口。继续点击它:
不做任何修改,点击OK。
至此,工程创建完成,为下图所示。
3.2.6 生成RTL输出文件
注意,在此之前一定要做Create HDL Wrapper.
在Sources->Design Sources->design_1 (design_1.bd)上右键点击Generate Output Products. 在弹出界面中更改Synthesis Options为Out of context per IP。必要时可增大Number of jobs。点击Generate。
等待RTL工程生成完成。
3.2.7 生成比特流
点击Generate Bitstream.
生成之后,点击Cancel。准备之后的SDK生成。
3.2.8 生成SDK
①: 点击File->Export->Export Hardware。弹出窗口中勾选Include bitstream,其余不变。点击OK。
②: 点击File->Launch SDK (高版本的Vivado由于集成Vitis的缘故,点击Tools->Launch Vitis)
3.2.9 PS端的AXI DMA相关API调用
此部分大多参考Xilinx Vivado/Vitis SDK的Board Support Packages(BSP)中的AXI DMA示例程序:axidma: Vitis Drivers API Documentation
PS: 主播也是今天才知道有Integrated Logic Analyzer(ILA)和Remote Target(远程目标下板)这种操作的。这就去给服务器装Vivado 2021.2(喜)