基于PCIe的NVMe协议在FPGA中实现方法

2023-05-16

        NVMe协议是工作在PCIE的最上层协议层的,故需要先搞清楚PCIE。本文基于Xilinx的UltraScale+,开发工具为Vivado2021.2。学习中以spec为主,其它资料辅助参考(重点介绍学习方法及资料,有时间再加细节)。请勿转载!

1 PCIe学习与实践

1.1 理论

     主要参考的文章是《老男孩读PCIe》,同时参考《古猫先生》,重点学习TLP报文部分,数据链路层和物理层的内容可以先不看。再买一本书《PCI Express 体系结构导读-王齐》用来查阅做笔记。

    

老男孩读PCIe介绍系列_Ha-Ha-Interesting的博客-CSDN博客_老男孩读pcie

PCIe最全科普贴流出!不说了,赶快Mark!_古猫先生的博客-CSDN博客

还有2本MindShare的英文书籍参考,备用即可。

 https://www.mindshare.com/files/ebooks/PCI%20Express%20System%20Architecture.pdf

https://www.mindshare.com/files/ebooks/PCI%20Express%20Technology%203.0.pdf

在NVMe工程中用到的TLP类型为mem读写config中断

  1. config TLP用户不用特别关心,在Xilinx IP GUI配置,由IP维护。它用于上电时host访问EP设备的reg,协商配置;
  2. 中断TLP用户也不直接使用,用户仅通过IO脉冲控制IP发出完整中断TLP,再检查IP给出的完成状态IO即可; 
  3. mem TLP是需要用户真正掌握的,但是IP的AXI\stream口出来的TLP格式可能不是标准的TLP,它是对TLP做了进一步处理的。

1.2 工程

        在Xilinx的Vivado中关于PCIe的IP有3个:PCIE4,XDMA,QDMA。后两个IP都基于前一个,使用难度递增、速率递增、资源占用也递增。

     下列文章中详细介绍了7系列PCIE(此IP使用标准TLP格式,不同于UP系列PCIE4)、XDMA IP的基础配置、官方Demo的生成、仿真分析。Demo中用Verilog代码设计了一个RootPort来和EP通信,模拟了上电后Bar扫描、分配地址、速率宽度等协商配置。Demo中的EP代码可以用于实际的设计中。在7系Demo与UP demo中PCIE HEAD扩展reg的偏移地址有个别不同,以实际PG为准。

开发板可以用黑金、米联客的板子。

PCIe基础知识及Xilinx相关IP核介绍_lu-ming.xyz的博客-CSDN博客_pcie ip核 xilinx

2 NVMe理论学习

2.1 理论

2.1.1 学习内容

  •     NVMe的学习主要以Spec为主,官方下载链接如下,我使用的是spec1.2版本,此本版应该是蛋蛋读NVMe系列文章所用,图表序号能对应上。选用的功能可以先不看,并在NVMe配置reg、Controller Data Structure(4KB)中配置为关闭。

NVMe Base Specification – NVM Expresshttps://nvmexpress.org/developers/nvme-specification/

  • 同时参考以下ssdfans blog,一共6篇,第5篇讲数据保护(可以选择不用),第6篇讲NameSpace(可以只用一个NS,NSID=1)

蛋蛋读NVMe之一(cmd processing)

蛋蛋读NVMe之二 (SQ,CQ和DB)

蛋蛋读NVMe之三 (PRP)

蛋蛋读NVMe之四(Trace)

蛋蛋读NVMe之五(Protection Information)

蛋蛋读NVMe之六(Namespace)

以下的系列4篇文章也可以参考对比:

NVMe 协议详解(一)_IFappy的博客-CSDN博客_nvme协议

NVMe详解(四)_IFappy的博客-CSDN博客_nvme smart-log 详解

下面文章对spec1.3做了部分翻译,有个别内容不准确,可以参考

【NVMe】NVMe 1.3协议中文翻译——第一章简介_ljyyyyyyyyy的博客-CSDN博客_nvme1.3协议

2.1.2 抓包工具trace

