PCIE 总线协议(转)

PCIE 总线协议(转),第1张

最近在学习 PCIE 总线协议,本人作为一个刚开始的小白,打算写写笔记加深下自己的理解。如果你也是刚开始入门的朋友,希望能你有所帮助。水平有限,如有错误,望批评指正。本人看的书主要有两本,一本是《PCI Express 系统结构标准教材》,《pci express system architecture》的中文版,还有一本是《深入浅出SSD》,由SSD技术社区SSDFan核心成员撰写,后者对于初学者而言更为友好一点。

概述

PCIe是从PCI发展过来的,“e” 是 “express”的简称,是“快”的意思,PCI使用并口数据传输,PCIe使用串口传输,但是PCIe的速度更快。并口传输每次可以传送多位数据,但是为何比串口慢?这便要考虑并行总线的时钟频率问题。

在低频情况下,并口传输确实比串口要快。在对传输速度不断提升的同时,时钟频率也需要不断提高,并口传输便会有一些问题。

如上图所示,在发送端,公共时钟第一个上升沿到来时,将多位数据发送出去。数据通过传输介质到达接收端,接收端在公共时钟第二个上升沿对数据进行采集。接收端需要接收正确的数据,就必须要保证数据在传输介质中的传输时间小于公共时钟周期,传输时间还随数据线长度增大而增大。受限制于传输时间,时钟频率无法做的很高。并且由于并行传输,每位数据到达接收端的时间都不相同,存在相位偏移,必须要等到最慢的那个bit数据到达,才可以进行采集。

PCIe使用串行传输便能避免上述问题,由于是一位一位的传输,不存在相位偏移。它的时钟信息通过8/10编码或者128/130编码(这个后面会说)嵌入在数据流中,接收端可以从数据流中恢复时钟信息。但是如果使用多条串行通道并行传输,便又会存在上述问题,PCIe有相应机制解决好这个问题。

PCIe速度

两个PCIe设备之间的连接,称为一个 Link,一个Link有两个方向,一边发送,一边接收,可以同时进行,这种通信方式称为全双工。每个方向上可以有 1~32个lane并行,每个lane 代表一对串行通道。

8/10编码 :在串行通道上传输时,将 8bits数据编码为10bits数据,做一个转换,使各位数据之间有更多的 1到0 和 0到1 的跳变,以便接收设备检测这些跳变,能更容易地恢复时钟。128/130编码的原因也是类似的。

这样,在串行通道上传输10位数据,实际上只传输了8位。

对于 PCIe1.0线上bit传输速率为 2.5 Gbps(2.5 Gigabit per second),使用8/10编码:

PCIe1.0 的带宽为: 2.5Gbps * 2(两个方向) * 8/10 = 0.5GB/s(Gigabyte per second)

对于 PCIe2.0线上bit传输速率为 5 Gbps(5 Gigabit per second),使用8/10编码:

PCIe1.0 的带宽为: 5Gbps * 2(两个方向) * 8/10 = 1GB/s(Gigabyte per second)

对于 PCIe3.0线上bit传输速率为 8 Gbps(8 Gigabit per second),使用128/130编码:

PCIe1.0 的带宽为: 8Gbps * 2(两个方向) * 128/130 ≈ 2GB/s(Gigabyte per second)

上表中列出三代 PCIe的带宽,其中“x1” “x2” “x4”等代表的是Link中的 lane 数目。

PCIe拓扑结构

基于PCIe的计算机系统如图所示,

CPU平时非常的忙,便把很多事交给根聚合体(Root Complex 简称RC)来干,RC可以访问内存,通过内部PCIe总线以及若干个PCIe Bridge,扩展出若干个其他的PCIe端口, RC内部十分复杂。

PCIe终端设备称为 Endpoint,比如 PCIe SSD,PCIe 网卡等等,Endpoint可以挂载到 RC 上,也可以挂载到Switch上。

