关于上一章
上一章介绍了物理层的 Gen1/Gen2 逻辑子模块。该层为串行传输和恢复准备数据包,并详细描述了完成这一任务所需的几个步骤。本章涵盖了与使用 8b/10b 编码/解码的 Gen1 和 Gen2 协议相关的逻辑。
关于本章
本章描述了第三代(Gen3)PCIe 的逻辑物理层特性。主要的变化包括相对于 Gen2 ,Gen3 在没有倍增频率(链路速度只是从 5 GT/s 提高到 8 GT/s)的情况下,将带宽提高两倍。这是通过在 Gen3 模式下取消 8b/10b 编码而实现的。另外,在 Gen3 速度下,必须采用更具鲁棒性的信号补偿机制。
关于下一章
下一章将介绍物理层与链路的电气接口,并讨论了信号均衡的必要性和实现信号均衡的模型。该章同时包括了 Gen1、Gen2 和 Gen3 速率下的发送端和接收端电气特性。
12.1 Gen3 简介
回顾一下,当 PCIe 链路进入训练状态时(即复位后),它总是使用 Gen1 速度,以实现向后兼容。如果设备在训练期间宣称(advertise)了更高的速度,链路将立即转换到 Recovery 状态,并尝试将速率改为链路双方共同支持的最高速度。
将 PCIe 协议升级到 Gen3 的主要动机是为了将带宽提高一倍,如第 408 页的表 12-1 所示。实现这一点的直接方法是简单地将信号速率从 5GT/s 增加到 10Gb/s,但这样做有几个问题:
• 更高的频率会消耗更多的功率,由于需要复杂的调节逻辑(均衡, equalization)来维持更高速度下的信号完整性,这一问题变得更加严重。事实上,在 PCISIG 的文献中提到,均衡逻辑的高功率需求是保持尽可能低的频率的一个重要动机。
• 一些电路板材料在较高频率下会出现明显的信号衰减。这个问题可以通过采用更好的材料和投入更多设计精力来克服,但会增加成本和开发时间。由于 PCIe 的设计目的是为各类系统所采用,所以目标是 PCIe 在低成本设计中也能够良好运行。
• 同样,允许新设计使用现有的基础设施(例如电路板和连接器),可以最大限度地减少电路板设计工作和成本。使用更高的频率会使其变得更加困难,因为必须调整走线长度和其他参数以支持新的时序需求,这使得高频率方案变得不那么理想。
表 12-1 不同链路位宽下的 PCIe 带宽一览
这些考虑导致 Gen3 spec 与前几代相比有两个重大变化:新的编码模型和更复杂的信号均衡模型。
12.1.1 新的编码模型
物理层的逻辑部分用新的 128b/130b 编码方案取代了 8b/10b 编码。当然,这意味着偏离了许多串行设计中成熟使用的 8b/10b 模式,但是 PCIe 设计者希望新的编码模式来挽回 8b/10b 编码所产生的 20% 的传输开销。使用 128b/130b 编码模式意味着通道(Lanes)现在传输的是 8 bits/byte,而不是 10 bits/byte,这意味着 Gen3 只需要 8.0GT/s 的数据速率,就能够相比 Gen2 增加一倍带宽,相当于链路收发双向上的带宽为 1GB/s。
为了说明这两种编码的区别,首先考虑图 12-1,它展示了 8b/10b 编码模式下数据包的一般结构。图中的箭头强调了代表 8b/10b 数据包帧符号的控制(K)字符。接收端通过识别这些控制字符,知道预期接收的数据包类型。请参阅第 380 页的“8b/10b 编码” 节,了解这种编码方案的优势。
图 12-1 8b/10b 通道编码方式
相比之下,第 410 页的图 12-2 展示了 128b/130b 的编码方式。这种编码不影响正在传输的字节,而是将字符分组为 16 个字节的块,每个块的开头有一个 2 比特的同步字段。2 比特同步字段表示该块是否包括数据(10b)或有序集(01b)。因此,同步字段用于向接收端表明数据流的开端以及预期的数据流类型。与 8b/10b 版本类似,有序集必须在所有通道上被同时传输。这要求所有通道之间能够正确地同步,这也是训练过程的一部分(见第 438 页“实现块对齐”)。
图 12-2 128b/130b 块编码方式
12.1.2 更复杂的信号均衡模型
PCIe Gen3 的第二项变化是在于物理层的电气子模块,包括在链路的发送端和接收端(可选的)进行更复杂的信号均衡。Gen1 和 Gen2 采用预先固定的 Tx 去加重(de-emphasis)数值,以达到良好的信号质量。然而,将传输频率提升到 5GT/s 以上会导致更严重的信号完整性问题,需要发送端和接收端采取更进一步的补偿措施。信号完整性问题一定程度上可以通过电路板板级的手段解决,但设计者希望让 PCIe Gen3 的外部基础设施尽可能地保持不变,所以将额外的均衡开销设计在 PHY 的发送端和接收端电路上。关于信号调节的更多细节,请参阅第 474 页的 “8.0GT/s 的解决方案 – 发送端均衡(Transmitter Equalization)”。
12.2 8.0 GT/s 编码
如前所述,Gen3 128b/130b 编码方法在整个链路范畴内封装数据报文,在单个链路上对数据进行分块编码。本节将进一步讨论编码的细节。
12.2.1 通道层面的编码
为了说明块(Blocks)的应用方式,请看第 411 页的图 12-3,其中展示了一个单通道数据块。首先是两个同步头(Sync Header)位,后面是 16 个字节(128 位)的信息,共 130 个传输位。同步头简单地定义了正在发送的是一个数据块 (10b) 还是一个有序集 (01b)。你可能已经注意到图 12-3 中的数据块的同步头值是 01b,而不是上面提到的 10b 值。这是因为在链路上传输数据块时,首先发送同步头的最低有效位(LSB)。请注意,同步头后面的符号也会先以最低有效位发送。
图 12-3 同步头与数据块示例
12.2.2 块对齐
与先前版本的实现方式一样,Gen3 首先进行位锁定(Bit Lock),然后尝试建立块对齐锁定(Block Alignment Lock)。这需要接收端找到划分块边界的同步头。发送端通过发送由 00h 和 FFh 字节交替组成的,RX 可识别的 EIEOS 符号集(pattern)建立块边界,如图 12-4 所示。因此,EIEOS 已经不只是用于表示退出电气空闲,还扩展应用于建立块对齐的同步机制。请注意,同步头位紧接在 EIEOS 之前和之后(图 12-4 中未显示)。关于这个过程的细节,请参见第 438 页的“实现块对齐”。
图 12-4 Gen3 EIEOS 符号集
12.2.3 有序集块
有序集的含义与 Gen1 和 Gen2 中的含义基本相同。它们用于管理通道协议(Lane protocol)。当发送有序集块时,它必须同时出现在所有通道上,并且几乎总是由 16 个字节组成,只有一个例外。这个例外是 SOS(SKP 有序集),它由时钟补偿逻辑(例如与链路中继器(Link Repeater)相关)以四个为一组的形式添加或删除 SKP 符号,因此 8、12、16、20 或 24 字节长度都是合法的。
有序集块的基本格式与数据块类似,只是同步头位数值是相反的,如第 412 页图 12-5 所示。
图 12-5 Gen3x1 有序集块示例
PCIe 规范为 Gen3 定义了七个有序集(比 Gen1 和 Gen2 PCIe 多一个有序集)。在大多数情况下,它们的功能与前几代相同。
- SOS - Skip Ordered Set:用于时钟补偿。更多细节见第 426 页 “有序集示例-SOS”。
- EIOS - 电气空闲有序集(Electrical Idle Ordered Set):用于进入电气空闲状态
- EIEOS - 电气空闲退出有序集(Electrical Idle Exit Ordered Set):现在用于两个目的:
— 电气空闲退出,这与前几代相同
— 用于指示 8.0GT/s 速率下的块对齐边界 - TS1 - 训练序列 1 有序集(Training Sequence 1 Ordered Set)
- TS2 - 训练序列 2 有序集(Training Sequence 2 Ordered Set)
- FTS - 快速训练序列有序集(Fast Training Sequence Ordered Set)
- SDS - 数据流开端有序集(Start of Data Stream Ordered Set):在 Gen3 中新增 - 详见第 413 页 “数据流和数据块”。1. STP - 开始 TLP:与早期版本很相似,但新增了字段:数据包双字(dword)数量。
- 2. SDP - 开始 DLLP
- 3. EDB - End Bad。用于使 TLP 无效,就像在早期的 Gen1 和 Gen2 设计中那样,但现在会连续发送四个 EDB 符号。另外,现在已经取消了 END(结束良好)符号;如果没有明确标记为坏,TLP 将被假定为良好。
- 4. EDS - 数据流的结束。数据流的最后一个双字(dword),表示至少有一个有序集将会出现。耐人寻味的是,数据流可能并没有因为这个事件而真正结束。如果紧随其后的有序集是 SOS,并且紧随其后的是另一个数据块,则数据流继续。如果跟随的是 EDS 而不是 SOS,或者如果 SOS 后面没有数据块,那么数据流就会结束。
- 5. IDL - 逻辑空闲。空闲标记只是在链路逻辑空闲状态下,没有 TLPs 或 DLLPs 准备传输时发送的数据零字节(data zero bytes)。
为了给读者一个有序集结构的示例,图 12-6 展示了 8.0GT/s 速率下 FTS 有序集的组成,只能通过同步头才能把它识别为有序集,并通过该块中的第一个符号(Symbol)识别为 FTS 类型。图的右侧列出了有序集标识符(每个有序集的第一个符号),用于识别当前正在传输的有序集的类型。
图 12-6 Gen3 FTS 有序集示例
12.2.4 数据流和数据块
链路通过发送一个 SDS 有序集,转换到 L0 链路状态来开始数据流传输(Enter a Data Stream)。在数据流中传输多个数据块,直到数据流以 EDS 标记(Token)结束(除非有错误提前结束)。 EDS 标记总是占据有序集之前的数据块的最后四个符号。Skip 有序集是一个例外,因为只要符合某些条件,它们就不会中断数据流。这种例外情况将在后文讨论。当链路状态从 L0 状态转换到任何其他链路状态,如恢复状态(Recovery),数据流就不再有效。关于链路状态的更多信息,请参阅第 518 页的“链路训练和状态机(LTSSM)”。
12.2.5 数据块帧结构
数据块由用于传递信息的 TLPs、DLLP 和 Token 组成。在一个数据块中还会用到五种类型的数据结构(称为标记,Token )。每一种都有便于接收端检测的数据图样(Pattern)。其中三种标记可能在一个数据块的开头发送(即,紧跟在同步数据块之后)。其中包括:
• 开始 TLP(STP) - 表示随后是 TLP 报文
• 开始 DLLP(SDP) - 表示随后是 DLLP 报文
• 逻辑空闲(IDLA) - 在没有数据包活动时发送
剩余的两种标记(Tokens)在数据块的末尾传递。
• 数据流结束(EDS) - 表示之后将从数据转换到有序集
• End Bad (EDB) - 报告检测到无效的数据包
图 12-7 提供了一个由单通道 TLP 传输组成的数据块的示例。
图 12-7 Gen3x1 帧结构示意图
总之,数据块的内容因链路当前的活动(activity)而异:
• IDLs - 当没有数据包被传送时,数据块只由 IDL 组成。(规范将 IDL 指定为标记之一)。
• TLPs - 在一个给定的数据块中可以发送一个或多个 TLPs,取决于链路宽度。
• DLLPs - 在一个给定的数据块中可以发送一个或多个 DLLPs。
• 上述活动的组合可在一个数据块中传送。
12.2.5.1 帧标记
该规范定义了五个允许出现在数据块中的帧标记(或简称为“标记” Token),为了方便起见,在第 417 页的图 12-8 中再次罗列了这些标记。这五个标记是:
1. STP - 开始 TLP:与早期版本很相似,但新增了字段:数据包双字(dword)数量。
2. SDP - 开始 DLLP
3. EDB - End Bad。用于使 TLP 无效,就像在早期的 Gen1 和 Gen2 设计中那样,但现在会连续发送四个 EDB 符号。另外,现在已经取消了 END(结束良好)符号;如果没有明确标记为坏,TLP 将被假定为良好。
4. EDS - 数据流的结束。数据流的最后一个双字(dword),表示至少有一个有序集将会出现。耐人寻味的是,数据流可能并没有因为这个事件而真正结束。如果紧随其后的有序集是 SOS,并且紧随其后的是另一个数据块,则数据流继续。如果跟随的是 EDS 而不是 SOS,或者如果 SOS 后面没有数据块,那么数据流就会结束。
5. IDL - 逻辑空闲。空闲标记只是在链路逻辑空闲状态下,没有 TLPs 或 DLLPs 准备传输时发送的数据零字节(data zero bytes)。
规范中显示标记的方式与第 417 页图 12-8 中显示的方式的不同之处在于,这幅图以小端(little-endian)顺序显示字节和位,而不是规范中使用的大端(big-endian)位表示。之所以这样显示,是为了说明各比特在通道上实际出现的顺序。
图 12-8 Gen3 帧标记示意图
12.2.5.2 数据包
STP 和 SDP,表示一个数据包的开始,如图 12-7 所示
• TLPs。一个 STP 标记开端是一个全 1 的半字节(4‘b1111),随后是 11 比特位宽的数据包双字长度字段。双字长度字段统计 TLP 所有的双字,覆盖标记、首部、可选的数据有效载荷、可选的摘要(digest)和 LCRC。这使接收端能够通过计算双字数,以识别 TLP 的结束位置。因此,正确的 Length 字段是非常重要的,因此它有一个 4 位的帧 CRC(Frame CRC),以及一个保护 Length 和帧 CRC 字段的偶数奇偶校验位。这些校验字段的组合为标记提供了强大的三比特翻转(triple-bit-flip)检测能力(能够检测出包含多达 3 比特不正确的报文)。11 位的长度字段最多允许整个 TLP 为 2K 个双字(8KB)。
• DLLPs。SDP 标记表示 DLLP 的开始,没有表示 DLLP 的长度字段,因为 DLLP 总是 8 个字节长:2 个字节的标记后面是 4 个字节的 DLLP 有效载荷和 2 个字节的 DLLP LCRC。也许是巧合,这个 DLLP 长度与前几代 PCIe 相同,但不再包括一个表示结束良好的符号。
EDB 标记被添加到无效的 TLPs 的末尾。对于一个正常的 TLP,没有 “结束良好” 的指示,除非明确标记为坏,否则它被认为是良好的。如果 TLP 最终被标记为无效,LCRC 数值将被反转,并在末尾附加一个 EDB 标记作为 TLP 的扩展,它不会被反映在长度字段中。物理层的接收端必须在每个 TLP 结束时检查 EDB,如果看到 EDB 就通知链路层。自然而然地,除了在 TLP 结束后的符号接收到 EDB 之外,其他任何时候接收 EDB 都将被接收端视为帧错误。
12.2.5.3 发送端帧要求
开始这个话题的讨论前,我们最好预先定义一些事物。首先,回顾一下,数据流从 SDS 之后的第一个符号开始,它可能包含由标记、TLP 和 DLLP 组成的数据块。数据流以有序集(除了 SOS)之前的最后一个符号结束,或者当检测到帧错误时结束。在数据流期间,除了 SOS 外,不能发送任何有序集。
其次,由于帧问题通常会导致帧错误,解释下在这种情况下会发生什么是很有用的背景知识。当帧错误发生时,它们被视为接收端错误,并向上层报告。接收端停止处理正在进行的数据流,只有当它看到一个 SDS 有序集时,才会开始处理一个新的数据流。为了响应帧错误,帧恢复逻辑通过将 LTSSM 从 L0 引导到恢复(Recovery)状态来启动。预期中,帧错误及其恢复过程将在物理层得到解决,不需要上层采取任何行动。此外,规范指出,从两个端口都进入恢复状态开始算起,完成这一过程的往返时间预期小于 1us。
现在,有了上述的背景知识,让我们继续讨论帧要求。在数据流中,发送端必须遵守以下规则:
• 当发送 TLP 时:
— STP 标记后必须紧跟着从链路层传递的 TLP 的全部内容,即使它是无效的。
— 如果 TLP 是无效的,EDB Token 必须紧跟在 TLP 的最后一个 dword 之后,但其不能包含在 TLP 的长度值中。
— STP 在链路上的每个符号时间内不能被发送多次。
• 当发送 DLLP 时:
— SDP 标记后面必须紧跟着从数据链路层传递的 DLLP 的全部内容。
— SDP 在链路上的每个符号时间内不能被发送多次。
• 当在数据流中发送一个 SOS(SKP 有序集)时:
— 在当前数据块的最后一个双字中发送一个 EDS 标记。
— 将 SOS 作为下一个有序集块发送。
— 在 SOS 之后立即发送另一个数据块。数据流以该后续数据块的第一个符号恢复。
— 如果安排了多个 SOS,它们不能像前几代那样背对背(back-to-back)地进行。相反,每个标记前面必须有一个以 EDS 标记结束的数据块。在此期间,数据块可以用 TLPs、DLLPs 或 IDLs 填充。
• 发送端要结束一个数据流时,在当前数据块的最后一个双字中发送 EDS 标记,然后使用 EIOS 进入低功率链路状态,或者用 EIEOS 处理所有其他情况。
• 如果链路上没有发送 TLP、DLLP 或其他帧标记,则必须在所有通道上发送 IDL 标记。
• 对于多通道链路:
— 在发送一个 IDL 标记后,下一个 TLP 或 DLLP 的第一个符号在开始时必须位于通道 0 中。EDS 标记必须始终是数据块的最后一个双字,因此可能不总是遵循这一规则。
— IDL 标记必须被用来在符号时间内填充本来是空的双字。例如,如果一个 x8 链路的 TLP 在通道 3 结束,但发送端没有另一个 TLP 或 DLLP 准备在通道 4 开始,那么 IDL 必须填充剩余的字节,直到该符号时间的结束。
— 由于数据包长度仍然是 4 字节的倍数,就像它们在早期几代中一样,它们将在 4 的倍数通道边界开始和结束。例如,在 x8 链路中,某个 DLLP 在通道 3 结束 ,可以通过将其 STP 标记放在通道 4 来开始下一个 TLP。
12.2.5.4 接收端帧要求
当在接收端看到数据流时,以下规则适用:
• 当需要帧标记时,接收到像其他东西的符号将被视作帧错误。
• 下面列表中显示的一些错误检查和报告是可选的,规范中指出这些可选项之间是互相独立的。
• 当收到 STP 时:
— 接收端必须检查帧 CRC 和帧奇偶校验字段,任何不匹配都将是一个帧错误。(注意,在报告这个错误时,错误帧的 STP 标记不被认为是 TLP 的一部分。)。
— 紧接 TLP 最后一个 DW 的符号是下一个要处理的标记,接收端必须检查它是否是 EDB 标记的开始,表明 TLP 已经无效。
— 可选择检查长度值是否为零;如果检测到,则为帧错误。
— 可选择检查在同一符号时间内是否有多个 STP 标记到达。如果检查并检测到,这就是一个帧错误。
• 当收到 EDB 时:
— 一旦检测到第一个 EDB 符号,或者在接收到它的任何剩余字节之后,接收端必须立即通知链路层。
— 如果标记中的任何符号不属于 EDB,则结果是一个帧错误。
— EDB 标记的唯一合法时间是在 TLP 之后;任何其他用途都将是帧错误。
— 紧跟在 EDB 标记之后的符号将是要处理的下一个标记的第一个符号。
• 当 EDS 标记作为数据块的最后一个 DW 被接收时:
— 接收端必须停止处理数据流。
— 接下来,只有接收到 SKP、EIOS 或 EIEOS 有序集是合法的;接收到任何其他有序集都将是一个帧错误。
— 如果在 EDS 之后收到 SKP 有序集,则除非检测到帧错误,否则接收端必须使用随后的数据块的第一个符号(Symbol)恢复数据流处理。
• 当收到 SDP 标记时:
— 紧随 DLLP 之后的符号是下一个要处理的符号。
— 可选择在同一符号时间内检查多个 SDP 标记。如果检查并出现这种情况,则为帧错误。
• 当收到 IDL 标记时:
— 允许下一个标记在 IDL 标记之后的任何 DW 对齐的通道上开始。对于 x4 或更窄的链路,这意味着下一个标记只能在下一个符号时间的通道 0 开始。对于更宽的链路,有更多的选择。例如,x16 链路可以在当前符号时间的 0、4、8 或 12 通道开始下一个标记。
— 唯一与 IDL 在同一符号时间内可接收的标记是另一个 IDL 或 EDS。
• 在处理数据流时,接收端将以下情况视为帧错误:
— 紧跟着 SDS 之后的有序集。
— 具有非法同步头(11b 或 00b)的块。可选地,在通道错误状态(Lane Error Status)寄存器中报告这个错误。
— 任何通道上接收的有序集块,未在前一个数据块中收到 EDS 标记。
— 紧跟在前一个块中的 EDS 标记之后,接收到数据块。
— 可以选择验证所有通道是否收到相同的有序集。
12.2.5.5 从帧错误中恢复
如果在处理数据流时发现帧错误,接收端必须:
• 报告接收端错误(如果可选的高级错误报告(Advanced Error Reporting)寄存器可用,则置位第 421 页图 12-9 所示的相应状态位)。
• 停止处理数据流。当看到下一个 SDS 有序集时,可以开始处理新的数据流。
• 启动错误恢复过程。如果链路处于 L0 状态,则需要转换到恢复状态。该规范规定,恢复状态的时间“预期”小于 1us。
• 请注意,从帧错误中恢复不一定会通过 Ack/Nak 机制,直接导致数据链路层发起的恢复活动。(译注:很多情况下,从帧错误中恢复将会在物理层解决)当然,如果 TLP 由于错误而丢失或损坏,那么将需要重放事件(replay event)。
原文: Mindshare
译者: Brook
校对: LJGibbs
转载自:知乎
推荐阅读
- DDR 学习时间 (Part Z - 1):芯片设计中的 DDR 模型杂谈
- PIPE v3.0 协议信号速览表
- PCI Express Technology 3.0:PCIe体系结构概述 2.2-2.3
- PCI Express Technology 3.0:PCIe体系结构概述 2.1 节
更多招聘及面经请关注FPGA的逻辑,欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。