[FPGA基础] DMA
Xilinx FPGA AXI DMA 使用文档
1. 概述
AXI DMA(Direct Memory Access)是 Xilinx FPGA 中用于高效数据搬运的 IP 核,基于 AXI4 协议,支持存储器映射(AXI4)和流式(AXI4-Stream)数据传输。AXI DMA 广泛应用于处理器与外设间的高速数据传输,如视频处理、网络数据包传输等。本文档详细介绍 Xilinx AXI DMA 的使用,涵盖功能概述、接口描述、设计流程、Vivado IP 配置及示例代码,仅聚焦 AXI DMA。
2. AXI DMA 功能简介
AXI DMA 提供灵活的数据搬运能力,减轻处理器负担,支持以下模式:
- Memory-Mapped to Memory-Mapped (MM2MM):通过 AXI4 接口在存储器间传输数据。
- Memory-Mapped to Stream (MM2S):将存储器数据转换为 AXI4-Stream 数据流。
- Stream to Memory-Mapped (S2MM):将 AXI4-Stream 数据流写入存储器。
- Scatter-Gather (SG):支持非连续存储器块的自动化传输。
- Simple DMA:直接寄存器控制的单次传输。
2.1 AXI DMA 关键特性
- 高带宽:支持突发传输,数据宽度可达32/64/128/256/512位。
- 双向通道:独立的 MM2S 和 S2MM 通道,可同时操作。
- 灵活控制:支持寄存器直接控制或 Scatter-Gather 模式。
- 中断支持:提供完成、错误等中断信号,便于处理器管理。
- 背压处理:通过 AXI4-Stream 的 TREADY 信号支持流控。
3. AXI DMA 接口描述
AXI DMA 包含以下主要接口(基于 PG021 AXI DMA v7.1):
接口名 | 类型 | 描述 |
---|---|---|
ACLK | 输入 | 全局时钟信号,所有接口同步于此。 |
ARESETN | 输入 | 全局复位信号,低电平有效。 |
AXI4-Lite 控制接口 | ||
S_AXI_LITE | AXI4-Lite 从接口 | 用于配置 DMA 寄存器(如控制、状态、缓冲区描述符地址)。 |
AXI4 存储器映射接口 | ||
M_AXI_MM2S | AXI4 主接口 | 读取存储器数据(MM2S 通道)。 |
M_AXI_S2MM | AXI4 主接口 | 写入存储器数据(S2MM 通道)。 |
AXI4-Stream 数据接口 | ||
M_AXIS_MM2S | AXI4-Stream 主接口 | 输出流数据(MM2S 通道)。 |
S_AXIS_S2MM | AXI4-Stream 从接口 | 接收流数据(S2MM 通道)。 |
中断信号 | ||
INTR_OUT | 输出 | 中断信号,通知传输完成或错误。 |
主要信号(以 AXI4-Stream 为例):
- M_AXIS_MM2S:TDATA(数据)、TVALID、TREADY、TLAST(数据包结束)。
- S_AXIS_S2MM:TDATA、TVALID、TREADY、TLAST、TUSER(可选用户信号)。
主要寄存器(通过 AXI4-Lite 访问):
- MM2S_DMACR:控制寄存器(启动/停止、模式选择)。
- MM2S_SA:源地址寄存器(Simple 模式)。
- MM2S_LENGTH:传输长度寄存器。
- S2MM_DMACR、S2MM_DA、S2MM_LENGTH:S2MM 通道类似。
- SG 模式寄存器:如描述符地址、状态寄存器等。
4. Xilinx FPGA 中的 AXI DMA 设计流程
在 Xilinx FPGA 中使用 AXI DMA 通常包括以下步骤:
4.1 需求分析
- 确定传输模式:MM2S、S2MM 或双向。
- 选择控制模式:Simple DMA(单次传输)或 Scatter-Gather(多块传输)。
- 确定数据宽度(32/64/128位等)和突发长度(最大256)。
- 分析存储器类型(DDR、BRAM)及带宽需求。
4.2 使用 Vivado IP 核
Vivado 提供 AXI DMA IP 核(PG021),以下为配置和相关 IP:
-
AXI DMA (PG021):
- 功能:核心 DMA 功能,支持 MM2S、S2MM 和 Scatter-Gather。
- 配置:
- 通道选择:启用 MM2S、S2MM 或两者。
- 数据宽度:32/64/128/256/512位。
- 模式:Simple DMA 或 Scatter-Gather。
- 突发长度:最大256次。
- 其他:中断使能、缓冲区深度等。
- 用途:处理器与 PL 间的高速数据搬运。
-
AXI Interconnect (PG059):
- 功能:连接 AXI4 和 AXI4-Lite 接口,支持时钟域和数据宽度转换。
- 配置:支持多主多从,数据宽度匹配 DMA 设置。
- 用途:连接 DMA 到存储器(如 DDR)或处理器。
-
AXI4-Stream Data FIFO (PG080):
- 功能:缓冲 AXI4-Stream 数据,支持异步时钟域。
- 配置:数据宽度匹配 DMA,深度可调。
- 用途:处理背压,平滑数据流。
-
Block Memory Generator (PG058):
- 功能:提供片上 BRAM,连接 AXI DMA 的存储器接口。
- 配置:数据宽度和深度匹配 DMA。
- 用途:小型存储器测试或低延迟应用。
-
AXI Verification IP (PG267):
- 功能:仿真验证 AXI4 和 AXI4-Stream 协议。
- 配置:模拟 DMA 的主/从接口。
- 用途:验证 DMA 配置和自定义逻辑。
在 Vivado 中:
- 打开 IP Catalog,搜索“AXI DMA”。
- 添加 AXI DMA IP,配置通道、数据宽度、模式等。
- 使用 Block Design 连接 AXI Interconnect、存储器(如 DDR 或 BRAM)和 AXI4-Stream 外设。
- 生成 IP 核并综合设计。
4.3 软件驱动开发
- 嵌入式系统(如 Zynq PS):
- 使用 Xilinx SDK 或 Vitis,加载 AXI DMA 驱动(xaxidma.h)。
- 配置 DMA 寄存器,设置源/目的地址、传输长度。
- 处理中断,监控传输状态。
- Scatter-Gather 模式:
- 准备缓冲区描述符链表,写入描述符地址寄存器。
- 使用驱动 API 管理描述符。
4.4 时序设计
- 确保 AXI4 和 AXI4-Stream 接口与 ACLK 同步。
- 使用 ARESETN 初始化 DMA 和相关逻辑。
- 遵循 VALID/READY(AXI4-Lite 和 AXI4-Stream)握手协议。
4.5 调试
- 使用 Vivado ILA 捕获 AXI4 和 AXI4-Stream 信号。
- 检查寄存器配置(通过 AXI4-Lite)、TVALID/TREADY 握手和 TLAST。
- 验证传输长度、地址对齐和中断触发。
- 使用 SDK/Vitis 调试器监控驱动行为。
5. 示例:AXI DMA MM2S 配置(Verilog + 驱动)
以下为 AXI DMA 的 Vivado 配置和简单驱动代码示例,展示 MM2S 传输(存储器到流)。
5.1 Vivado 配置
-
添加 AXI DMA IP:
- 数据宽度:32位。
- 启用 MM2S 通道,禁用 S2MM。
- 模式:Simple DMA。
- 突发长度:16。
- 启用中断。
-
连接 Block Design:
- AXI4-Lite:连接到处理器(如 Zynq PS)。
- M_AXI_MM2S:连接到 AXI Interconnect,再到 DDR 或 BRAM。
- M_AXIS_MM2S:连接到 AXI4-Stream 从设备(如自定义 IP 或 FIFO)。
- INTR_OUT:连接到处理器中断控制器。
-
生成位流:
- 综合、实现并生成 FPGA 比特流。
5.2 简单 AXI4-Stream 从设备(Verilog)
module axi4_stream_slave #(parameter C_S_AXIS_DATA_WIDTH = 32
) (input wire s_axis_aclk,input wire s_axis_aresetn,input wire [C_S_AXIS_DATA_WIDTH-1:0] s_axis_tdata,input wire s_axis_tvalid,output wire s_axis_tready,input wire s_axis_tlast
);// 简单接收逻辑
reg [C_S_AXIS_DATA_WIDTH-1:0] data_buffer [0:15];
reg [3:0] buffer_index;
reg tready;assign s_axis_tready = tready;always @(posedge s_axis_aclk or negedge s_axis_aresetn) beginif (!s_axis_aresetn) begintready <= 1'b0;buffer_index <= 4'b0;end else begintready <= (buffer_index < 15); // 缓冲区未满if (s_axis_tvalid && tready) begindata_buffer[buffer_index] <= s_axis_tdata;if (s_axis_tlast) beginbuffer_index <= 4'b0;end else if (buffer_index < 15) beginbuffer_index <= buffer_index + 1;endendend
endendmodule
5.3 驱动代码(C,基于 Zynq PS)
#include <xaxidma.h>
#include <xparameters.h>
#include <xil_printf.h>#define DMA_DEV_ID XPAR_AXIDMA_0_DEVICE_ID
#define TX_BUFFER_BASE 0x10000000 // DDR 地址
#define TX_LENGTH 64 // 传输字节数XAxiDma AxiDma;int main() {XAxiDma_Config *CfgPtr;int Status;// 初始化 DMACfgPtr = XAxiDma_LookupConfig(DMA_DEV_ID);Status = XAxiDma_CfgInitialize(&AxiDma, CfgPtr);if (Status != XST_SUCCESS) {xil_printf("DMA 初始化失败\r\n");return XST_FAILURE;}// 禁用中断,Simple 模式XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DMA_TO_DEVICE);// 设置 MM2S 传输Status = XAxiDma_SimpleTransfer(&AxiDma, TX_BUFFER_BASE, TX_LENGTH, XAXIDMA_DMA_TO_DEVICE);if (Status != XST_SUCCESS) {xil_printf("DMA 传输启动失败\r\n");return XST_FAILURE;}// 等待传输完成while (XAxiDma_Busy(&AxiDma, XAXIDMA_DMA_TO_DEVICE)) {// 忙等待}xil_printf("DMA 传输完成\r\n");return XST_SUCCESS;
}
5.4 示例说明
- 硬件:AXI DMA 配置为 MM2S 模式,从 DDR 读取数据并输出到 AXI4-Stream 从设备。Verilog 代码实现简单的流接收逻辑。
- 软件:Zynq PS 通过 AXI4-Lite 配置 DMA,启动 Simple 模式传输,读取 DDR 数据。
- 功能:从 DDR 地址 0x10000000 读取 64 字节数据,传输到流接口。
- 可扩展为 Scatter-Gather 模式,处理非连续数据。
6. 注意事项
-
时钟与复位:
- 确保 AXI4、AXI4-Stream 和 AXI4-Lite 接口与 ACLK 同步。
- 使用 ARESETN 初始化 DMA 和外设。
-
握手协议:
- 确保 AXI4-Stream 的 TVALID/TREADY 正确握手,避免数据丢失。
- AXI4-Lite 配置需等待 READY 信号。
-
存储器对齐:
- 源/目的地址需与数据宽度对齐(如32位对齐4字节)。
- 突发传输需符合存储器边界。
-
性能优化:
- 增大突发长度(最大256)以提高带宽。
- 使用 Scatter-Gather 模式处理大块或非连续数据。
- 启用中断以减少处理器轮询开销。
-
调试与验证:
- 使用 AXI VIP 验证 AXI4 和 AXI4-Stream 接口。
- 通过 ILA 检查寄存器配置、握手信号和 TLAST。
- 使用 SDK/Vitis 调试器验证驱动行为。
7. 设计工具推荐
- SZ901:
SZ901 是一款基于XVC协议的FPGA网络下载器。- 最高支持53M
- 支持4路JTAG独立使用
- 支持端口合并
- 支持国产FLASH烧写
- 下载器无限扩展
- 配备专属程序固化软件,一键烧写,能大大减小程序固化时间!