switch(交换器)扩展了PCIe端口,将一个PCIe端口扩展为若干个,靠近RC的端口称为上游端口,扩展出来的端口称为下游端口。下游端口可以挂载其他switch或者Endpoint,并且对他们进行管理。从上游过来的数据,它需要鉴定:1.否是是传给自己的数据,如果是便接收。2. 是不是自己下游端口的数据,如果是便转发 3.如果都不是,便拒绝。从下游端口挂载的Endpoint传给RC的数据,switch也会检查并转发。

每个数据身上都有自己的目的地信息,switch识别信息并一层一层地传送到目的地,称为路由(我个人的理解)。

路由的方式有三种:地址路由,ID路由和隐式路由(后面会说到)。

对于switch多个下游端口上的 Endpoint(例如图中的EP1和EP2) 同时向RC发送数据,switch中会有相应的仲裁机制(后面会说到),确定数据的优先级,将优先级高的数据传送到上游端口中去。

switch结构如上图所示,其内部有一条总线和多个PCI-PCI Bridge,用来实现端口的扩展。如果要switch实现上述的管理功能,就需要对每个 Bridge进行一些配置。各个 Bridge 都要实现 “配置头1寄存器”,即Bridge里面有很多寄存器,对这些寄存器进行配置,就可以让switch实现相应的功能(后面会说到)。

其他:对于PCIe 系统中的一次 事务 (事务定义为请求者和完成者之间完成一次信息传送,需要完成的一系列一个或多个数据包传送的过程),由请求者发起,完成者接收数据并完成相应的事情。

请求者是能够在PCIe中发起事务的设备。根聚合体RC和Endpoint是请求者类型。

完成者是请求者寻址或者说作为目标的设备。请求者读取完成者的数据或者是请求者将数据写入完成者,根聚合体RC和Endpoint也是完成者类型。

PCIe事务简介

PCIe 运用数据包实现设备之间的数据传输,根聚合体RC可以和各种Endpoint通信,理论上任何两个Endpoint都可以直接通信,但实际上很少这样做,因为两个不同设备的数据格式不⼀样,除⾮这两个设备是同⼀个⼚商的。通常都是Endpoint与RC通信,或者Endpoint通过RC与另外⼀个Endpoint通信。

通信涉及一种称为处理层数据包(Transaction Layer packet,  TLP )的数据包发送和接收。

PCIe的事务分为4大类:

存储器事务

IO事务

配置事务

消息事务

上表为PCIe事务种类,其中Memory Read Lock是历史遗留物,为的是兼容老设备,我们可以忽略。其余的种类下面会介绍。

事务又可以分为报告事务(Posted)和非报告事务(Non-Posted)。

对于非报告事务而言,请求者发送一个TLP请求数据包给完成者,稍后,完成者返回一个TLP完成数据包给请求者,表示完成者已经成功收到了请求TLP数据包。非报告事务被作为 分离事务处理 (下面会说)。对于Read 请求,完成者需要将读出的数据放进TLP完成数据包,发送给请求者。对于 Write 请求,完成者通过发送TLP完成数据包,告诉请求者执行的状态,这种情况下TLP完成数据包中没有数据。

对于报告事务而言,请求者发送一个TLP请求数据包给完成者,完成者不返回一个TLP完成数据包给请求者,即请求者并不知道完成者收到了没有以及执行的怎么样。为的是获取最佳性能。报告事务TLP中可以带数据也可以不带数据。

下图为PCI-X分离事务模型,PCIe与之类似

请求者告诉完成者需要在它那读点数据。

完成者说现在不能马上给你。

完成者先把请求者的电话、地址啥的保存一下。

完成者发出分离响应,让请求者把总线腾出来,给别人用用。请求者开始等待。

完成者数据准备完毕,申请使用总线,在一段时间内将数据发送给请求者。

上图为各个数据包类型及英文缩写,对于配置读/写 (configuration Read/Write) 和消息 (Message) 事务,后面会再介绍。

事务协议

非报告读事务

对于非报告读事务,请求者发送TLP请求数据包给完成者,完成者收到数据包并进行解析数据包,将需要的数据放入TLP完成数据包,返回给请求者。完成者可以在每个CpID中返回最多 4KB的数据。

