官宣:基于LV My FPGA SATA硬盘IP正式发布

1、背景
众所周知,在传统的FPGA应用领域中,经常需要将采集到的大量原始数据或者处理后的数据存到本地,但是FPGA不像上位机,没有系统,所以做数据存储会非常麻烦,也就是我们俗称的数据流盘。
虽然,我们可以将一部分数据存放到DDR里面缓冲,但是内存的容量太有限了,一般也就是几十GB,价格贵,并且一旦掉电数据就会丢失,弊端很多。因此,很多厂商发明了磁盘阵列系统,用多个廉价的SATA或者NVME接口的固态硬盘进行并行读写,突破了带宽和容量的限制,比如采用8个工业级的1T SATA固态硬盘,同时进行读写操作,可以实现平均3.2GB/s的读写速度,容量更是高达8T,当然,磁盘容量和数量还可以进一步扩充。
但是这类商业磁盘阵列系统,价格非常昂贵,体积大,不方便集成。因此,很多FPGA高手就会想着去买成熟的SATA或者NVME商业IP核,这类FPGA IP动辄十几万甚至几十万,很多小公司或者个体户无法承受这么昂贵的成本。所以他们会转向采用传统的SD卡或者Flash来存放数据,但是限制很明显,那就是SD卡或者Flash的容量太小,速度太慢,称不上是流盘系统,顶多也就是记录一下少量的参数和状态信息。
针对目前磁盘阵列和流盘(数据存储)行业里面遇到的这些问题,我们神电测控联合FPGA专家花费了半年时间攻关,终于完成了基于LabVIEW My FPGA软件工具包下的SATA固态硬盘IP软件、FPGA SATA Demo以及配套的上位机软件。
2、官宣
时隔半年,LabVIEW My FPGA软件工具包,终于迎来了一位重量级成员,那就是基于FPGA的高速磁盘阵列(流盘)IP。
用户可以在LabVIEW FPGA环境下,直接使用我们封装好的SATA磁盘VI(Socket CLIP),然后自动编译下载到FPGA芯片里面运行,分分钟实现一套高速磁盘阵列系统,性能和指标可以完全PK市面上现有的流盘系统。
当然了,对于很多不需要磁盘阵列的应用,也可以单独使用一个低成本的SATA固态硬盘作为FPGA的贴身保镖,实现FPGA数据的在线实时流盘,就像飞机的黑匣子那样,真正补齐了FPGA的最后一块短板。
传统的SATA FPGA IP使用起来非常麻烦,我们专门将SATA底层复杂的逻辑进行优化和封装,然后移植到我们的LabVIEW My FPGA工具包里面来,直接通过图形化的方式进行调用,门槛极低,只要有一点LabVIEW基础,就可以非常轻松地开发出基于FPGA的高速流盘系统了,当然,用户也可以直接基于我们编写好的LabVIEW FPGA SATA Demo程序进行少量修改和适配,定制出适合自己的FPGA SATA流盘板卡或者阵列。
下面我们详细讲解一下,如何利用LabVIEW编写FPGA SATA固态硬盘高速读写程序,同时还可以将FPGA读取SATA固态硬盘的数据通过PCIe上传到上位机进行观察回放。
3、硬件准备
众所周知,我们的LabVIEW My FPGA软件工具包主打开源国产化,不限制任何厂家FPGA硬件。为了测试我们封装好的My FPGA SATA IP(VI),我们从市场上随便淘了一个便宜的带标准SATA接口的Kintex-7 FPGA开发板,如图100-1所示。厂家是杭州言曼科技,感兴趣的用户可以在网上搜索一下。同时,这个K7开发板还支持PCIe高速通信,正好后续磁盘数据回放里面可以用上,将FPGA从SATA里面读取的数据通过PCIe总线发送给上位机进行显示。
注意:一般的K7开发板厂家都没有集成SATA接口,是因为他们提供不了SATA例程。而KU和KU+开发板一般会预留SATA接口,但是这样的板子价格比较贵。

这款K7开发板上面预留了4路标准SATA接口,可以同时连接4个独立的SATA固态硬盘。这里我们选择了一个商业级的256GB容量的mini SATA固态硬盘,如图100-2所示。有条件的用户也可以尝试一下工业级的SATA盘,工业级的SATA盘读写性能要比商业级更快,且速度更稳定。

由于FPGA开发板上预留的是标准SATA接口,mini SATA盘不能直接连,用户可以直接在淘宝上买一个mini SATA转标准SATA口的转接板,如图100-3所示;这种转接板一般需要外部独立供电,网上有很多这种接口的电源,比如图100-4所示的可以专门给SATA供电的12V电源适配器。



将前面的miniSATA固态硬盘、转接板、电源适配器组装一下,就可以接到FPGA开发板上了,实物如图100-5所示。当然了,用户也可以直接从PC或者工控机里面拆一个标准SATA接口的硬盘或者网上买一个,如图100-6所示,这样就不需要那个转接板了。


二者区别就是:miniSATA硬盘体积小,重量轻,易于集成;标准SATA盘体积大,一般用于传统PC或者工控机领域。
为了将FPGA从SATA固态硬盘里面读出来的数据传输给上位机进行回放显示,我们可以借助FPGA的PCIe通信口。因为现在很多笔记本都有雷电口,所以只要买一个TypeC雷电口转PCIe扩展坞跟FPGA开发板的PCIe连起来,就可以很方便的实现上位机(笔记本)跟下位机FPGA之间的PCIe数据通信了,并且相较于传统的工控机,更容易携带和调试。如图100-7所示。

4、下位机FPGA SATA硬盘读写程序开发
下面我们先来讲解一下如何利用LabVIEW编写一个下位机FPGA程序,实现对SATA固态硬盘的读写;通过3个FPGA SATA Demo程序向大家展示一下,使用LabVIEW调用我们封装好的SATA IP是多么的简单实用。
1首先,新建一个LabVIEW项目,右击“我的电脑”选择新建“终端和设备”,如图100-8所示。

2在弹出来的对话框里面,找到Kintex7-325T家族,展开之后,找到里面带SATA后缀的FPGA终端,如图100-9所示。选中之后,可以看到FPGA终端里面多出来一个SATA Socket CLIP,如图100-10所示。


下面,我们简单介绍一下,SATA IP在LabVIEW My FPGA下每个端口的含义:
1)图100-11显示的是SATA IP的两个复位信号。可以对底层的SATA IP核和硬盘进行复位操作,一般情况下,FPGA VI运行的时候,执行一次复位即可。

2)图100-12显示的是SATA IP的寄存器读写端口。可以对底层的SATA IP核进行寄存器读写操作,比如我们可以对指定寄存器地址写入或者读取的扇区首地址、连续读写的扇区个数进行配置,也可以读取SATA IP内部的寄存器工作状态,这个在后续的Demo程序里面再给用户做详细的介绍。

3)图100-13显示的是SATA IP读写命令是否执行结束标志。如果SATA磁盘处于单次或者连续读取或者写入忙状态,CMD_BUSY处于高电平,读写完成后该信号拉低,而CMD_END信号在读写完成后会拉高一个时钟周期,用户可以任选其一作为完成信号。

4)图100-14显示的是SATA IP数据流写入和读取端口。我们按照标准的四线握手进行封装,这样用户就可以直接将LabVIEW FPGA里面的FIFO与下面的WR和RD进行互联,在后续的FPGA VI程序框图中可以看到,非常简单。需要注意的是:这6个端口需要放在200MHz(推荐大于等于150M时钟)时钟域里面运行,因为SATA IP底层走的GTX时钟是150MHz,数据位宽是32位,也就是单个SATA磁盘的最大理论带宽是150M×4Byte/s=600MByte/s.除了这6个端口外,其余的SATA REG寄存器和状态端口全部放在低速的50MHz时钟域里面运行就可以了。

5)图100-15显示的是SATA IP寄存器和状态信息端口。如果SATA硬盘出现故障,我们可以通过下面的6个状态输出口进行排查,比如,如果SATA硬盘跟FPGA断开了,那么LED_LINK_UP会熄灭。如果SATA IP初始化成功的话,LED_LINK_UP和GTX_PLLLOCKED会点亮。

3虽然,上面我们简单介绍了一下封装到LabVIEW FPGA下的SATA IP端口含义,但是很多用户不知道具体怎么使用。下面我们通过3个FPGA SATA VI Demo示例程序向用户讲解一下调用过程。这3个FPGA VI下位机程序,如图100-16所示。
这3个FPGA SATA VI示例程序分别实现了对SATA固态硬盘的单次读写、连续读写以及通过PCIe由上位机实现对FPGA SATA的操控和数据回放。

4双击打开第一个FPGA SATA单次读写VI(实验100.1-SATA固态硬盘高速流盘-FPGA-单次.vi),里面一共有3个定时循环,如图100-17所示。相当于3个独立并行的线程,分别是“SATA寄存器操作线程”、“SATA数据流读写线程”和“模拟数据产生用户线程”。对应的FPGA VI前面板,如图100-18所示。


1)第1个定时循环“SATA寄存器操作线程”,是一个标准状态机架构,可以对SATA IP进行手动复位、扇区地址、扇区数量进行设置,然后自动实现数据流读写,同时还能计算出单次读写消耗的时间,方便用户对SATA盘平均读写速度的计算。我们看看最后一个状态,当单次读写完成后,CMD_END会拉高一个时钟周期,根据这个状态信息重新回到Idle状态,然后等待下一次的SATA操作。需要注意的是:单次往SATA硬盘侧写入的扇区数量不能超过65535个,另外,我们封装的SATA地址和容量单位都是扇区,单个扇区大小为512字节,相当于地址偏移量是512.假设一个SATA盘的容量是256GB,那么等效的扇区个数就是256GB/512B=500M,扇区地址就是0~500M-1.

2)第2个定时循环“SATA数据流读写线程”,位于200MHz系统时钟域里面,因为单个SATA固态硬盘底层调用的GTX时钟最小是150MHz。这个线程里面的程序框图非常简单,用户只需要将读写数据缓冲区FIFO按照标准四线握手的方式跟SATA WR和RD端口互连起来即可,如图100-20所示。这样做的好处是,可以将用户线程跟SATA线程隔离开,不同的行业应用,只需要在用户线程里面读取或者写入数据就可以了。

3)第3个定时循环“用户线程”,看过我们宝典前面串口、IIC、SPI、千兆以太网等相关内容的用户知道,我们习惯于将通信线程跟用户线程分开,二者之前通过FIFO进行数据交互,同时也可以实现跨时钟域访问。本节实验程序里面的用户线程,是用来模拟SATA写入数据的,可以将FPGA VI前面板上的“写入数据”输入控件里面的数值写到SATA硬盘里面去,当然也可以将SATA硬盘里面的数据读出来更新到显示控件“读出数据”里面,如图100-21所示。

4)需要提醒用户的是:对SATA固态硬盘写固定值和写随机的数据,速度是不一样的,如果对多个连续扇区进行固定值写入,速度非常快,商业盘可以到400多MB/s,如果是变化的数据,一般是150MB/s左右;工业级的SATA盘更快,可达稳定的400MB/s。。
5上面的Demo程序实现了FPGA对SATA盘的单次最大不超过65535个扇区的连续读写,如果想要实现更多扇区的连续读写,可以打开我们的第2个FPGA SATA Demo示例程序。其实整体程序框图跟单次读写是类似的,只不过我们稍微调整了一下状态机读写退出的机制而已,如图100-22所示。将单次读写完成后的扇区数量进行累加,直到满足用户指定的扇区总数量才会停止退出这个状态机,这样就实现了对整个SATA盘的连续读写。

6无论是前面的FPGA SATA单次还是连续读写,用户都可以手动在FPGA VI前面板上通过控件和按钮实现对SATA盘的操作,这样便于用户理解和掌握SATA盘数据读写机制,整个过程非常直观,这一切都得益于我们打通了LabVIEW FPGA VI在线前面板交互式功能。不需要单独编写上位机的情况下,也能直接操作FPGA VI前面板,效果非常好,具体演示我们会在后续实验环节给大家讲解。
熟悉和掌握我们的My FPGA SATA IP用法之后,就可以研究我们提供的模拟真实场景下的第3个FPGA VI Demo应用案例,那就是“磁盘阵列回放系统”。下位机FPGA可以将SATA磁盘里面的数据读出来通过USB2.0、USB3.0、千兆以太网或者PCIe高速总线传输给上位机(可以是Windows主机也可以是Linux RT实时系统),进行离线观察和显示。
双击打开FPGA终端下的第3个“实验100.3-SATA固态硬盘高速流盘-FPGA-连续+PCIe DMA.vi”示例程序,可以看到,我们是在前面FPGA SATA连续读写例程里面,加上宝典第7章的PCIe总线通信,实现了磁盘阵列的数据操控和回放功能。具体的下位机FPGA程序框图,如图100-23所示。这里不再赘述了。



这个FPGA SATA VI程序前面板相应的增加了一些PCIe控件,如图100-24所示。

5、上位机SATA磁盘阵列回放程序开发
光有下位机FPGA SATA VI程序还不够,很多客户希望有一个独立的上位机软件可以实现对下位机FPGA程序的控制,这样才是一个完整的项目开发。为此,我们单独编写了一个基于PCIe总线传输的磁盘阵列数据流盘回放的上位机软件,提供给大家。如图100-25所示。

1双击打开这个上位机VI程序前面板,如图100-26所示。可以看到,我们是在本书前面第7章的PCIe上位机例程基础上稍加修改就实现了SATA磁盘阵列的回放程序。上位机VI前面板上主要增加的是FPGA SATA下位机前面板上的一些控件,这样用户就可以通过PCIe下行通道将上位机参数下发给FPGA程序,即使不借助FPGA VI在线前面板也能实现由上位机来独立操控下位机FPGA程序了;同时也把下位机FPGA前面板上的SATA显示控件也就是状态信息通过PCIe上行通道传输到上位机显示出来,方便用户独立观察;最后就是将FPGA从SATA磁盘里面读出来的数据通过DMA FIFO传输到上位机回放出来。

2上位机对应的程序框图一共有3个线程,分别是“下发SATA控制参数”、“读取SATA数据流”和“读取SATA状态信息”。下面简单介绍一下3个线程对应的程序框图。
1)首先是“下发SATA控制参数”这个while循环(线程),负责将上位机前面板的控件信息和参数,比如SATA盘的扇区地址、连续读写扇区长度、读还是写、分频系数等通过PCIe下行通道(比如ch13)下发给FPGA,如图100-27所示。不熟悉的用户可以看看我们宝典第7章PCIe部分的相关内容和案例。

2)接着是“读取SATA数据流”这个while循环(线程),负责将下位机FPGA从SATA硬盘里面读取的数据流通过PCIe DMA上行通道(比如ch9)读到上位机,然后放到波形图里面实时显示,如图100-28所示。

3)最后是“读取SATA状态信息”这个while循环(线程),可以将下位机FPGA SATA盘当前正在读写的扇区地址、连续读写扇区长度、SATA盘连接状态、错误信息等通过PCIe上行通道(比如ch8)读到上位机,如图100-29所示。这样,即使我们不借助FPGA VI在线前面板交互式功能,也能实时观察下位机FPGA SATA的运行情况。

