Amiya · 2021年08月30日

FPGA实现高带宽NVMe SSD读写

项目背景

近期实验室项目需对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所需存储空间。

640.jpg

系统通过Cortex A53对NVMe设备初始化,并将指令存放至PL端BRAM中,通过更新Doorbell完成命令发送和完成。前端采集数据可由DDR缓存通过AXI总线发送至PCIe总线并路由至M.2 SSD。

测试平台

640 (1).jpg

ZCU106无M.2接口,因此选用FMC接口作为高速接口,通过FMC转M.2卡连接SSD。转接卡可以自己做但是没必要,某鱼淘了一个,性价比还不错,主要是性能ok,链接放在这,算是给老哥打个广告。购买链接:https://m.tb.cn/h.4vq8Z9n

性能测评
640 (2).jpg

本系统使用ARM裸机结合FPGA实现NVMe SSD读写速度如图所示。在使用ZCU106硬件系统下,配合使用忆芯科技1TB SSD(国产主控+颗粒)写入速度稳定达到2.3GB/s,读取速度稳定达到2.5GB/s(预计三星970 Pro速度可以达到更高)。

资源情况

ResourceUtilizationAvailableUtilization%
LUT2447123040010.62
LUTRAM14481017601.42
FF287534608006.24
BRAM5431217.31
GT42020
BUFG105441.84
PCIe1250

系统资源使用率远低于ZCU106资源,可移植到嵌入式系统作为存储子系统应用。

应用范围
NVMe Host IP,内部使用Xilinx PCIe 核,可以通过简易的寄存器总线控制,轻松高效管理/访问各类NVMe SSD。

  • NVMe SSD 数据拷贝机/烧录机
  • NVMe SSD数据记录仪
  • NVMe SSD 功能和读写性能测试
  • 数据中心大容量高速存储设备
  • AI 计算云端/设备端高速存储
  • SMART NIC控制器

系统特征

  • NVMe Host符合NVMe协议标准1.3,支持各种常用命令,如:Identify、Write, Read, Flush 等。
  • NVMe Host采用软硬协同设计,系统灵活性高。
  • NVMe Host使用DDR作为数据缓冲区,DMA传输稳定,使用国产忆芯硬盘测试PCIe Gen3×4条件下,写入速度稳定2.3GB/s,读取速度稳定2.5GB/s。
  • PCIe基于Xilinx硬核开发,NVMe Host可随Xilinx PCIe升级而提升性能。

系统升级
本课题最终存储实时带宽30GB/s,因此需对系统进行扩展,系统扩展选用CMOS数据分送给4片FPGA,每片FPGA下挂2个NVMe硬盘完成系统存储。
640 (3).jpg

系统对每个FPGA做双盘存储,双盘存储的示意图如图所示:

Image

此存储方案激活两个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的性能。于是改进方案:

  • 第一:优化Liunx底层
  • 第二:RTOS
  • 第三:裸机

本人对Linux不太熟,第一种方案直接放弃。RTOS研究了几天,不太感冒直接放弃。裸机,用C语言直接底层驱动PCIe和NVMe,尝试了一下去读PCIe和NVMe的Specification,感觉可以,于是裸机开发。

历时5个月,终于成了,喜极而泣,可以毕业了。还好效果也不错,写入速度超过了大部分商业公司IP。

END

作者:比特波特
原文链接:https://mp.weixin.qq.com/s/4BJik1VXoOGxqQXKFkgZ6g
微信公众号:
hack电子.jpg
推荐阅读
更多IC设计技术干货请关注IC设计技术专栏。
推荐阅读
关注数
20186
内容数
1307
主要交流IC以及SoC设计流程相关的技术和知识
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息