UCIe Spec v3.0 (3):Die-to-Die Adapter(适配层)

3 Die-to-Die Adapter(适配层)

(本文版权归作者所有,任何形式的转载都请注明出处)

如 Figure 3-1 所示,

  • 适配层主要的功能可以总结为:
    • 保证数据传输可靠性
    • 多协议层复用时仲裁
    • 链路状态管理
    • 协议/参数协商
  • 适配层属于“中间层”,上下游接口分别为:
    • Flit aware D2D interface(FDI),适配层与协议层的接口。
    • Raw D2D interface(RDI),适配层与物理层的接口。

在这里插入图片描述

  适配层和协议层一样,都要遵守互用性规则。支持多协议栈复用,考虑效率和实现代价,允许多协议栈复用一条物理 FDI 链路。如 Figure 3-2 所示的几种配置举例,(a)单协议栈;(b)单 CXL 协议栈,CXL.ioCXL.cachemem 通过 ARB/MUX 复用;(c)两个 CXL 协议栈通过 Stack MUX 复用;(d)Enhanced Multi_Protocol_Enable 协商成功的情况下,两个不同协议栈复用。

在这里插入图片描述

3.1 Stack Multiplexing(协议栈复用)

  若参数 Multi_Protocol_Enable 协商成功,则支持两个协议栈复用同一条物理链路,条件是每个协议栈所需的带宽仅为物理层提供带宽的一半。两个协议栈必须为相同协议,且具有相同的协议能力,即两个协议栈必须完全对称。这种对称限制包括 Multi_Protocol_Enable + MTP 在 Mainband 协商成功的情况,包括 Management Port Gateway multiplexer(MPG mux)也要在两个协议栈分别例化。如 Figure 8-35(b) 所示,若 Stack 0 = PCIe + MTP,则不允许 Stack 1 = Streaming + MTP;Figure 8-35(d) 同理。其中,MTP 不占用独立的协议栈,而是与主协议复用同一个栈,例如 Stack 0 = PCIe + MTP,MTP 和 PCIe 共享相同的 Stack ID。Stack ID 为 1bit,即只支持两个协议栈复用。

  两个复用的协议栈,分别维护两个独立的链路状态机,每个栈处理各自的 Sideband 消息,各自独立的完成状态转换。

Note:

  • Multi_Protocol_Enable 与 Raw Format 互斥。Raw Format 要求 Adapter 完全透传,Multi_Protocol_Enable 需要 Adapter 修改部分字段,如 Stack ID。

  Multi_Protocol_Enable 的另一个核心限制是:Adapter 必须保证不会在链路上连续发送来自同一协议栈的 Flit !!! 这个限制覆盖所有 case,包括 FDI 上传输的 Flit、发生 Retry 时来自 Retry Buffer 的 Flit、以及暂停后恢复的数据流。那么,如何做到呢?—— 插入 NOP。NOP Flit 为全 0 的包,无任何意义,只用于占位,接收方收到后直接丢弃,不能透传到协议层。当两个栈都有 Flit 发送,Adapter 按 Stack 0 -> Stack 1 -> Stack 0 -> Stack 1 … 交替仲裁发送;若只有一个栈有 Flit 发送,需要插入 NOP 保证其不连续,即 Stack 0 -> NOP -> Stack 0 -> NOP …

Note:

  • Multi_Protocol_Enable 限制颇多,既要两个协议栈完全对称;又限制不能连续发送,插入 NOP 浪费带宽,传输效率低下。那么其适用场景或设计初衷是什么?—— 核心逻辑是用高带宽物理链路去带多个低带宽协议栈,例如两个 CXL 68B Flit Mode 协议层(每个等效 32 GT/s SERDES 带宽),复用到一条能承载其聚合带宽的 UCIe 链路,而协议层逻辑不需要改动,只是 Adapter 多了 Flit 粒度的交错发送逻辑。Multi_Protocol_Enable 满足了兼容性的同时,提供了最小改动成本的方案。

  Enhanced Multi_Protocol_Enable 允许非对称协议栈复用。MTP 场景下,两栈可以是不同的协议,允许有或没有 MPG mux,如 Figure 8-35(e)(f)(h) 所示。前提是,两个不同的栈必须支持至少一种共用的 Flit Format。

Note:

  • Enhanced Multi_Protocol_Enable 与 Raw Format 互斥,理由同上。

  Enhanced Multi_Protocol_Enable 支持动态分配带宽。当只有一个栈需要传输 Flit 时(无竞争),单个栈可以占用 100% 带宽;当两个栈都有 Flit 传输时,Adapter 需要仲裁,基本的轮询仲裁策略意味着两栈各占 50% 带宽(允许更灵活的仲裁策略)。若某个协议栈的能力,最多只能消化一半带宽,则 Enhanced Multi_Protocol_Enable 支持对特定的栈节流,而另一个栈不节流,依然通过插入 NOP 实现。

  Enhanced Multi_Protocol_Enable 同 Multi_Protocol_Enable,两栈的链路状态机相互独立,互不影响。

  对比一下 Multi_Protocol_Enable VS Enhanced Multi_Protocol_Enable

Multi_Protocol_EnableEnhanced Multi_Protocol_Enable
协议必须相同可以不同
格式完全对称,必然同格式必须支持至少一种共同格式
带宽分配每个栈强制限制为 50% 带宽带宽能力通告 + 动态分配带宽 + 节流
仲裁方式插入 NOP 保证同栈 Flit 不连续两栈 Flit 公平仲裁
链路状态机两栈独立维护两栈独立维护
协议互斥不支持 Raw Format不支持 Raw Format

在这里插入图片描述

3.2 Link Initialization(链路初始化)

  Flit 能在 Mainband 上传输之前,需要经过链路初始化。Figure 3-3 展示了链路初始化的过程,共分为 4 个阶段:① stage 0,两 Die 独立执行复位,无需链路两侧交互,复位无需同时完成;② stage 1 发生在物理层,Sideband 初始化,两 Die 建立 Sideband 通信通道;③ stage 2 发生在物理层,Mainband 训练,通过 Sideband 协商数据最大传输速率;④ stage 3 由 Adapter 主导,两侧 Die 通过 Sideband 交换协商参数。stage 3 完成后,通告协议层,可以开始 Flit 传输。

  链路初始化需要“从底层到顶层”依次执行,stage 0 上电复位后,stage 1~2 先建好物理层,stage 3 再经过 Adapter 协商完成后,才能允许 Flit 正常传输。Sideband 是后续链路训练的控制通道,必须先建立 Sideband;stage 2 通过 Sideband 协商好数据最大传输速率,作为后续 Adapter 协商协议与传输格式的依据,此时物理层已建立好;stage 3 阶段协商好协议、格式、是否支持 Retry 等,Adapter 将协商结果通过 FDI 告知协议层,整个链路初始化完成。

在这里插入图片描述

3.2.1 Stage 3 of Link Initialization: Adapter Initialization(链路初始化 stage 3:Adapter 初始化)

  stage 2 完成后,会将 RDI 链路状态变为 Active。stage 3 中,Adapter 完成一系列的参数协商后,会将 FDI 链路状态变为 Active。

3.2.1.1 Part 1: Determine Local Capabilities(Part 1:确定 local die 的能力)

  在和对 Die 协商之前,需要先确定本地的基本信息,包括:“物理层是否已成功建链?” “物理层协商的数据传输速率是多少?” “当前配置和速率是否需要 Retry?”

  对于 Retimer,还需要额外确定 Retimer Rx Buffer 所需的 Credit 数量。