4)需要提醒用户的是:上位机初始化打开下位机FPGA PCIe对应的通道号之前,最好用Winobj工具观察一下上位机设备管理里面映射出来的PCIe具体通道号名称是多少,如图100-30所示。很多用户在这个地方翻车了,一上来直接运行上位机VI,导致崩溃退出,这是因为看书不仔细,实际上,本书第7章关于Winobj的用法做过详细的介绍,不记得的用户可以回顾一下。为了同时识别多个FPGA板卡,每个FPGA板卡里面的DMA通道名称不能相同,比如第一块FPGA硬件是ch0~ch7,第2块FPGA硬件是ch8~ch15.而下位机FPGA程序框图使用的是ch0、ch1和ch5,那么针对第2块FPGA硬件的上位机PCIe通道号就要偏移累加8,也就是ch8、ch9和ch13的由来。

6、实验测试结果
这里我们直接测试第3个FPGA SATA流盘示例程序,也就是SATA磁盘阵列数据回放系统。
1首先,直接运行下位机FPGA VI,在FPGA程序生成规范里面勾选“加载至FPGA时运行”,等待编译完成后,可以看到对应的FPGA芯片资源消耗情况,如图100-31所示;接着自动弹出交互式下载对话框,由于我们还没有将Xilinx下载器接到FPGA开发板上,所以LabVIEW会提示找不到Cable,如图100-32所示。


2接下来,将Xilinx JTAG下载器接到FPGA开发板上,如图100-33所示。给FPGA板子和SATA硬盘上电。

然后,打开这个路径下的这个ini文件
(C:\Program Files (x86)\National Instruments\LabVIEW 2015\vi.lib\FPGAPlugInAG\My_FPGA_Robot_BoaRD)
确保download+debug=1,然后直接运行刚刚编译好的下位机FPGA VI,等待几秒钟,可以看到FPGA开发板上的Done指示灯熄灭,说明FPGA被JTAG控制了,正在下载程序,下载完成后,Done指示灯会重新点亮,但是FPGA VI前面板并没有进入在线交互式运行,而是直接弹出一个错误提示框,如图100-34所示。

这是因为下位机FPGA里面含有PCIe程序框图,而PCIe从设备下载bit文件之后必须要重启主机才能识别,识别之后,主机才会给从设备FPGA提供100MHz PCIe时钟;如果FPGA程序框图里面的任何一个定时循环时钟不存在,都会报这个超时错误,关于这点我们在宝典第7章做过非常详细的讲解和提醒,不记得的用户一定要多看几遍。
3既然FPGA SATA程序下载到FPGA芯片里面运行了,只需要热重启一下主机或者插拔一下我们的TypeC雷电转PCIe模块,就可以让主机识别到下位机FPGA PCIe设备,比如,打开设备管理器,可以看到加载成功的PCIe驱动,如图100-35所示。同时,FPGA开发板上的LED0指示灯闪烁起来了,这个是Xillybus PCIe心跳指示灯,说明FPGA里面的PCIe工作正常。

4然后将ini文件里面的1改成0,也就是download+debug=0,相当于告诉LabVIEW FPGA直接进入在线前面板交互式运行,不要去下载bit文件了,因为前面已经下载过了,不然就会陷入下载bit,PCIe重启的死循环了。改完之后,再次点击运行下位机FPGA VI程序,此时,可以看到下位机FPGA前面板活了,并且“PCIe_Status[]”状态布尔数组里面的LED0闪烁了,说明PCIe工作正常,同时“LED_LINK_UP”和“GTX_PLLLOCKED”都点亮了,说明SATA IP初始化成功,如图100-36所示。

5由于我们的LabVIEW My FPGA有这个在线前面板交互式功能,所以不用打开上位机,直接就能测试SATA盘读写是否正常。比如我们想把1234写入到扇区地址从0开始的1M个连续空间(1M×512Byte)里面,那么用户可以在下位机FPGA VI前面板上输入以下参数,如图100-37所示。注意:分频系数设置为1,这样可以保证产生源数据的速度要大于理论值600MB/s,才不会拖累SATA。