TLP请求数据包类型如上图所示,请求者可以是根聚合体RC或者 Endpoint(但是Endpoint 不能发起配置读/写请求)。完成者可以是根聚合体RC、switch、Bridge或者 Endpoint。

请求者利用完成数据包中的一个标记字段和它之前发送的具有相同标记值的请求数据包关联起来,这使得请求者可以管理多个未完成的事务。

上图中传输通道是一种抽象,实际的传输可能需要多个switch转发数据包,TLP请求数据包和TLP完成数据包中都有自己的目的地信息,这便又涉及到路由的问题。

如果由于错误,完成者不能获得请求的数据,则它返回一个没有数据的完成数据包(Cpl)和一个错误状况指示。请求者在软件层确定如何处理错误。

非报告写事务

非报告写事务种类如上图所示,请求者将数据写入完成者。

请求者发送带数据的TLP写请求数据包,完成者接收并解析数据包,并向请求者发送不带数据的完成数据包,完成数据包包含正常完成和出现错误的两种情况的信息,如果出现错误,请求者确定如何在软件层处理错误。

请求者可以是根聚合体RC或者 Endpoint(但是Endpoint 不能发起配置读/写请求)。

上图中传输通道也是一种抽象,涉及路由的问题

报告存储器写事务

如图所示,存储器写事务是报告事务。

请求者发送带数据的写请求数据包,完成者不返回完成数据包,而是告诉请求者写请求数据包已成功到达目的地。这就意味着请求者并不知道是否出错。由于没有返回完成数据包,节约了时间,所以报告事务同非报告事务相比性能更高。

如果完成者接收的写请求错误或者由于内部错误,无法将数据写入目的地,便无法通过硬件协议告知请求者。完成者可能记录错误并生成错误消息通知到根聚合体RC。由软件处理该错误。

同样有路由的问题

报告消息事务

消息事务也是报告的,分为带数据和不带数据两种

消息事务可以是请求者发送到完成者,也可以是根聚合体RC到所有 Endpoint的广播,还有是Endpoint发送给根聚合体RC。

完成者接收消息中的数据,或者完成消息指定的任务。

同样有路由的问题

一个事务例子

由CPU发起的非报告读存储器,目标是 Endpoint。

switch在上游端口接收到数据包,传送给哪个下游端口,便是路由的问题,数据包中有相应的目的地信息,switch可以识别并完成转发,这些事情在后续笔记中介绍。

PCI优先启动

电脑启动中,按下F2或DEL键进入主板的BIOS/CMOS中设置。

下面是一些例子,

简单说明了不同种类的PC在选择AGP作为显示输出主设备时不同设置的方法。

如果您无法确定您的PC

是否有这样一个选项,请参考您的PC的相关资料或与生产厂商的技术支持取得联系。

a.

在BIOS/CMOS设置选项区域,选择“Integrated Peripherals” “Init Display First”,

然后选择“PCI”.

b. 在BIOS/CMOS 设置选项区域,选择“BIOS Features Setup” “VGA Boot from”,

然后选择“PCI”.

1. 不管通信使用的是什么协议,其最终所要传输的都是数据,其不同在于数据帧格式的定义与数据的编码方式不同。

2. TCP/IP协议栈中的数据要想将数据通过PCIE传输,那你就要了解TCP/IP中的数据是什么,这就要求你先要对TCP/IP中的每个帧数据去帧头帧尾,一般帧头帧尾都有一些重要信息可以帮助进行信息重组与恢复,最后按照数据传输时的一些编码方式进行解码,得到有效的数据。下面的事情其实就是你讲数据传输给PCIE了。

3. PCIE2.0标准上基本只说到了数据链路层Transaction Layer,所以你如果在PC端,还需要编写自己的PCIE驱动程序(Windows上可以参考WDK的PCI接口驱动实例,Linux上相应会更方便一些),这样就可以和你基于FPGA的PCIE板卡通信了。

4. FPGA PCIE通信板卡确保有PCIE的相关 *** 作程序。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7975789.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-12
下一篇 2023-04-12

发表评论

登录后才能评论

评论列表(0条)

保存