1. PCIe基础知识

PCI-Express(peripheral component interconnect express)是一种高速串行计算机扩展总线标准,它原来的名称为“3GIO”,是由英特尔在2001年提出的,旨在替代旧的PCI,PCI-X和AGP总线标准。

与大多数总线一样,PCIe总线也包括电气属性和协议组成两部分。完整的了解PCIe是相对复杂的,所以从应用的角度来讲,我先从基本的协议入手,对PCIe有个初步的认识。拓展学习可以参考官方协议规范文档《PCI Express Base Specification》(ps:也是厚厚的700页啊~~全当工具书)。

PCIe 规范对于设备的设计采用分层的结构,有事务层、数据链路层和物理层组成,各层有都分为发送和接收两功能块。

在发送端,应用程序(设备核A)在事务层形成事务层包(TLP——Transaction Layer Package),储存在发送缓冲器里,等待推向下层。在数据链路层,在TLP 包上再串接一些附加信息,这些信息是对方接收TLP 包时进行错误检查要用到的,形成数据链路层包(DLLP——Data Link Layer Package);在物理层,对DLLP 包进行编码,占用链路中的可用通道,从发送器发送出去。

在接收端,实际上是发送端的“逆”过程。如果说发送端是在不断组包,那么接收端就是不断的拆包,最后提取出有用的数据信息供B设备的应用程序使用。

整个过程实际上和以太网的过程很相似,都是在不同层级上进行数据的扩展。在FPGA的开发过程中,实际上从事务层到物理层都是封装好了的,组成标准IP核。用户通过IP核要求的总线协议(如AXI4-Stream)与之进行数据交换。

2. 事务层协议

2.1 数据包结构

有了IP核之后,实际上我们最关心的就是事务层包的数据格式。

事务层数据包(TLP)主要由:一个或多个可选的前缀(TLP Prefixes)、一个帧头(TLP Header)、一个数据有效负载(Data Payload)和一个可选的摘要(TLP Dignest)组成,下面简单介绍一下各部分。

  • 前缀(TLP Prefixes)

    有PCIe V2.1总规范引入,主要起扩展帧头的作用。如果用不到,可以省去该字段。

  • 帧头(TLP Header)

    TLP Header是TLP中最重要的标志,不同的TLP其头的定义并不相同。TLP 头标长3 或者4 个DW(DW = double word——双字,32位),格式和内容随事物类型变化;

  • 数据有效负载(Data Payload)

    即主设备要传输的数据。数据的长度最小为0,最大为1024DW,视具体情况而定。该字段也是一个可选项,因为有些TLP并不需要传递数据,如存储器读请求、配置和I/O写完成TLP也不需要。

  • 摘要(TLP Dignest)

    摘要是一个可选项,长度为1DW。一个TLP是否需要Dignes是由Header中TD字段决定。如果接受设备支持ECRC校验的功能的话,则该字段用来防止TLP中的数据校验码ECRC。

2.2 帧头含义详述

TLP Header长3 DW或者4 DW,格式和内容随事务类型的不同而不同。但是对于所有TLP Header来讲,都拥有相同的第一个DW定义,如下图所示(R:Reserved,为0)。

  • Fmt([31:29])——Format of TLP

Fmt是关于头标长度和该TLP是否有数据(字段)的信息,如下图所示。实际上是3 DW还是4 DW是根据要访问目标的地址位宽有关。

  • Type([28:24])

    Type的5位编码与Fmt字段一起用于规定事务类型、头标长度和是否有数据负载,如下图所示,只列举了一部分常用的类型,完整版可以查阅官方协议规范。

  • TC([22:20])

    Traffic Class,传输类型也代表优先级,优先级高的先得到服务。这里是3比特,说明可以分为8个等级,0-7,TC默认是0,数字越大,优先级越高。

  • Attr([18]、[13:12])

    该字段表述TLP的属性,由3位组成,注意不是连续的。具体含义见规范。

  • TH([16])

    位为 1 表示当前 TLP 中含有 TPH(TLP Processing Hint)信息,TPH 是 PCIe V2.1 总线规范引入的一个重要功能。TLP 的发送端可以使用 TPH 信息,通知接收端即将访问数据的特性,以便接收端合理地预读和管理数据。

  • TD([15])

    表示 TLP 中的 TLP Digest(之前说ECRC可选)是否有效,如果这个这个bit置起来,说明该TLP包含ECRC,接收端应该做CRC校验;

  • EP([14])

    表示当前 TLP 中的数据是否有效,为 1 表示无效,为 0 表示有效。

  • AT([11:10])

    Address Type,地址种类,与 PCIe 总线的地址转换相关,可暂时不考虑。

  • Length([9:0])

    用来描述 TLP 的有效负载(Data Payload)大小。PCIe 总线设置 Length 字段的目的是提高总线的传送效率。Length 字段以 DW 为单位,其最小单位为 1 个 DW。

