目录
- 1、前言
- 免责声明
- 2、我已有的PCIE方案
- 3、RIFFA简介
- RIFFA概述
- RIFFA架构
- RIFFA驱动
- RIFFA方案的局限性
- 4、RIFFA 源码详解
- 用户接口
- 5、vivado工程详解
- 6、工程移植说明
- vivado版本不一致处理
- FPGA型号不一致处理
- 其他注意事项
- 7、上板调试验证并演示
- 8、福利:工程代码的获取
1、前言
PCIE是目前速率很高的外部板卡与CPU通信的方案之一,广泛应用于电脑主板与外部板卡的通讯,PCIE协议极其复杂,想要掌握不容易,所以Xilinx和Altera等FPGA厂商直接推出了相关IP供用户使用,比如Xilinx的XDMA,这种IP直接集成了PCIE通信的所有内核资源,并已封装为AXIS接口,用户在使用时只需要按照AXIS流数据格式收发即可,相当于傻瓜式使用PCIE,但是,如果你想装个杯,想要自己研究甚至手写一个PCIE收发器呢?那本文就适合你的胃口了。。。
本工程基于RIFFA源码架构做PCIE传输层(即TLP包),调用Xilinx官方的 7 Series Integrated Block for PCI Express(3.3) IP核做PCIE物理层和链路层(PCS/PMA),RIFFA源码架构具有AXI4-Stream的用户接口,可与Xilinx的PCIE IP直接对接,基于此在Xilinx 7系列FPGA平台搭建了基于RIFFA源码的PCIE通信架构,在这个架构上,我们可以做更多的应用;
本文详细描述了RIFFA的实现设计方案,使用Xilinx的PCIE IP作为桥接工具,实现PCIE简单通讯,工程代码编译通过后上板调试验证,文章末尾有演示效果,适用于在校学生、研究生项目开发,也适用于在职工程师的自我学习提升,可应用于医疗、军工等行业的告诉接口传输领域;
本工程只是验证RIFFA在FPGA上的可行性,并没有进行项目层面上的大批量数据通信,后面我会出几篇基于RIFFA的测速和视频采集例程,那才是真正具有项目意义的例程,敬请期待。
提供完整的、跑通的工程源码和技术支持;
工程源码和技术支持的获取方式放在了文章末尾,请耐心看到最后;
免责声明
本工程及其源码即有自己写的一部分,也有网络公开渠道获取的一部分(包括CSDN、Xilinx官网、Altera官网等等),若大佬们觉得有所冒犯,请私信批评教育;基于此,本工程及其源码仅限于读者或粉丝个人学习和研究,禁止用于商业用途,若由于读者或粉丝自身原因用于商业用途所导致的法律问题,与本博客及博主无关,请谨慎使用。。。
2、我已有的PCIE方案
我的主页有PCIE通信专栏,该专栏基于XDMA的轮询模式实现与QT上位机的数据交互,既有基于RIFFA实现的PCIE方案,也有基于XDMA实现的PCIE方案;既有简单的数据交互、测速,也有应用级别的图像采集传输,以下是专栏地址:
点击直接前往
此外,我的主页有中断模式的PCIE通信专栏,该专栏基于XDMA的中断模式实现与QT上位机的数据交互,以下是专栏地址:点击直接前往
3、RIFFA简介
RIFFA概述
RIFFA(Reusable Integration Framework for FPGA Accelerators)即是 FPGA 加速器的一种可重用性集成框架,是一个第三方开源 PCIE 框架。RIFFA 是一个通过 PCI Express 总线实现 cpu 和 FPGA 数据通信的简单框架,该框架要求具备一个支持 PCIe 的工作站和一个带有PCIe 连接器的 FPGA 板卡。RIFFA 支持 Windows,Linux,Altera 和 Xilinx,可以通过 C / C ++、Python、MATLAB 或Java 驱动来实现数据的发送和接收。驱动程序可以在 Linux 或Windows 上运行,每一个系统最多支持 5 个 FPGA 设备。在用户端有独立的发送和接收端口,用户只需编写几行简单代码即可实现与 FPGA IP 内核通信。
RIFFA 不依赖于 PCIe Bridge,因此不受桥连实现的限制。RIFFA 使用直接存储器访问(DMA)传输和中断信号传送数据。这实现了 PCIe 链路上的高带宽,运行速率可以达到PCIe 链路饱和点。下图显示了使用 32 位,64 位和 128 位接口的设计性能。实线为理论最大带宽值,虚线为可实现最大带宽值。PCIe Gen 1 和 2 使用 8 位/ 10 位编码,将最大可实现带宽限制为理论值的 80%。 我们的实验表明,在几乎所有情况下,RIFFA 可以实现理论带宽的 80%。128 位接口达到理论最大值的 76%。
RIFFA架构
RIFFA架构如下:
在硬件方面,简化了接口,以便通过 FIFO 简便的将数据取出和存入。数据的传输由RIFFA 的 RX 和 TX DMA Engine 模块用分散收集聚合方法来实现。RX Engin 模块收集上位机传来的有效数据,收集完成发给 Channel 模块,TX Engin 收集 Channel 模块传来的数据,打包发给 PCI Express 端点。根据 PCIe 链路配置,RIFFA 接口支持 32 位,64 位和 128位宽度,计划为 PCIe Gen3 端点的 256 位接口提供支持。
PC 接收 FPGA 板卡数据是用户应用程序调用库函数 fpga_recv,然后由 FPGA 端启动。用户应用程序线程进入内核驱动程序,然后开始接收上游 FPGA 的读请求,将数据分包发送,如果没收到请求,将会等待它达到。
启动发送函数后,服务器将建立一个散列收集元素的列表,将数据存储地址和长度等信息放入其中,将其写入共享缓冲区。用户应用程序将缓冲区地址和数据长度等信息发送给 FPGA。FPGA 读取散射收集数据,然后发出相应地址的数据写入请求,如果散列收集元素列表的地址有多个,FPGA 将通过中断发出多次请求。
TX 搬移的数据全部写入缓存区后,驱动程序读取 FPGA 写入的字节数,确认是否与发送数据长度一致。这样就完成了传输。其过程如下图所示。
PC 机发送数据到 FPGA 板卡过程与 PC 机接收 FPGA 板卡数据过程相似,下图说明了该流程。刚开始也是用户应用程序调用库函数 fpga_send,传输线程进入内核驱动程序,然后 FPGA 启动传输。
启动 fpga_send,服务器将申请一些空间,将要发送的数据写入其中,然后建立一个分散收集列表,将存储数据的地址和长度放入其中,并将分散收集列表的地址和要发生的数据长度等信息发给 FPGA。FPGA 收到列表地址后,读取该列表的信息,然后发出相应地址和长度的读请求,然后将数据存储,最后一起发给 FPGA 板卡。
RIFFA驱动
提供Winwods和Linux驱动源码,源码包括c++、java、python等语言,Winwods驱动支持X86和X64架构,Linux驱动支持20以下版本,驱动文件夹如下:
说明如下:
1、 c_c++ 是 c 语言的测试程序与驱动程序源码,在 driver 中也有一份。
2、 java 是 java 语言的测试程序与驱动程序源码,在 driver 中也有一份。
3、 matlab 是 matlab 语言的测试程序与驱动程序源码,在 driver 中也有一份。
4、 python 是 python 语言的测试程序与驱动程序源码,在 driver 中也有一份。
5、README.md 文件是项目说明,是一种使用 markdown 语法写的文件。
6、如果要对 riffa 框架进行深入研究,请读者认真细读研究内部的文件,包括驱动程序。
RIFFA方案的局限性
RIFFA方案由于是轻量级的,所以相比于Xilinx官方推出的XDMA方案而言,对于大批量数据传输而言稳定性并不理想;此外,RIFFA方案的驱动安装也比较复杂和麻烦,依然没有Xilinx官方推出的XDMA方案简单;但是RIFFA方案也有自己的优点,那就是代码可以完全看到,且是verilog的,对于学习和研究具有很高的价值,比如你需要做优化,可以用RIFFA方案研究底层逻辑,在此基础上做性能优化,是一个快速且快捷的方式;
对Xilinx官方推出的XDMA方案感兴趣的朋友,可以去我的PCIE专栏看XDMA部分的代码,博客地址在这里:点击直接前往
4、RIFFA 源码详解
用户接口
RIFFA源码架构可以适配不同的FPGA型号,就Xilinx 7系列FPGA而言,需要调用Xilinx官方的 7 Series Integrated Block for PCI Express(3.3) IP核做PCIE物理层和链路层(PCS/PMA),所以RIFFA源码的用户接口必须适应Xilinx的AXI4-Stream,理清了这个概念,就可以来理解代码了,用户接口部分代码在工程代码架构中的位置如下:
5、vivado工程详解
开发板FPGA型号:Xilinx xc7a100tfgg484-2
开发环境:Vivado2020.2;
输入输出:RIFFA方案;PCIEX4;
应用:搭建基于RIFFA方案的PCIE通信架构;
工程BD如下:
RIFFA配置界面如下,可根据需要自行修改:
调用了Xilinx的PCIE桥接IP,注意,非XDMA;
综合后的工程代码架构如下:
红框标出了RIFFA的verilog源码,这部分是重点,感兴趣的兄弟应该仔仔细细研读这部分代码。如果只看个框图或者大概没有意义,把这部分代码看懂了,月薪20k绝对不成问题。。。
FPGA资源消耗和功耗预估如下:
6、工程移植说明
vivado版本不一致处理
1:如果你的vivado版本与本工程vivado版本一致,则直接打开工程;
2:如果你的vivado版本低于本工程vivado版本,则需要打开工程后,点击文件–>另存为;但此方法并不保险,最保险的方法是将你的vivado版本升级到本工程vivado的版本或者更高版本;
3:如果你的vivado版本高于本工程vivado版本,解决如下:
打开工程后会发现IP都被锁住了,如下:
此时需要升级IP,操作如下:
FPGA型号不一致处理
如果你的FPGA型号与我的不一致,则需要更改FPGA型号,操作如下:
更改FPGA型号后还需要升级IP,升级IP的方法前面已经讲述了;
其他注意事项
1:由于每个板子的DDR不一定完全一样,所以MIG IP需要根据你自己的原理图进行配置,甚至可以直接删掉我这里原工程的MIG并重新添加IP,重新配置;
2:根据你自己的原理图修改引脚约束,在xdc文件中修改即可;
3:纯FPGA移植到Zynq需要在工程中添加zynq软核;
7、上板调试验证并演示
Windows10系统简单测试效果如下:
8、福利:工程代码的获取
福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料获取方式:私,或者文章末尾的V名片。
网盘资料如下: