[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_LITEAXI4-Lite 从接口用于配置 DMA 寄存器(如控制、状态、缓冲区描述符地址)。
AXI4 存储器映射接口
M_AXI_MM2SAXI4 主接口读取存储器数据(MM2S 通道)。
M_AXI_S2MMAXI4 主接口写入存储器数据(S2MM 通道)。
AXI4-Stream 数据接口
M_AXIS_MM2SAXI4-Stream 主接口输出流数据(MM2S 通道)。
S_AXIS_S2MMAXI4-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_DMACRS2MM_DAS2MM_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 中:

  1. 打开 IP Catalog,搜索“AXI DMA”。
  2. 添加 AXI DMA IP,配置通道、数据宽度、模式等。
  3. 使用 Block Design 连接 AXI Interconnect、存储器(如 DDR 或 BRAM)和 AXI4-Stream 外设。
  4. 生成 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 配置

  1. 添加 AXI DMA IP

    • 数据宽度:32位。
    • 启用 MM2S 通道,禁用 S2MM。
    • 模式:Simple DMA。
    • 突发长度:16。
    • 启用中断。
  2. 连接 Block Design

    • AXI4-Lite:连接到处理器(如 Zynq PS)。
    • M_AXI_MM2S:连接到 AXI Interconnect,再到 DDR 或 BRAM。
    • M_AXIS_MM2S:连接到 AXI4-Stream 从设备(如自定义 IP 或 FIFO)。
    • INTR_OUT:连接到处理器中断控制器。
  3. 生成位流

    • 综合、实现并生成 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) begin
    if (!s_axis_aresetn) begin
        tready <= 1'b0;
        buffer_index <= 4'b0;
    end else begin
        tready <= (buffer_index < 15); // 缓冲区未满
        if (s_axis_tvalid && tready) begin
            data_buffer[buffer_index] <= s_axis_tdata;
            if (s_axis_tlast) begin
                buffer_index <= 4'b0;
            end else if (buffer_index < 15) begin
                buffer_index <= buffer_index + 1;
            end
        end
    end
end

endmodule

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;

    // 初始化 DMA
    CfgPtr = 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. 注意事项

  1. 时钟与复位

    • 确保 AXI4、AXI4-Stream 和 AXI4-Lite 接口与 ACLK 同步。
    • 使用 ARESETN 初始化 DMA 和外设。
  2. 握手协议

    • 确保 AXI4-Stream 的 TVALID/TREADY 正确握手,避免数据丢失。
    • AXI4-Lite 配置需等待 READY 信号。
  3. 存储器对齐

    • 源/目的地址需与数据宽度对齐(如32位对齐4字节)。
    • 突发传输需符合存储器边界。
  4. 性能优化

    • 增大突发长度(最大256)以提高带宽。
    • 使用 Scatter-Gather 模式处理大块或非连续数据。
    • 启用中断以减少处理器轮询开销。
  5. 调试与验证

    • 使用 AXI VIP 验证 AXI4 和 AXI4-Stream 接口。
    • 通过 ILA 检查寄存器配置、握手信号和 TLAST。
    • 使用 SDK/Vitis 调试器验证驱动行为。

7. 设计工具推荐

  • SZ901
    SZ901 是一款基于XVC协议的FPGA网络下载器。
    • 最高支持53M
    • 支持4路JTAG独立使用
    • 支持端口合并
    • 支持国产FLASH烧写
    • 下载器无限扩展
    • 配备专属程序固化软件,一键烧写,能大大减小程序固化时间!