3. 报文举例

因为PICe的报文种类非常多,只举两个进行举例说明。

3.1 寄存器读报文

如下图所示,是一个32位寻址的寄存器读的完整报文(上节只介绍了第一个DW)。首先解释一下多的几个字段的含义。

  • Requester ID

    该字段字段包含生成TLP报文的PCIe设备的总线号(Bus Number)、设备号(Device Number)和功能号(Function Number)。唯一的找到目标设备,那是因为不同的Endpoint设备空间会映射到Host内存空间的不同位置。

  • Tag

    Requester ID、Tag合起来组成Transaction ID,在同一时间段内,PCIe设备发出的每一个Non-Posted数据请求TLP,其Transaction ID必须唯一。也就是Tag必须唯一。

  • Last DW BE和1st DW BE

    在PCIe 总线以字节为基本单位迕行数据传递,但是 Length 字段以 DW 为最小单位。为此TLP 使用 Last DW BE 和 First DW BE 返两个字段迕行字节使能,使得在一个 TLP中,有效数据以字节为单位。

  • Address

    对一个PCIe设备来说,它开放给Host访问的设备空间首先会映射到Host的内存空间,Host如果想访问设备的某个空间,TLP Header当中的地址应该设置为该访问空间在Host内存的映射地址。

值得注意的是:报文是以DW划分来进行说明,但实际过程中,顶层应用与PCIe IP核采用64位数据的AXI4通信,所以在发送TLP所需字段数据时,主要大小端的问题。

3.2 完成报文

有non-posted request TLP,才有Completion TLP。有因才有果。前面看到,Requester 的TLP当中都有Requester ID和Tag,来告诉接收者发起者是谁。那么响应者的目标地址就很简单,照抄发起者的源地址就可以了。因此,Completion TLP的Header如下:

  • compl Status

    完成情况指示。000--成功完成;001--不支持该请求。其余情况可查阅规范。

  • Byte Count

    是指还剩下多少字节的数据需要读取。

其余字段可自行查阅规范。

4. 机制简述

4.1 Non-Posted和Posted

PCIe总线规定了两类数据传送方式,分别是Non-Posted和Posted数据传送方式。

在PCIe总线中,Non-Posted总线事务分两部分进行,首先是发送端向接收端提交总线读写请求,之后接收端再向发送端发送完成(Completion)报文。PCIe总线使用Split传送方式处理所有Non-Posted总线事务,存储器读、I/O读写和配置读写这些Non-Posted总线事务都使用Split传送方式。简单的说就是“一问一答”的方式。

而Posted总线事务,是只向终端发送报文,而终端无需反馈完成报文,所以是一种“单向发送”的机制。

