文献标识码:A
DOI:10.16157/j.issn.0258-7998.190034
中文引用格式:孙丰霞,张伟功,周继芹,等. UM-BUS总线测试系统中PCIe的设计与实现[J].电子技术应用,2019,45(5):61-65.
英文引用格式:Sun Fengxia,Zhang Weigong,Zhou Jiqin,et al. Design and implementation of PCIe on UM-BUS test system[J]. Application of Electronic Technique,2019,45(5):61-65.
0 引言
UM-BUS[1-2]总线是一种具有动态重构能力的高速串行总线。为了验证UM-BUS总线在传输速率及带宽灵活性方面的优势,本文设计了一个UM-BUS测试系统[3],其功能是将采集的总线数据缓存到SDRAM存储器中,并实现FPGA端SDRAM存储器与PC的通信,将数据传输至PC进行分析和处理。
鉴于PCIe1.1(PCI Express)采用点对点串行连接、全双工的传输方式,并可根据实际需求灵活配置成x1、x4、x8和x16通道,单通道单向传输带宽可达250 MB/s,本文采用PCIe1.1[4]x4通道,基于DMA[5-6](Direct Memory Access)传输机制共同实现了SDRAM存储器与PC之间的通信传输设计。
1 研究背景
1.1 UM-BUS总线介绍
UM-BUS总线采用多线路并发冗余的总线型拓扑结构,采用节点互连方式,最多可以连接30个总线节点设备,采用32条通道进行数据的并发传输,单通道速率可达200 Mb/s。其拓扑结果如图1所示,其中n表示总线上的节点数,m表示物理通道数。
1.2 UM-BUS总线测试系统介绍
本文UM-BUS总线测试系统是针对采用16通道并发传输的UM-BUS总线而设计的,理论速率可达400 MB/s,满足当前大多数测试和应用带宽需求。为了将采集的高速总线数据传输到PC进行分析处理,完成测试功能需求,本文在UM-BUS总线测试系统中设计并实现了PCIe1.1技术。
如图2所示,在UM-BUS测试系统中,系统要求PC能够对由数据采集模块采集处理后的数据通过外部SDRAM存储器进行缓冲,然后通过PCIe接口将数据传输至PC进行保存。目前UM-BUS总线数据采集模块和高速缓存模块设计已完成,本文重点是PCIe通信接口的设计与实现。
2 PCIe通信接口设计
为了更好地发挥PCIe总线的高带宽优势,本文采用Xilinx公司Virtex-5系列XC5VLX85T的FPGA来设计PCIe通信接口,通过其内部嵌入的PCIe IP硬核Endpoint Block Plus for PCI Express1.1[7]来实现。为了提高CPU的运行效率,引入DMA设计,本文采用总线主控DMA(BUS Master DMA,BMD)的方式控制PCIe IP硬核从而控制高速数据的传输。
3 硬件逻辑设计
针对Xilinx公司XC5VLX85T PFGA,在Windows系统平台下,以Xilinx的参考案例XAPP1052[8]为基础,实现了PCIe总线的BMD功能逻辑设计。
如图3所示,BMD主要由以下五部分构成:
(1)PCIe IP硬核:对外与其他PCIe设备通信,对内与发送引擎和接收引擎进行数据传输。
(2)设备控制模块:接收通过接收引擎解析的数据,并将数据存储在SDRAM中;将SDRAM中的数据读出,供发送引擎组织TLP[9]包使用。为了匹配PCIe IP核和SDRAM两侧不同时钟域、不同速率的数据缓冲和位宽转换,设计了FIFO缓冲模块。
(3)寄存器控制模块:解析来自PC的命令和配置,并通知发送引擎、接收引擎和设备控制模块作出相应的执行操作。
(4)接收引擎模块:接收并解析TLP包,根据TLP的包头信息,将对应的数据写入寄存器控制模块的寄存器中,或者对接收到的存储器读TLP进行拆包。
(5)发送引擎模块:负责把待发送数据组织成TLP包,并传送给PCIE IP核。
3.1 DMA传输的逻辑设计与实现
DMA传输包括两个过程,即DMA读(PC端到FPGA端)和DMA写(FPGA端到PC端)。
3.1.1 DMA读设计与实现
DMA读操作包含两个过程,发送引擎组装DMA读请求TLP并发送,接收引擎接收PC返回的CPLD TLP。
本文在接收引擎中设置了4个TAG存储器,每个TAG存储器对应一个等待完成包的读请求,TAG存储器用来保存读请求的设备访问地址及长度,对每个读请求,PC可能会用多个CPLD TLP来应答,当PC送来CPLD TLP时,接收引擎根据CPLD TLP中的TAG标识,查找对应的TAG存储器,获得设备侧SDRAM的写入地址。因此,当发送引擎发送读请求TLP时,必须等待可用的TAG存储器,并以可用的TAG存储器编号作为读请求的TAG标识。当对可用TAG进行优先级排除时,优先级设置为0、2、1、3,以下的程序片段为接收引擎中TAG空闲信号TAG_empty_o及TAG标号TAG_empty_Index优先级设置方法,其中TAG_Valid为接收引擎收到的TAG对应的TAG标识。
为此设计的DMA读操作如下所示:
(1)发送DMA读请求TLP
①共需要发送rmrd_count个DMA读请求TLP, rmrd_count由软件在寄存器控制模块中设置。当接收引擎有空闲TAG时,发送DMA读请求TLP的第一个64 bit,使用该空闲的TAG 编号TAG_empty_Index_i来作为TAG标识,即trn_rd[41:40]={TAG_empty_Index_i}。
②根据32 bit地址信息组装DMA读请求TLP的第二个64 bit并发送。
(2)接收PC返回的CPLD TLP
流程如图4所示。
①接收CPLD TLP的第一个64 bit,解析得到TLP包数据长度。
②当接收缓冲FIFO为空且收到的TAG标识有效时,将解析得到的数据写入FIFO中进行缓存。
③接收CPLD TLP后续数据并将其写入FIFO进行缓存。
④若是CPLD TLP传输完成,判断接收到的数据长度。如若实际接收的数据长度与TLP包应传输长度一致,则当前CPLD TLP正确接收完成,清除TAG有效标识,此时TAG存储器处于空闲状态,可用于新的DMA读请求。
3.1.2 DMA写设计与实现
DMA写操作实现的主要方法是将TLP包头中的各个字段正确填充,并将数据按照64 bit并行放在TLP包头,传输给PCIe IP硬核,然后硬核以PCIe协议串行传输给PC。DMA写操作在发送引擎中实现,操作流程如图5所示。
(1)发送FIFO读取SDRAM存储器数据。当需要传输的数据量大于等于4 096 B时,传输数据量为4 096 B,否则传输数据量为SDRAM中剩余数据量。
(2)若发送FIFO读取数据完成,则发送DMA写TLPs。
①设置TLP包计数值cur_wr_count,初始值为零:cur_wr_count<=cur_wr_count+1′b1,将DMA写请求各字段填入TLP包头的第一个64 bit中发送。
②将32 bit地址和第一个32 bit数据填入TLP包头的第二个64 bit字发送。
③将每个TLP所需传输的数据填入TLP后续的64 bit字进行发送。
(3)重复步骤(2),直至cur_wr_count达到所需传输TLP包个数设定值,DMA写操作完成。
3.2 SDRAM控制模块设计
本文采用了片外扩展SDRAM存储芯片,片内编写SDRAM控制器的方式实现数据的缓存。采用两片32 M×16 bit SDRAM,SDRAM存储器只进行单端口数据操作,SDRAM控制器被设计成有左端口和右端口的双口控制器,在逻辑上将控制器实现左端口输入数据、右端口输出数据的功能。双口设计实现了数据传输方向的灵活控制。
图6是SDRAM控制逻辑的状态机,其中S0和S2是等待命令状态。S1表示经DMA读方式缓存在接收缓冲FIFO的数据有写入SDRAM的请求时,SDRAM控制器成为左口模式,数据存入SDRAM。S3表示有DMA写请求,发送缓冲FIFO有读取SDRAM数据请求时,SDRAM控制器成为右口模式,数据从SDRAM存储器读出后被传输到发送缓冲FIFO。
4 软件设计
软件设计包括驱动程序设计和应用软件程序设计。
本文PCIe驱动程序是在Windows 7操作系统下开发设计的,选用Jungo公司软件WinDriver生成,极大地简化了硬件驱动程序开发的工作量,具有极强的平台移植性。WinDriver支持Xilinx的BMD模式,能够根据硬件设备的描述自动产生设备驱动程序源代码程序框架,用户在Visual Studio2015下根据要实现的功能添加代码,完成驱动程序的开发。
应用软件程序的开发则使用了Visual Studio2015,主要功能是测试直接访问读写和DMA读写的正确性。在实现PCIe数据传输过程中,数据传输流程为:数据从PC内存通过PCIe接口以DMA读的方式向下传输到FPGA内部发送缓存FIFO中,FPGA内部SDRAM控制逻辑再将数据传输到SDRAM存储器中进行存储,向下传输成功后,FPGA内部逻辑从SDRAM存储器中将存储的数据读出,然后通过PCIe接口以DMA写的方式将数据传回PC内存,与原始数据进行比对校验。
5 FPGA测试验证
为了对设计实现的PCIe接口进行测试验证,需将硬件部分烧录到板卡的FPGA芯片后,通过板卡的PCIe金手指插到PC的主板上,重启PC,检测到新的硬件插入后便可安装相应的PCIe驱动文件,成功安装后进行功能测试。
上位机软件界面如图7所示,从图中可以看到,测试包括DMA读操作、DMA写操作及寄存器读写操作,步骤如下:
(1)进行DMA读操作,将所要传输的数据文件读入PC机内存,然后写入FPGA端;
(2)进行DMA写操作,FPGA通过DMA写将数据写回PC,并以文件的形式保存在PC上,PC对写回的数据和初始数据进行校验;
(3)直接访问操作,对指定地址的寄存器进行读写操作。
在进行DMA读写操作过程中,同时通过ChipScope Analyzer工具捕获各模块的端口数据来验证DMA读写操作过程中数据传输的正确性。以DMA读为例,如图8所示,接收引擎模块从PCIe IP硬核接收信号trn_rd,解析得到有效数据,接收缓冲FIFO读取其有效数据并输出dout信号,SDRAM存储器读取信号SDR_Din并进行存储。对比PC发送的原始数据和SDR_Din信号数据,得知DMA读操作正确。从图7软件界面可知,DMA读写数据长度107 640 B,PC原始数据与经DMA读写两个操作返回的数据全部一致,故而DMA读写正确。
经过多次测试,每次通信数据总量不少于100 GB,并未在DMA读写两个通道中发现不一致的数据,没有丢帧和误码现象。由此推算,PCIe通信数据误码率低于10-8。
DMA读写速度如表1所示。
在x4模式下,DMA的加入,写速率提升了近9倍,读速率提升了约10倍,并且PCIe总线的平均DMA读写速度稳定在500 MB/s以上,均超过16通道的总线测试系统的400 MB/s高速数据传输要求。
6 结论
本文设计实现了UM-BUS总线测试系统中PCIe1.1 x4链路通道的应用方案,采用基于FPGA的PCIe总线的DMA数据传输方式解决了总线测试系统中PCIe通信接口模块与PC间的高速数据传输问题,并完成了测试系统中的SDRAM高速缓存处理,最后结合WinDriver软件对PCIe功能进行了测试。测试结果表明,PCIe总线的DMA读写速度稳定在500 MB/s以上,均超过UM-BUS总线16通道并发传输的总线测试系统的400 MB/s带宽需求。
参考文献
[1] 张伟功,周继芹,李杰,等.UM-BUS总线及接入式体系结构[J].电子学报,2015,43(9):1776-1785.
[2] 邓哲,张伟功,朱晓燕,等.动态可重构总线数据传输管理方法设计与实现[J].计算机工程,2013,39(1):264-269.
[3] 王春亮.基于UM-BUS系统的总线测试方案研究[D].北京:首都师范大学,2014.
[4] 王嘉良,赵曙光.用FPGA实现PCI-E接口和DMA控制器设计[J].计算机技术与发展,2011,21(6):181-184.
[5] 王之光,高清运.基于FPGA的PCIe总线接口的DMA控制器的设计[J].电子技术应用,2018,44(1):9-12.
[6] 李超,邱柯妮,张伟功,等.基于PCIE总线主模式DMA高速数据传输系统设计[J].电子技术应用,2015,41(9):142-145.
[7] Xilinx DS551.LogiCORE IP endpoint block plus v1.15 for PCI express[Z].2011.
[8] LAWLEY J.Bus master performance demonstration reference design for the Xilinx endpoint PCI express solutions[Z].USA:Xilinx,2015.
[9] 王齐.PCI Express体系结构导读[M].北京:机械工业出版社,2010.
作者信息:
孙丰霞1,张伟功1,2,3,周继芹3,王 莹1
(1.首都师范大学 信息工程学院,北京100048;
2.首都师范大学 北京成像技术高精尖创新中心,北京100048;
3.首都师范大学 高可靠嵌入式系统技术北京市工程技术研究中心,北京100048)