手把手教你学会 Xilinx PCIE/XDMA 读写DDR系列(三) ——XDMA读写DDR项目工程讲解和下板测试

因最近想通过PCIE把数据从FPGA传到PC,借此机会和大家一起学习XDMA读写DDR

制作不易,记得三连哦,给我动力,持续更新!!!

完整工程文件下载:XDMA读写DDR工程   提取码:4sxh


在前两篇文章的学习中,我们已经成功配置了XDMA读写DDR所需的两个关键IP核,并深入学习了XDMA读写DDR的理论知识。现在是时候趁热打铁,一次性搞定整个XDMA读写DDR工程的构建,并对其功能进行验证了。本章将引导我们逐步完成以下步骤,确保我们的工程顺利实现:

好的,废话不多说,直接来干货!!!!!

一、整体设计全貌

整体设置主要包括四个部分:数据输入部分,读写DDR部分(图中写错了),DDR配置部分,XDMA配置部分。

亮点:同时接出来了用户数据接口,以后可以很方便的接用户数据,并且此接口为AXI4协议接口,同时也留出来PC端用户接口,用于用户通过PC传输指令到FPGA。

实现整体功能为:实现数据流到DDR,然后通过PCIE读出,并从PCIE写数据,然后读DDR的回环测试。

数据流方向:user DATA -->> DDR --> PC --> DDR --> uesr DATA

接下来讲把每个模块单独拎出来,独立进行讲解。

二、模块介绍

(1)数据输入模块

        此模块的功能:为此设计模拟输入数据源,同时也为以后用户外接数据留出接口

        主要通过AXI_data_out模块产生AXI数据,然后通过AXI data fifo对数据进行缓存,然后输出标准的AXI协议的数据。

AXI_data_out具体部分代码:

module AXI_data_OUT (
  input wire clk,
  input wire rst_n,
  output reg valid,
  output reg last,
  input wire fifo_ready,
  output reg [31:0] data
);

  reg [11:0] count;

  always @(posedge clk or posedge rst_n) begin
    if (~rst_n) 
        count <= 0;
    else if (count < 400)
        count <= count + 1;
    else
        begin
            count <= 0;
        end 
    end
  
/* 
因
字
数
限
制
  
部
分
代
码
省
略
*/


endmodule

(2)读写DDR模块

        此模块主要为把用户数据写入DDR,以及读出PC端写入DDR的数据,进行软硬件数据交互,并且通过总线连接到AXI connect IP。

        通过wr_addr模块把数据转化成总线形式,把数据地址和数据通过AXI协议总线连接到AXI Smartconnect IP,同时添加ILA查看读写数据总线状态,方便后期调试数据使用。

        

wr_addr部分具体代码:

module wr_addr
(
    input                       clk,
    input                       rst_n,
    
    input                       i_valid,
    input                       i_last,
    input   [31:0]              i_data,
    output  reg                 fifo_ready,
    
    input                   xdma_valid,
    input                   i_fifo_ready,
    output                  o_valid,
    output                  o_last,
    output  [31:0]          o_data,
    
    
    //AXI总线    
        input wire  m00_axi_init_axi_txn,
		output wire  m00_axi_txn_done,
		output wire  m00_axi_error,
		input wire  m00_axi_aclk,
		input wire  m00_axi_aresetn,
		output wire [C_M00_AXI_ID_WIDTH-1 : 0] m00_axi_awid,
		output wire [C_M00_AXI_ADDR_WIDTH-1 : 0] m00_axi_awaddr,
		output wire [7 : 0] m00_axi_awlen,
		output wire [2 : 0] m00_axi_awsize,
		output wire [1 : 0] m00_axi_awburst,
		output wire  m00_axi_awlock,
		output wire [3 : 0] m00_axi_awcache,
		output wire [2 : 0] m00_axi_awprot,
		output wire [3 : 0] m00_axi_awqos,
		output wire [C_M00_AXI_AWUSER_WIDTH-1 : 0] m00_axi_awuser,
		output wire  m00_axi_awvalid,
		input wire  m00_axi_awready,
		output wire [C_M00_AXI_DATA_WIDTH-1 : 0] m00_axi_wdata,
		output wire [C_M00_AXI_DATA_WIDTH/8-1 : 0] m00_axi_wstrb,
		output wire  m00_axi_wlast,
		output wire [C_M00_AXI_WUSER_WIDTH-1 : 0] m00_axi_wuser,
		output wire  m00_axi_wvalid,
		input wire  m00_axi_wready,
		input wire [C_M00_AXI_ID_WIDTH-1 : 0] m00_axi_bid,
		input wire [1 : 0] m00_axi_bresp,
		input wire [1 : 0] m00_axi_rresp,
		input wire  m00_axi_rlast,
		input wire [C_M00_AXI_RUSER_WIDTH-1 : 0] m00_axi_ruser,
		input wire  m00_axi_rvalid,
		output wire  m00_axi_rready          
);

    wire         aw_ready;
    wire         w_ready;
  
    reg           [31:0]    aw_addr_cnt;

    reg            [1:0]       state, state_next;
    localparam            s0 = 2'b00, s1 = 2'b01, s2 = 2'b10, s3 = 2'b11;
    