3.2.1.2 Part 2: Parameter Exchange with Remote Link Partner(Part 2:与 remote die 交换参数)

  如 Table 3-1 所示,给出了 Adapter 需要协商的能力参数一览表。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  本地能力确认之后,Adapter 通过发送 {AdvCap.*} Sideband 消息,来向对 Die 通告能力。协商的两者分为 Upstream Port(UP)和 Downstream Port(DP),DP 是双方握手协商的发起者,也是最终决策者。

  如 Figure 3-4 所示,DP/UP 握手流程有以下 3 步:

  • step 1:DP 先发出 {AdvCap.*},通告自己的能力;
  • step 2:UP 收到后,根据 DP 能力,调整自己的通告,返回 {AdvCap.*}
  • step 3:DP 根据双方通告的能力,决策出最终能力,发出 {FinCap.*}

Note:

  • 怎么理解 DP/UP 以握手形式协商?—— DP 是发起方,UP 是响应方,协商参数是取两者通告能力的“交集”。不需要给出能力的“全集”,而是需要 UP 根据 DP 通告能力进行调整,再由 DP 最终决策。

  如果双方通告支持 PCIe 或 CXL 协议,则需要通过 {AdvCap.Adapter}{FinCap.Adapter} 协商 Flit Mode。

  协议参数的决策规则如下:

  • 若双方均通告了 “68B Flit Mode”,则 {FinCap.Adapter} 消息中对应的 bit 置 1;
  • 若双方均通告了 “CXL 256B Flit Mode”,则 {FinCap.Adapter} 消息中对应的 bit 置 1;
  • 若双方均通告了 “PCIe Flit Mode”,则 {FinCap.Adapter} 消息中对应的 bit 置 1;
  • 若通告了 “Streaming protocol”,则没有 {FinCap.Adapter} 消息。

  如果协商结果为 “68B Flit Mode” 或 “CXL 256B Flit Mode”,则必须通过 {AdvCap.CXL}{FinCap.CXL} 对其他详细信息进行二次协商,最终结果由 {FinCap.CXL}{FinCap.Adapter} 共同决定。

  除协议参数外,其他参数的决策规则如下:

  • 若双方均通告了 “Raw Format”,则 {FinCap.Adapter} 消息中对应的 bit 置 1;
  • 若双方均通告了 “Retry”,且未通告 “Raw Format”,则使能 Adapter Retry,并将 {FinCap.Adapter} 消息中对应的 bit 置 1;
  • 若双方均通告了 “Enhanced Multi_Protocol_Enable”,则 {FinCap.Adapter} 消息中的 3bit(Enhanced Multi_Protocol_Enable / Stack0_Enable / Stack1_Enable)都需要置 1;
  • 若双方均通告了 “Multi_Protocol_Enable”,且未通告 “Enhanced Multi_Protocol_Enable”,则 {FinCap.Adapter} 消息中的 3bit(Multi_Protocol_Enable / Stack0_Enable / Stack1_Enable)都需要置 1;
  • 若 “Enhanced Multi_Protocol_Enable” 和 “Multi_Protocol_Enable” 均未被通告,则:
    • 当 stack 0 使能,stack 1 未使能,则 {FinCap.Adapter} 消息中的 Stack0_Enable 置1;
    • 当 stack 0 未使能,stack 1 使能,则 {FinCap.Adapter} 消息中的 Stack1_Enable 置1;
    • 当 stack 0 和 stack 1 都被使能,则 {FinCap.Adapter} 消息中的 Stack0_Enable 置1。
  • 若双方均通告了 “CXL_LatOpt_Fmt5/6”,则 {FinCap.Adapter} 消息中对应的 bit 置 1。

Note:

  • Raw Format 优先级最高,一旦双方通告则无条件采纳。
  • Raw Format 与 retry 协议互斥,原因是 Raw Format 禁止了 Adapter 对 Flit 的任何中间处理,自然也包括 Retry。
  • 若未通告 “Enhanced Multi_Protocol_Enable” 或 “Multi_Protocol_Enable”,则两个协议栈,哪个使能用哪个;若都使能,则用 stack 0。

在这里插入图片描述

  DP/UP 握手协商仅适用于 PCIe 和 CXL 协议。对 “Streaming protocol” 和不带其他协议复用的纯 “Management Transport Protocol” 协议场景,双方各自独立通告,无需某一方做最终决策,事务流中没有 {FinCap.*} 消息传递。协议在 Sideband 消息中为厂商预留了自定义字段,见 Table 7-8 和 Table 7-10。

在这里插入图片描述

在这里插入图片描述

  流协议双方最终的能力参数,基于双方通告能力交集隐式的确定,不通过 {FinCap.*} 消息显式的告知:

  • Flit Format 根据 Table 3-10 的真值表确定;
  • 若双方均通告了 “Retry”,且未协商 “Raw Format”,则使能 Adapter Retry 功能;
  • 若双方协商了 “Multi_Protocol_Enable”,则两栈均启用;
  • 若至少一方未通告 “Multi_Protocol_Enable” 或 “Enhanced Multi_Protocol_Enable”,则两栈哪个使能用哪个,都使能用 stack 0。

  对于 Enhanced Multi_Protocol_Enable,两栈需要分别协商。{AdvCap.Adapter}{FinCap.Adapter} 消息传递负责 stack 0 协商,而 stack 1 需要 {MultiProtAdvCap.Adapter}{MultiProtFinCap.Adapter} 消息协商。若协商了 “68B Flit Mode” 或 “CXL 256B Flit Mode”,stack 1 复用 {AdvCap.CXL}{FinCap.CXL} 消息,其中 stack 0 的 MsgInfo = 'h0000,stack 1 的 MsgInfo = 'h0001

  如 Figure 3-5 到 Figure 3-9 所示,举了不同场景下协商的消息流。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  整个参数交换协商过程的超时门限为 8ms(-0%/+50%),即 stage 3 的 part 1 和 part 2。定时器仅在 RDI 处于 Active 状态时累加。当 Adapter 收到对 Die 的 {AdvCap.*.Stall}{FinCap.*.Stall}{MultiProtAdvCap.*.Stall}{MultiProtFinCap.*.Stall} 时,定时器必须重置。若定时器超时,则当做 UIE 错误处理,并将 RDI 状态带入 LinkError。对于 Retimer 来说,需要每隔 4ms 回复一次 stall,避免 package 内的 UCIe Die 陷入超时。

Note:

  • UCIe 的超时机制可以类比“看门狗”。系统运行期间,需要定时“喂狗”,避免对方认为你跑飞了或是发生了其他故障。
3.2.1.3 Part 3: FDI bring up(Part 3:FDI 建链)

  一旦参数协商完成,Adapter 需要执行 FDI bring up,将 FDI 状态带入 Active。到此全部链路初始化过程完成,即可开始 Flit 传输。若多协议栈复用,各栈的状态机独立,初始化过程可以不同时完成。

  FDI 带宽取决于主频和实际链路位宽;而 RDI 带宽是固定的,因为 PHY 的每条 Lane 的带宽是固定的。本章后续给出的例子,均以先进封装下的 x64 配置给出。

3.3 Operation Formats(操作格式)

3.3.1 Raw Format for All Protocols(Format 1)

  Raw Format 格式被定义为 Format 1,Adapter 仅透传,不支持 Adapter Retry。具体 Flit 字段格式如 Figure 3-10 所示。

在这里插入图片描述

