11 物理层 - 逻辑(Gen1 和 Gen2)(Physical Layer - Logical (Gen1 and Gen2))
上一章
前一章描述了确认/否定确认协议:一种基于硬件的自动机制,用于确保链路层数据包(TLP)在链路上的可靠传输。确认数据链路层包(Ack DLLP)用于确认 TLP 的正确接收,而否定确认数据链路层包(Nak DLLP)则指示传输错误。本章将介绍正常操作规则以及错误恢复机制。
本章
本章描述物理层的逻辑子模块。该子模块负责为串行传输与接收恢复准备数据包。完成这一过程需要多个步骤,本章将对这些步骤进行详细说明。本章涵盖使用 8b/10b 编码的 Gen1 和 Gen2 协议相关的逻辑。Gen3 协议不使用 8b/10b 编码,其逻辑将在第 407 页的《物理层 - 逻辑(Gen3)》章节中单独描述。
下一章
下一章将介绍第三代(Gen3)PCIe 的物理层特性。主要变化包括:通过取消 8b/10b 编码需求,在不增加频率的情况下将带宽提升至 Gen2 的两倍。Gen3 速度下需要更强大的信号补偿机制。这些变更的复杂性远超预期。
11.1 物理层概述
本物理层概述将介绍 Gen1、Gen2 与 Gen3 实现之间的关系。随后重点阐述与 Gen1 和 Gen2 相关的逻辑物理层实现。Gen3 的逻辑物理层实现将在下一章中描述。
物理层位于外部物理链路与数据链路层之间的接口最底层。它将来自数据链路层的出站数据包转换为串行化比特流,并通过链路的所有通道进行时钟同步传输。该层还在接收端从链路的所有通道中恢复比特流。接收逻辑将比特流反串行化为符号流,重新组装数据包,并将 TLP 和 DLLP 转发至数据链路层。
图 11-1:PCIe 端口分层架构
各分层的内容为概念性描述,并未定义精确的逻辑模块。但若设计者确实按照规范进行分区设计,其实现将受益——因为持续提升的数据速率对物理层的影响远大于其他层。按分层职责划分设计,可使物理层适应更高时钟频率,同时尽可能减少对其他层的改动。
PCIe 规范 3.0 版本并未使用特定术语来区分各版本规范所定义的不同传输速率。基于此,本书定义并使用以下术语:
- Gen1:第一代 PCIe(rev 1.x),运行速率为 2.5 GT/s。
- Gen2:第二代 PCIe(rev 2.x),运行速率为 5.0 GT/s。
- Gen3:第三代 PCIe(rev 3.x),运行速率为 8.0 GT/s。
物理层由两个子模块组成:逻辑部分和电气部分,如图 11-2 所示。两者均包含独立的发送和接收逻辑,支持双工通信。
图 11-2:物理层的逻辑子模块与电气子模块
11.1.1 评论
该规范描述了物理层的功能,但在实现细节上刻意保持模糊。显然,规范编写者不愿提供具体细节或示例实现,因为他们希望为各供应商留出空间,使其能够通过巧妙或创新的逻辑设计来增加产品价值。不过,就我们的讨论而言,示例是必不可少的,因此我们选取了一个能阐明相关概念的示例。需要明确的是,该示例未经测试或验证,设计人员也无需被迫以这种方式实现物理层。
11.1.2 发送逻辑概述
为简化起见,我们先从该层发送端的高层概览开始,如图 11-3(第 365 页)所示。从顶部开始,可以看到从数据链路层进入的数据包字节首先进入一个缓冲区。在此处设置缓冲区是合理的,因为有时需要延迟来自数据链路层的数据包流,以便将有序集包及其他项目注入字节流中。
对于 Gen1 和 Gen2 操作,这些被注入的项目包括控制字符和数据字符,用于标记数据包边界并构成有序集。为区分这两种字符类型,会添加一个 D/K# 位(数据或“控制”位)。逻辑电路可根据字符来源判断 D/K# 应取何值。
Gen3 操作模式不使用控制字符,因此通过数据模式来构成有序集,以标识传输的字节是否与 TLP/DLLP 或有序集相关。在 128 位(16 字节)数据块的开头插入一个 2 位同步头。同步头告知接收方接收到的数据块是数据块(与 TLP 或 DLLP 相关的字节)还是有序集块。由于 Gen3 模式中没有控制字符,因此不需要 D/K# 位。
图 11-3:物理层发送细节
接下来,来自上层的并行数据字节被发送到字节条带化逻辑,在此处它们被分散或条带化到该链路的所有通道上。每个通道传输一个数据包字节,并且每个发出的数据包都会使用所有活动通道。链路的通道同时进行传输,因此字节必须以足够快的速度进入该逻辑以适配这一过程。例如,如果有八个通道,来自上层的八个并行字节可能会到达字节条带化逻辑,从而允许数据同时被时钟同步到所有通道上。
接下来是扰码器,它通过将伪随机模式与输出数据字节进行异或运算来混合比特位。虽然这看似可能引入问题,但实际上并不会,因为扰码模式是可预测的而非真正随机,因此接收端可以使用相同的算法轻松恢复原始数据。如果扰码器失去同步,接收端将无法解析比特流。为防止此问题,扰码器会定期重置(Gen1 和 Gen2)。这样,即使扰码器彼此失步,它们也会很快重新初始化并恢复同步。对于 Gen1 和 Gen2 模式,每当检测到 COM 字符时就会触发重新初始化;对于 Gen3 模式,则在检测到 EIEOS 有序集时触发。Gen3 模式采用了更复杂的基于 24 位的扰码器,因此需要通过 Gen3 扰码器的替代路径,如图 11-3(第 365 页)所示。
对于 Gen1 和 Gen2 模式,经过扰码的 8 位字符随后由 8b/10b 编码器进行编码以便传输。回顾一下,字符是一个 8 位未编码的字节,而符号是 8b/10b 逻辑输出的 10 位编码结果。8b/10b 编码具有若干优势,但确实会增加开销。
对于 Gen3,显示了一条绕过编码器的独立路径。换句话说,数据包的扰码字节在传输时不经过 8b/10b 编码。同步位生成器在每个数据包的每 16 字节块之前添加一个 2 位同步头。所添加的 2 位同步头用于标识后续的 16 字节块是数据块还是有序集块。每 16 字节(128 位)添加一个 2 位同步头,这是 Gen3 的 128b/130b 编码方案的基础。
最后,符号被串行化为比特流,并转发至物理层的电气子模块,然后传输到链路的另一端。
11.1.3 接收逻辑概述
图 11-4(第 367 页)展示了构成接收端逻辑的关键要素。以下描述的过程针对每个通道执行。这次从底部开始,首先要提及的是接收器时钟与数据恢复(CDR)。该过程的第一步是基于输入比特流中的跳变恢复时钟。这个恢复后的时钟忠实再现了发送数据时使用的发送器时钟,并用于将输入比特锁存到解串缓冲器中。
CDR 过程的后续步骤是找到 Gen1/Gen2 符号边界,并将恢复后的时钟除以 10,以将 10 位符号锁存到弹性缓冲器中。对于 Gen3,下一步是获取块锁定,然后将与该块中 16 个字节对应的 8 位符号锁存到弹性缓冲器中——更多内容将在下一章讨论。
控制弹性缓冲区的逻辑通过检测到 SOS(SKP 有序集)时按需添加或删除 SKP 符号,来调整恢复时钟与接收器本地时钟之间的微小时钟差异。最后,接收器的本地时钟将每个符号移出弹性缓冲区。
图 11-4:物理层接收逻辑细节
使用 8b/10b 解码器,Gen1/Gen2 符号被解码,从而将 10 位符号转换为 8 位字符。解扰器采用与发送端相同的加扰方法恢复原始数据。最后,来自每个通道的字节被解条带化,形成字节流并向上转发至数据链路层。只有 TLP 和 DLLP 被加载到接收缓冲区并发送至数据链路层。
11.2 发送逻辑细节(仅限 Gen1 和 Gen2)
本节提供了与前一节所述步骤相关的更多详细信息。在讨论过程中,请参考第 369 页图 11-5 中的框图。
11.2.1 发送缓冲区
再次从图顶部开始,缓冲区从数据链路层接收 TLP 和 DLLP,以及指定新数据包何时开始的“控制”信息。如前所述,缓冲区允许我们不时暂停字符流,以便插入控制字符和有序集。图中还显示了一个“节流”信号返回至数据链路层,以便在缓冲区满时停止字符流。
11.2.2 多路复用器与控制逻辑
如图 11-6(第 370 页)所示的多路复用器,用于将特殊控制(K)字符插入来自缓冲区的数据流中。只有物理层使用 K 控制字符;这些字符在传输过程中被插入,并在接收端被移除。该多路复用器的四个不同输入包括:
- 发送数据缓冲区。当数据链路层提供数据包时,多路复用器会选通字符流通过。来自缓冲区的所有字符均为 数据(D)字符,因此当选通发送缓冲区内容时,D/K# 信号被驱动为高电平。
- 起始字符和结束字符。这些控制字符被添加到每个 TLP 和 DLLP 的开头和结尾(参见第 371 页图 11-7),使接收方能够轻松检测数据包的边界。共有两种起始字符:STP 表示 TLP 的起始,而 SDP 表示 DLLP 的起始。数据链路层的指示信号与数据包类型共同决定插入何种帧定界字符。此外还有两种结束字符:用于正常传输的”正常结束”字符(END),以及用于处理某些错误情况的”异常结束”字符(EDB)。起始字符和结束字符均为 控制(K)字符,因此在插入起始字符和结束字符时,D/K# 信号会被拉低(控制字符列表参见第 386 页表 11-1)。
图 11-5:物理层发送逻辑细节(仅限 Gen1 和 Gen2)
- 有序集。如前所述,控制字符仅由物理层使用,上层协议无法感知。链路层需要某些通信来启动和维护链路操作,这通过交换有序集来实现。每个有序集以称为逗号(COM)的 控制(K)字符开头,并根据所传递的有序集类型包含其他 K 或 数据(D)字符。有序集始终按四字节边界对齐,并在多种情况下传输,包括:
- 错误恢复、启动事件(如热复位)或退出低功耗状态。在这些情况下,链路两端会交换训练序列 1 和 2(TS1 和 TS2)有序集。
- 复用器会定期插入 SKIP 有序集模式,以协助接收器进行时钟容差补偿。有关此过程的详细说明,请参阅第 391 页的“时钟补偿”部分。
- 当设备希望将其发送器置于电气空闲状态时,必须通知链路另一端的远程接收器。复用器通过插入电气空闲有序集来实现此操作。
- 当设备希望将链路电源状态从 L0s 低功耗状态切换至 L0 全功率状态时,会向接收端发送一组快速训练序列(FTS)有序集。接收端利用该有序集重新同步其 PLL 与发送端时钟。
- 逻辑空闲序列。当没有待发送的数据包或有序集时,链路处于逻辑空闲状态。为使接收端 PLL 保持锁定在发送端频率上,发送端必须持续发送信号,因此在此情况下会插入逻辑空闲字符。逻辑空闲序列非常简单,仅由一串 Data 00h 字符组成。
图 11-6:发送逻辑多路复用器
图 11-7:TLP 与 DLLP 数据包帧结构(含起始与结束控制字符)
11.2.3 字节条带化(适用于宽链路)
本例中的下一步是字节条带化,但仅当端口实现多个通道(称为宽链路)时才需要此操作。条带化是指将字符流中每个连续的外发字符依次路由到连续的通道上。所使用的通道数量在链路训练过程中根据共享该链路的两个设备所支持的能力进行配置。
以下示意图展示了三种字节条带化的示例。在图 11-8(第 372 页)中,展示了一个单通道链路(x1)。这种情况并不特别有趣,因为数据包以字节为单位进入物理层并以相同方式输出,但该图说明了字符序列的绘制方式。
第 372 页的图 11-9 展示了来自多路复用器的传入双字数据包。每个字节被定向到相应的通道。最后,第 373 页的图 11-10 展示了一个八通道()链路。在此示例中,需要两个双字来填充所有 8 个通道。这就要求双字的到达速率是前一个示例的两倍。每个通道上传输的数据格式将在后续章节中描述。
图 11-8:x1 字节条带化
图 11-9:x4 字节条带化
图 11-10: 双字并行数据的字节条带化
11.2.4 数据包格式规则
11.2.4.1 通用规则
- 每个数据包的总长度(包括起始字符和结束字符)始终是四个字符的整数倍。这是数据长度以双字为单位进行度量的自然延伸。
- TLP 以 STP 字符开始,并以 END 或 EDB 字符结束。
- DLLP 以 SDP 开始,以 EN数据(D)字符终止,且长度恰好为 8 个字符(SDP + 6 个字符 + END)。
- 在传输逻辑空闲后开始传输数据包时,STP 和 SDP 字符被放置在通道 0 上。在其他情况下,它们可能从可被 4 整除的通道编号开始。
- 接收端的物理层允许监控这些规则的违反情况,并可能将其作为接收器错误报告给数据链路层。
11.2.4.2 示例:x1 格式
第 374 页图 11-11 所示的示例展示了通过 x1 链路(仅有一条通道运行的链路)传输的数据包格式。图中显示了一系列数据包,其间穿插了一个 SKIP 有序集。末尾处展示了逻辑空闲状态,代表发送端没有更多数据包需要发送时,使用空闲字符作为填充的情况。
图 11-11: 数据包格式
11.2.4.3 x4 格式规则
- STP 和 SDP 字符始终在通道 0 上发送。
- END 和 EDB 字符始终在通道 3 上发送。
- 当发送诸如 SKIP 之类的有序集时,它必须同时出现在所有通道上。
- 当传输逻辑空闲时,它们必须同时在所有通道上发送。
- 任何违反这些规则的行为都可能作为接收器错误上报至数据链路层。
11.2.4.4 x4 格式示例
图 11-12 展示了通过 x4 链路发送数据包时的格式。示例中先发送一个 TLP,随后在所有通道上传输用于接收器时钟补偿的 SKIP 有序集;接着发送一个 DLLP,最后在所有通道上传输逻辑空闲字符。该示例强调:数据包总长度始终是 4 个字符的整数倍,起始字符出现在通道 0,结束字符出现在通道 3;有序集和逻辑空闲必须同时出现在所有通道上。
图 11-12:x4 数据包格式示例
| 时间顺序 | Lane 0 | Lane 1 | Lane 2 | Lane 3 |
|---|---|---|---|---|
| TLP 起始 | STP | Sequence | TLP | TLP |
| TLP 数据 | TLP | TLP | TLP | TLP |
| TLP 结束 | LCRC | LCRC | LCRC | END |
| SKIP OS | COM | COM | COM | COM |
| SKIP OS | SKP | SKP | SKP | SKP |
| SKIP OS | SKP | SKP | SKP | SKP |
| SKIP OS | SKP | SKP | SKP | SKP |
| DLLP | SDP | DLLP | DLLP | END |
| 逻辑空闲 | Idle(00h) | Idle(00h) | Idle(00h) | Idle(00h) |
11.2.4.5 大链路宽度数据包格式规则
以下规则适用于通过 x8、x12、x16 或 x32 链路传输数据包时:
- 当传输在发送逻辑空闲状态后重新开始时,STP/SDP 字符始终在通道 0 上发送。此后,在连续发送数据包时,这些字符只能发送到通道编号能被 4 整除的通道上(通道 4、8、12 等)。
- END/EDB 字符发送到通道编号能被 4 整除后再减 1 的通道上(如通道 等)。
- 如果数据包未在链路的最后一个通道上结束,且没有更多数据包待发送,则使用 PAD 符号填充剩余通道。逻辑空闲状态不能用于此目的,因为它必须同时出现在所有通道上。
- 所有通道必须同时发送有序集合。
- 同样,使用逻辑空闲时必须将其发送到所有通道。
- 任何违反这些规则的行为都可能作为接收器错误报告给数据链路层。
11.2.4.6 x8 数据包格式示例
图 11-13 展示了通过 x8 链路传输数据包的格式。示例中先发送一个 TLP,随后发送 SKIP 有序集,再发送 DLLP,最后发送一个在 Lane 3 结束的 TLP。此时发送端没有更多数据包待发送,但当前数据包没有占满所有可用通道。多余通道不能使用逻辑空闲填充,因为逻辑空闲必须同时出现在所有通道上。因此规范选择使用 PAD 控制字符填充剩余通道。最后,如果仍无更多数据包要发送,则所有通道同时进入逻辑空闲传输。
图 11-13:x8 数据包格式示例
| 时间顺序 | Lane 0 | Lane 1 | Lane 2 | Lane 3 | Lane 4 | Lane 5 | Lane 6 | Lane 7 |
|---|---|---|---|---|---|---|---|---|
| 逻辑空闲 | Idle | Idle | Idle | Idle | Idle | Idle | Idle | Idle |
| TLP 起始 | STP | Sequence | TLP | TLP | TLP | TLP | TLP | TLP |
| TLP 数据 | TLP | TLP | TLP | TLP | TLP | TLP | TLP | TLP |
| TLP 结束 | LCRC | LCRC | LCRC | LCRC | LCRC | LCRC | END | — |
| SKIP OS | COM | COM | COM | COM | COM | COM | COM | COM |
| SKIP OS | SKP | SKP | SKP | SKP | SKP | SKP | SKP | SKP |
| SKIP OS | SKP | SKP | SKP | SKP | SKP | SKP | SKP | SKP |
| SKIP OS | SKP | SKP | SKP | SKP | SKP | SKP | SKP | SKP |
| DLLP | SDP | DLLP | DLLP | END | — | — | — | — |
| TLP 起始 | STP | Sequence | TLP | TLP | TLP | TLP | TLP | TLP |
| TLP 结束与填充 | LCRC | LCRC | LCRC | END | PAD | PAD | PAD | PAD |
| 逻辑空闲 | Idle | Idle | Idle | Idle | Idle | Idle | Idle | Idle |
11.2.5 加扰器
在我们的示例中,下一步是加扰,如图 11-5(第 369 页)所示,其目的是防止数据流中出现重复模式。重复模式会在链路上产生”纯音”,即由该模式引起的持续频率,从而产生比正常情况更多的噪声或电磁干扰(EMI)。通过将这种能量分散到更宽的频率范围来减少这一问题,是加扰的主要目标。此外,在宽链路上,一条通道上的加扰传输还能减少对相邻通道的干扰。这种”空间频率去相关”(即减少串扰噪声)有助于每条通道上的接收器区分所需信号。
为了帮助接收器保持与加扰序列的同步,控制字符不会被加扰,因此即使加扰器失去同步,这些字符也能被识别。此外,每次 COM 控制字符(K28.5)到达时,都会重新初始化链路两端的加扰器,从而使其重新同步。
11.2.5.1 加扰器算法
规格中描述的扰码器如图 11-14 所示(第 378 页)。它由一个 16 位线性反馈移位寄存器(LFSR)构成,其反馈点实现了以下多项式:
图 11-14:扰码器
该 LFSR 的时钟频率是数据字节输入时钟频率的 8 倍,其输出被时钟同步至一个 8 位寄存器中,并与 8 位数据字符进行异或运算,从而生成加扰后的数据输出。
11.2.5.2 部分加扰器实现规则
- 在多通道链路实现中,每个通道关联的加扰器必须协同工作,保持每个 LFSR 中相同的同步值。
- 加扰仅应用于“D”字符,即与 TLP、DLLP 以及逻辑空闲(00h)字符相关的字符。但 TS1 和 TS2 有序集内的“D”字符不进行加扰。
- 加扰从不应用于“K”字符以及有序集内的字符,例如 TS1、TS2、SKIP、FTS 和电气空闲。这些字符绕过加扰器逻辑。原因之一是为了确保即使加扰器意外失序,接收器仍能识别这些字符。
- 合规性模式字符(用于测试)也不会被加扰。
- COM 字符是一种不会被加扰的控制字符,用于在发送端和接收端将 LFSR 重新初始化为 FFFFh。
- 除 COM 字符外,LFSR 通常会在发送每个 D 或 控制(K)字符时串行前进八次,但在发送与 SKIP 有序集相关的 SKP 字符时不会前进。原因是接收端可能会添加或删除 SKP 符号以进行时钟容差补偿。如果忽略这些符号,接收端字符数量的变化将导致接收端 LFSR 的值与发送端 LFSR 的值失去同步。
11.2.5.3 禁用加扰
默认启用加扰,但规范允许在测试和调试时禁用加扰。这是因为测试可能需要控制发送的确切比特模式,而由于硬件负责处理加扰,软件无法合理强制指定特定模式。规范未定义任何具体的软件机制来指示物理层禁用加扰,因此这必须通过特定设计实现。
若设备禁用了加扰,则需通过发送至少两个 TS1 和 TS2 序列(其控制字段中设置了相应比特位,详见第 539 页”配置状态”章节)将此信息告知相邻设备。作为响应,相邻设备也会禁用其加扰功能。
11.2.6 8b/10b 编码
11.2.6.1 通用
前两代 PCIe 采用 8b/10b 编码。每条通道均配备 8b/10b 编码器,可将 8 位字符转换为 10 位符号。该编码方案由 IBM 于 1984 年获得专利,如今广泛应用于千兆以太网和光纤通道等串行传输技术中。
11.2.6.2 动机
8b/10b 编码在串行传输中实现了几个重要目标,其中最重要的包括以下三点:
- 将时钟嵌入数据中。 8b/10b 编码确保数据流中包含足够多的跳变沿,使接收端能够从数据中恢复时钟,从而不需要像并行总线那样额外分发时钟。这避免了并行总线设计中的飞行时间、时钟偏斜等限制,也避免了分发高频时钟带来的 EMI 增加和布线困难。
以数据字节 00h 为例,图 11-15 展示了其编码结果。原本没有跳变的 8 位字符被转换成一个具有 5 次跳变的 10 位符号。8b/10b 编码保证比特流中的游程长度(连续 1 或连续 0 的数量)在任何情况下都不超过 5 个连续比特。
- 维持直流平衡。 PCIe 采用交流耦合链路,在线路中串联电容,以隔离链路另一端的直流信号分量。这允许发送端和接收端使用不同的共模电压,也使长距离路径中的电气设计更容易。线路在被驱动时会充电,因此共模电压可能在运行过程中发生变化。通常信号变化很快,不会造成明显问题;但如果信号平均值长期偏向某一电平,共模电压就会漂移,这种现象称为 DC Wander,会降低接收端的信号完整性。
为补偿这一现象,8b/10b 编码器会跟踪上一个已发送符号的差异(Disparity)。差异表示前一个符号中 1 和 0 的数量关系:1 多于 0 称为正差异,0 多于 1 称为负差异,1 和 0 数量相等称为中性差异。如果前一个符号具有负差异,则下一个符号应倾向于使用更多的 1 来抵消这种偏差。
- 增强错误检测。 8b/10b 编码也有助于检测传输错误。10 位值共有 1024 种可能编码,而原始字符只有 256 种。为维持直流平衡,许多字符会根据当前运行差异(CRD)选择两种可能编码之一,因此理论上需要约 512 种编码。然而,由于很多中性差异编码的正负版本相同,实际使用的编码数量少于 512。结果是超过一半的 10 位模式不会被合法使用。如果传输错误改变了某个符号的比特模式,它很可能落入这些非法模式之一,从而可被接收端立即识别。更多内容参见“差异”一节。
8b/10b 编码的主要缺点是开销较大:每传输 8 位有效数据,需要在线路上传输 10 位符号。从接收端角度看,实际有效传输性能因此下降 20%。这是不小的代价,但为了获得嵌入时钟、直流平衡和错误检测等优势,仍被认为是可以接受的。
图 11-15:8 位字符 00h 的编码示例
11.2.6.3 10 位符号的特性
根据关于 8b/10b 编码的文献记载,该设计并非严格意义上的 8 位到 10 位转换。实际上,它先进行 5 位到 6 位编码,再进行 3 位到 4 位编码。这些子块属于内部设计,但其存在有助于解释合法符号的某些特性,具体如下所列。不符合这些特性的符号将被视为无效。
- 比特流中永远不会包含超过五个连续的 1 或 0,即使从一个符号的末尾到下一个符号的开头也是如此。
- 每个 10 位符号包含:
- 四个 0 和六个 1(不一定连续),或
- 六个 0 和四个 1(不一定连续),或
- 五个 0 和五个 1(不一定连续)。
- 每个 10 位符号被细分为两个子块:第一个子块宽度为 6 位,第二个子块宽度为 4 位。
- 6 位子块中包含不超过四个 1 或四个 0。
- 4 位子块中包含不超过三个 1 或三个 0。
11.2.6.4 字符符号表示法
8b/10b 使用一种特殊的字符命名简写方式。图 11-16 展示了如何从一个 8 位字符推导出这种简写:
- 将字符划分为 3 位子块和 5 位子块。
- 交换两个子块的位置。
- 将每个子块转换为十进制数。
- 数据字符采用
Dxx.y形式,控制字符采用Kxx.y形式。其中xx是 5 位字段的十进制值,y是 3 位字段的十进制值。
例如,数据字节 6Ah 可以表示为 D10.3。
图 11-16:8b/10b 命名法
11.2.6.5 差异
11.2.6.5.1 定义
差异是指 10 位符号中 1 和 0 数量之间的不平衡,用于帮助维持链路上的直流平衡。包含更多 0 的符号被称为负(-)差异,而包含更多 1 的符号则被称为正(+)差异。当符号中 1 和 0 数量相等时,则称为中性差异。有趣的是,大多数字符编码为具有正或负差异的符号,但有些字符仅编码为具有中性差异的符号。
11.2.6.5.2 CRD(当前运行差异)
CRD 表示链路上当前差异状态的信息。由于它仅是一个比特位,因此只能为正或负,并且在发送下一个符号时并不总是发生变化。要理解其工作原理,需记住下一个被解码的符号可能具有负、中性或正差异,然后考虑以下示例:如果 CRD 为正,则发送一个具有负差异的符号会将其变为负;发送中性差异的符号会保持其为正;而发送正差异的符号则会导致错误,因为 CRD 仅为一个比特位,无法变得更正。
CRD 的初始状态(在任何字符传输之前)在发送方和接收方之间可能不匹配,但事实证明这并不重要。当接收方在训练完成后看到第一个符号时,它会检查是否存在差异错误,如果发现错误,只需更改 CRD。这不会被视为错误,而只是调整 CRD 以匹配接收方和发送方。此后,只有两种合法的 CRD 情况:如果新符号具有中性差异,CRD 可以保持不变;如果新符号具有相反的差异,CRD 可以翻转为相反的极性。不合法的情形是:新符号的差异与 CRD 相同。这种情况将构成差异错误,并且在初始调整之后除非发生错误,否则不应出现。
11.2.6.6 编码过程
实现 8b/10b 编码有多种不同方式。最简单的方法可能是实现一个包含所有可能输出值的查找表。然而,这种表可能需要相对较多的门电路。另一种方法是将解码器实现为逻辑块,这通常是首选方案,因为它通常能产生更小、更经济的解决方案。编码逻辑的具体细节在参考文献中有详细描述,因此我们在此将重点放在其工作原理的整体框架上。
图 11-17(第 384 页)展示了一个 8b/10b 编码的示例框图。新的输出符号基于三个要素生成:输入字符、该字符的 D/K# 指示以及 CRD。根据输出符号计算出新的 CRD 值,并反馈用于下一个字符的编码。编码完成后,生成的符号被送入串行器,由其逐位输出。第 385 页的图 11-18 展示了一些 8b/10b 编码示例,这些示例将有助于后续的案例分析。
图 11-17:8 位到 10 位(8b/10b)编码器
图 11-18:8b/10b 编码示例
11.2.6.7 传输示例
图 11-19 展示了三个字符的编码与传输过程:第一个和第二个为控制字符 K28.5,第三个为数据字符 D10.3。
在此示例中,初始 CRD 为负值,因此 K28.5 编码为 001111 1010b。该符号具有正极性(1 的数量多于 0),导致 CRD 极性翻转为正。下一个 K28.5 编码为 1100000101b,具有负极性,此次使 CRD 翻转为负。最后,D10.3 编码为 010101 1100b。由于其极性为中性,CRD 在此情况下保持不变,仍为负值,以用于下一个字符。
在以下示例中使用这两个字符:
图 11-19:示例 8b/10b 传输
| D/K# | 十六进制 字节 | 二进制位 HGF EDCBA | 字节 名称 | CRD -abcdei fghj | CRD + abcdei fghj |
|---|---|---|---|---|---|
| 控制 (K) | BC | 10111100 | K28.5 | 0011111010 | 1100000101 |
| 数据 (D) | 6A | 01101010 | D10.3 | 0101011100 | 0101010011 |
表 16:示例传输
| CRD | 字符 | CRD | 字符 | CRD | 字符 | CRD | |
|---|---|---|---|---|---|---|---|
| 待传输的字符 | - | K28.5 (BCh) | + | K28.5 (BCh) | D10.3 (6Ah) | - | |
| 传输的比特流 | 产生 0011111010 CRD 为 + | 产生 1100000101 CRD 为 - | 产生 0101011100 CRD 为中性 |
CRD 的初始值无关紧要。接收方可根据输入比特流确定。
11.2.6.8 控制字符
8b/10b 编码为链路管理提供了若干特殊控制字符。表 11-1 展示了这些控制字符及其用途。
表 11-1:控制字符编码与定义
| 字符名称 | 8b/10b 名称 | 描述 |
|---|---|---|
| COM | K28.5 | 任意有序集中的第一个字符;接收端在训练期间也利用它实现符号锁定。 |
| PAD | K23.7 | 数据包填充字符。 |
| SKP | K28.0 | SKIP 有序集中的可丢弃字符,用于时钟容差补偿。 |
| STP | K27.7 | TLP 起始字符。 |
| SDP | K28.2 | DLLP 起始字符。 |
| END | K29.7 | 有效数据包结束字符。 |
| EDB | K30.7 | 无效或被“作废”的 TLP 结束字符。 |
| FTS | K28.1 | 快速训练序列字符,用于从 L0s 低功耗状态退出至 L0。 |
| IDL | K28.3 | 电气空闲有序集的一部分,用于指示链路即将进入电气空闲。 |
| EIE | K28.7 | 电气空闲退出有序集的一部分,在高于 2.5 GT/s 的速率下用于退出电气空闲。 |
- COM(Comma,逗号):主要作为有序集的首个符号。COM
的两种 10
位编码都很容易被接收端识别:它们以两个相同极性的比特开头,随后紧跟五个相反极性的比特(
0011111010b或1100000101b)。这一特性在初始训练阶段非常有用,可帮助接收端锁定传入的符号流。 - PAD:在多通道链路上,如果待发送的数据包没有覆盖所有可用通道,且没有更多数据包待发送,则使用 PA数据(D)字符填充剩余通道。
- SKP:作为 SKIP 有序集的一部分,用于实现时钟容差补偿。
- STP / SDP:分别用于标识 TLP 和 DLLP 的起始位置。
- END:用于标识无错误的 TLP 或 DLLP 的结束。
- EDB:用于标识转发设备希望作废的 TLP 的结束。例如,采用直通转发的交换机可能在尚未完整缓存并校验整个数据包之前就已经开始转发部分数据;若转发过程中检测到错误,则必须作废已发往目标的数据包。作废方式是以 EDB 结束数据包,并将 LCRC 反转为错误值。接收端检测到作废数据包后会直接丢弃,不返回 ACK 或 NAK。
- FTS:快速训练序列的一部分,用于将链路从 L0s 待机状态恢复至完全活动的 L0 状态。
- IDL:电气空闲有序集的一部分,用于通知接收端链路正在进入低功耗状态。
- EIE:PCIe 2.0 新增,用于帮助处于电气空闲状态的链路开始唤醒过程。
11.2.6.9 有序集
11.2.6.9.1 概述
有序集用于链路伙伴物理层之间的通信,可视为通道管理数据包。根据定义,它们是一系列不属于 TLP 或 DLLP 的字符。对于 Gen1 和 Gen2 而言,有序集始终以 COM 字符开头。由于每个通道在技术上都是独立的串行路径,因此有序集会在所有通道上同时复制。这还允许接收端验证对齐和去偏移。有序集用于链路训练、时钟容差补偿以及更改链路电源状态等场景。
11.2.6.9.2 TS1 和 TS2 有序集(TS1OS/TS2OS)
训练序列一和训练序列二用于链路初始化和训练。它们使链路双方能够实现位锁定和符号锁定,协商链路速度,并报告与链路操作相关的其他变量。这些内容在第 510 页“TS1 和 TS2 有序集”一节中有更详细的描述。
11.2.6.9.3 电气空闲有序集(EIOS)
希望进入低功耗链路状态的发送端在停止传输前发送此有序集。接收端收到后,会知道准备进入低功耗状态。EIOS 由四个符号组成:一个 COM 符号后跟三个 IDL 符号。接收端检测到此有序集后,会通过忽略输入错误来准备链路进入电气空闲状态,直到退出电气空闲状态。发送端在发送 EIOS 后不久,会将其差分电压降至低于 20 mV 峰值。
11.2.6.9.4 FTS 有序集(FTSOS)
发送端发送适当数量的 FTS(最小数量由链路邻居在训练期间提供),以将链路从低功耗 L0s 状态恢复到完全运行的 L0 状态。接收端检测到 FTS 后,识别出链路正在退出电气空闲状态,并利用这些符号恢复比特锁和符号锁。FTS 有序集由四个符号组成:一个 COM 符号后跟三个 FTS 符号。
11.2.6.9.5 SKP 有序集(SOS)
该有序集由四个符号组成:一个 COM 符号后跟三个 SKP 符号。它以固定间隔传输,用于时钟容差补偿,具体描述见第 391 页的”时钟补偿”和第 396 页的”接收器时钟补偿逻辑”。本质上,接收器会评估 SOS 并根据需要在内部添加或删除 SKP 符号,以防止其弹性缓冲器出现下溢或上溢。
11.2.6.9.6 电气空闲退出有序集(EIEOS)
该有序集在 PCIe 2.0 规范中新增,定义为提供退出电气空闲链路状态所需的低频序列。对于采用 8b/10b 编码的 EIEOS,通过重复使用 K28.7 控制字符,呈现为 5 个 1 后跟 5 个 0 的重复字符串。这种低频字符串产生的低频信号具有更高的信号电压,更易于在接收端被检测到。事实上,规范明确指出该模式能确保接收器正确检测到电气空闲退出,这是加扰数据无法实现的。关于电气空闲退出的详细信息,请参阅第 736 页的”电气空闲”章节。
11.2.7 串行器
每个通道上的 8b/10b 编码器将数据送入串行器,该串行器按位顺序输出符号(参见第 384 页图 11-17),最低有效位(a)最先移出,最高有效位(j)最后移出。每个通道的符号将以 250 MHz 或 500 MHz 的频率提供给串行器,以支持比 2.5 GHz 或 5.0 GHz 快 10 倍的串行比特率。
11.2.8 差分驱动器
实际将比特流发送到线路上的差分驱动器采用 NRZ 编码。NRZ 编码意味着不使用特殊或中间电压电平。差分信号技术可提升信号完整性,支持更高频率和更低电压。关于驱动器电气特性的详细信息,请参见第 462 页”发送器电压”章节。
11.2.9 发送时钟(Tx Clock)
每个通道的串行输出由 Tx 时钟信号控制。如前所述,时钟频率必须精确控制在中心频率 ±300 ppm 的范围内(总偏差 600 ppm)。该时钟源有两种选择:可由内部生成,或从可选的外部参考时钟导出。针对外围卡件的 PCIe 规范包含系统板为此提供的 100 MHz 参考时钟定义。该参考时钟通过内部倍频生成驱动内部逻辑的本地时钟,以及串行器使用的 Tx 时钟。
11.2.10 其他发送相关主题
11.2.10.1 逻辑空闲
为了防止接收端的 PLL 发生漂移,在没有 TLP、DLLP 或有序集需要传输的时段内,必须发送某些内容。此时,逻辑空闲字符会被注入到字符流中。逻辑空闲字符具有以下特性:
- 它是一个值为 00h 的 8 位数据字符。
- 发送时,该字符会在所有通道上同时传输,此时链路处于逻辑空闲状态(请注意不要与电气空闲状态混淆——后者是指输出驱动器完全停止发送,导致接收端 PLL 失去同步的状态)。
- 逻辑空闲字符是乱序的,但接收器可以将其与其他数据区分开来,因为它出现在数据包帧上下文之外(即:在 END 或 EDB 之后,但在 STP 或 SDP 之前)。
- 它采用 8b/10b 编码。
- 在逻辑空闲传输期间,SKIP 有序集仍会定期发送。
11.2.10.2 发送信号偏移
发送端应尽量减小各通道之间引入的偏移,以便为 PCB
布线和其他变化留出尽可能多的接收端偏移预算。规范列出的发送端偏移要求为:Gen1
为 500 ps + 2 UI,Gen2 为
500 ps + 4 UI,Gen3 为
500 ps + 6 UI。其中 UI(Unit
Interval,单位间隔)表示链路上的一个比特时间。换算结果如表 11-2
所示。
表 11-2:允许的发送端信号偏移
| 规范版本 | 允许的发送端偏移 |
|---|---|
| Gen1 | 1300 ps |
| Gen2 | 1300 ps |
| Gen3 | 1250 ps |
11.2.10.3 时钟补偿
11.2.10.3.1 背景
像 PCIe 这样的高速串行传输需要解决一个特定的时钟问题。接收器从传入的比特流中恢复时钟,并用它来锁存数据位,但这个恢复的时钟与接收器内部时钟不同步,最终必须开始使用其内部时钟来同步数据。即使它们有一个可选的外部参考时钟,最多也只能在指定频率容差范围内生成内部时钟。因此,其中一个时钟几乎总是比另一个略快。如果发送器时钟更快,数据包到达的速度将超过接收处理的速度。为了补偿,发送器必须在比特流中注入一些“可丢弃字符”,以便在必要时接收器可以丢弃它们,避免缓冲区溢出。对于 PCIe,这些可删除字符采用 SKIP 有序集的形式,该有序集由一个 COM 字符后跟三个 SKP 字符组成(见图 11-20)。有关此主题的更多详细信息,请参阅第 396 页的“接收器时钟补偿逻辑”。
11.2.10.3.2 SKIP 有序集插入规则
发送器需要定期发送 SKIP 有序集,并遵循以下规则:
- SKIP 有序集必须在 1180 到 1538 个符号时间之间调度插入(一个符号时间是发送一个符号所需的时间,相当于 10 个比特时间,因此在 2.5 GT/s 速率下,一个符号时间为 4 ns;在 5.0 GT/s 速率下,一个符号时间为 2 ns)。
- 它们只能在数据包边界处插入(不允许中断正在传输的数据包),并且必须在所有通道上同时发送。如果数据包正在传输中,SKP 有序集必须等待。然而,最大可能的数据包大小需要超过 4096 个符号时间,在此期间本应发送多个 SKIP 有序集。 这种情况通过累积本应发送的 SKIP 有序集,并在下一个数据包边界处一次性全部注入来处理。
- 由于该有序集必须在所有通道上同时传输,多通道链路可能需要在某些通道上添加 PA数据(D)字符,以使有序集能够在所有通道上同时传输(参见第 377 页图 11-13)。
- 在低功耗链路状态下,用于调度 SKIP 有序集的任何计数器都必须重置。当发送器未发送信号时,这些计数器无需工作,且唤醒链路来发送它们也没有意义。
- 在合规模式进行期间,不得传输 SKIP 有序集。
图 11-20:SKIP 有序集
11.3 接收逻辑细节(仅限 Gen1 和 Gen2)
图 11-21 展示了逻辑物理层的接收端逻辑。本节描述了从数据在每个通道上串行接收开始,直到数据包字节流被时钟同步进入数据链路层为止的数据包处理过程。
图 11-21:物理层接收逻辑详情(仅限 Gen1 和 Gen2)
11.3.1 差分接收器
接收端逻辑的第一部分如图 11-22 所示,包括每条通道的差分输入缓冲器。该缓冲器检测峰峰值电压差,并判断该差值代表逻辑 1 还是逻辑 0。
有关接收器特性的详细讨论,请参见第 492 页的“接收器特性”部分。
图 11-22:每条通道的接收端逻辑前端
11.3.2 接收时钟恢复
11.3.2.1 通用
接下来,接收器利用输入数据流中的比特跳变生成接收时钟(Rx Clock),通常通过锁相环(PLL)实现。该恢复时钟的频率(2.5 或 5.0 GHz)与用于将比特流传输到线路上的发送时钟(Tx Clock)相同。接收时钟用于将输入比特流时钟同步到解串器中。解串器必须与 10 比特符号边界对齐(这一过程称为实现符号锁定),随后其符号流输出通过一个除以 10 后的接收时钟版本时钟同步到弹性缓冲器中。尽管两者都必须精确到中心频率的 以内,但接收时钟可能与本地时钟略有差异,若如此,则需要进行补偿。
11.3.2.2 实现比特锁定
回顾一下,8b/10b 编码方案保证了入站串行符号流中会频繁出现电平跳变。接收端锁相环利用这些跳变生成与发送端时钟同步的接收时钟——发送端时钟原本用于将比特流从发射器输出。当接收器锁定发送时钟频率时,即视为实现了”位锁定”。
在链路训练过程中,发送器会向接收器发送一长串 TS1 和 TS2 有序集,接收器利用其中的比特跳变实现位锁定。正常运行时链路上存在足够的跳变,使接收器能够在此后维持位锁定状态。
11.3.2.3 位锁定丢失
若链路进入低功耗状态(如 L0s 或 L1),此时数据包传输停止,接收器将失去同步。为避免错误电路将此视为异常,发送器在进入低功耗状态前会发送电气空闲有序集(EIOS),通知接收器关闭其输入门控。
11.3.2.4 重新获取位锁定
当发送端准备将链路从 L0s 状态唤醒时,会发送特定数量的 FTS 有序集(实际数量由设计决定),接收端利用这些有序集重新获取位锁定和符号锁定。恢复过程只需相对较少的 FTS,因此恢复延迟较短。由于链路在 L0s 状态停留时间较短,接收端 PLL 在开始接收 FTS 之前通常不会与发送时钟产生过大偏差。若链路处于 L1 低功耗状态,发送端则会开始发送 TS1OSs。这将导致链路重新训练,且唤醒时间比 L0s 唤醒时间更长。若链路出现更严重错误,且 Ack/Nak 机制在四次重试 TLP 后仍无法成功恢复错误,数据链路层将通知物理层重新训练链路。在此过程中,位锁定将在重新训练期间重新建立。
11.3.3 解串器
11.3.3.1 通用
输入数据通过 Rx 时钟被锁存到每个通道的解串器(串并转换器)中(参见第 394 页图 11-22)。产生的 10 位符号通过 Rx 时钟的十分频版本被锁存到弹性缓冲器中。
11.3.3.2 实现符号锁定
当接收逻辑开始接收比特流时,它只是一堆无序的比特(JABOB),没有任何标记来区分符号或边界。接收逻辑必须找到一种方法来定位 10 位符号的起始和结束位置,而逗号(COM)符号正是为此目的而设计的。
COM 符号的 10 位编码包含两个相同极性的比特,随后是五个相反极性的比特(0011111010b 或 1100000101b),使其易于检测。需要注意的是,COM 控制字符与其他所有控制字符一样,不会被发送器加扰,这确保了接收端能够看到预期的序列。一旦检测到 COM,逻辑就知道下一个接收到的比特将是下一个 10 位符号的第一个比特。此时,解串器被认为已实现”符号锁定”。
COM 符号用于实现符号锁定,具体方式如下:
- 在链路首次建立或需要重新训练时,链路训练期间会传输 TS1 和 TS2 有序集。
- 当发送 FTS 有序集以通知接收器将链路状态从 L0s 切换至 L0 时。
11.3.4 接收器时钟补偿逻辑
11.3.4.1 背景
前文已经提到,链路两端发送器和接收器使用的时钟不要求完全同频。当链路不使用公共参考时钟时,某一端时钟可能略快于另一端。规范要求两端时钟都必须位于中心频率的 ±300 ppm 范围内;最坏情况下,一端为 +300 ppm,另一端为 -300 ppm,两者之间的最大差异可达 600 ppm。这相当于每约 1666 个符号时钟就会产生 1 个符号时钟的增益或损失。
链路训练完成后,接收器中的接收时钟(Rx Clock)与链路另一端的发送时钟(Tx Clock)保持一致,因为接收时钟是从输入比特流中恢复出来的。但该恢复时钟仍可能与接收器本地时钟存在细微差异,因此需要时钟补偿机制。
11.3.4.2 弹性缓冲区的作用
为补偿最坏情况下的频率差异,接收路径中内置了弹性缓冲器(Elastic Buffer)。接收到的符号使用恢复时钟写入缓冲器,再使用接收器本地时钟读出。弹性缓冲器通过添加或删除 SKP 符号来补偿频率差异。
当 SKIP 有序集到达时,监控弹性缓冲器状态的逻辑会进行判断。如果本地时钟运行较快,符号读出速度将快于写入速度,缓冲器将接近下溢;此时逻辑会在该有序集中额外添加一个 SKP 符号,以快速补充缓冲器。反之,如果恢复时钟运行较快,缓冲器将接近上溢;此时逻辑会删除一个 SKP 符号,以快速释放缓冲器空间。这些操作可以弥补符号到达速率与消耗速率之间的差异,防止数据混淆或丢失。
发送器会定期发送 SKIP 有序集来实现这一目的。顾名思义,SKP 字符本质上是可丢弃字符。删除或添加 SKP 符号可防止弹性缓冲器上溢或下溢,随后这些符号会与其他控制字符一起在转发至下一层前被丢弃。因此,它们只占用少量带宽,不会影响数据包的传输流程。
弹性缓冲器上溢或下溢导致的符号丢失属于错误状态,但接收端是否检查此类情况是可选的。如果接收端实现了该检查并检测到此情况,则会向数据链路层报告接收器错误。
发送器每 1180 到 1538 个符号时间调度一次 SKIP
有序集传输。然而,如果发送器刚好在 1538
个符号时间边界处开始传输最大尺寸 TLP,原本计划发送的 SKIP
有序集就会被延迟。因此,接收器必须能够容忍两个 SKIP
有序集之间的最大间隔,该间隔取决于设备支持的最大数据包有效载荷大小。两个
SKIP 有序集之间允许的最大符号数 n 为:
n = 1538 + (Maximum_Payload_Size + 28)
其中 28 表示 TLP 开销,包括最大报头 16 字节、可选 ECRC 4 字节、LCRC 4 字节、序列号 2 字节,以及帧定界符 STP 和 END 共 2 字节。
11.3.5 通道间偏移
11.3.5.1 各通道间的飞行时间会有所不同
对于宽链路,通道间的偏移是一个无法避免的问题,必须在接收端进行补偿。符号通过相同的发送时钟在所有通道上同时发送,但不能期望它们在同一时刻精确到达接收端。通道间偏移的来源包括:
- 电气驱动器和接收器之间的差异
- 印刷电路板阻抗变化
- 走线长度不匹配
当携带数据包的串行比特流到达接收端时,必须消除这种通道间偏移,才能按正确顺序接收字节。此过程称为链路去偏移。
11.3.5.2 有序集助力去偏移
有序集的独特结构及其在所有通道上同时发送的特性,使其可用于检测通道间的时序偏差。规范并未定义具体实现方法,但在 Gen1 和 Gen2 中,接收端逻辑只需在每个通道上查找 COM 字符即可。若该字符未在所有通道上同时出现,则对提前到达的 COM 字符进行延迟处理,直至所有通道的 COM 字符对齐。
11.3.5.3 接收端通道间去偏移能力
通道间去偏移可以通过调整输入信号上的模拟延迟线实现;也可以在弹性缓冲器之后完成。后一种方式的优势是,到达时间差已经被接收器本地时钟数字化为符号时间。如果某个通道的输入在某个时钟边沿到达,而另一个通道尚未到达,则早到达的 COM 只需延迟适当数量的符号时钟周期,即可与晚到达的 COM 对齐。
接收端允许的最大偏移是符号时钟周期的整数倍,这表明规范制定者可能考虑过类似实现方式。允许值见表 11-3。
表 11-3:允许的接收端信号偏移
| 规范版本 | 允许的接收端偏移 |
|---|---|
| Gen1 | 20 ns(5 个符号时钟,每个符号 4 ns) |
| Gen2 | 8 ns(4 个符号时钟,每个符号 2 ns) |
| Gen3 | 6 ns(约 4 个符号时钟,每个符号 1.25 ns) |
在 Gen3 模式下,没有可用于去偏移的 COM 字符,但检测有序集仍可以提供所需的时间对齐信息。
11.3.5.4 去偏移机会
所有通道上需要同时存在一个明确的模式来执行去偏移,任何有序集都可以满足这一要求。链路训练会发送这些有序集,但在正常链路运行期间,SKIP 有序集会被定期发送。通过检查其到达时间,可以持续监测歪斜情况,以防因温度或电压变化而改变。如果歪斜确实发生变化,链路需要转换到 Recovery LTSSM 状态进行纠正。然而,如果这种情况发生在数据包传输过程中,可能会引发接收器错误,导致数据包丢失,进而可能触发 TLP 重传。
图 11-23:接收器的链路去偏移逻辑
11.3.6 8b/10b 解码器
11.3.6.1 通用
PCIe 的前两代使用 8b/10b,而 Gen3 则不再使用。我们先探讨其工作原理,再考虑 Gen3 的差异。请参考第 401 页的图 11-24。每个接收通道都包含一个 10b/8b 解码器,其输入来自弹性缓冲器。该解码器配备了两个查找表(D 表和 K 表),用于将 10 位符号流解码为 8 位字符以及 D/K# 信号。D/K# 信号的状态表示:如果在 D 表中找到匹配的接收符号,则接收到的符号为数据(D)字符;如果在 K 表中找到匹配的接收符号,则为控制(K)字符。
11.3.6.2 极性计算器
解码器根据接收到的第一个符号的极性来设置极性值。在第一个符号之后,一旦实现符号锁定并初始化极性,后续每个符号的极性计算都应遵循相应规则。若不符合规则,则会报告接收器错误。
11.3.6.3 代码违规与差异错误检测
11.3.6.3.1 概述
解码器的错误检测逻辑可检测接收到的符号流中的非法符号。部分错误检查在接收端为可选操作,但规范要求必须对这些错误进行检查并作为接收器错误进行报告。检测到的错误分为两类:
11.3.6.3.2 代码违规
- 任何包含超过四个 1 或四个 0 的 6 位子块均视为错误。
- 任何包含超过三个 1 或三个 0 的 4 位子块均为错误。
- 任何包含超过六个 1 或六个 0 的 10 位符号均为错误。
- 任何包含超过五个连续 1 或五个连续 0 的 10 位符号均为错误。
- 任何无法解码为 8 位字符的 10 位符号均为错误。
11.3.6.3.3 差异错误
在接收端,符号的差异必须与当前 CRD(当前运行差异)所要求的数值相匹配,否则将检测到差异错误。某些差异错误可能直到处理后续符号时才能被发现。
(参见第 401 页图 11-25)。例如,如果一个符号中的两个比特位因错误而翻转,该错误可能不可见,且该符号可能被解码为有效的 8 位字符。此类错误将无法在物理层中被检测到。
图 11-24:每通道 8b/10b 解码器
图 11-25:延迟差异错误检测示例
| CRD | 字符 | CRD | 字符 | CRD | 字符 | CRD | |
|---|---|---|---|---|---|---|---|
| 传输的字符流 | - | D21.1 | - | D10.2 | - | D23.5 | + |
| 传输的比特流 | - | 1010101001 | - | 0101010101 | - | 1110101010 | + |
| 经过错误处理后的比特流 | - | 1010101011 ↑ | + | 0101010101 | + | 1110101010 | + |
| 解码后的字符流 | - | D21.0 | + | D10.2 | + | 无效 ↑ | + |
| 此处发生错误 此处检测到错误 |
11.3.7 解扰器(Descrambler)
解扰器由 8b/10b 解码器提供输入。它仅对与 TLP 或 DLLP 关联的数据(D)字符进行解扰(D/K# 为高电平)。它不解扰控制(K)字符或有序集,因为这些字符在发送端未被加扰。
11.3.7.1 部分解扰器实现规则
- 在多通道链路上,每个通道关联的解扰器必须协同工作,在所有 LFSR 中保持相同的同步值。
- 解扰操作应用于与 TLP 和 DLLP 关联的“D”字符,包括逻辑空闲(00h)序列。有序集内的“D”字符不被解扰。
- “K”字符和有序集字符绕过解扰器逻辑。
- 合规模式字符不会被解扰。
- 当 COM 字符进入解扰器时,它会将 LFSR 值重新初始化为 FFFFh。
- 除一种例外情况外,每接收一个字符(数据(D)字符或 控制(K)字符),LFSR 都会串行前进八次。LFSR 不会在与接收到的 SKIP 有序集相关的 SKP 字符上推进。LFSR 在检测到 SKP 时不推进的原因在于,传输的 SKP 字符数量与从弹性缓冲区输出的 SKP 字符数量可能存在差异(如第 396 页”接收器时钟补偿逻辑”所述)。
11.3.7.2 禁用解扰
默认情况下,解扰功能始终处于启用状态,但规范允许在测试和调试时禁用它,不过并未提供标准的软件禁用方法。如果解扰器在其所有配置通道上接收到至少两个设置了”禁用解扰”位的 TS1/TS2 有序集,则会禁用解扰器。
11.3.8 字节去条带化
第 403 页的图 11-26 展示了来自 x8 链路解扰器的八个字符流被去条带化为单个字节流,该字节流随后被送入字符过滤逻辑。
图 11-26:x8 字节解条带化示例
11.3.9 过滤与数据包对齐检查
由字节解条带化逻辑提供的串行字节流包含 TLP、DLLP、逻辑空闲序列、STP/SDP/END/EDB/PAD 等控制字符以及有序集。其中,逻辑空闲序列、控制字符和有序集在到达下一层之前被检测并消除。剩余的是 TLP 和 DLLP,这些数据连同每个数据包起始和结束的指示符一起被发送至接收缓冲区。
11.3.10 接收缓冲区(Rx Buffer)
Rx 缓冲区在去除起始和结束字符后,保存接收到的 TLP 和 DLLP。这些接收到的数据包已准备好发送至数据链路层。由于规范中未描述与数据链路层的接口,设计者可自由决定数据总线宽度等细节。例如,我们可以 假设接口时钟为 250 MHz,链路采用 Gen1 速率。在此情况下,这些层之间数据总线上的字节数将与支持的通道数相同。
11.4 物理层错误处理
11.4.1 通用
物理层错误会作为接收器错误上报给数据链路层。根据规范,部分错误必须被检查并触发接收器错误,而其他错误则是可选的。
必须进行的错误检查:
- 8b/10b 解码错误:差异错误、非法符号
可选的错误检查:
- 符号锁定丢失(参见第 396 页“实现符号锁定”)
- 弹性缓冲器上溢或下溢
- 通道去偏斜错误(参见第 398 页“通道间偏斜”)
- 数据包不符合格式规则
11.4.2 数据链路层对接收器错误的响应
如果物理层向数据链路层指示接收器错误,数据链路层将丢弃当前正在接收的 TLP,并释放为该 TLP 分配的所有存储空间。随后,它会调度一个 NAK 返回给该 TLP 的发送端。这将导致发送端从重放缓冲区重新发送 TLP,从而自动纠正错误。数据链路层还可能指示物理层启动链路重新训练。
如果实现了 PCI Express 扩展高级错误能力寄存器集,接收器错误会在可纠正错误状态寄存器中设置接收器错误状态位。如果已启用,设备可以向根复合体发送 ERR_COR(可纠正错误)消息。
11.5 活动状态电源管理
在某些条件下,存在多种链路电源状态以实现节能。这些状态包括 L0s、L1、L2 和 L3,分别代表逐渐降低的功耗以及将链路恢复到完全运行状态 L0 所需的更长恢复时间。L0s 状态只能在硬件控制下进入,而 L1 可由硬件或软件发起。由于 L0s 和 L1 可由硬件控制,规范将其统称为 ASPM(活动状态电源管理)状态。有关链路和设备电源管理的更多详细信息,请参见第 735 页的“活动状态电源管理(ASPM)”部分。
11.6 链路训练与初始化
正如本章中简要提及的,物理层还负责在复位后初始化链路。然而,该主题内容过于庞大,无法在此详述,而是涵盖在第 505 页的第 14 章“链路初始化与训练”中。