目录
正文
0 概述
最近因仪表项目需求,需要上位机PC端通过PCIE接口与FPGA功能子卡进行数据通信,故开始研究基于Xilinx A7 FPGA实现PCIE接口功能。
1 准备工作
要实现上位机Host端与FPGA子卡设备端通过pcie接口通信,需要3个必备条件:
(1)上位机应用程序;
(2)pcie驱动程序;可以从Xilinx官网下载对应系统驱动,然后进行二次开发,添加用户所需的驱动函数
(3)FPGA子卡端PCIE逻辑程序;
需要阅读的Specification和User Guide如下:
1. PCI.Express.Base.Specification.v2.0 - PCIE总线协议说明书
如果仅从项目应用角度而言,只需要通读一遍,有个大概印象,熟悉高频专业术语即可,不用花大量时间去啃,因为Xilinx官方会提供PCIE IP核,将底层逻辑都封装好,开发者只需关注用户开发逻辑即可。PS:当然,如果有时间,深入研究肯定更好。
2. DMA/Bridge Subsystem for PCI Express v4.1 (pg195)
xilinx官方用户手册,讲解PCIE XDMA IP核的用法
PS:以前用ISE开发软件的时候,由于Xilinx官方提供的PCIE DMA方式是基于xapp1052文档讲述的Demo例程,需要用户去理解Demo工程,并自行增加用户所需的功能逻辑,我那个时候研究了一段时间后,还是没有完全搞定,就搁置了。
现在Vivado开发软件提供的XDMA IP核封装的更简单,使用更非常方便,解决了我这种PCIE小白很多开发障碍,首推。
2. 开发流程
(1)Xilinx 提供的 DMA Subsystem for PCIExpress IP 是一个高性能,可配置的适用于 PCIE2.0, PCIE3.0 的 SG 模式
DMA,提供用户可选择的 AXI4 接口或者 AXI4-Stream 接口。
PCIE XDMA IP核配置的关键参数为BAR参数设置。PCIE DMA interface软件已默认使能,用户可以通过使能PCIE to AXI_Lite Master接口与主机端
进行寄存器的读写操作。XDMA IP核是基于AXI 4.0总线进行接口封装的,需要用户对AXI总线基础知识有所了解更优。
(2)基于XDMA IP核进行FPGA工程开发,选择Block Design开发方式(类似于ISE原理图开发方式),当然直接通过RTL逻辑开发方式也可以,
但是各个模块的接口信号需要自己去连接,太繁琐且容易出错,不如图形化设计方便。我是参考米联客/黑金开发板教程来设计的FPGA工程,主要实现
两个功能:
a. 主机端与FPGA设备端通过DMA方式,进行数据包的发送&接收功能;
b. 主机端与FPGA设备端通过BAR方式,进行寄存器的读写功能;
(3)接口说明如下:
Bram PORTA_0(write only), Bram PORTB_0(read only)这个双向接口是DMA写数据包和回读数据包接口,这么设计而不直接用Block Ram连接,是便于用户
增加自己的逻辑:例如用户通过Bram PORTA_0写入数据包内容,然后主机端通过 Bram PORTB_0回读数据包内容。这是常见的用法,比如FPGA子卡为一个数据采集卡,需要将实时采集的视频数据组包后,通过中断方式,通知主机将已准备好的数据包回读到PC端。
3. 测试结果
用户通过Bram PORTA_0写入数据包内容:0x07_06_05_04_03_02_01_00(每个数据为64位位宽) ~ 0xff_fe_fd_fc_fb_fa_f9_f8,循环发送,共计512个数据。
主机通过 Bram PORTB_0回读数据包内容,然后将回读的数据写入bin文件,进行数据验证。
上图为FPGA写入的数据包内容。FPGA抓取数据点位宽设置为32位,为了节省资源。可知,数据点从0x07_06_05_04_03_02_01_00开始。
上图为主机端回读的数据包内容。FPGA抓取数据点位宽设置为32位,为了节省资源。可知,起始数据点从0x07_06_05_04_03_02_01_00开始,有一个时钟的延时。由于上位机写入回读数据的bin文件格式需要用Ultra Editor来打开,就不贴图了。
4 总结
1. 参见上图可知,Bram PORTA_0_clk该时钟信号始终为0,这一点很奇怪,理论上应该与s_axi_clk。所以我在用户逻辑部分,对Bram PORTA_0端口操作,模块时钟选择的为axi_clk总线时钟。
2. BAR地址设置:PCIE to AXI Transiation为什么设置为0x44A0_0000,是可以FPGA端随意设置,还是由PCIE驱动端与FPGA端共同商定,设置为相同的地址即可,我抽空实测一下。