本文引用自CSDN,作者:ARTBES。原文地址:https://blog.csdn.net/weixin_42166371/article/details/117573776
项目背景
近期实验室项目需对2GB/s的高速数字图像数据实时存储,后续数据带宽将提升至30GB/s。经调研,SATA协议的固态硬盘理论存储有效带宽为600MB/s,NVMe协议的固态硬盘理论带宽随PCIe协议而不同。NVMe协议的固态硬盘在PCIe Gen2、Gen3条件下,理论有效带宽分别为2GB/s、3.938GB/s。目前,NVMe SSD最高搭载PCIe Gen4通路,其理论有效带宽为7.877GB/s。
基础知识
NVMe协议基于PCIe协议之上实现NVMe Host与NVMe SSD之间高速数据通信。所以在学习NVMe协议之前,需要对PCIe协议系统的学习。
PCIe
PCIe设备分为RC设备和EP设备,本系统中NVMe Host为PCIe RC设备。对于PCIe RC设备,x86和NVIDIA等架构均有实现,但每个公司对PCIe RC的具体架构实现方案不同且不开源,并且PCIe Spec没有对PCIe RC规定其实现方式及RC需要完成的功能。网上大多数对PCIe的介绍仅停留在协议层,作者在这里纠结了好久,也做了很多无用功,下面对学习PCIe时看的资料做出整理,希望对大家有所帮助。(切记,我们要实现的是PCIe RC,EP和RC设备有很大的区别)
个人觉得掌握PCIe知识,以上资料足够,当然对于PCIe RC的实现,大家还需要在摸索摸索,毕竟,没有现成的实现方案。
NVMe
NVMe同PCIe一样也是标准的协议,对于NVMe协议的入门建议大家可以看看这本书
《NVMe科普教程 》古猫著(新手必备)
出了新手村以后,必要的还是需要反复啃一下NVMe的Specification。注意NVMe 1.3和1.4有一些不同,我先读了1.4,后续发现大多数硬盘都是1.3版本的NVMe协议,后续又读了1.3。大家可以直接上手NVMe 1.3。
《NVM ExpressTM base specification revision 1.3》
学习完以上所有资料基本对NVMe及PCIe知识体系会有一个完整的了解,那么接下来我们讨论一下架构问题。
架构分析
现有NVMe存储系统均为复杂计算体系中的存储子系统,目前暂无NVMe 主控芯片用于搭建独立存储系统。无论是基于x86还是NVIDIA架构的NVMe存储系统,都为基于操作系统的独立软硬件一体实体系统,无法将其嵌入或整合至另外的处理系统中,无法实现嵌入式NVMe存储功能并用于高温、冲击、振动等恶劣条件场景下的信号处理及存储系统。
FPGA 具有开发周期短、设计灵活性高等特点,且主流 FPGA 供应商 Xilinx 和Intel 公司均提供了功能丰富的 IP 以缩短项目开发时间。FPGA 提供带宽为 12.5 Gbps的 GTX 高速通道及带宽为 16.3 Gbps 的 GTY 等高速通道,其高速通道可外接 M.2 接口的 NVMe 协议固态硬盘。但FPGA适合高带宽的数据吞吐及处理,完成系统调度等任务较为复杂。因此Xilinx推出ZYNQ系列芯片以ARM为主处理器,FPGA为协同处理器为基本架构,软硬协同的处理方式使系统更具灵活性。
考虑到PCIe协议的高速吞吐量及NVMe协议的特性本系统采用软硬结合的方式实现NVMe协议。PL端实现PCIe的协议层,PS端实现PCIe总线枚举及NVMe协议。
软件实现层面,Xilinx提供了裸机开发及Petalinux工具开发。其中Petalinux工具使用内核自带PCIe驱动及NVMe驱动实现系统功能,但由于其操作系统指令需经过系统层、块设备层、驱动层的处理,在嵌入式处理器中会产生较大的访问延迟。因此本系统采用裸机的方式实现上述功能,其中裸机需要完成的有PCIe初始化、PCIe总线枚举、NVMe初始化及NVMe命令。
方案介绍
本方案由Xilinx官方开发板ZCU106和FMC NVMe SSD转接卡组成,支持主流厂家SSD实现高速数据存储功能。本方案采用软硬协同实现NVMe协议,写入速度稳定2.3GB/s,读取速度稳定2.5GB/s。软硬协同的架构使NVMe Host可随系统硬件升级而升级,从而提高读写速度。
硬件使用ZCU106主芯片ZU7EV内部集成PCIe RC硬核,完成PCIe协议层。软件使用ZCU106主芯片PS端ARM处理器,完成PCIe和NVMe Host功能。
本测试系统使用DDR产生伪数据,由ARM裸机启动完成NVMe协议,PL端实现PCIe协议及NVMe所需存储空间。
系统通过Cortex A53对NVMe设备初始化,并将指令存放至PL端BRAM中,通过更新Doorbell完成命令发送和完成。前端采集数据可由DDR缓存通过AXI总线发送至PCIe总线并路由至M.2 SSD。
测试平台
ZCU106无M.2接口,因此选用FMC接口作为高速接口,通过FMC转M.2卡连接SSD。转接卡可以自己做但是没必要,某鱼淘了一个,性价比还不错,主要是性能ok,链接放在这,算是给老哥打个广告。购买链接:https://m.tb.cn/h.4vq8Z9n。
性能测评
本系统使用ARM裸机结合FPGA实现NVMe SSD读写速度如图所示。在使用ZCU106硬件系统下,配合使用忆芯科技1TB SSD(国产主控+颗粒)写入速度稳定达到2.3GB/s,读取速度稳定达到2.5GB/s(预计三星970 Pro速度可以达到更高)。
资源情况
Resource | Utilization | Available | Utilization% |
---|---|---|---|
LUT | 24471 | 230400 | 10.62 |
LUTRAM | 1448 | 101760 | 1.42 |
FF | 28753 | 460800 | 6.24 |
BRAM | 54 | 312 | 17.31 |
GT | 4 | 20 | 20 |
BUFG | 10 | 544 | 1.84 |
PCIe | 1 | 2 | 50 |
系统资源使用率远低于ZCU106资源,可移植到嵌入式系统作为存储子系统应用。
应用范围
NVMe Host IP,内部使用Xilinx PCIe 核,可以通过简易的寄存器总线控制,轻松高效管理/访问各类NVMe SSD。
系统特征
系统升级
本课题最终存储实时带宽30GB/s,因此需对系统进行扩展,系统扩展选用CMOS数据分送给4片FPGA,每片FPGA下挂2个NVMe硬盘完成系统存储。
系统对每个FPGA做双盘存储,双盘存储的示意图如图所示:
此存储方案激活两个PCIe IP,使PL端实现两个PCIe RC,从而两个NVMe硬盘互不干扰,实现双盘存储功能,此方案的好处在于两个独立的RC可以更好的开发PCIe总线带宽,从而更好的开发NVMe硬盘存储功能,理论上存储速度可以翻倍。
此外,由于PCIe采用Xilinx硬核,目前XDMA的IP的RC功能最高支持到PCIe 3.0,后期随着XDMA的RC功能升级到PCIe4.0甚至5.0,本方案的架构无需改变,仅升级IP就可以做到NVMe硬盘速度采用PCIe4.0甚至5.0的总线速度。
个人体会
讲一下个人开发这个工程的心理路程,算是给各位同仁一点激励。2020年10月,刚开始拿到这个项目,评估了一下,难度还是蛮大的,有一些纯逻辑实现NVMe协议的方法,瞬间感觉要延毕了。沮丧了几天后,重拾心情,考虑了一下NVMe的特性,决定把初始化等流程放到PS,把大量数据吞吐放到PL。PS端可以借用Linux、RTOS和裸机。搜集资料有个老外使用Petalinux工具,借助Linux操作系统完成NVMe协议。跟着老外的教程,一步步走下来,发现读写速度也太低了,这连SATA3.0的速度都没达到,完全没发挥NVMe的性能。于是改进方案:
本人对Linux不太熟,第一种方案直接放弃。RTOS研究了几天,不太感冒直接放弃。裸机,用C语言直接底层驱动PCIe和NVMe,尝试了一下去读PCIe和NVMe的Specification,感觉可以,于是裸机开发。
历时5个月,终于成了,喜极而泣,可以毕业了。还好效果也不错,写入速度超过了大部分商业公司IP。
如果需要讨论,联系方式如下:
北京市可线下,地址:北京市海淀区中关村南大街5号北京理工大学。
非京可联系:Tel:13810602873(微信同号)
E-mail:liuzhenyu@bit.edu.cn
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧ END ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