<think>好的,我现在需要解决用户在FPGA中遇到的AXI DMA相关错误问题。首先,我得回忆一下AXI DMA的基本工作原理和常见错误类型。用户可能遇到的问题可能包括数据传输失败、DMA通道无法启动、中断未触发等。根据提供的引用资料,特别是引用[5]提到的常见问题解决方案,可以找到一些线索。 首先,用户提到的错误可能涉及驱动配置、设备树设置、DMA通道配置或硬件连接。例如,设备树中的DMA节点是否正确引用了DMA控制器的地址和通道?驱动是否加载正确?引用[1]中的设备树示例显示了如何配置axi_dma_0的通道,用户需要检查自己的设备树是否类似,特别是dmas和dma-names是否正确。 接下来,用户可能需要检查驱动是否支持当前的DMA IP核版本。引用[4]提到项目支持Xilinx 4.x内核,如果用户使用的是其他版本,可能会有兼容性问题。此外,零拷贝功能(引用[2])是否被正确启用,内存分配是否对齐,这也是常见问题点。 然后,硬件层面的问题也不容忽视。比如AXI信号线的时序是否正确,DMA控制器的时钟和复位是否稳定。用户可能需要使用Vivado的调试工具,如ILA,来捕获信号,查看传输过程中是否有错误发生。 另外,中断处理是否正确配置?DMA传输完成后是否触发了中断,而驱动是否能够正确处理这些中断?引用[5]提到驱动需要正确的中断绑定,用户应检查设备树中的中断号是否与实际硬件匹配。 最后,建议用户按照步骤逐一排查:从设备树配置开始,确认驱动加载,测试DMA传输,检查硬件信号。如果问题依旧,可能需要查看驱动的日志信息,或者参考社区和文档中的类似案例。</think>### FPGA AXI DMA错误解决方案分步指南 #### 1. 验证设备树配置 - **关键点**:检查DMA通道定义与硬件地址是否匹配,确认`dmas`属性引用正确的DMA控制器和通道ID。 - **操作步骤**: 1. 对比设备树中的DMA节点与硬件设计文件(如Vivado Block Design中的地址映射)。例如: ```dts &axi_dma_0 { dma-channel@40400000 { // 检查基地址是否与硬件一致 xlnx,device-id = <0x0>; // TX通道ID }; dma-channel@40400030 { xlnx,device-id = <0x1>; // RX通道ID }; }; ``` 2. 确保`axidma_chrdev`节点中的`dmas`属性顺序正确:`<&dma_controller 通道ID>`,如引用[1]的示例。 - **常见错误**:通道ID顺序颠倒导致TX/RX方向混淆[^1]。 #### 2. 驱动加载与版本兼容性 - **关键点**:确认驱动支持当前内核版本和DMA IP核配置。 - **操作步骤**: 1. 使用`dmesg | grep axidma`查看驱动加载日志,确认无`probe failed`错误。 2. 检查驱动源码中的`xilinx_dma.c`是否包含对应IP核的兼容性字符串(如`xlnx,axi-dma-1.00.a`)[^4]。 3. 若使用自定义IP,需在驱动中添加匹配的`of_device_id`条目。 #### 3. 内存对齐与零拷贝配置 - **关键点**:DMA传输要求物理内存连续且对齐(通常4KB边界)。 - **操作步骤**: 1. 用户空间使用`posix_memalign`分配内存: ```c void *buf; posix_memalign(&buf, 4096, BUFFER_SIZE); ``` 2. 驱动中通过`dma_map_single`映射内存,检查返回值是否为有效DMA地址[^2]。 3. 启用零拷贝时,确认SG(Scatter-Gather)模式已配置,IP核支持多包传输。 #### 4. 中断处理调试 - **关键点**:验证中断信号连接和注册状态。 - **操作步骤**: 1. 在Vivado中检查AXI DMA IP的`mm2s_introut`和`s2mm_introut`是否连接到PS的中断控制器。 2. 使用`cat /proc/interrupts`查看DMA中断触发次数。 3. 在驱动中添加调试输出,确认中断处理函数被调用: ```c static irqreturn_t axidma_isr(int irq, void *dev) { printk(KERN_INFO "DMA interrupt received\n"); // ...处理逻辑 } ``` #### 5. 硬件信号完整性验证 - **关键点**:使用ILA抓取AXI4-Stream信号时序。 - **操作步骤**: 1. 在Vivado中插入ILA核,监控以下信号: - `m_axis_mm2s_tvalid`/`tready` - `s_axis_s2mm_tvalid`/`tready` - 突发传输时检查`tlast`信号 2. 触发传输后观察信号是否满足时序要求: - TVALID在TREADY为高时保持稳定 - 传输结束标志`tlast`在最后一个数据包置高 #### 6. 使用调试工具链 - **关键点**:通过sysfs和用户空间工具定位问题。 - **操作步骤**: 1. 查看DMA通道状态: ```bash cat /sys/class/axidma/tx_channel_0/status # 应返回"IDLE"或"RUNNING" ``` 2. 使用`axidma_benchmark`测试工具(引用[2]项目)验证基础传输: ```bash axidma_benchmark -t tx -d 0 -l 1024 # 发送1024字节测试数据 ``` 3. 若测试失败,检查返回的错误代码(如`-EIO`表示DMA引擎超时)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值