Xilinx PCIE DMA--Sparten6/Kintex-7 BMD 搭建

本文深入解析PCIe DMA技术,以Xapp1052为案例,详细介绍了FPGA与PC之间的DMA数据流,包括DMA操作原理、软件开发环境搭建、Kintex-7 BMD工程构建及Sparten6 BMD工程搭建。同时,提供了基于Windriver的软件开发指导,适合初学者入门。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

前言

1、DMA数据流简介

1.1 FPGA发DMA数据到PC

1.2 数据从PC搬到FPGA

2、PCIE 软件开发环境

3、Xapp1052下载

4、Kintex-7 BMD工程搭建

5、Sparten6 BMD工程搭建

参考文献


 

 

前言

本文主要以xapp1052作为学习材料,以Sparten6/Kintex-7芯片作为搭建BMD工程举例。

关于BMD工程的仿真环境的搭建,可以参考“Xilinx PCIE DMA 仿真环境搭建”

相关博客可以参考:

         五、Xilinx PCIE CORE学习

        六、Xilinx PCIE DMA--Sparten6/Kintex-7 BMD

        七、Xilinx PCIE DMA 仿真环境搭建

        八、 win10 jungo windriver

 

 

本文仅是基于xapp1052,搭建两种芯片的BMD工程。

关于xapp1052有几点说明:

(1)首先,官方提供的xapp1052工程,主要用于测试DMA收发数据的效率,

          官方提供完整的DMA收发示例、PIO仿真文件、示例工程可以板级调试;

(2)其次,该xapp1052工程没有将PC发送的FPGA的数据存储下来,而仅是与一个固定数值做比较,测试DMA传输效率;

(3)以及,该xapp1052工程发送的数据,仅是发送 通过PIO配置WDMATLPP寄存器里的数据,即用于测试DMA传输效率;

(4)最后,鉴于本人是初学者,整理的比较浅显,还是请读者多看看参考文献吧!

 

软件:ISE14.4/14.7

官网:xapp1052

 

 

1、DMA数据流简介

简述PIO与DMA的区别:

PIO操作:通常,PIO传输的数据仅有一个,即MWr、CPLD这类TLP报文里,仅包含一个有效数据。

DMA操作:通常,DMA传输的数据有多个,即MWr、CPLD这类TLP报文里,     包含多个有效数据。

                 只不过,为了进行DMA的操作,需要提前配置一些控制寄存器;这些配置控制寄存器的过程,是PIO操作。

                 当MWr、CPLD开始传输多个有效数据时,才是DMA操作。所以,显的复杂一点。

 

DMA数据传输概述:

首先需要说明:

下面介绍的传输类型,是FPGA作为master主动发起读写请求,PC作为从机进行响应;

实际使用中,FPGA、PC谁都可以作为master,下面的介绍仅是一种参考。

 

(1)FPGA发DMA数据到PC

首先,PC通过下文figure3配置步骤1-7,该过程是PIO操作,每次配置一个寄存器;

然后,DMA发送模块,发起 存储器写访问事务(MWr),给PC 发送包含数据的写TLP数据包,举例如下图7-5所示。

即这个TLP数据包,包含 1个头标 +n个DW数据,实现DMA数据的传输!

最后,待数据传输完毕,FPGA应该会发送一个中断信号,提示PC数据传输结束;

(2)PC发DMA数据到FPGA

首先,PC通过下文figure4配置步骤1-6,该过程是PIO操作,每次配置一个寄存器;

然后,FPGA的DMA发送模块,发起存储器读请求事务(MRd),给PC发送一个储器 读请求TLPs,该过程是PIO操作

再然后,PC返回带数据的完成报文CPLD,FPGA的DMA接收模块、接收该数据流,该过程是DMA操作;

PC返回的CPLD报文如下图所示,下图仅是个举例,可能不完全正确

该CPLD数据包,包含:一个头标 + n个数据,实现数据的DMA传输!应该类似于下图吧,下图可能不完全正确!

仅是方便理解,才贴上下图的 .......    =。=

最后,带数据传输完毕,FPGA应该会发送一个中断信号,提示PC数据传输结束;

详细传输流程,见下文吧。

 

1.1 FPGA发DMA数据到PC

有一点需要说明一下,

在上面的步骤4中,组织PCIe Memory Write TLPs时,发送模块发送的是写MEM数据包,即存储器写访问事务(MWr)类型,将待发送的DMA数据发送给PC;

这里FPGA发送模块并不是通过CPLD完成报文的形式将数据发送给PC的。

读者可以细细品味一下两者的区别。

