第一章项目背景
光纤项目是明德扬承接自某研究所的项目。该项目功能是接收4路光纤数据,经过内部DDR3缓存后,通过PCIE接口上送到电脑保存。其中光纤采集到数据后,需要做一定的算法处理,该算法处理由客户实现,明德扬保留易修改、易插入的模块接口。
该项目实质就是一个数据采集卡功能:采集到高速数据并保存到电脑本地,具有速率高、数据量大的特点。采集卡项目均可参考此方案实现。该项目使用到光纤接口,可以学习到光纤IP核的应用。
本项目可以通过PCIE,实现对FPGA的配置。特别是实现了可分别配置和读取1路接收FPGA、4路发送FPGA寄存器的功能。关于上位机,如DSP、ARM、单片机、电脑,如何与FPGA通信交互的,可以参考此方案。(在优化版本中,也提供了通过串口配置的方案,即将PCIE配置改为用串口配置。)PCIE部分不作讲解,要注意。该项目有对应的视频专题课,并提供代码学习。
第二章系统功能和架构
上图是本项目整体的简图,包括4个发送板、1个接收板和PC电脑。其中本项目主要实现提接收板功能。
接收板包括四片的DDR3、一个PCIE接口、四路光纤接口。当然接收板上还有很多其他接口,但是对于我们的项目来讲,主要的就是这三种接口。接收卡通过PCIE接口,直接插到PC的插槽上,跟PC进行相连。发送板可以通过光纤口发送数据,从接收板看来,可以认为外部有四路光纤口,接受这四种光纤的数据。
本项目中,四路发送板,每一个发送板其实它是一个AD采集卡。每个发送板它大概有16路的AD的采集,采集好数据汇总通过光纤送到这个接收卡。
接收卡从光纤接受到数据后,把数据汇聚起来,做适当的处理后,将数据保存到DDR3中,等待被读出送给PCIE接口,然后上送给PC电脑,这个就是我们整体的功能。
第三章FPGA架构
上图是FPGA的内部实现架构。根据功能,可以大概划分成光纤功能、存储控制功能、PCIE功能三大部分。
第1节光纤功能
本项目通过光纤模块,实现接收板和发送板的通信,通信速率是2.5Gbps,采用XILINX的官方IP核:7SeriesFPGAsTransceiversWizard(以下简称:GTXIP核)。关于该IP核的设置,有兴趣的读者,可以阅读我们之前发表的文章《XILINX(K7)和CycloneV之间的光纤通信设置》一文。由于使用到4路光纤,在设置高速收发器IP核时,注意要生成4路通道。当生成后,每路通道给用户侧的数据发送接口只有两个:发送数据tx_data和K码指示tx_kchar。同理,接收方向则是rx_data和rx_kchar。我们注意到,数据接口只有数据和K码指示,而不是明德扬常见的包文形式。事实上,两个较高级的设备之间通信,一般就是采用包文的形式,一次发一组数据,每组数据可以达到几千字节。为实现分组发送,特自定义了光纤协议层包文格式,如下表。
包文头数据长度校验和无效值数据16位16位16位16位数据长度个数据上面是光纤协议层的包文格式,其有一个16位的包文头(固定为0x55d5),一个16位的长度指示(指示后面数据的长度,单位为字节),一个16位的校验码,一个16位的无效值,以及数据。在FPGA内部架构图中的光纤打包模块,当从上游模块收到一个包文时,就计算该包文的长度、校验和,然后产生包文头+数据长度+校验和+无效值字段,再加上输入的包文数据,送给GXTIP核。GTXIP核再通过光纤送给发送板。同理,发送板那里,也应该有一个打包模块,其要发送数据给接收卡,就会将包文封装成上面格式,再通过光纤传输到接收板。接收板从GTXIP核接收数据,在光纤解包模块中,搜索包文头55D5。如果搜索到包文头,下一状态就获取数据长度和校验和。根据数据长度,接收后面的数据。边接收数据边计数数据的校验和。当接收数据完毕,校验和也计算完了。这个时候,就对比收到的校验和与计算的校验和,是否相同。如果相同,说明包文是正确的;如果不同,说明包文是错误的。
上面就是光纤的基本功能,主要涉及到光纤打包、光纤解包等。事实上,如果光纤采用的是Aurora协议,那么推荐采用另一个IP核:Aurora8B10B。这个IP核使用AXI4-stream总线接口,并且已经是包文的格式。因此使用起来更加简单。
第2节存储控制功能
本项目接收光纤数据后,首先会保存到DDR3中,等存够一定数据时,读出数据,送到PCIE。接收板一共有4片DDR3,每片DDR3的数据位宽是16位。要注意的是,虽然有4片DDR4,但这4片DDR3不是各自独立工作的。在硬件设计时,将DDR3的地址线、控制线共用,数据线分开。也就是说,4片DDR3同时进行读写,对FPGA来说,这相当于一片64位的DDR3。由于光纤数据一共有4路,并且4路数据都同时过来的,但只有一片64位的DDR3,如果不做处理,必须会有冲突。所以必须要做一个调度模块:4路光纤数据,首先会保存到内部的写FIFO中;调度模块判断4路FIFO的空闲情况,从而决定读取哪一路数据,存到DDR3中。没有被读取的,则继续保存在FIFO中,直到被调度出来。在设计调度模块时,要注意如下几点:
a.调度的优先级
一共有4路数据,那么调度器的优先级如何选择,即如果4路中有多于1路均同时有数据,那么该如何选择哪一路。例如,您可以指定第0~3路优先级依次由高变低,即当第0路有数据,一定选择0路;当第0路没有数据了,再决定看下一路。当采用此方式时,就要考虑是否存在如下情况:第0路一直有数据,导致其他路一直无法读出送到DDR3呢,这是要思考的问题。
b.调度的单位调度的单位是指:选择了一路数据后,会读取多少个数据才结束。可供选择是1个数据、多个数据,或者是读到FIFO空为止。这里要思考的是,1个数据最灵活,但是最繁琐,会出现频率调度的情况;如果是越多的数据,调度没有那么繁琐了,但也意味着写FIFO要临时存比较多的数据才行,所以这里要有一个平衡。
c.调度的起启水线调度的起启水线:当FIFO存够多少个数据,才可以被调度器调度。这个是要考虑DDR的写速度、光纤的输入速度、以及调度单位的。例如,如果调度单位为1024个数据,起启水线100,当DDR写速度比光纤速度快时,就可能会存在DDR写到一半时,新的数据还没有来的情况。当然,最省事的,就是将起启水线设置为跟调度单位一样,这样就绝对不存在问题,但这会存在一定的浪费。为什么呢?我们设想如下场景,当往DDR写数据的同时,光纤也会同时有新的数据送到写FIFO。我们可以计算DDR的写速度,以及新数据输入速度,根据速度差,得到起启水线。最理想的情况,就是当最后一个数据写到FIFO时,刚好也要将该数据写到DDR,然后调度结束。这样做的好处,就是将FIFO的深度设置为最适合的大小,从而节省资源。在FPGA领域,貌似还不能理解FIFO深度多一点或者少一点有什么所谓。但在芯片设计领域则是经常考虑的点。笔者在做芯片设计时,经常要花很多精力去计算出最省资源的方案。其实这也说明了FPGA设计和芯片设计的区别,区别是做得更细、设计得更好。bytheway,就如我一直在强调的,FPGA和芯片是一个讲究做“细节”的技术,很多人可以做很粗的功能,但很少人可以做很细的功能,例如图像显示很多人都会,但用较少资源来实现图像显示,那就不会了。
第3节PCIE功能
PCIE实现FPGA与上位机通信的功能,通信包文有两种,一种是业务包文,一种是配置包文。配置包文是用来对接收卡、发送卡内的寄存器读写的包文。例如上位机对接收卡通道的开户和关闭,对发送卡的数据收发控制、上位机读取接收卡的内部状态等,均是由配置包文来实现的。业务包文是指发送卡里的AD采集的数据,是真正上位机要保存的数据。下面上位机和FPGA的通信格式。
1.包文类型:用来指示是业务包文还是配置包文。业务包文的包文类型为16'h55AA;配置包文的类型为16'hF8F8。
2.读写属于:用于上位机指示对FPGA的寄存器进行写,还是读其值。
3.板卡编号:用来指示当前包文是对哪个板卡进行配置,可以理解为设备地址。例如是对接收卡或具体的一个发送卡进行寄存器读取。编号为0~3表示发送板0~3,编号4为接收卡。
4.寄存器地址:这个可以理解为寄存器地址。
5.寄存器数据:对寄存器配置的数据,如果是读的话,则填0。
上位机当要配置或者读取寄存器时,会按格式产生一个配置包文,通过PCIE传给FPGA。FPGA的内部有一个PCIEIP核。该IP核支持AXI4并且是包文形式,从PCIE里接收到包文数据,并送往协议解析模块。
协议解析模块分析该包文,特别是对包文编号进行识别。根据编号,如果是接收卡配置包文,则直接对内部的寄存器进行读取;如果是某一路发送板配置包文,则将该包文转发到该路光纤接口。
如果是读取寄存器数据,则会将配置包文返回给上位机,具体路径是:协议解析模块处理后,将寄存器数据补充到包文的数据域,然后读该包文转给6选1SP调度模块。在该调度模块中,从6路包文(1路是业务包文,1路是接收卡返回的配置包文,其他4路是4个光纤返回的配置包文),选取一路发给PCIEIP核。上位机从包文类型中,识别出业务包文还是配置包文,做相对应的处理。
需要了解更多相关资料请联系:易老师
明德扬科技教育