下面的文章实际抓取了NVMe报文,并做了分析,有助于理解NVMe工作的完整流程。PCIE协议可以使用分析仪抓取报文,分析仪串在链路中,抓取上行、下行报文。目前看到的文章中主要有2家:力科、Saniffer。

从PCIe trace中分析NVMe_Ingram14的博客-CSDN博客_pcie trace

【71】力科PCIe 协议分析仪常见操作_linjiasen的博客-CSDN博客_pcie协议分析仪

Saniffer公司的分析仪及软件,可以联系他们获取软件及SSD启动抓取的完整报文、分析仪的使用培训教程等等。

PCIe和NVMe SSD初始化过程简介_SSD学院_SSDtime

PCIe和NVMe SSD初始化过程简介-面包板社区           同一篇文章的不同链接。

2.1.3 Spec中重点关注的内容(我的调试)

1、spec1.2中7.6.1 Initialization 介绍了上电后整个通信链路建立的过程:host写NVMe reg、创建Admin Queue,通过Admin创建IO Queue。之后才能进行数据的读写。

2、spec 7.2.1command processing 介绍了取SQ,执行,返回CQ,中断的详细过程。注意在步骤4指令执行时,可能包含多个纯TLP报文完成数据读写,图中并未标出;

3、第1章主要是一些名词解释,重点1.6节。

4、第2章是PCIE的寄存器配置,此部分内容在使用Xilinx IP时用户不能直接访问,而是通过IP GUI设置参数即可。在IP中必须注意class code要改为下方协议中值,否则无法识别为NVMe控制器。电源管理PM、中断MSI\MSI-X\等都在GUI配置,由IP负责维护reg

 5、第3章重点3.1节,是NVMe协议层reg,需要mem TLP来读写,这些reg有专门的地址,即TLP中的地址段。先不展开细说了,重点提示如下:

  • INTMS,INTMC:这两个reg不是可选,但是也可不用,属于在协议层控制中断屏蔽。需要在本地维护一个中断屏蔽mask reg,置位mask<=mask | MS ,清除mask<=mask &(~MC),读取时都返回mask的值,而不是MC or MS 自己的值。
  • AQA中由host写入的是ASQ、ACQ的队列深度,ASQ是Admin Submission Queue,其中一条指令缩写ASQE,占用64B。ACQE占用16B;
  • ASQ中存储AdminSQ的基地址,要读取其中ASQE时,地址=baseaddr+head doorbell*64。而IO SQ的基地址不在这些reg中,它是在用Admin指令创建IO队列时才由host分配的,需要FPGA自己维护保存;
  • SQTail DBL,CQHead DBL是由host维护写入FPGA中。编号0的是Admin,>=1是IO。Tail总是指向空,表示下一次可以写入的指针位置。Head≠Tail则表示Queue中还有Entry没有取走。SQHead DBL由PL自己维护,每读走一个SQE后+1.CQTail DBL由PL维护,每向host写一个CQE,Tail+1,注意队列的满空,以及从尾部返回到头部循环时,报文中的P位要0-1反转一次。

 6、第4章 Memory structure,介绍了NVMe中一些基本的定义。重点4.1SQCQ定义,4.2SQE,4.3PRP,4.6CQE格式。其他的SGL、MR、CMB、Fused Operation都不用,arbitration只用默认的RoundRobin即可。

  • 注意Queue的empty、full

  • ASQE,IOSQE都包含64B=16DW,两者DW0的格式相同。一条SQE中本身包含两个PRP,一个PRP指向4K空间,超过8K空间需要使用PRP List,一个List的最大空间为4K,一个PRP地址本身占用8B,则一个List中最多512个PRP,若还有更多的PRP则第一个list的最后一个PRP指向下一个List的存放地址。PRP计算方法,考虑4K对齐(所谓4K对齐,是指如果访问地址不是从4K边界开始的,那么本次对多只能操作起始地址->4K边界尾)。

    SSD NVMe核心之PRP算法_Ingram14的博客-CSDN博客

 7、第5章是Admin指令。重点关注强制cmd中红圈部分,是初始化使用到的,顺序参见spec1.2 的7.6.1 Initialization 章节。5.11 Identify command中的data structure和namespace structure特别重要,至于figure91 电源可以只要一种即可,不支持切换。先创建CQ,后创建SQ;先删除SQ,后删除CQ。删除cmd就是把创建指令设置的各项参数都复位。

 

 8、第6章是NVM=IO 指令,重点是读写。flush指令若没有用缓存,或确定数据已全部写入外部存储,可以不做操作,直接回复CQE即可。

 9、第7章重点关注7.2指令的处理流程,7.6 控制器初始化过程(整理链路建立过程)。