3.3.2 68B Flit Format(Format 2)

  68B Flit Format 格式被定义为 Format 2,只有当协商最大速率 ≤ 32 GT/s 时可用。若支持 CXL 68B Flit Mode 或 PCI NFM 协议,Format 2 为强制支持;若支持 Streaming protocol,Format 2 为选择性支持

  协议层发送 64B payload,Adapter 添加 2B Header + 2B CRC,整体位宽为 68B(非 64B 对齐)。2B Header 字段定义如 Table 3-2 和 Table 3-3 所示,两种字段格式区别在于是否支持 Retry。若不支持 Retry,Adapter 依然要填 CRC 字段,强烈建议若接收端校验失败,则当做 UIE 处理。2B CRC 编码需要依据 2B Flit Header + 64B payload 共 66B 有效信息生成,生成校验码时需要填 0 补全到 128B,生成的 2B CRC 校验码填充到 68B Flit 中的 Byte[66] 和 Byte[67]。

Note:

  • 无论是否支持 Adapter Retry,都需要 CRC 校验。只是当误码率低时,无需支持 Retry。此时一旦发生极小概率的 bit error,无法通过 Retry 恢复,只能当做 UIE 处理。
  • Retry 的粒度为完整的 68B Flit,而非 TLP。

在这里插入图片描述

在这里插入图片描述

3.3.2.1 68B Flit Format Alignment and Padding Rules(68B Flit 对齐处理)

  字节移位是 Format 2 主要的复杂度来源,需要一直将上一包多余的 4Byte 移位到一下包。RDI 上数据总是以 256B 的倍数传输,不足 256B 的需要填充 0 以对齐。Retimer Credit 粒度为 256B Flit。

  协议提供了一种数据流暂停机制(Pause the Data Stream,PDS),用于链路 IDLE 状态时节约功耗。当链路无包发送时,需要插入 PDS token 表示数据流暂停。PDS token 是变长结构,包括 2B 特殊协议头 PDS Flit Header 和后续以 0 填充的 Byte,后续填充 0 的长度取决于当前的字节偏移和对齐情况。数据流以 PDS Flit Header 为终止标志,剩余位填充 0 直到对齐 64B 边界。随后,至少还需插入 2 包全 0 的 64B data chunk,以保证接收端的字节移位寄存器成功重置。此时,若仍未对齐 256B 边界,需要再额外填 0 补齐。

  PDS Flit Header 以及后续以 0 填充的 Byte 不能传递到协议层。

  如 Table 3-3 所示,PDS Flit Header 需要满足:

  • Byte[0].bit[4] = 'b1 ------(1)
  • Byte[1].bit[7] = 'b1 ------(2)
  • Byte[1].bit[6] = 'b1 ------(3)
  • Byte[1].bit[5:4] = 'b00 AND SeqNum[7:0] = ~(NEXT_TX_FLIT_SEQ_NUM - 1) ------(4)

Note:

  • Flit Header 中做了哪些抗干扰设计?
    • 区分 Regular Flit Header 和 PDS Flit Header 的编码复用了 Byte[0].bit[4]、Byte[1].bit[7]、Byte[1].bit[6],不连续,即至少出现 3bit 翻转,才可能混淆。
    • 当 Byte[1].bit[5:4] = 'b00 时,SeqNum 取反码,即使任 1bit 翻转,大概率也不会落在正常 SeqNum 区间,不会与正常 SeqNum 混淆。

  无包发送时,除了 PDS 外,还可以选择插入 NOP。此处需要权衡【从 PDS 状态恢复传输的时延】vs【插入 NOP 空转的功耗浪费】。

  为了保证字节移位寄存器的正确性,必须等到 PDS token 完全通过 RDI,才能拉低 lp_irdy/lp_valid,即 PDS 必须连续不间断直到传输完成。也不允许在 PDS token 中间,插入正常数据流,正常数据流需要在完整 PDS 发完后再发。

  CRC Bytes 在任何情况下必须紧跟 payload 发送,不能因为 PDS 推迟,以确保接收端正确识别检验码。

  若使能 Retry,接收端识别到上述 (1) (2) (3) (4) 条件中任意 2 个为真,则认为是 PDS Flit Header;若未使能 Retry,接收端必须识别到条件 (1) (2) 都为真,则认为是 PDS Flit Header。

Note:

  • 当误码率很低时,可以不使能 Retry。检查条件 (1) (2) 跨 Byte 不连续的 2bit 即可识别 PDS Flit。当极小概率的 bit error 发生在 (3) (4),则不影响 Header 的识别,bit error 可忽略,不会陷入 UIE。
  • 使能 Retry 时,条件放宽。若发生 bit error,校验出来重传即可。

  Retry 或 RDI Retrain 时,新 Flit 位置需要从头摆放,字节移位寄存器都会重置,所以必须插入 PDS token 起到重新对齐的作用。对于 Retry,需要在发送端的 Flit 从 Retry Buffer 取出之前插入 PDS token;对于 Retrain,需要在拉高 lp_stallack 之前插入 PDS token。此外,当 RDI 进入 Retrain 时,PDS token 可能在路上,接收端尚未收到,Adapter 只能以状态切换为优先,丢弃后续收到的部分 68B Flit。

  在 PDS token 后收到任何有效 Flit 都会恢复数据流,接收端需要验证 SeqNum(ps:PDS token 后第一包一定是 256B 对齐的)。若未使用 Retry,如 Table 3-2 所示格式,未提供 SeqNum,那么必须通过正常 payload Flit 或 test Flit 恢复数据流。NOP 全 0,与 PDS Flit 冲突,无法恢复数据流。

Note:

  • 传输校验码不能代表数据流恢复,只有 有效 Flit 才能恢复数据流。

  如果 Retry 使能,PDS 错误可以当做 Link Retrain;如果 Retry 未使能,PDS 错误可以当做 LinkError。

Note:

  • PDS 错误可以是包长错误或 bit 翻转。

  给出了几个例子:Figure 3-11 是正常 FLit 传输场景;Figure 3-12 是插入 PDS token 场景,PDS token 未越过 256B 边界;Figure 3-13 是插入 PDS token 场景,PDS token 越过 256B 边界,用额外 0 补齐。

在这里插入图片描述

在这里插入图片描述

3.3.3 Standard 256B Flit Formats(Format 3/4)

  Standard 256B Flit Formats 格式来自于原生 PCIe/CXL 协议,包括 Standard 256B End Header Flit Format(Format 3)和 Standard 256B Start Header Flit Format(Format4)。若协商 PCIe FM 协议,则 Format 3 为强制支持;若协商 CXL 256B Flit Mode 协议,则 Format 4 为强制支持;若协商 Streaming 协议,则 Format 3/4 为选择性支持。

  如 Figure 3-14 ~ 3-19 所示,橙色字段协议层填 0,为 Adapter 预留。原生 PCIe 协议中的 6B DLP 字段在 UCIe 中仍存在,其中 DLLPs 需要 bypass 掉 Tx Retry Buffer,它们一部分由协议层填充,一部分由 Adapter 填充。DLP Byte 0~1 由 Adapter 填充,协议层下发的 DLP Byte 0~1 被丢弃,并替换为 UCIe Flit Header。剩余 DLP Byte 2~5 由协议层和 Adapter 共同填充。如 Table 3-4 和 3-5 所示,Flit Header 即 DLP Byte 0~1,可能不全由 Adapter 填充:① 当 DLP Byte 2~5 为 Flit_Marker 时,协议层负责将 Byte0.bit[4] 置 1;② Byte0.bit[7:6] 即 Protocol ID,由协议层负责填充。

