PCIE是目前速率很高的外部板卡与CPU通信的方案之一,广泛应用于电脑主板与外部板卡的通讯,PCIE协议极其复杂,想要掌握不容易,所以Xilinx和Altera等FPGA厂商直接推出了相关IP供用户使用,比如Xilinx的XDMA,这种IP直接集成了PCIE通信的所有内核资源,并已封装为AXIS接口,用户在使用时只需要按照AXIS流数据格式收发即可,相当于傻瓜式使用PCIE,但是,如果你想装个杯,想要自己研究甚至手写一个PCIE收发器呢?那本文就适合你的胃口了。。。
本文详细描述了RIFFA的实现设计方案,使用Xilinx的PCIE IP作为桥接工具,实现PCIE简单通讯,工程代码编译通过后上板调试验证,文章末尾有演示效果,可直接项目移植,适用于在校学生、研究生项目开发,也适用于在职工程师做项目开发,可应用于医疗、军工等行业的数字成像和图像传输领域;
本工程只是验证RIFFA在FPGA上的可行性,并没有进行项目层面上的大批量数据通信,后面我会出几篇基于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架构如下:
在硬件方面,简化了接口,以便通过 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 板卡。
提供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 框架进行深入研究,请读者认真细读研究内部的文件,包括驱动程序。
开发板:Xilinx xc7a100tfgg484-2
开发环境:Vivado2020.2;
输入输出:PCIEX4;
工程BD如下:
RIFFA配置界面如下,可根据需要自行修改:
调用了Xilinx的PCIE桥接IP,注意,非XDMA;
综合后的工程代码架构如下:
红框标出了RIFFA的verilog源码,这部分是重点,感兴趣的兄弟应该仔仔细细研读这部分代码。如果只看个框图或者大概没有意义,把这部分代码看懂了,月薪20k绝对不成问题。。。
福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料获取方式:私,或者文章末尾的V名片。
网盘资料如下: