1. 为什么使用PCIe传输
在FPGA需要和处理器打交道时,无论是X86,还是PowerPC,以及一些嵌入式的ARM等,对外的接口常见如下表。
其中,USB需要外部的PHY对接FPGA,而且需要firmware;以太网走到TCP才会保证不丢数据;PCI逐渐淘汰了,占用引脚多,而且带宽有限;SATA侧重存储,其协议的局限性比较高;RapidIO在一些场合使用,结构可以做到Full Mesh结构,但是这些年发展速度比较慢。
而PCIe具备如下优点:
A. 带宽高,目前FPGA有PCIe Gen3 x16,或者PCIe Gen4 x8,链路速度可以达到128Gbps;
B. FPGA直连,不需要外部PHY;
C. 协议保证数据无误传输,两级CRC,重传机制,保证数据无误;
D. 软件生态丰富,各种系统原生支持,通过简单的驱动就可以完成数据交互;
E. 在PCIe之上的协议逐渐增多,例如NVMe是基于PCIe的上层协议;
Xilinx从15年前,V4系列开始,一直在PCIe的解决方案上深耕,提供众多的应用方案级的解决方案,方便用户专注于自己的应用。早期,Xilinx提供的有Application Notes,例如XAPP859,XAPP1052等,构建了基本的双向数据传输。当时一些第三方公司,类似于PLDA,NwLogic也出针对Xilinx FPGA的PCIe传输方案。
后来,Xilinx团队2017年附近推出XDMA解决方案,并持续增加功能、修正Bug,到目前为止,XDMA已经成为一个功能强大、成熟稳定的Xilinx FPGA解决方案。功能上涵盖了SG功能,AXI-Lite功能,多通道分离,AXI-MM和AXI-Stream支持等。稳定性上,经过4年的逐步完善,目前已经有众多的客户基于这套方案实现产品,涵盖医疗、电力、通讯、数据中心等各种应用。
最重要的是,XDMA是免费的!!!
2. XDMA IP配置实例
Xilinx XDMA支持的系列包括7系列,UltraScale系列,UltraScale+系列各种系列,界面配置基本相同。这里以KU040的一个板子做例程,其他系列可以参考。Vivado使用2018.3,Vivado的版本,做XDMA,建议尽量使用新一些的版本。详细的说明,参考Xilinx的文档PG195,下面主要摘取影响使用的关键部分。
配置IP
第一页,IP基本配置。
红色框根据实际板卡硬件来选择,Lane Width是物理的位宽;Link Speed是希望运行在那个速率。速率和位宽越高,最终的带宽就越高,对应FPGA内的资源和频率也相对多一些。
绿色框是选择接口方式,AXI Memory Mapped选择用户接口是AXI内存映射的接口,常见用于对接DDR、RAM等有地址寻址的外设。AXI Stream的用户接口是流接口,类似于一段数据包,FIFO流等。IP只能支持其中一种选择,不能说多通道混合使用不同的用户接口,所以用户需要分析自己的数据接入方式,慎重选择。
常见的,例如ADC采集,如果带DDR,则可以把ADC暂存在DDR中,XDMA使用AXI-MM的方式读取DDR数据;也可以ADC通过FIFO缓存后,XDMA使用AXI-Stream读取FIFO,不过需要注意ADC速度非常高的时候容易溢出。
例如,读取外部网络报文,报文长短不一,使用AXI-Stream接口方式比较合适。
第二页,VID,DID,Class等选择。
如果没有特殊的需要,这一页可以不变。尤其是Vendor ID,Device ID,尽量不修改,因为Xilinx提供的驱动是对应这些VID,DID的。
第三页,PCIe BAR空间。
红色框,PCIe to AXI Lite Master Interface可以选择上。通常,这个接口可以用作寄存器接口。上位机需要控制板卡内的用户寄存器,可以通过这个接口扩展。
通常来说,寄存器接口尽量对齐,比如常用32bit寄存器。
第四页,杂项
需要关注的是用户中断数量,是从用户层通知CPU的中断。注意,XDMA本身的操作中断不算在内,这里是用户产生的中断。
第五页,DMA通道选择
需要关注的是红色框,读写通道数量选择,根据实际的业务来选择。例如有4路ADC数据传输,可以选择C2H为4,当然,也可以4路ADC数据在FPGA内合并后成1路,然后只选择C2H为1 。
生成example design例程
上一步IP配置后,在生成的IP上,右键点击,选择打开open example design。
生成的例程,如果选择是AXI-MM的用户接口,那么这个接口对接的是AXI接口形式的Block RAM,上位机可以读/写这片RAM。如果选择的是AXI-Stream接口,例程中将Stream读写环回,上位机写下去的内容再读回去。
此外,第三页BAR空间如果勾选了PCIeto AXI Lite Master Interface,例程中会额外多出来一个AXI接口的Block RAM。如果需要,可以将这块修改为寄存器接口。
修改约束引脚后,生成bit文件,下载到FPGA中,并重启电脑,注意这里说的是重启电脑,不是关机再开机。电脑重启的开始,BIOS会重新扫描PCIe设备,才能被CPU枚举。
3. Block Design下快速构建XDMA Subsystem
上面的例程,例化一个IP,然后打开example design的方式。实际使用,可以用block design快速构建XDMA的设计。
下面举例,快速构建一个XDMA到DDR4传输的设计。
1. 新建block design,加入XDMA IP和DDR4 MIG IP。XDMA配置参考上面描述的内容,DDR4根据板卡实际的选择配置。
2. 连接关系很简单,XDMA的M_AXI接口通过AXI_Interconnect连接DDR4,这里AXI_Interconnect起到时钟域转换的作用。
3. 地址分配,将DDR4的空间分配到XDMA中即可。
4. 生成block design的wrapper,修改正确的引脚约束后,生成bit文件。下载到FPGA后重启电脑。
Block Design的方式,适用于快速构建比较复杂的设计,例如包含DDR4,Datamover等各种基于AXI互联的IP。
4. 驱动和软件应用
通过pci utility查看设备
pci utility工具,用于查看PCIe设备各种属性的工具。Linux系统默认自带了pci utility工具,windows下也有对应版本,在GitHub上搜索。
lspci命令,列举所有pci和pcie设备:
红色框,即上面配置的XDMA example design。
lspci -vv -s 02:00.0 命令,详细列出位于02:00.0槽位的Xilinx设备详细信息。
这里把一些信息列举下来:
A. Region 0,这个是上面PCIe to AXI Lite Master Interface选择的空间。Region 1,这个是XDMA IP自身内部寄存器空间,不用关心。
B. MaxPayload size是256字节,是系统协商的,不能修改。MaxReadReq是最大请求字节,协商后是512字节。
C. LnkCap字段,是协商后的PCIe链路状态,上面写的速度是8G,位宽是x4。PCIe IP上选择的是8G,这个目前协商到了。位宽选择x8,实际是x4,因为这个机箱用的一个x4PCIe延长线,限制了适配到x8位宽。
D. LnkCtl2,显示设备最大能支持到8G的链路速度。
5. 驱动安装,Linux环境
Linux的驱动在GitHub上,https://github.com/Xilinx/dma_ip_drivers,下载到宿主机。
readme.txt中有驱动使用说明,目录结构、安装使用等。tests目录下有安装脚本,测试脚本等。
5.1. 驱动安装
tests目录下,sh load_driver.sh即安装驱动,安装成功会提示。
安装完毕,查看/dev目录下,多出来一些xdma0开头的设备。
文件目录分别说明下
A. _c2h_x,是card to host的设备,板卡向CPU传输数据的时候使用这个设备;
B. _h2c_x,是host to card的设备,CPU向板卡发送数据的时候使用这个设备;
C. _control,是XDMA的内部寄存器控制设备,一般用户不需要使用;
D. _user,是PCIe to AXI Lite Master Interface选择的空间;
E. _event_x,是IP配置第四页,选择的用户层中断对应的设备;
5.2 软件测试,Linux环境
如果IP配置选择AXI-Memory Map,参考dma_memory_mapped_test.sh,这个脚本写入一段数据到BlockRAM中,然后读出对比。
如果IP配置选择AXI-Stream接口,参考dma_streaming_test.sh,脚本写入一段数据,回环后读回校验。
上述两个例子,用下面的命令测试。
sh dma_memory_mapped_test.sh 1024 1 1 1
Block Design下,DDR4显示已经校准完毕。使用dma_memory_mapped_test.sh测试,数据写入DDR4,然后再从DDR4读回。
FAQ
1. Windows下安装驱动,安装后驱动有一个感叹号,不能正常使用。
Windows从Win764bit开始,安装驱动必须的签名,Win7的签名和Win10的签名还不同。Xilinx提供的Windows驱动不包括驱动签名,安装的时候就出现感叹号。
这个问题可以百度下,开机的时候选择禁止驱动签名。或者购买微软的签名即可。
例如下图,是一个公司购买了签名,签名这个驱动后的状态,可以直接安装好驱动。
2. Linux下,Stream模式接收溢出。
IP设置为Stream模式,默认Linux上有循环Buffer来处理接收的数据。如果Stream接收的速率太高,超过驱动和应用能处理的范围,就会出现溢出的问题。出现溢出后,驱动里做了错误恢复,一段数据就丢掉了。
审核编辑:刘清
-
处理器
+关注
关注
68文章
19125浏览量
228888 -
FPGA
+关注
关注
1625文章
21640浏览量
601385 -
USB接口
+关注
关注
9文章
699浏览量
55550 -
PCIe
+关注
关注
15文章
1213浏览量
82382
发布评论请先 登录
相关推荐
评论