PCIe架构概述(五)


物理层

概述 

物理层是PCIe的最低层次,TLP和DLLP类型的数据包都从数据链路层转发到物理层,以通过链路进行传输,然后转发到接收器上的数据链路层。规范将“物理层”讨论分为两部分:逻辑部分和电气部分,我们还将在此处保留该划分方式。逻辑物理层包含与准备数据包以在链路上进行串行传输的逻辑,以及接收从链路来的数据包进入物理层的的数据逻辑。电气物理层是物理层的模拟接口,它连接到链路(Link),并由每个通道(Lane)的差分驱动器和差分接收器组成。

物理层-逻辑

来自数据链路层的TLP和DLLP被记录到物理层的缓冲区(buffer)中,在缓冲区(buffer)中会对数据包添加开始和结束字符,以便于在接收器处检测包边界。由于开始和结束字符出现在数据包的两端,因此也称为“组帧/framing”字符。图2‐28中,字符被添加在TLP和DLLP上,还展示了每个字符的字段大小。


图2‐28 物理层的TLP和DLLP结构


在这一层中,数据包的每个字节被拆分到链路所使用的所有通道(Lane)。这个过程被称为字节的条带化(Byte Striping)。实际上,每个通道都作为跨链路的独立串行路径运行,并且它们的数据全部在接收器处汇总在一起。每个字节都经过加扰(扰码,减少传输线上出现的连续0或1),以减少传输线链路上的EMI(电磁干扰)。对于前两代PCIe(第1代和第2代PCIe),使用所谓的8b/10b编码逻辑将8位字符编码为10位“符号/symbol”。此编码将开销添加到传出的数据流中,但也会添加许多有用的特性(有关此特性的更多信息,请参见“8b/10b编码”)。Gen3物理层逻辑以Gen3速度传输时,不使用8b/10b编码对数据包字节进行编码。而是使用另一种称为128b/130b编码的编码方案,它会把数据包的字节扰码后进行传输。然后将每个通道(第1代和第2代)上的10b符号或每个通道(第3代)上的数据包字节串行化,并以2.5 GT/s(Gen1)或5GT/s(Gen2)或8GT/s(Gen3)的速率在链路的每个通道上差分输出。


当接收器到达所有通道时,它们以训练完成的时钟速度对输入数据包的bit进行接收。如果使用8b/10b(在Gen1和Gen2模式下),则使用解串器将数据包的串行位流转换为10位符号,以便为8b/10b解码做好准备。但是,在解码之前,符号会通过弹性缓冲区(elastic buffer),这是一种巧妙的设备,可以补偿两个相连设备的内部时钟之间的频率差异。接下来,通过8b/10b解码器将10位符号流解码回正确的8位字符。PCIe Gen3 与前面所述的这个过程不同,对于 Gen3 的物理层逻辑来说,当接收到以 Gen3 速率传输的数据包串行比特流时,将使用串并转换器将这个比特流转换为字节流,这个串并转换器已经建立了块锁定(Block Lock,这是链路训练中的一个要素)。字节流通过执行时钟容差补偿的弹性缓冲区(elastic buffer)。如果以Gen3速度计时的数据包未进行8b/10b编码,则跳过8b/10b解码器级。最终, 每个通道中的 8bit 字符都将经过解扰,然后经过反条带化(un-striped)之后将所 有通道内的字节聚合重新恢复成单符号流(single character stream),这样就在接 收端恢复出了发送端所发出的数据流

链接训练和初始化(Link Training and Initialization)

物理层的另一个任务就是负责链路的初始化以及训练过程。在这个全自动化 的过程中,为了让链路准备好进行正常工作,我们采用了几个步骤,主要为确定 几个可选条件的状态。例如,链路宽度可以从1通道到32通道,并且可以提供多种速度。链路训练过程将会发现这些可选项并通过一个状态机来寻求一个建立最佳连接的组合,也就是说链路训练将会确认这些可选项具体的值(链路宽度、速率等)。在这个过程中,为了确保执行正确以及最优的操作,我们需要检查或者建立一些东西,例如:

•链路宽度(Link width)

•链路数据速率(Link data rate)

•通道反转-反向连接的通道(Lane reversal)(就是通道TX-RX接错了,成了TX-TX)

•极性反转-通道极性反向连接(Polarity inversion)(就是TX_P接RX_P接成TX_P连接了对端的 RX_N)

•每个通道的位锁定(bit lock)——恢复出发送方的时钟。

•每个通道的符号锁定(symbol lock)——在比特流中找到一个可辨认的 位置。

•多通道链路中的 Lane-to-Lane 偏斜去除(de-skew)。

物理层-电气(Physical Layer-Electrical)