10、第8章大部分都不用看,关注8.6 Doorbell Stride。在硬件使用时=0,用在doorbell reg 地址分配上,=0则紧凑排布。

2.2 工程实现

三种实现方案NVMe协议,基于3种不同的IP,QDMA仅支持ultralscale+器件。

2.2.1 PCIE4

PCIE4是ultralscale+器件中的型号,手册为PG213。与7 Series Integrated Block for PCI Express IP(PG054)略有不同,7系的IP用户数据stream接口分为tx,rx两个,报文格式基本与标准TLP相同;

PCIE4 IP的用户接口分为4个:CQ/CC,RQ/RC。XX中前一位是用户的角色:C代表用户是完成方被动响应,R代表用户请求方主动发起;后一位表示请求数据or完成数据。报文格式与标准TLP略有不同。

​​

Admin,IO指令都用PL纯逻辑实现,节约资源。用于和ASMedia USB转NVMe芯片的通信,此转接芯片的协议严格遵守了NVMe spec,不需要PC端有NVMe的驱动,PC将其识别为USB设备。

Controller data structure和Namespace data structure各占用4KB的空间,可以把参数提前配好,用一个ROM+.coe初始化文件的方式,供Admin读取。

调试时先确保PCIE层通信正常,可以使用WinDriver来调试CQ/CC口,即调试NVMe reg。注意使用金手指上的复位来复位PCIE4 IP。根据SQE中LBA的个数决定PRP List长度,读写数据前先读取PRPList,并压入FIFO中,用一个出一个。

2.2.2 XDMA

该方案用MicroBlaze核解析Admin指令,IO指令用PL逻辑实现,MB核占用资源。该方案需要PC端驱动的配合,无法与ASMedia芯片配合使用。

Demo由复旦大学设计,并且有配套论文,硬件基于KCU105开发板。设计中创建了一个Admin Queue,8个IO Queue。启用了XDMA的4条stream通道、descriptor bypass通道、AXI-master、AXI-slave。

  • AXI-slave:用户配置XDMA的内部reg,控制中断,数据传输启动、停止等;

  •  AXI-master:host用来配置NVMe协议中的reg(维护在PL中),如doorbell head/tail;
  • descriptor bypass通道:用户写入地址+长度,告知host要取回,或发出数据的信息。
  • 4条stream通道:传输数据。数据可以是SQE、CQE等指令,也可以是要转移的数据。在demo设计中,2条steam用于读写SQE/CQE/PRP,2条steam用于读写数据。

https://github.com/yhqiu16/NVMeCHA

2.2.3 QDMA

Xilinx官方提供了Demo,使用QDMA+收费的NVMeTC。其Admin指令由MB核解析,且MB上运行了linux系统,占用大量资源。仅用于和PC通信。 

Documentation Portalhttps://docs.xilinx.com/r/en-US/pg329-nvme-target-controller?tocId=R9sEYjIxu5Zmhve4J9K7gg

在手册中搜索  Download the reference design files,下载工程。

3 测速软件

crystal disk mark:测速更准确。

HD_speed:可以长时间连续测试,由写+读+验证模式。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于PCIe的NVMe协议在FPGA中实现方法 的相关文章

  • TF坐标变换

    文章目录 TF坐标变换TF功能包TF工具乌龟例程中的TF创建TF广播器创建TF监听器实现乌龟跟随运动 存在的问题总结参考 TF坐标变换 坐标变换是机器人学中一个非常基础 xff0c 同时也是非常重要的概念 机器人本体和机器人的工作环境中往往
  • Linux下目录文件的操作(opendir,readdir,closedir) 以及DIR,dirent,stat等结构体详解

    From http blog chinaunix net uid 27213819 id 3810699 html 注 xff1a 为什么要说 目录文件 xff1f 其实在linux中 目录也是一种 文件 xff0c 只是它的内容是上级的
  • 堆栈的工作原理

    声明 xff1a 以下均为个人收集的一些资料 xff0c 非原创 每一个使用c语言的都应该知道栈的重要性 xff0c 我们能够使用C C 43 43 语言写出诸多复杂的程序 xff0c 很大功劳一部分有归于栈的实现 xff0c 因为它可以帮
  • RTK+GPS提高定位精度原理解析(一个小白写给另一个小白系列)

    RTK 43 GPS提高定位精度原理解析 xff08 一个小白写给另一个小白系列 xff09 GPS定位原理回顾RTK基本概念RTK组成RTK传输差分示意RTK数据链接坐标转换RTK应用后记 我们在上一篇文章导航定位系统的原理解析 xff0
  • Python 嵌套函数中内部函数引用外部函数循环变量情况

    Python 嵌套函数中内部函数引用外部函数循环变量情况 Python中的嵌套函数也称为闭包 xff08 Closure xff09 有一个特点就是内部函数可以引用外部函数内的变量并且在外部函数返回后保存该引用变量的值 xff1b 但是如果
  • Git查看版本改动—— git diff

    HEAD 表示当前版本 xff0c 也就是最新的提交 上一个版本就是 HEAD xff0c 上上一个版本就是 HEAD xff0c 往上100个版本写100个 比较容易数不过来 xff0c 所以写成 HEAD 100 HEAD 2 相当于
  • PyQt5编程-鼠标事件

    处理鼠标事件的频率不低于键盘事件 包括按下 松开鼠标按键 xff1b 移动鼠标到特定区域或离开特定区域 xff1b 更改鼠标指针的形状 xff0c 等等 1 按下 松开鼠标按键 按下并释放鼠标按钮时 xff0c 将调用以下方法 xff1a
  • latex 正文设置为双栏,图片如何占两栏

    xff08 1 xff09 插入一栏图片时 xff0c 使用的是 xff1a begin figure end figure 96 xff08 2 xff09 插入双栏图片时 xff0c 需在figure的上标中加入星号 begin fig
  • VIO松耦合和紧耦合对比

    松耦合 xff08 结果级融合 xff09 xff1a 两个独立的运动估计过程中分别处理视觉和惯性测量的信息 xff0c 最终将他们的输出 xff08 位置和姿态 xff09 融合作为结果 紧耦合 xff08 特征级融合 xff09 xff
  • zed2相机运行VINS-mono

    zed2相机标定请参考专栏前面博文 xff01 一 zed2相机运行VINS mono 1 下载VINS mono mkdir p vins ws src cd vins ws src git clone https github com
  • C语言指针笔试题

    1 我们先来看第一段代码和它的输出 span class token keyword int span span class token function main span span class token punctuation spa
  • Gazebo 官网教程学习笔记--Model Editor

    终端打开Gazebo Gui 界面 然后快捷键CTRL 43 M 打开 Model Editor xff0c 或者在edit 下选择model editor 界面如下 1 工具栏 包含用于编辑模型的工具 2 调色板 也称为左面板 有两个选项
  • 《大厂算法面试》小书

    算法面试是大多数小伙伴的弱势 xff0c 但是大厂几乎都会考算法 xff0c 如果在面试过程中不刻意准备一下算法 xff0c 很大概率被挂 其实对于前端和移动端来说 xff0c 算法要求的并不是很高 xff0c 只要把一些常见的算法题刷完
  • ROS通信架构上——Topic和Msg

    Topic 异步通信方式 Node间通过publish subscribe机制通信 相关的命令 xff1a rostopic rostopic list 列出当前所有topicrostopic info topic name 显示某个top
  • Type-C显示器是什么,Type-C显示器的5大优势

    在显示器领域内 xff0c USB Type C接口还处于发展阶段 xff0c 目前已经在新推出的一些高端显示器和旗舰显示器中有配置 USB Type C接口的出现 xff0c 将会形成以显示器为核心的桌面解决方案 xff0c 用户可以把任
  • SLAM综述

    SLAM综述 前言一 概述二 Lidar SLAM激光雷达传感器激光雷达SLAM系统 xff08 Lidar SLAM System xff09 2D SLAM3D SLAM深度学习与激光雷达Feature amp Detection xf
  • VisionPro使用 C# 开发

    VisionPro 常用控件的说明 工具设置窗体 CogPMAlignEditV2 模版匹配设置窗体控件 CogPMAlignEditV2 Subject 工具关联对象 如 xff1a CogPMAlignEditV2 Subject 61
  • rosdep update 失败及解决办法

    一 问题 reading in sources list data from etc ros rosdep sources list d Hit https raw githubusercontent com ros rosdistro m
  • 在STM32上运行ROS节点——rosserial&stm32开发及调试方法

    近期接手了一些ROS机器人项目 xff0c 这里将开发中遇到的问题和解决方法记录下来 stm32强大的外设资源为机器人底层设备控制带来了极大的便利 xff0c 本文简述借助rosserial项目在stm32中运行ROS节点的方法 基本原理
  • 动态存储区、静态存储区、堆和栈的区别

    C c 43 43 程序经过编译连接后形成的二进制映像文件 xff0c 这文件包含 xff1a 栈 xff0c 堆 xff0c 数据段 xff08 只读数据段 xff0c 已经初始化读写数据段 xff0c 未初始化数据段即BBS xff09