Note:

  • DLLPs(Data Link Layer Packets)是原生 PCIe 协议中的数据包,可以用于 PM、流控、重传等,不同用途采用格式也不同。PCIe 6.0 引入 Flit Mode,将 DLLPs 信息组成 6B DLP(Data Link Layer Payload)。

  对于 Streaming 协议,Figure 3-17 给出了可用格式。协议层仅填充 Protocol ID,且禁止 Protocol ID 设为 'b00

  FDI 为传输 DLLP 提供了独立接口,Adapter 对于 DLLP 的处理完全遵循 PCIe 协议的所有规则。Tx 方向(协议层 -> Adapter),Adapter 从 FDI DLLP 接口提取 DLLP(非 Flit_Marker),将 DLLP 插入 DLP Byte 2~5;Adapter 还负责从 FDI DLLP 接口解出 Update_FC,可能需要更新为 Optimized_Update_FC,填入 DLP 字段。Rx 方向(Adapter -> 协议层)反之,从 Flit 中提取 DLLP 后驱动 FDI 接口传输到协议层。

  计算两组 CRC(CRC0 和 CRC1),256B Flit 分为两个 128B 半区,每组独立做 CRC-16。每个半区算出的 2B CRC 分别填入 Flit 末尾字段。不足 128B 的 chunk,用 0 填充后计算。

  若未使能 Retry,Adapter 仍需要提供 CRC。强烈建议接收端校验,校验失败按 UIE 处理。

  Table 3-5 展示了使能 Retry 的 Flit Header 格式,相比于 Table 3-4 展示的无 Retry 格式,多出了 SeqNum 和 Ack/Nak 用于 Retry 的信息。

  如 Figure 3-16 和 3-19 所示,对于 Management Flit,Byte 238-241 由协议层填充 4B Management Transport Credit Return DWORD(CRD)。Format 3 的 Byte 232~235 和 Format 4 的 Byte 234~237 由协议层填 0。

  若 PCIe/CXL.io 与 MTP 复用同一协议栈,Byte 238~241 占据相同位置,则 Adapter 需要:

  • 若 Flit Type = 'b10,为 Management Flit,Byte 238~241 为 CRD,透传;
  • 若 Flit Type = 'b00,非 Management Flit,Byte 238~241 为 DLP,按对应规则处理。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3.3.4 Latency-Optimized 256B Flit Formats(Format 5/6)

  Latency-Optimized 256B Flit Formats(LOpt)是协议强烈推荐使用的格式,以获得低时延收益。定义了两种格式 Format 5 和 Format 6,区别在于 Flit 中是否有附加 Bytes。

  对于 Streaming 协议,Format 5/6 为选择性支持,协议层只负责填 Protocol ID,且禁止填 'b00

  对于 PCIe FM,Figure 3-23 给出了格式举例。

  计算两组 CRC(CRC0 和 CRC1),规则同 Format 3/4。不同之处在于,LOpt 格式通过重新排布,CRC0 和 CRC1 分布在两个 128B 半区,每个半区为 126B payload + 2B CRC,刚好不需要补 0 填充。同上,若不是使能 Retry,仍建议做 CRC 校验,校验失败当做 UIE 处理。

  依据 Flit_Type 区分 Management Flit,若为 Management Flit,协议层必须 Flit_Type 赋值为 'b10;普通协议报文 Flit_Type 赋值为 'b00

  如 Figure 3-22 所示,对于使用 Format 5 的 Management Flit,协议层将 4B CRD 填充 Byte 240 ~ 243。

  若 PCIe/CXL.io 与 MTP 复用协议栈(采用 Format 5),则:

  • 若 Flit_Type = 'b10,则 Byte 122 ~ 125、244 ~ 253 置 0;
  • 若 Flit_Type = 'b00,则 Byte 122 ~ 125 为 DLP,Byte 250 ~ 253 为 Flit_Marker 或 Optimized_Update_FC,Byte 248 ~ 249 填 0。

  如 Figure 3-26 所示,对于使用 Format 6 的 Management Flit,协议层将 4B CRD 填充 Byte 250 ~ 253。

  若 PCIe/CXL.io 与 MTP 复用协议栈(采用 Format 6),则:

  • 若 Flit_Type = 'b10,则 Adapter 透传 Byte 122 ~ 125、248 ~ 253;
  • 若 Flit_Type = 'b00,则 Byte 122 ~ 125 为 DLP,Byte 250 ~ 253 为 Flit_Marker 或 Optimized_Update_FC,Byte 248 ~ 249 填 0。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  LOpt Flit Header 格式见 Table 3-4 和 Table 3-5。LOpt 与 Standard 256B 的区别在于:Standard 256B 的 DLP 与 Flit_Marker 复用相同字段;而 LOpt 的 DLP 和 Flit_Marker 分别占用独立字段,Byte0.bit[4] 表示 DLP/Flit_Marker 的有效位。

3.3.5 Flit Format-related Implementation Requirements for Protocol Layer and Adapter

在这里插入图片描述

在这里插入图片描述

3.4 Decision Table for Flit Format and Protocol(Flit 格式与协议决策表)

  Table 3-8、3-9、3-10 给出了三张真值表,3-8 用于协商协议类型,3-9 和 3-10 用于协商格式。一旦协议和格式在链路初始化阶段协商成功,运行时禁止更改,切换需要复位重走初始化流程。三张表覆盖了所有组合,如未协商成功,需要关闭链路,并上报 LinkError。

在这里插入图片描述

Note:

  • 若最大速率 ≤ 32GT/s,无论是 CXL 还是 PCIe 协议,{AdvCap.Adapter} 中必须通告 “68B Flit Mode” 参数,将其置 1;否则置 0。
  • 通告阶段,{AdvCap.CXL} 允许 “CXL.io” 和 “PCIe” 同时置 1,但最终协商 {FinCap.CXL} 只允许其一被置 1。

  Table 3-9(真值表 1)适用于协议协商为 PCIe 或 CXL(允许 MTP 复用),且以下三个参数均未被通告:

  • Enhanced Multi_Protocol_Enable
  • Standard 256B Start Header for PCIe protocol capability
  • Latency-Optimized Flit with Optional Bytes for PCIe protocol capability

  Table 3-10(真值表 2)适用于 Streaming 协议或单独协商的 MTP(即未与其他 PCIe/CXL/Streaming 复用),这些场景的特点是没有 {FinCap.*} 类型的消息,需要看双方通告能力的交集(AND 逻辑)。此外,若上述三个参数之一被通告,则必须参照真值表 2。

在这里插入图片描述

  若未协商出结果或者协商出非法组合(如 68B Flit Format 2 + MTP),允许协议层或 Adapter 关闭链路,并上报 LinkError。

3.5 State Machine Hierarchy(状态机层次结构)

  UCIe 的链路状态管理是分层结构,每层状态独立维护,各层的状态转换依次进行。

  如 Figure 3-27 所示,举了不同配置下的状态机层级结构。Adapter LSM 是必须的,每个协议栈都需要,负责与对 Die 协商链路状态。对于 CXL,存在 CXL.ioCXL.memcache 复用协议栈,需要 ARB/MUX vLSMs 管理每个子协议的状态,即 FDI 接口 pl_state_sts 表示的是 vLSM 状态;对于 PCIe 或 Streaming 协议,FDI 接口 pl_state_sts 表示的是 Adapter LSM 状态。

  RDI SM 用于维护物理层状态,即使物理层为 Multi-Module PHY Logic,上层仍只能看到一个接口和状态机。

  三种状态机需要遵循以下规则:

  • vLSM 状态转换遵循 CXL 协议规则,通过 Mainband 传递 ALMPs 实现;
  • Adapter LSM 状态转换通过在 Sideband 传递 {LinkMgmt.Adapter*} 消息实现,该类型消息由 Adapter 发起和接收;
  • RDI SM 状态转换通过在 Sideband 传递 {LinkMgmt.RDI*} 消息实现,该类型消息由物理层发起和接收。