链路上的物理发送器和接收器通过交流耦合的链路进行连接,如图2‐29页所示。术语“交流耦合”仅表示设备之间的物理路径中放置有电容,并用于通过信号的高频(AC交流)分量,同时阻塞低频(DC直流)部分。许多串行传输都使用这种方法,因为它允许发送器和接收器的共模电压(信号的正负交叉的电平,即0,1电平之间)不同,这意味着它们不需要具有相同的参考电压。如果两个设备距离比较近,即使需要相同的参考电压也不是一个大问题,但是如果它们在不同的建筑物中,则很难获得完全相同的公共参考电压。


图2‐29 物理层电气

命令集/有序集(Ordered Sets)

最后要介绍的一种在设备之间发送的流只使用物理层。尽管这种信息对于接收端来说很容易进行识别,但是它并没有被封装成数据包的形式,原因是它没有包起始字符和包结束字符。因此作为一种替代方法,这种信息被组织成了一种被叫做“命令集(Ordered Sets)”的东西,它起始于发送端的物理层,终止于接收端的物理层,如图 2-30 所示那样。对于 Gen1 和 Gen2 的数据率下,一个命令集使用一个单独的 COM 字符作为起始,然后后面接着 3 个或以上的其他字符用于定义要发送的信息。关于这些不同类型字符在 PCIe 中的命名的更细节的讨论 请见“Character Notation”一节,对于现阶段来说只要知道 COM 字符的特性能 让我们达到想要的设计目标即可。命令集的大小总是 4byte 的整数倍,图 2-31展示了一个命令集的例子。在 Gen3 操作模式中,命令集的格式就不同于上述的 Gen1/Gen2 格式了。更多详细内容请见 Chapter 14“Link Initialization & Training”。命令集永远只会终止于链路的对端设备,而不会被交换器路由转发至 PCIe 网络中,也就是说对端设备如果是交换器那么它的最终目的地就是交换器。


图2-30 命令集的起点和终点


命令集在链路训练(Link Training)过程中同样有所应用,请参阅 Chapter 14 “Link Initialization & Training”。它们也被用于补偿发送端和接收端内部时钟的轻微差异,这一过程被称为时钟容忍度补偿(clock tolerance compensation)。最后一点,命令集还可以用于指示链路进入或者退出低功耗状态。


图2-31 有序集结构

协议回顾(Protocol Review Example)

现在,让我们通过一个示例来回顾整个链路协议,这个例子将从请求者发起一个 Memory Read 请求(MRd)开始,直到请求者从完成者(Completer)获得所请求的数据为止,讲解这过程中所发生的操作步骤。

内存读取请求(MRd 请求)

对于讨论的第一部分,请参阅图2–32。请求者的设备核心或软件层将请求发送到事务层,并包括以下信息:32位或64位内存地址,事务类型,流量类别,字节启用,属性等要读取的数据量。


图2-32 内存读取请求阶段