随机推荐

  • kubemini-基础使用

    起始 minikube 是一个本地的 k8s 专注于为 k8s 创建一个简单的学习和开发环境 你只需要一个 Docker 或者类似兼容的 容器 xff0c 或者一个虚拟机环境 xff0c k8s 只需要一个单独的命令 xff1a minik
  • 详解信号量和互斥锁之间的区别和联系

    一 xff1a 信号量与互斥锁之间的区别 xff1a 1 xff1a 互斥量用于线程的互斥 xff0c 信号线用于线程的同步 这是互斥量和信号量的根本区别 xff0c 也就是互斥和同步之间的区别 2 xff1a 互斥量值只能为0 1 xff
  • python基础学习(十二)——python中代码的执行顺序以及if __name__ ==‘__main__‘作用和原理

    xff08 1 xff09 代码执行顺序 python程序是顺序执行的 xff0c Python中首先执行最先出现的非函数定义和非类定义的没有缩进的代码 python程序执行时 按照自上而下的顺序 xff1a 首先执行没有缩进的代码 xff
  • c学习--不同c文件中的同名全局变量及同名函数53

    如果在不同的c文件中定义了同名的全局变量 xff0c 则它们会占用相同的内存空间 xff0c 而且编译链接时不会报错 xff01 这可以参考全局变量的内存初始化顺序 对于局部变量而言 xff0c 内存分配的顺序和代码的顺序是一样的 全局变量
  • 基于STM32的FreeRTOS学习之任务基础知识(六)

    记录一下 xff0c 方便以后翻阅 RTOS系统的核心是任务管理 xff0c 初学RTOS系统必须先掌握任务的创建 删除 挂起和恢复等操作 1 什么是多任务系统 玩裸机一般都是在main函数里用while 1 做一个死循环完成所有处理 xf
  • git 推送出现 “fatal: The remote end hung up unexpectedly“ 解决方案

    https blog csdn net qq 41241767 article details 98181952 git 推送出现 34 fatal The remote end hung up unexpectedly 34 解决方案 h
  • 操作系统的设计指导思想——主奴机制

    在学习操作系统的过程中我们会发现一个问题 xff1a 应用程序是应用程序 xff0c 操作系统也是程序 xff0c 操作系统程序凭什么能对应用程序进行组织 管理和协调而不受应用程序损害呢 xff1f 我们认为凭的是特权机制 要想让操作系统做
  • VScode如何配置Git

    注意 xff1a 食用本篇博客的前提是你已经安装好了Git xff0c 并且也有一定的Git基础 因为有些git中比较常用的功能我会略过 第一步 xff1a 配置Git环境变量 右键 我的电脑 xff0c 选择 属性 xff0c 在弹出的对
  • FMC/FSMC/EXMC总线NORFlash/PSRAM接口(异步-复用-不突发/同步-复用-突发)

    请勿转载 目录 1 简介 1 1 框图 1 2 接口定义 1 3 读写时序图 时序配置参数 1 4 PSRAM控制器异步工作模式分类 1 5 PSRAM寄存器配置 1 5 1 控制寄存器BCR 1 5 2 片选时序寄存器BTR 1 5 3
  • 开平方_复数有效值+角度的verilog代码

    1 逐位比较法 二进制 FPGA篇 xff08 一 xff09 基于verilog的定点开方运算 1 逐次逼近算法 该篇文章中有详细描述 假设被开方数rad i 7 0 xff0c 则结果qout 3 0 位宽为4位 xff0c 从最高位到
  • GOOSE报文分析_详解GOOSE服务

    https www cnblogs com software4y p 10017602 html http blog sina com cn s blog af8298410102wnvm html https www cnblogs co
  • 循环冗余校验(CRC)之verilog实现

    有一个网站在这一方面做的特别好 xff0c 直接生成代码 链接 xff1a http www easics com webtools crctool 循环冗余校验 xff0c 也称为CRC检验 xff0c 这是一个很常见的 xff0c 很成
  • 从原理上解释什么是DDR的ZQ校准?

    前言 首先我们我们看下下图的电路 xff0c 在DDR的电路中通常有ZQ部分的电路 xff0c 外接1 高精度的240ohm电阻 xff0c 那么这个240ohm电阻究竟是做什么用的呢 xff1f 很多做了硬件或者驱动开发很多年的工程师仍然
  • 串行数据异步动态相位采样处理iodelay-iserdes应用+CDR数据恢复方案

    目录 一 用iserdes的LVDS视频接口 二 LVDS 4倍异步过采样 ISERDES2 三 8倍过采样 CDR数据恢复 Select IO 替代 RocketIO 典型应用SD SDI 四 4倍过采样 CDR数据恢复 一 用iserd
  • 接收灵敏度dbm与W

    一 基本概念 xff1a 接收灵敏度 官方概念 xff1a 接收机能够识别到的 最低的电磁波能量 单位也是dBm 解读 xff1a 接收灵敏度 xff0c 就是你的耳朵能听到的最小的声音 耳朵灵敏度高的 xff0c 能够听到很远的声音 例如
  • 三段式过流保护、差动保护

    1 基本原理 供电系统中的线路 设备等故障 xff0c 会产生短路电流 短路电流比线路正常工作时大很多 通过电流互感器测量这个电流值 xff0c 和电流值的持续时间 xff0c 达到整定值时输出跳闸信号 xff0c 这个就是过电流保护的基本
  • Unexpandable Clocks不可扩展时钟 UG903

    同源时钟可能同步 xff0c 可能异步 xff1f 同源时钟由同一个PLL MMCM产生 xff0c 相位固定 xff0c 能否产生小数倍关系 xff1f 不可扩展时钟能否归类到异步时钟 xff1f 不可扩展时钟是指时钟引擎无法在1000个
  • allegro 尺寸标注操作未到板边的处理

    1 进入尺寸标注 2 右击选择线性 xff0c parameters中可以改参数 xff0c 默认即可 3 打开尺寸层 xff0c 点击板边框 如果有圆弧没有标注到板边 xff0c 可以在右侧find中关闭其它项 xff0c 点击两个板边标
  • 安装boost

    安装boost 从官网下载并解压到适当位置 Boost网站 在解压后的目录中找到 bootstrap bat点击运行 xff0c 并等待结束 这时会出现b2 exe文件 xff0c 点击运行 xff0c 耐心等待结束 xff08 安装后产生
  • 基于PCIe的NVMe协议在FPGA中实现方法

    NVMe协议是工作在PCIE的最上层协议层的 xff0c 故需要先搞清楚PCIE 本文基于Xilinx的UltraScale 43 xff0c 开发工具为Vivado2021 2 学习中以spec为主 xff0c 其它资料辅助参考 重点介绍