vLSM(for CXL)Adapter LSMRDI SM
所属层级协议层(CXL 子协议 ARB/MUX)适配器层物理层
管理对象CXL 子协议链路状态单个协议栈的链路状态整个物理层链路状态
协调方式Mainband 上的 ALMPs(CXL 定义)Sideband 上的 {LinkMgmt.Adapter*} 消息Sideband 上的 {LinkMgmt.RDI*} 消息
对外接口FDIFDI(对于 PCIe/Streaming)RDI

在这里插入图片描述

  下面介绍状态转换规则(优先级与依赖关系):

  • Active:Adapter LSM 必须等到 RDI SM 进入 Active 后,才能开始协商进入 Active;vLSM 必须等到 Adapter LSM 进入 Active 后,才能开始协商进入 Active。Active 状态转换,必须底层先准备就绪。即必须先保证物理层准备好,Adapter 才能正常工作;Adapter 准备好后,上层协议才能正常工作。
  • Retrain:RDI SM 必须先进入 Retrain,然后才能将 Retrain 状态传播给 Adapter LSM;若 RDI SM 处于 Retrain 状态,则必须将该状态传播给所有处于 Active 的 Adapter LSM;在所有相关的 Adapter LSM 都转换到 Retrain 状态前,Adapter 不能请求 RDI 退出 Retrain 状态。Retrain 可以在不完全关闭链路的情况下重新进行物理层训练,由物理层率先感知到,并进入 Retrain 状态;随后通知适配层,适配层在所有协议栈都准备好后才能允许物理层退出 Retrain 状态,确保重训练过程中,上层协议不会在链路不稳定时发数据。
  • PM(L1/L2):对于 CXL 协议,必须等到 CXL.ioCXL.cachemem 都进入 PM 状态,对应的 Adapter LSM 才能转换到 PM 状态;必须等到所有 Adapter LSM 都进入 PM 状态(多协议栈复用),RDI SM 才能进入 PM 状态。上层协议必须先进入低功耗,再向适配层和物理层传导,直到整体进入低功耗状态。
  • LinkError:RDI SM 必须先进入 LinkError 状态,随后 Adapter LSM 才能转换到 LinkError 状态;RDI SM 会将 LinkError 通过 Sideband 消息传播给所有 Adapter LSM;对于 CXL 协议,Adapter LSM 必须先进入 LinkError 后,才能将 LinkError 传播给两个 vLSM;LinkError 优先级高于 LinkReset/Disabled;在所有相关的 Adapter LSM 和 CXL vLSM 都进入 LinkError 状态之前,Adapter 不能请求 RDI 退出 LinkError 状态。当发生 LinkError 错误,LinkError 状态由物理层逐层上报处理。若同时发生复位或禁用,优先处理 LinkError,保证系统安全。
  • LinkReset/Disabled:Adapter LSM 通过 Sideband 与对 Die 协商 LinkReset/Disabled 转换;当所有相关的 Adapter LSM 都进入 LinkReset/Disabled 状态时,才能将此状态传播给 RDI SM;Disabled 优先级高于 LinkReset;若 RDI SM 进入 LinkReset/Disabled 状态,RDI SM 必须将此状态传播给所有 Adapter LSM;对于 CXL 协议,若 Adapter LSM 进入 LinkReset/Disabled 状态,Adapter LSM 必须将此状态传播给两个 vLSM。LinkReset/Disabled 由适配层发起,通过 Sideband 协商。只有当该 Adapter 下管理的所有协议栈都进入复位或禁用状态后,才会通知物理层。如果复位和禁用同时发生,会执行优先级更高的 Disabled。

  对于 UCIe Retimer,负责与远端协商状态转换,保证与远端 Die 间状态的同步,以及不会因为长时间等待响应而超时。举个例子,如 Figure 1-18 所示,若 UCIe Die 0 发送 Acitve 请求消息给 Retimer 0,则 Retimer 0 必须与 Retimer 1 协商,确认 Active 消息已经发给 UCIe Die 1,且 UCIe Die 1 已返回响应。Off-package 互联不能进入低功耗,直到 UCIe Die 0 和 Die 1 所有相关状态均进入低功耗。在 Retimer 与远端协商期间,必须每 4ms 发送一次 “Stall” 避免超时。

3.6 Power Management Link States(电源管理状态)

  对于 PCIe 和 CXL 协议,PM 状态是强制支持的。FDI 支持 L1/L2 两种低功耗状态,其遵循 CXL 256B Flit Mode 模式的握手规则和状态转换。RDI 同样支持 L1/L2 两种低功耗状态,但是允许物理层内部将 L1/L2 映射为一种省电模式。允许全局时钟门控,或系统级 flow(如 Package C-states)。对于 Streaming 或其他自定义协议,收到 PM 请求后,允许发送 PMNAK 拒绝进入低功耗状态。

  当 MTP 和其他协议复用时,MTP 需要与同栈复用的主协议行为和流程保持一致。当 Adapter 接收到来自 MPG mux 的 PM 请求,需要考虑 MTP 和主协议的 L1/L2 状态均就绪,才能进入低功耗状态。当从 L1/L2 唤醒时,MTP 必须跟随主协议一起唤醒。

  进入低功耗状态流程如下:

  1. 协议层发起 PM 请求:PM 由协议层发起,通过监控链路空闲时间,通过 FDI 发起 PM 流程。至于空闲多久发起 PM,协议不做硬性要求。
    1. 对于 CXL 协议,Adapter 实现 ARB/MUX,负责 CXL 的 PM 握手(采用 CXL 256B Flit Mode 协议与格式,所有 ALMPs 都要经过 Retry Buffer)。即使 CXL 68B Flit Mode,也使用 CXL 256B Flit Mode 的格式和流程,只是 Flit 会被分片为 64B chunk,Adapter 添加 Header + CRC 后组成 68B Flit。
    2. 对于 PCIe 协议,原生 PCIe 协议通过 DLLP 实现 PM 握手,但在 UCIe 中 PM 由 Adapter 接管,原 PM DLLP 不使用。
  2. Adapter LSM 进入 PM 状态:通过 Sideband 消息与对 Die 协商。如果适配层为多协议栈复用,则每个协议栈的 Adapter LSM 独立执行 PM 流程。
  3. RDI 进入 PM 状态:一旦所有 Adapter LSM 进入 PM 状态,Adapter 将在 RDI 上发起 PM,保证物理层不会在某协议栈还在工作中就贸然休眠。
  4. 物理层进入 PM 状态:物理层收到 RDI 的休眠请求后,执行实际的省电行为(如关钟)。由于 Mainband 被关闭,所以必须保证 Sideband 一直处于 Active,用于唤醒。