6然后点击一下“Start”按钮,此时,可以看到“单次写入扇区首地址(512字节)”这个控件里面的数值在不断增加,说明FPGA正在往SATA硬盘里面写入数据,等到1M个扇区空间全部写完之后,“连续读写消耗时间(ms)”控件里面显示出5.151s,如图100-38所示。这就是本次连续写操作花费的时间,这样我们就可以计算出当前这块商业SATA盘的平均写入速度:1M×512Byte/5.151s=99.398MB/s,这个速度还可以,因为这个盘比较老,读写次数太多导致的,如果对这个盘格式化一下,写入速度马上就能飙到150MB/s。工业级的SATA固态盘写入速度可以到450MB/s,读取速度更快。另外,如果写入固定值和变化值,SATA固态盘的读写速度也是有很大差别的。前面Demo1和Demo2每次读写的是固定值,所以速度更快,这里的Demo3是一个连续的正弦信号,变化值,所以速度会慢一些,这个是SATA盘本身机制的问题,跟FPGA没有关系。

7下面,我们测试一下SATA读取速度,将“单次读写扇区首地址(512字节)”重新设置为0,总容量还是1M不变,将“Write”按钮切换到Read模式,按下“一直读取”按钮,如图100-39所示。然后再点击“Start”触发读取操作,很明显,地址增加的速度要比写入更快,等待读取完成后,可以看到本次读取操作花费的时间是997ms,如图100-40所示,也就是0.997s,等效的平均读取速度是1M×512Byte/0.997s=513.54MB/s,因为读取操作不需要对SATA进行擦除和校验,所以速度更快。


8最后,我们打开上位机测试程序,利用上位机直接对下位机FPGA进行SATA控制和数据读写操作。注意:切换到上位机控制模式,要把FPGA VI前面板上的“一直读取”关闭掉,如图100-41所示。

9首先,测试一下上位机控制FPGA写入SATA硬盘功能,将5.12GByte的正弦信号一次性写入SATA固态硬盘,参数设置如图100-42所示。分频系数设置为1,点亮“Start”按钮,然后点击“Send”发送按钮,即可将这些参数下发给FPGA,等待FPGA将10M扇区全部写入完成后,可以看到耗费的时间是32.424s,如图100-43所示。等效的写入平均速度就是:10M×512Byte/32.424s=157.9MB/s,对于商业盘来说,这个速度还是非常不错的。


10最后,测试一下上位机控制FPGA读取SATA数据流回放功能,准备将SATA固态硬盘里面的连续5.12GByte正弦信号一次性读取到上位机进行实时回放,参数设置如图100-44所示。分频系数设置为1,将“Write”按钮切换到Read模式,点亮 “Start”按钮,然后点击“Send”发送按钮,即可将这些参数下发给FPGA,此时,上位机前面板波形图控件里面立刻出现了连续的正弦信号;等待FPGA将10M扇区全部读取完成后,可以看到耗费的时间是23.51s,如图100-45所示。等效的读取平均速度就是:10M×512Byte/23.51s=217.779MB/s,可以看出,商业盘的读写速度稳定性没有工业级的好。


7、结论
本节实验我们测试的是单个SATA固态硬盘的读写和回放功能,实际上,如果用户需要更高带宽和更大容量的磁盘阵列来实现流盘系统,可以多买几个SATA硬盘,接到FPGA板子上,然后直接在FPGA VI里面将读写线程复制几份,加上并转串和串转并线程就可以实现磁盘阵列的Raid0模式了,比如下面图100-46就是我们实际项目里面开发的一款高集成度的FPGA SATA板卡,支持最大3.2GB/s的流盘速度。更多具体信息,欢迎大家联系我们神电测控。微信:myview30;邮箱:DLW30@126.com