参考文献:

  1. 《PCIe Solutions on Xilinx FPGAs 初学者指南 V1.0》——hanson@comtech.com.cn
  2. 《PCIe总线的分层协议介绍》
  3. 《PCI Express Base Specification V2.1》
  4. 《PCIe学习(一):PCIe基础及生成PIO例程分析》——judyzhong
  5. 《老男孩读PCIe之五:TLP结构》—— [http://www.ssdfans.com]

FPGA实战操作(2) -- PCIe总线(协议简述)的更多相关文章

  1. FPGA实战操作(2) -- PCIe总线(例程设计分析)

    1.框架总览 平台:vivado 2016.4 FPGA:A7 在实际应用中,我们几乎不可能自己去编写接口协议,所以在IP核的例程上进行修改来适用于项目是个不错的选择. 通过vivado 中有关PCI ...

  2. 4.1 PCIe总线的基础知识

    与PCI总线不同,PCIe总线使用端到端的连接方式,在一条PCIe链路的两端只能各连接一个设备,这两个设备互为是数据发送端和数据接收端.PCIe总线除了总线链路外,还具有多个层次,发送端发送数据时将通 ...

  3. 012 PCIe总线的基础知识

    一.PCIe总线的基础知识 与PCI总线不同,PCIe总线使用端到端的连接方式,在一条PCIe链路的两端只能各连接一个设备,这两个设备互为是数据发送端和数据接收端.PCIe总线除了总线链路外,还具有多 ...

  4. I2C总线协议的软件模拟实现方法

    I2C总线协议的软件模拟实现方法 在上一篇博客中已经讲过I2C总线通信协议,本文讲述I2C总线协议的软件模拟实现方法. 1. 简述 所谓的I2C总线协议的软件模拟实现方法,就是用软件控制GPIO的输入 ...

  5. AXI总线协议

    AXI总线协议 (一).概述 AXI (高性能扩展总线接口,Advanced eXtensible Interface)是ARM AMBA 单片机总线系列中的一个协议,是计划用于高性能.高主频的系统设 ...

  6. SPI总线协议及SPI时序图详解

    SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口.SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚 ...

  7. [I2C]I2C总线协议图解

    转自:http://blog.csdn.net/w89436838/article/details/38660631 1  I2C总线物理拓扑结构      I2C 总线在物理连接上非常简单,分别由S ...

  8. I2C总线协议的简要说明

    为了快速的了解I2C总线协议,此处采用另类的方式进行说明. 倘若你和另外一个人只能通过一个开关加灯泡的装置在不同的两个房间进行交流,以下是很简单能说明的一个模型: 你的房间有一个开关,另外一间房间有一 ...

  9. I2C总线协议的总结介绍

    在看天翔哥的视频之后,他强调要把I2C协议好好研究一下,那么就对一些基本的通信手段是十分有帮助的..那么就来了解一下I2C总线协议的一些知识吧. I2C(Inter-Integrated Circui ...

随机推荐

  1. android studio打包apk

    转载:http://chenfeicqq.iteye.com/blog/1889160 1)Android Studio菜单Build->Generate Signed APK      (2) ...

  2. centos环境下创建数据库和表的方法

    centos环境下创建数据库和表的方法 //查询数据库的命令: mysql> SHOW DATABASES; +--------------------+ | Database         ...

  3. Android JIN简单单步调试

    ADTr20已经比较完美支持NDK开发了.可以集成ndk编译,只需在项目右键Add Native Support,就能自动生成jni文件,并部署编译环境(注意这个过程是不可逆的,手动删除jni文件后, ...

  4. POJ 2396 Budget (有源汇有上下界最大流)

    题意:给定一个矩阵的每行的和和每列的和,以及每个格子的限制,让你求出原矩阵. 析:把行看成X,列看成Y,其实就是二分图,然后每个X到每个Y边一条边,然后加一个超级源点和汇点分别向X和Y连边,这样就形成 ...

  5. Shell编程-03-Shell中的特殊变量和扩展变量

    目录 特殊变量 变量扩展 特殊变量     在Shell中的特殊变量主要分别两种位置参数变量.状态变量两种. 位置参数变量     Shell中的位置参数变量主要是指$0.$1.$#等,主要用于从命令 ...

  6. ARPG游戏打击感相关的技术简单总结

    说好的技术总结,根据近期的工作总结一下体现游戏打击感相关的技术.一般arpg的游戏打击感除了场景的氛围的烘托,策划的数值:连击,奖励伤害数字的连贯积累反馈,硬直加物理击飞ragdoll,更不可忽视的也 ...

  7. mysql免安装版初始化

    解压之后复制my-default.ini到本地目录下的my.ini 修改key: basedir = D:\\software\mysql-5.7.12-winx64  datadir = D:\\s ...

  8. ASP.NET 邮件发送

    ASP.NET 邮件发送用NET的MAIL类即可实现. 邮件发时,为不影响进程,所以采用多线程实现比较好. /// <summary> /// 多线程邮件发送 多线程需注意不要引用到外部方 ...

  9. C#DataTable一些使用方法

    C#DataTable一些使用方法   1,使用DataTable必须要引用System.Data. 2,定义一个DataTable DataTable dt=new DataTable(); 3,为 ...

  10. linux 使用内存作为 /tmp 临时文件夹

    方法一:cat /etc/fstabtmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0 方法二:mount tmpfs /tmp -t tmpfs -o s ...