在这里插入图片描述

  退出低功耗状态流程如下:

  1. 协议层发起 Active 请求:通过 FDI 和 RDI 传递到本 Die 物理层。
  2. 物理层唤醒后重训练:通过 Sideband 消息唤醒对 Die 物理层,两端开始 Retrain。
  3. 适配层恢复 Active 状态:一旦物理层完成 Retrain,RDI 两端都处于 Active 状态,适配层通过 Sideband 消息与对 Die 协商退出 PM 状态。对于 PCIe 或 Streaming 协议,此操作会通过 FDI 将协议层转换到 Active 状态。
  4. vLSM 唤醒(only for CXL):对于 CXL 协议,只唤醒 Adapter LSM 不够,还需要交换 ALMP 才能将协议层唤醒。

3.7 CRC Computation(CRC 计算)

  UCIe 采用 CRC-16,CRC 生成多项式为 ((x + 1)*(x^{15} + x + 1) = x^{16} + x^{15} + x^{2} + 1),保证 3bit 错误被检出。本原多项式 ((x^{15} + x + 1)) 能检出 2bit 错误,((x + 1)) 能再额外检出 1bit 错误。

  固定 CRC 输入长度为 128B,不足 128B 的用 0 补齐。最终不需要通过链路传输的字段填 0。CRC 需要在最终组包后计算填充,如 Flit Header 或 DLP。RSV 字段都填 0。

  CRC-16 算法如 Figure 3-29 所示,每个 Byte 内从 LSB 开始,一直计算到 MSB。C[15:8] 对应 CRC Byte 1,C[7:0] 对应 CRC Byte 0。CRC LFSR 初始值为 0000H

在这里插入图片描述

  协议给出了 CRC 生成的 RTL 代码作为 “Golden Reference”。Tx 侧输入 128B Flit,通过该计算逻辑,生成 2B CRC 校验码;Rx 侧接收到 Flit 后,以相同逻辑生成 2B CRC 校验码,并与收到的校验码比对。若比对不相同,则说明发生传输错误,需要 Retry。