/* 
因
字
数
限
制
  
部
分
代
码
省
略
*/
    
   
    assign m00_axi_wdata      = w_data        ;
	assign m00_axi_wvalid     = w_valid       ;
	assign m00_axi_wlast      = w_last        ;
	assign m00_axi_wstrb      = w_strb        ;
	
	assign m00_axi_awaddr     = aw_addr       ;
	assign m00_axi_awlen      = aw_len        ;
	assign m00_axi_awsize     = aw_size       ;
	assign m00_axi_awburst    = aw_burst      ;
	assign m00_axi_awvalid    = aw_valid      ;
	assign aw_ready         = m00_axi_awready ;

	assign b_resp           = m00_axi_bresp   ;
	assign b_valid          = m00_axi_bvalid  ;
	assign m00_axi_bready     = b_ready       ;
	
	
	assign m00_axi_araddr     = ar_addr       ;
    assign m00_axi_arlen      = ar_len        ;
    assign m00_axi_arsize     = ar_size       ;
    assign m00_axi_arburst    = ar_burst      ;
    assign m00_axi_arvalid    = ar_valid      ;
    assign ar_ready         = m00_axi_arready ;
    
    assign r_data           = m00_axi_rdata   ;
    assign r_last           = m00_axi_rlast   ;
    assign r_resp           = m00_axi_rresp   ;
    assign r_valid          = m00_axi_rvalid  ;
    assign m00_axi_rready     = r_ready       ;
  
endmodule

(3)DDR配置模块 和 XDMA配置模块

        这两个模块在前两个章节已经做了具体的介绍,如果需要可以去前两个章节进行详细查看和学习:

DDR配置快速入口:

手把手教你学会 Xilinx PCIE/XDMA 读写DDR系列(一) DDR/MIG配置详细步骤_xlinx pcie xdma 流模式-CSDN博客

XDMA配置快速入口:

手把手教你学会 Xilinx PCIE/XDMA 读写DDR系列(二) ——XDMA详细配置步骤_xdma创建设备流程-CSDN博客

因以前有详细介绍,在这里就不过多介绍了。

三、下板测试

(1)XDMA驱动安装

       1、环境设置

        由于 Xilinx 提供的 XDMA 驱动程序未经过数字认证签名,而是使用测试签名,所以我们还需要在Windows 系统中开启允许加载已进行测试签名的驱动程序,以便启用此驱动程序的安装,否则安装不了XDMA 的驱动。
下面我们介绍如何在 Windows 系统中启用或禁用测试签名代码的使用。按键盘上的 Win+x 快捷键,在弹出的菜单窗口中选择“Windows PowerShell(管理员)(A)” ,以管理员身份运行 PowerShell
在 PowerShell 中输入如下命令以启用测试签名代码的加载:

        在 Windows 系统中启用测试签名代码的加载后, 要使更改生效,必须重新启动计算机。 另外 PCIe 程序下载完成后, 也需要重启电脑(对主机进行热启动),以使电脑能检测到 PCIe 设备,所以现在我们重启安插有开发板的电脑主机。

        2、下载XDMA驱动:

        可以通过官网下载最新版本,也可以 通过直接下载我使用的这个稳定版本

        Windows XDMA驱动下载

        3、安装XDMA驱动

          以 Win10 为例。进入解压缩后的x64\XDMA_Driver\Win10_Release 目录下,鼠标右键点击 XDMA.cer 文件,在弹出的菜单中选择“安装证书(I)”,如下图所示:

然后一路next即可,显示下图表示证书导入成功

        安装完证书后,进入当前目录下的 XDMA_Driver 目录,鼠标右键点击 XDMA.inf 文件,在弹出的菜单中选择“安装(I)”,如下图所示:

在弹出的“Windows 安全中心”界面中选择“始终安装此驱动程序软件(I)”,如下图所示:

弹出操作成功完成窗口, 点击“确定”按钮如下图所示:

(2)下载bit文件测试

通过vivado下载工程编译出的bit文件,然后重启插板卡的主机

1、检测XDMA设备

        完成驱动的安装后,点击设备管理器中的“扫描检测硬件改动” 按钮,会显示出 Xilinx Drivers,如下图所示:

2、测试代码

        进入解压后的驱动文件的bin目录下,里面包含一些使用XDMA驱动程序的基本应用程序如下图所示并执行其中的应用程序的方式是在该文件窗口中:

在打开的Powershell窗口中输入下面命令:

.\xdma_test.exe

        执行结果可以看到, XDMA 使用的是 AXI-MM 接口模式,使用的是双通道的 h2c 和 c2h,在每个 h2c和 c2h 通道上传输 4096 字节的数据并验证数据是匹配的。 从 xdma_test 的检测结果和读写测试中可以知道我们设计的 XDMA Vivado 工程是没有问题的。

3、测试读DDR里面的数据

在打开的Powershell窗口中输入下面命令:

.\xdma_rw.exe c2h_0 read 0x00000000 -b -f datafile4K_rd.bin -l 4096

该命令以二进制的形式创建并打开文件 datafile4k_rd.bin 文件,通过 c2h_0 通道从 DDR 内存地址0x00000000 中读取 4096 字节数据写入到 datafile4k_rd.bin 文件。

测试结果:

如上图用16进制打开之后,就是刚刚在数据输入模块写入的数据,测试结果没问题,说明 此工程从DDR -->PCIE 没问题。

4、测试从PC写数据到DDR

在打开的Powershell窗口中输入下面命令:

.\xdma_rw.exe h2c_0 write 0x00000000 -b -f datafile4K.bin -l 4096

该命令以二进制的形式读取文件 datafile4k.bin 并通过 h2c_0 通道将其前 4096 字节(对于 datafile4k.bin文件而言是整个文件数据) 数据写入到 DDR 内存地址 0x00000000。 执行结果如下图所示:

然后通过ila看DDR的信号:

如上图可以看出,ila上的数据就是从PC写入的3个数据,说明此工程中 PCIE--> DDR也没问题

总结:

这样的话,此工程的读写DDR全部测试完成,并且读写DDR都没有问题,下一次我们可以结合以前写的Aurora的使用,来创建一个通过光纤传输数据到DDR,然后再通过PC读出的一个大工程,这部分后续有时间会继续更新。

如果感觉文章对您有用,麻烦三连支持一下,方便下次用到的时候,就可以快速找到我,非常感谢您的支持!!!

xilliix pcie dma 驱动 (基于 xilnx xdma ip核 4.0 的WDF驱动) --- # XDMA Windows Driver This project is Xilinx's sample Windows driver for 'DMA/Bridge Subsystem for PCI Express v4.0' (XDMA) IP. *Please note that this driver and associated software are supplied to give a basic generic reference implementation only. Customers may have specific use-cases and/or requirements for which this driver is not suitable.* ### Dependencies * Target machine running Windows 7 or Windows 10 * Development machine running Windows 7 (or later) * Visual Studio 2015 (or later) installed on development machine * Windows Driver Kit (WDK) version 1703 (or later) installed on development machine ## Directory Structure ``` / |__ build/ - Generated directory containing build output binaries. |__ exe/ - Contains sample client application source code. | |__ simple_dma/ - Sample code for AXI-MM configured XDMA IP. | |__ streaming_dma/ - Sample code for AXI-ST configured XDMA IP. | |__ user_events/ - Sample code for access to user event interrupts. | |__ xdma_info/ - Utility application which prints out the XDMA core ip | | configuration. | |__ xdma_rw/ - Utility for reading/writing to/from xdma device nodes such | | as control, user, bypass, h2c_0, c2h_0 etc. | |__ xdma_test/ - Basic test application which performs H2C/C2H transfers on | all present channels. |__ inc/ - Contains public API header file for XDMA driver. |__ libxdma/ - Static kernel library for XDMA IP. |__ sys/ - Reference driver source code which uses libxdma |__ README.md - This file. |__ XDMA.sln - Visual Studio Solution. ```
在Windows上对Xilinx XDMA驱动进行测试,我们可以遵循以下步骤: 1. 下载安装Xilinx XDMA驱动:首先,我们需要从Xilinx官方网站上下载安装适用于我们目标设备的XDMA驱动程序。确保选择与您所使用的设备操作系统版本兼容的驱动程序。 2. 配置硬件设置:安装驱动后,我们需要连接Xilinx XDMA适配器到计算机,并确保设备正常工作。这涉及到检查硬件连接、配置适配器、设置中断线路等等,确保所有配置都正确完成。 3. 编译运行示例代码:Xilinx提供了许多示例代码,可以帮助我们了解如何使用XDMA驱动进行数据传输。我们可以选择一个适合我们测试需求的示例代码,按照指导进行编译运行。 4. 测试功能:使用示例代码可以测试Xilinx XDMA驱动在数据传输方面的功能。检查数据传输的性能稳定性,确保数据可以准确地从主机计算机传输到外设设备,以及从外设设备传输回主机。 5. 调试故障排除:在测试过程中,可能会遇到一些问题。如果出现错误或其他异常情况,我们需要根据错误日志或调试工具进行故障排除。这可能涉及检查配置文件、调整驱动设置、查看硬件状态等等。 6. 进行性能测试:对Xilinx XDMA驱动进行性能测试是很重要的。我们可以使用不同大小类型的数据进行测试,评估数据传输速度延迟。这有助于确定驱动的性能瓶颈以及是否满足我们的需求。 7. 编写自己的应用程序:一旦我们确认Xilinx XDMA驱动正常工作并满足我们的需求,我们可以开始编写自己的应用程序。这可以是一个数据采集应用程序、实时数据处理应用程序等等,根据我们的具体应用场景进行开发。 总结起来,测试Xilinx XDMA驱动需要下载安装驱动、配置硬件设置、编译运行示例代码、测试功能、调试故障排除、性能测试以及编写自己的应用程序。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值