下图是官方提供的xapp1052中,测试FPGA发DMA数据到PC的步骤。

关于下图步骤6有一点需要说明,

PC通过PIO操作配置WDMATLPP寄存器,将测试数据data写入WDMATLPP寄存器;

然后,当启动DMA操作时,发送引擎将WDMATLPP中的数据data重复发送给PC,用以测试DMA写MEM(指PC内存)的效率。

下图是官方提供xapp1052中发送模块对应的几种事务类型,这里引用博主CLGo 的博客里的相关介绍。

值得注意的是:

(1)BMD_64_CPLD_FMT_TYPE是PIO模式

       标志着发送一个带数据的完成包,这个使用在PC端向FPGA发送一个存储器读请求后,FPGA通过这个报文将存储器信息返回到PC端;

(2)BMD_64_MWR_FMT_TYPE、BMD_64_MWR64_FMT_TYPE:是DMA模式

       标志着FPGA发送储器 写请求TLPs(MWr),这个使用在启动DMA写时,发送引擎组建存储器写请求包将数据发送到PC上; 

(3)BMD_64_MRD_FMT_TYPE、BMD_64_MRD64_FMT_TYPE :是DMA模式,

       标志着FPGA发送储器 读请求TLPs(MRd)

       这个使用在PC配置启动DMA读时,发送引擎组建存储器读请求包,PC发送带数据的完成包到FPGA上,被接收引擎接收。

1.2 数据从PC搬到FPGA

大概过程如下:

(1)首先电脑申请一片连续内存,

(2)接着电脑通过PIO模式配置FPGA上的控制状态寄存器(就是表格中的Step1~Step6),

(3)然后FPGA检测到读DMA请求后,发送引擎组装 储器 读请求报文(MRd) 并发送,

(4)接收引擎接收电脑反馈的完成包CPLD,

(5)最后,FPGA发送中断结束传输。

下图是官方提供的Xapp1052中,测试PC发DMA数据到FPGA的步骤。

关于Xapp1052提供的BMD接收引擎,并结合上面的步骤(4)和下面的步骤1-8有一点需要说明一下:

在接收引擎开始接收来自PC返回的CPLD数据包时,接收引擎并没有将该DMA数据存入FPGA内部缓存MEM,

而是将接收到的数据与RDMATLPP寄存器中的数据进行数据比较,但配置RDMATLPP寄存器的过程,却没有在下面的步骤1-8中体现。在xapp1052的PDF中,相关描述如下:

 

下图是官方提供xapp1052中接收模块对应的几种事务类型,这里引用博主CLGo 的博客里的相关介绍。

值得注意的是:

(1)BMD_MEM_RD32_FMT_TYPE 、BMD_MEM_WR32_FMT_TYPE :是PIO事务

         两种标头对应的TLP是以PIO的模式传输,其作用是上位机读写DMA控制状态寄存器,就是上文的DMA体系结构中的Control and Status Registers。

(2)BMD_CPL_FMT_TYPE 、BMD_CPLD_FMT_TYPE :是DMA事务,

        是FPGA发送 DMA读请求(MRd)后,PC端反馈的完成包CPLD是DMA模式。 
 

下图是PIO配置一些寄存器的整理:

 

2、PCIE 软件开发环境

        目前对PCIe 部分的上位机驱动开发的软件比较常用的是windriver 和DDK 这2 款开发工具。DDK 是Device Development Kit,设备开发包的意思。为windows 设备驱动程序开发包。一般是在VC 或者VS 软件环境下进行开发。相对于Windriver,DDK 需要开发人员对驱动更加深入的了解。
         Windriver 是jungo 公司为驱动程序开发提供的一个工具,特别适合初学者使用。它把PC 硬件系统的驱动程序开发进行了高度的集成和封装,开发者甚至不需要设计驱动程序,所需要做的工作几乎仅仅是保证设备的硬件和相应固件设计正确,然后进行
应用程序的设计,而应用程序的设计也可以通过对Windriver 产生的debug 程序进行修改而得到。

        WinDriver™ PCI / ISA User's Manual

 

        软件驱动开发
        安装好Windriver后,即可完成PCIe驱动的开发了。首先你需要安装VS2008,用来打开Windriver的驱动源码,并进行修改和测试。下面我们来详细的了解整个软件
         开发和测试的流程。
         Step1 : 我们首先找到Windriver的安装目录,如图所示,在安装目录下有各个公司的开发工程以及开发软件包。这里我们找到xilinx文件夹,进入下一步。

         打开Windriver 软件,并新建工程项目,用户可以为自己的设备生成相关的INF 驱动文件,这里如果用户下载了我们板卡所提供的PCIE 文件至开发板,则可在如图8-2-4 中找到我们的XILINX PCIe 设备,点击Gneratate .INF file。

          如图8-2-5所示,用户可以自定义厂商的ID,设备ID以及设备类型,修改相关属性后,勾选上automatically install the INF file,即可完成PCIE的驱动安装。

        安装完成后,用户即可在设备管理器中找到自定义的设备