事务层使用上面所述的那些信息来构建一个MRd TLP。关于TLP内部格式的细节我们稍后再进行描述,目前我们只需要知道TLP的Header大小为 3DW 或 4DW,这取决于它的地址字段的大小(32bit 地址对应 3DW Header,64bit 地址对应 4DW Header)。此外,在Header中还有事务层加入的 Requester ID字段 (bus#,device#,function#),完成者可以通过这个 Requester ID 字段来返回完成包。TLP随后被置入相应优先级的虚拟通道缓冲区(buffer)中,等待轮到它被发送。一旦这个TLP被选中,流量控制逻辑将会确认对端设备的接收缓冲区buffer(VC,虚拟通道)有足够的可用空间来接收这个TLP,然后MRd TLP就被向下发送至数据链路层。

在数据链路层中,数据包被加上12bit的序列号(Sequence Number)以及32bit的LCRC。并在重传缓冲区(Replay Buffer)中保存这个TLP的副本, 然后这个数据包就被向下转发至物理层。

在物理层中,数据包被加上包起始字符以及包结束字符,然后在所有可用的通道上进行字节条带化(byte striping),再进行扰码(Scramble)、8b/10b 编码。最终这个数据包的比特在链路上的每个通道内以串行差分的形式传输到对端接收。

完成者(Completer)接收到输入的比特流,它将这个比特流先进行串并转换将比特流恢复成10bit符号,然后让它们通过一个弹性缓存(elastic buffer)。随后10bit符号被解码后恢复成字节,然后每个通道上的字节都被解扰(de-scramble)以及反条带化(un-striped)。接下来 Completer 物理层检测到包起始字符和包结束字符,并将它们从TLP中剥除。剩余的 TLP 被向上转发至数据链路层。

完成者(Completer)的数据链路层将对接收到的TLP进行LCRC错误校验,并检查TLP序列号以确定是否存在TLP丢失或TLP失序。若这些步骤都无错,数据链路层将生成一个Ack信息,里面包含了与这个MRd TLP中相同的序列号。然后再给这个Ack信息加上16bit的CRC,这样就组成了一个Ack DLLP,将这个Ack DLLP送回物理层,由物理层加上相应的组帧符号(framing symbol),并把Ack DLLP传输给请求者Requester。

请求者(Requester)的物理层接收到Ack DLLP后,对其组帧符号进行检查和剥除, 然后向上转发至数据链路层。如果数据链路层对其CRC校验无错,它将会用Ack DLLP内的序列号与重传缓冲区(Buffer)中保存的TLP副本的序列号进行比较,并将与Ack DLLP中序列号相匹配的TLP副本从重传Buffer中清除。相反地,若请求者(Requester)接收到的是一个Nak DLLP,那么它将把序列号匹配的这个MRd TLP进行重传。由于DLLP仅对数据链路层有意义,所以在这些 DLLP 的操作中将不会有东西向上转发给事务层。

除了上述的产生Ack DLLP之外,完成者(Completer)的数据链路层还将把TLP向上 转发给事务层。在完成者(Completer)的事务层中,TLP 被置于与其优先级相对应的虚拟 通道接收buffer中,等待被处理。然后可以对TLP进行ECRC校验(ECRC 为 可选项),若校验无错,那么TLP Header的内容(地址、Requester ID、MRd 事务类型、请求数据总量、流量类型等)将被向上转发至 Completer 的软件层。

完成数据

下面开始介绍此次举例回顾 PCIe 协议的另一半内容,请参考图 2-33。为了服务 MRd 请求,Completer 的 Device Core/软件层将会向它的事务层发送一个带有数据的完成包(Completion with Data,CplD)请求,这个完成包请求中包含了与 MRd 请求中相同的 Requester ID、Tag,还包含了事务类型以及另外的完成包 头内容,并且完成包中还包含了被请求的数据。


图2-33 完成数据阶段


事务层使用CplD请求中的这些信息来构建一个 CplD TLP,这种 TLP 的 Header 固定为3DW(这是由于 CplD TLP 使用Requester ID作为路由信息,因此不会需要用到 64bit 的地址)。事务层也会将自身的 Completer ID添加到 CplD TLP Header 中。这个数据包随后被放置入一个合适的虚拟通道的发送 Buffer中,一旦这个虚拟通道被仲裁选中并要发送这个CplD TLP,流量控制逻辑将会确认对端设备有足够的可用缓冲区空间来接收它,当确认足够后则将这个CplD TLP向下转发至数据链路层。


如前文所述那样,数据链路层给数据包加上12bit的序列号(Sequence Number)和 32bit 的 LCRC。然后将添加完这些信息的TLP保存一份副本在重传Buffer(Replay Buffer)中,之后变将数据包向下转发至物理层。


如前所述,物理层给数据包加上包起始字符和包结束字符,并将其在所有可用通道上进行字节条带化,再进行扰码、8b/10b 编码。最终,这个 CplD TLP数据包在链路的所有通道上以串行差分的形式被传输至对端。


当请求者(Requester)接收到这个CplD TLP的输入比特流时,它将比特流转换恢复成10bit符号(10bit symbol),并让10bitsymbol流通过一个弹性缓存。随后10bit符号被解码恢复为字节,并进行解扰和字节反条带化(un-striped)。然后物理层就能检测到这个CplD TLP 的包起始字符和包结束字符,并将这两个字符剥去。之后便将剩余的 CplD TLP 向上转发至数据链路层。


和之前一样,数据链路层对CplD TLP进行LCRC校验,并检查序列号以确 定是否存在TLP丢失或出现TLP失序。如果并未出现错误,数据链路层将产生一个Ack DLLP,其中包含了与CplD TLP中相同的序列号,并给这个 Ack DLLP加上16bit CRC,然后将其送回给物理层加上相应的组帧字符(framing symbol) 并将这个Ack DLLP传输给 Completer。


Completer 的物理层将会检测并剥除Ack DLLP的组帧字符,并将剩余的部 分向上转发给数据链路层,在这里对Ack DLLP的CRC进行校验。若校验无错,Completer的数据链路层将Ack DLLP中的序列号与重传Buffer中的TLP 的序列 号进行对比。与Ack DLLP序列号相匹配的TLP将被从重传Buffer中清除。反之,若Completer接收到的是一个Nak DLLP,那么它将使用重传 Buffer 中存储的CplD TLP副本来进行重传。


同时,Requester的事务层在某个虚拟通道的缓存中接收到了这个 CplD TLP。作为一个可选操作,事务层可以校验这个TLP的ECRC。若校验无错,事务层将这个CplD TLP的Header内容、数据荷载以及请求完成状态信息向上呈交给Requester的软件层。至此,大功告成。

后半部分参考Michael ZZY的翻译

作者:极客石头

在搞事情的路上越走越远。

发表评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注