module crc_gen (
  input logic [1023:0] data_in,
  output logic [15:0]  crc_out
);
always_comb begin
   crc_out[ 0] = ^(data_in & 1024'hfffdfff3ffd7ff0ffddff33fd57f00fdfdf3f3d7d70f0dddd33315558002fff1ffdbff27fd2ff11fd9bf2a7d02f1f1dbdb27252d211139996aa8800cffd5ff03fdf7f3cfd75f0c3dd7730cd5d50301f5fbc3e777acce155b8026ff29fd0bf1c7db6f249d24b1245926292b0905c9e34bb446466a6a8280f0fdddf333d557000d);
   crc_out[ 1] = ^(data_in & 1024'h7ffefff9ffebff87feeff99feabf807efef9f9ebeb8786eee9998aaac0017ff8ffedff93fe97f88fecdf953e8178f8eded93929690889cccb55440067feaff81fefbf9e7ebaf861eebb9866aea8180fafde1f3bbd6670aadc0137f94fe85f8e3edb7924e9258922c9314958482e4f1a5da232335354140787eeef999eaab8006);
   crc_out[ 2] = ^(data_in & 1024'hc002800f002200cc02a80ff02020c0c2828f0f2222ccceaaa7ffd000e002400d802d00ee02640d582fd0e0e2424d8dad2deeec66695577ff3002a00fc02080c3028a0f3c2288cf32a2afcfe0a043c18885331eaa47fd900d602f40e382490db62db4edba6d9d6d4f6fa361cb44bb9b995957d7f0f02220ccc2aa8fff2002c00e);
   crc_out[ 3] = ^(data_in & 1024'h6001400780110066015407f810106061414787911166675553ffe80070012006c0168077013206ac17e870712126c6d696f7763334aabbff98015007e01040618145079e114467995157e7f05021e0c442998f5523fec806b017a071c12486db16da76dd36ceb6a7b7d1b0e5a25dcdccacabebf878111066615547ff90016007);
   crc_out[ 4] = ^(data_in & 1024'h3000a003c008803300aa03fc08083030a0a3c3c888b333aaa9fff40038009003600b403b809903560bf438389093636b4b7bbb199a555dffcc00a803f0082030c0a283cf08a233cca8abf3f82810f062214cc7aa91ff6403580bd038e092436d8b6d3b6e9b675b53dbe8d872d12ee6e65655f5fc3c08883330aaa3ffc800b003);
   crc_out[ 5] = ^(data_in & 1024'h18005001e0044019805501fe040418185051e1e4445999d554fffa001c004801b005a01dc04c81ab05fa1c1c4849b1b5a5bddd8ccd2aaeffe6005401f8041018605141e7845119e65455f9fc1408783110a663d548ffb201ac05e81c704921b6c5b69db74db3ada9edf46c39689773732b2afafe1e044419985551ffe4005801);
   crc_out[ 6] = ^(data_in & 1024'h0c002800f002200cc02a80ff02020c0c2828f0f2222ccceaaa7ffd000e002400d802d00ee02640d582fd0e0e2424d8dad2deeec66695577ff3002a00fc02080c3028a0f3c2288cf32a2afcfe0a043c18885331eaa47fd900d602f40e382490db62db4edba6d9d6d4f6fa361cb44bb9b995957d7f0f02220ccc2aa8fff2002c00);
   crc_out[ 7] = ^(data_in & 1024'h06001400780110066015407f810106061414787911166675553ffe80070012006c0168077013206ac17e870712126c6d696f7763334aabbff98015007e01040618145079e114467995157e7f05021e0c442998f5523fec806b017a071c12486db16da76dd36ceb6a7b7d1b0e5a25dcdccacabebf878111066615547ff9001600);
   crc_out[ 8] = ^(data_in & 1024'h03000a003c008803300aa03fc08083030a0a3c3c888b333aaa9fff40038009003600b403b809903560bf438389093636b4b7bbb199a555dffcc00a803f0082030c0a283cf08a233cca8abf3f82810f062214cc7aa91ff6403580bd038e092436d8b6d3b6e9b675b53dbe8d872d12ee6e65655f5fc3c08883330aaa3ffc800b00);
   crc_out[ 9] = ^(data_in & 1024'h018005001e0044019805501fe040418185051e1e4445999d554fffa001c004801b005a01dc04c81ab05fa1c1c4849b1b5a5bddd8ccd2aaeffe6005401f8041018605141e7845119e65455f9fc1408783110a663d548ffb201ac05e81c704921b6c5b69db74db3ada9edf46c39689773732b2afafe1e044419985551ffe400580);
   crc_out[10] = ^(data_in & 1024'h00c002800f002200cc02a80ff02020c0c2828f0f2222ccceaaa7ffd000e002400d802d00ee02640d582fd0e0e2424d8dad2deeec66695577ff3002a00fc02080c3028a0f3c2288cf32a2afcfe0a043c18885331eaa47fd900d602f40e382490db62db4edba6d9d6d4f6fa361cb44bb9b995957d7f0f02220ccc2aa8fff2002c0);
   crc_out[11] = ^(data_in & 1024'h006001400780110066015407f810106061414787911166675553ffe80070012006c0168077013206ac17e870712126c6d696f7763334aabbff98015007e01040618145079e114467995157e7f05021e0c442998f5523fec806b017a071c12486db16da76dd36ceb6a7b7d1b0e5a25dcdccacabebf878111066615547ff900160);
   crc_out[12] = ^(data_in & 1024'h003000a003c008803300aa03fc08083030a0a3c3c888b333aaa9fff40038009003600b403b809903560bf438389093636b4b7bbb199a555dffcc00a803f0082030c0a283cf08a233cca8abf3f82810f062214cc7aa91ff6403580bd038e092436d8b6d3b6e9b675b53dbe8d872d12ee6e65655f5fc3c08883330aaa3ffc800b0);
   crc_out[13] = ^(data_in & 1024'h0018005001e0044019805501fe040418185051e1e4445999d554fffa001c004801b005a01dc04c81ab05fa1c1c4849b1b5a5bddd8ccd2aaeffe6005401f8041018605141e7845119e65455f9fc1408783110a663d548ffb201ac05e81c704921b6c5b69db74db3ada9edf46c39689773732b2afafe1e044419985551ffe40058);
   crc_out[14] = ^(data_in & 1024'h000c002800f002200cc02a80ff02020c0c2828f0f2222ccceaaa7ffd000e002400d802d00ee02640d582fd0e0e2424d8dad2deeec66695577ff3002a00fc02080c3028a0f3c2288cf32a2afcfe0a043c18885331eaa47fd900d602f40e382490db62db4edba6d9d6d4f6fa361cb44bb9b995957d7f0f02220ccc2aa8fff2002c);
   crc_out[15] = ^(data_in & 1024'hfffbffe7ffaffe1ffbbfe67faafe01fbfbe7e7afae1e1bbba6662aab0005ffe3ffb7fe4ffa5fe23fb37e54fa05e3e3b7b64e4a5a42227332d5510019ffabfe07fbefe79faebe187baee619abaa0603ebf787ceef599c2ab7004dfe53fa17e38fb6de493a496248b24c5256120b93c697688c8cd4d50501e1fbbbe667aaae001b);
 
end // always_comb
endmodule // crc_gen

3.8 Retry Rules(重传规则)

  对于 BER > 1e-27 的配置,要求 Adapter 必须支持 Retry,除非只支持 Raw Format。如果不支持 Retry,则链路训练期间不得通告 BER > 1e-27 的传输速率,除非格式为 Raw Format。不同配置的 BER 见 Table 5-32。一旦 Retry 在链路初始化期间(Stage 3 Part 2)成功协商,在运行期间不能禁用,即使实际速率降低。若要禁用 Retry,只能重新链路初始化时协商(比如 RDI 进入 Reset)。若 Adapter 为多协议栈复用,则各协议栈共享 Tx Retry Buffer。

在这里插入图片描述

  UCIe Retry 机制是 PCIe Retry 的简化版,先简单介绍下 PCIe Retry:

  • 核心机制:传统 PCIe(NFM)基于 SeqNum + LCRC + Ack/Nak DLLP,采用回退式重传,即中间发现某 SeqNum 丢包或错误,重传该 SeqNum 前所有未被 Ack 的 TLPs。PCIe 6.0(FM)引入 FEC 和 Selective Replay,FEC 可以尝试纠正字节错误,Selective Replay 可以实现只重传丢包或出错的 TLP。
  • Tx 侧:为每个 TLP 分配一个 12bit 序列号 NEXT_TRANSMIT_SEQ,与 32bit LCRC 一起发出,并存入 Tx Retry Buffer。等收到 Ack 后,对应 SeqNum 的包从 Buffer 中删除,REPLAY_TIMEOUT_FLIT_COUNT 计数清 0;若收到 Nak,则触发重传。
    • Ack 携带的 SeqNum 表示:在此 SeqNum 之前的所有 Flit 都可以释放。
    • 对于 Nak,
      • Standard Replay 的 SeqNum 表示:此 SeqNum 之前所有 Flit 都需要重传。
      • Selective Replay 的 SeqNum 表示:只需重传此 SeqNum 的 Flit。
  • Rx 侧:接收端检验 LCRC 与 SeqNum,无错误返回 Ack;若发现错误或丢包,则返回 Nak。PCIe 6.0 的 Selective Replay 机制额外引入了 Rx Retry Buffer 缓存接收包,用于“断点续传”。
  • Ack/Nak Flit 限流规则:通过 CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS 控制 Explicit Sequence number Flits 和 Ack/Nak Flit 的发送比例, CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS < 3 表示每发 3 包 Explicit Sequence number Flits,才能返回 1 包 Ack/Nak Flit。在 Tx 侧,“未确认”的 Flit 需要堆积在 Tx Retry Buffer 中等待响应。
  • 超时重传:发送端监控 REPLAY_TIMEOUT_FLIT_COUNT,超过一段时间未收到 Ack,则触发重传;重传失败的次数受 FLIT_REPLAY_NUM 限制,超过一定次数后,则判定链路严重失效,需要进入 Recovery 状态重训练。

Note:

  • PCIe 中,Explicit Sequence number Flits 是指传输正常 TLP 数据 payload 的 Flit;Ack/Nak Flit 不消耗 SeqNum,不会使 Tx 端 NEXT_TX_FLIT_SEQ_NUM 递增,payload 以 NOP 填充。两种 Flit 通过 DLP 中的特殊字段区分。
  • PCIe 中,CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS 的作用是什么?—— “有用的”数据连续发送,响应“累积着”返回,避免响应过度占用带宽。但 Tx 侧同样不能无限制的等待响应,根据 PCIe 协议的 “Replay Schedule Rule 0” 规则,设置 REPLAY_TIMEOUT_FLIT_COUNT 用于统计“已发送多少包 Flit 但未收到响应”。若计数器超过阈值,即 REPLAY_TIMEOUT_FLIT_COUNT ≥ 1500,则直接重传所有“未确认” Flit,并记录一次 Replay Timer Timeout Error(可能是死锁,超时强制解除兜底,或者链路严重损坏等原因)。当 Tx Retry Buffer 为空或收到 Ack 时,反映出链路状况良好,REPLAY_TIMEOUT_FLIT_COUNT 清 0 且不累加。

  UCIe Retry 相对于 PCIe Retry 的不同之处在于:

  • UCIe 不支持 Selective Replay 和 Rx Retry Buffer。
  • UCIe 的 Explicit Sequence number Flits 和 Ack/Nak Flit 是交替发送的,即 CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS < 3 需要改成 CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS < 1。当没有待发送的 Ack/Nak Flit 时,允许连续发送 Explicit Sequence number Flits。UCIe 的响应周转更快,可以节约 Tx Retry Buffer 开销。
  • UCIe 最大支持 SeqNum 为 255,位宽 8bit(PCIe SeqNum 位宽 10bit)。所有相关的计算需要将 1023 替换为 255。
  • UCIe 中 REPLAY_TIMEOUT_FLIT_COUNT 位宽 9bit,取值范围 0 ~ 1FFh。
    • UCIe REPLAY_TIMEOUT_FLIT_COUNT 计数器通过时钟累加,断流时不依赖 NOP。区别于 PCIe,该计数器通过 Flit 数累加。即使无包发送,PCIe 也要发送连续的 NOP Flit,保证该计数器的正确累加。
    • UCIe 的超时阈值调整为 375,即 REPLAY_TIMEOUT_FLIT_COUNT ≥ 375 时达到超时,并记录一次 Correctable Internal Error。
  • UCIe 的 FLIT_REPLAY_NUM 计数器建议遵循 PCIe 针对速率 ≤32GT/s 的规则。
  • UCIe 不支持撤回 Nak 的机制,NAK_WITHDRAWAL_ALLOWED 始终为 0。
  • UCIe 不支持 IDLE Flit 握手流程。因为 PCIe 在进入 L0 状态前需要专门交换 IDLE Flit 来同步链路层状态。UCIe 将其移除,因为 UCIe 链路进入 Active 是通过 Sideband 协商的,不需要在 Mainband 上再发 IDLE Flit。Adapter 会丢弃所有 Header Byte = 0 的包(IDLE Flit)。
  • 对 UCIe,所有 SeqNum、Retry 机制中的相关变量初始化(对应 PCIe 的 DL_Inactive 状态)在 RDI Reset 时完成。
  • 每次 FDI 进入 Active 时,双方要有个 SeqNum 确认过程(Sequence Number Handshake Phase)。在 SeqNum 握手阶段,可以发送 payload Flit 或 NOP Flit,关键在于 Ack 中的 SeqNum。如果收到的 SeqNum 符合预期(正常情况下,进入 Active 前 SeqNum 都会归 0),则握手成功;若传输了 128 个 Flit 都没握手成功,则需要重新进入 Retrain(证明链路不可用,试图通过 Retrain 修复)。
  • UCIe 内部认为 Prior Flit was Payload 标志始终为 1(对应上述不支持 Nak 撤回机制),该字段最终在 Flit Header 中不存在。
  • MAX_UNACKNOWLEDGED_FLITS 表示未确认 Flit 的最大 outstanding,UCIe 中需要设置为以下两者中的最小值:
    • Tx Retry Buffer 深度
    • 127(在 PCIe 中,该值为 511)
  • 当收到包含无效 SeqNum 的 Ack/Nak 或 SeqNum 为 0 的 Explicit Sequence number Flits 时,UCIe 会当做 UIE 处理。(PCIe 当做 Data Link Protocol Error,叫法不同)
  • PCIe 中的 “Recovery” 对应 UCIe 是 “Retrain”。

Note:

  • UCIe 对计数器位宽、阈值的调整,如 REPLAY_TIMEOUT_FLIT_COUNT,是因为相比较于 PCIe 链路,UCIe 链路质量较好,Retry 次数明显降低。
  • PCIe 在不同速率场景,对 FLIT_REPLAY_NUM 累加规则不同。如 64GT/s 速率下,FLIT_REPLAY_NUM 每次 +1;速率 ≤ 32GT/s 时,FLIT_REPLAY_NUM 每次 +2。(Standard Replay)
  • PCIe 针对损坏的 NOP Flit 返回的 Nak 可以撤回,不需要重传无意义的 NOP,属于带宽性能方面的优化。实现流程大概是:
    1. 收到当前包,校验失败,需要返回 Nak 时,先不发,等待下一包(当前包的 Header 不可信,只能等下一包提供信息)。
    2. 收到下一包,查看 Prior Flit was Payload 标志,指示“前一包是否为有效 payload”。若 Prior Flit was Payload = 0,则前一包 Nak 撤回。
    3. 若连续两包都校验失败呢?—— 无法辨别,概率又太小,正常发送 Nak 即可。
  • PCIe 中的 “IDLE Flit 握手阶段” 到了 UCIe 的语义可以等价为 “RDI Reset/Retrain”。
  • 关于 MAX_UNACKNOWLEDGED_FLITS 的问题:
    • Tx Retry Buffer 深度意味着什么?—— 最多能吸收多少 RTT(环回时延)。
    • 若 Tx Retry Buffer 满了该怎么办?—— 反压。
    • 最大值为什么取 SeqNum 范围(255)的一半?—— 防止 SeqNum 卷绕,导致链路上可能存在两包相同 SeqNum 的首传和重传包,所以需要至少留一半 SeqNum 空间给首传包。
  • PCIe 规定,Explicit Sequence number Flits 的 SeqNum 不能为 000h,该编码只用于 IDLE Flit。
  • 由于 UCIe 允许空闲时不发 NOP(省电),若 UCIe 在休眠前发出一包 Ack,这包 Ack 可能到对端之前发生丢包或 CRC 错误,而对端 Retry Buffer 中的相关包会挂死,可以通过超时强制恢复,但是需要的时间久。协议建议每次进入休眠之前,至少发两包 Ack(可以不连续),确保至少有一包被正确接收。

3.9 Runtime Link Testing using Parity(运行时校验)

  UCIe 支持在数据传输过程中,插入奇偶校验。该功能可以通过寄存器配置开启或关闭(每个数据传输方向分别配置),且需要在 Retrain 状态时通过 Sideband 与对 Die 协商,每次改配都必须经过 Retrain 才能生效。当功能启用时,对每 256 × 256 × N Bytes 数据,由 Adapter 插入 64 × N Bytes 校验码。计算方式如下:

ParityByte[X].bit[0]=⨁bit0bit7(DataByte[X]⊕DataByte[X+64∗N]⊕DataByte[X+128∗N]⊕...⊕DataByte[X+(256∗256∗N−64∗N)]) ParityByte[X].bit[0] = \bigoplus_{bit0}^{bit7} (DataByte[X] \oplus DataByte[X+64*N] \oplus \\ DataByte[X+128*N] \oplus ... \oplus DataByte[X+(256*256*N-64*N)]) ParityByte[X].bit[0]=bit0bit7(DataByte[X]DataByte[X+64N]DataByte[X+128N]...DataByte[X+(256256N64N)])

  其中,校验位的每 Byte 高 7bit 为 Reserved,即 ParityByte[X].bit[7:1]=0ParityByte[X].bit[7:1]=0ParityByte[X].bit[7:1]=0NNN 可以通过寄存器配置,建议 N=4N=4N=4,则校验码位宽刚好 256B,对齐一包 Flit 长度; XXX 的取值范围是 0 ~ (64N-1)。

  双方各自独立维护 Byte 计数器,用来计算和校验。双方不需要交换计数信息,因为校验码的插入位置固定。校验码需要覆盖链路上所有除校验码本身的任何 Byte,包括 NOP Flit、PDS Flit 等。若链路状态离开 Active,比如进入 PM 或 Retrain,计数器必须归零。每当双方插入/接收校验码时,双方计数器也需要归零。

Note:

  • 由于 Raw Format 透传,本协议不定义 Raw Format 的奇偶校验行为。

  当 Adapter LSM 处于 Retrain 或 L1 状态时,通过 Sideband 与对 Die 交换消息,确认在转换到 Active 之前接收方校验功能已就绪。即发出去的 {ParityFeature.Req} 未被响应之前,不得请求 RDI 退出 Retrain / L1。允许在建链期间启用校验,可以通过 Sideband 访问对 Die 的寄存器或其他实现方案,但软件还是需要触发 Retrain 使其生效。允许软件在启用校验之前禁用 L1。

  如 Figure 3-30 所示,若 Die 0 启用校验功能(Runtime Link Testing Tx Enable = 1),则必须通过 Sideband 向远端 Die 1 发起 {ParityFeature.Req}。若远端 Die 1 已开启并准备好接收校验码(Runtime Link Testing Rx Enable = 1),则返回 ParityFeature.Ack。如 Figure 3-31 所示,若 Die 1 尚未开启校验功能,则返回 ParityFeature.Nak,Die 0 收到 ParityFeature.Nak 后需要通过寄存器上报软件发生了 Nak。

Note:

  • 如果启用了校验功能,允许切换到更高时延的路径(生成/校验可能需要额外的处理时延)。系统提供了显式的 Ack/Nak 握手机制,来确保双方有充足的时间切换到备用路径。

  对于 Retimer,校验码字节不会写入 Rx Buffer,也不会消耗 Credit,校验过后直接丢弃。

  若检测到奇偶校验错误,该错误被视为 Correctable Error 处理并上报。

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值