软件驱动开发

Step1 : 我们首先找到Windriver的安装目录,如图8-2-7所示,在安装目录下有各个公司的开发工程以及开发软件包。这里我们找到xilinx文件夹,进入下一步。

Step2 : 使用VS2008 打开“安装路径\xilinx\virtex5\bmd\diag\x86\msdev_2008”里的工程,如图8-2-8所示。本工程虽然是Virtex5型号的FPGA PCI驱动代码,但也同样适用于大部分Xilinx公司的PCIE的驱动代码的开发。

Step3 :此时如果你确定已经下载好了PCIE DMA的FPGA文件,我们可以点击菜单栏下的“启动调试(F5)”,来进行工程调试。

 

PCIe功能调试项说明
PCIe功能调试项说明

        这里我们更加关注DMA的相关测试,我们选择测试项7,即Direct memoryaccess(DMA)-Interrupts completion method,按照操作步骤选择open dma,并选择From device或者to device,来确定数据的传输方向,填入TLP的个数,以及TLP的测试数据。

         OK,现在我们大致已经知道如何通过Windriver所提供的开发工具在VS2008的测试与开发,那么接下来我们再来分析下VS2008下的驱动代码。

VS2008驱动代码分析
1.通过VS2008打开Virtex5的BMD工程,如图8-2-11所示,包含6个c文件。图8-2-11 BMD 驱动文件

 

          实际上用户几乎不需要做大量的修改,如果用户只需要进行DMA方面开发的话,只需要通过MenuDMAOpen函数
将需要配置的DMA数据大小,数据缓存,以及完成方式配置到该函数中,并启动DMA即可。

static void MenuDMAOpen(WDC_DEVICE_HANDLE hDev, PDIAG_DMA pDma, BOOL fPolling)
{
DWORD dwStatus, dwOptions, dwTotalCount, i;
UINT32 u32Pattern;
WORD wSize, wCount;
BOOL fIsRead;
BOOL fEnable64bit;
BYTE bTrafficClass;
/* Get input for user */
if (!MenuDMAOpenGetInput(&wCount, &u32Pattern, &dwOptions))
return;
fIsRead = dwOptions & DMA_FROM_DEVICE ? FALSE : TRUE;
pcie_opratetype = dwOptions & DMA_FROM_DEVICE ? FALSE : TRUE;
/* The BMD reference design does not support s/g DMA, so we use contiguous
*/
dwOptions |= DMA_KERNEL_BUFFER_ALLOC;
/* Get the max payload size from the device */
wSize = VIRTEX5_DMAGetMaxPacketSize(hDev, fIsRead) / sizeof(UINT32);
dwTotalCount = (DWORD)wCount * (DWORD)wSize;
/* Open DMA handle */
dwStatus = VIRTEX5_DMAOpen(hDev, &pDma->pBuf, dwOptions,dwTotalCount * sizeof(UINT32),
&pDma->hDma);
if (WD_STATUS_SUCCESS != dwStatus)
{
printf("\nFailed to open DMA handle. Error 0x%lx - %s\n", dwStatus,
Stat2Str(dwStatus));
return;
}
printf("\nDMA handle was opened successfully (handle 0x%lx)\n", pDma->hDma);
printf("Payload packet size in dwords 0x%hx\n", wSize);
/* Prepare the device registers for DMA transfer */
fEnable64bit = FALSE;
bTrafficClass = 0;
VIRTEX5_DMADevicePrepare(pDma->hDma, fIsRead, wSize, wCount, u32Pattern,fEnable64bit,
bTrafficClass);
if (!fPolling) /* Enable DMA interrupts (if not polling) */
{
VIRTEX5_DmaIntEnable(hDev, fIsRead);
if (!VIRTEX5_IntIsEnabled(hDev))
{
dwStatus = VIRTEX5_IntEnable(hDev, DiagDmaIntHandler);
if (WD_STATUS_SUCCESS != dwStatus)
{
printf("\nFailed enabling DMA interrupts. Error 0x%lx - %s\n",
dwStatus, Stat2Str(dwStatus));
goto Error;
}
printf("\nDMA interrupts enabled\n");
}
}
else /* Disable interrupts (polling) */
VIRTEX5_DmaIntDisable(hDev, fIsRead);



/*
在下面代码中
我们可以将所需要dma写入的数据填入pDma->pBuf,
该试验我们填入的是一串递增数据i,然后PCIE DMA将会按照用户设置的TLP包的个数,
当前TLP所支持的最大TLP的数据大小wSize,以及本次操作的读写类型fIsRead设置为0
选择DMA写。

*/


/* Initialize the DMA buffer with user defined pattern */
for (i = 0; i < dwTotalCount; i++)
{
if (fIsRead)
((UINT32 *)(pDma->pBuf))[i] = i;
else ((UINT32 *)(pDma->pBuf))[i] = 0xdeadbeaf; /* to be overwritten by
WRITE dma */
}
/* Start DMA */
printf("Start DMA transfer\n");
VIRTEX5_DMAStart(pDma->hDma, fIsRead);
TimeStart();
/* Poll for completion (if polling selected) */
if (fPolling)
{
if (VIRTEX5_DMAPollCompletion(pDma->hDma, fIsRead))
{
DmaTransferVerify(hDev, pDma->pBuf, dwTotalCount, u32Pattern,
fIsRead);
}
else
printf("timeout\n");
}
return;





Error:
DIAG_DMAClose(hDev, pDma);
}




如果用户需要读取从PCIE的设备端返回的数据,则从中断处理函DiagDmaIntHandler中读取pIntResult->pBuf即可,如下表代码所示。

static BOOL DIAG_DMAVerifyPattern(WDC_DEVICE_HANDLE hDev, PVOID pBuf,
DWORD dwTotalCount, UINT32 u32Pattern, BOOL fIsRead)
{
DWORD i;
/* Transfer to device, check HW error bit */
if (fIsRead)
return VIRTEX5_DmaIsReadSucceed(hDev);
//Transfer from device, check DMA buffer
for (i = 0; i < dwTotalCount; i++)
{
if (((UINT32 *)(pBuf))[i] != i)
{
VIRTEX5_ERR("Data mismatch, pBuf[%ld] = %08X, u32Pattern = %08X\n",i, ((UINT32
*)(pBuf))[i], u32Pattern);
return FALSE;
}
}
return TRUE;
}

 

 

 

3、Xapp1052下载

Step1:登录www.xilinx.com官网,在搜索栏中输入xapp1052,xapp1052是xilinx专为用户PCIe DMA开发应用的demo,里面包含有PCIE DMA开发与应用的硬件代码与上位机的驱动代码。如图8-3-1所示,用户需要下载图中的xapp1052.pdfxapp1052.zip。

Step2:将xapp1052.zip解压后我们即可发现以下文

 

 

4、Kintex-7 BMD工程搭建

4.1 Generate PCIE DMA IP CORE

4.2 DMA_64工程搭建

在下图的代码中,有几个.V文件需要说明一下,

(1)xilinx_pcie_2_1_ep_7x.v :来自IPCore的 example 的 顶层。

         在该文件里,例化的app pcie_app_7x 可能一些管脚比较多,而这些多出来的管脚,在pcie_app_7x_bmd.v文件里不存在,这样会导致PIO仿真报错。因此注意对比删除。

(2)pcie_app_7x_bmd.v        :来自xapp1052里的128事例工程,复制过来后,需要将128修改为64即可。

(3)axi_trn_top.v等                :来自xapp1052里的128事例工程,直接复制过来即可。

(4)其他所有文件                  :从xapp1052里复制即可。

代码层次如下:

将BMD_PCIE_20.V如下图所示,设置为全局的文件。这样我们的工程就基本建立完成。

5、Sparten6 BMD工程搭建

暂不更新

 

 

>>点击这里返回导航页<<

 

 

 

 

参考文献

作者博客
1、CLGoPCIe学习(三):PCIe DMA关键模块分析之二
 PCIe学习(二):PCIe DMA关键模块分析之一
2、鹿天斐Virtex6 PCIe 超简版基础概念学习(二)--优快云
 Virtex6 PCIe 超简版基础概念学习(二)--简书
 Virtex6 PCIe 超简版基础概念学习(一)--简书
3、俞则人 PCIE_DMA实例一:xapp1052详细使用说明
4、ShaliewFPGA-PCIe开发
5、wbh_waterVivado vc707 pcie传输实验(超详细)
 vivado pcie DMA传输实战
6、渝雪柒柒PCIE_DMA:xapp1052学习笔记
  

 

 

 

 

 

 

 

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. ```
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值