首页 / 资讯中心 / 文章详情

UCIe 1.0规范解读:chiplet互连的关键技术与实践指南

UCIe 1.0规范解读:chiplet互连的关键技术与实践指南 ★ FEATURED ARTICLE
简介UCIeUniversal Chiplet Interconnect Express1.0规范官方PDF于2022年2月24日发布面向芯片设计、先进封装与Chiplet互连领域的工程师和研究者用于解决不同厂商die之间缺乏统一高速互连标准的问题。文档系统阐述了协议层对PCIe 6.0和CXL 3.0/2.0传输模式的兼容支持定义了Die-to-Die适配器、物理层电气特性及机械尺寸要求并详细说明单模块/多模块配置、Retimer信号再生技术、关键性能目标与互操作性要求是搭建模块化SoC互连体系的权威参考。规范全文按章节组织从引言、UCIe组件协议层、D2D适配器、物理层、接口到配置模式、Retimer、性能目标和互操作性均有清晰目录压缩包内共1个文件为PDF格式整体大小约6.32MB内容即规范正文便于按需检索。已有1070人学习下载读者可直接查阅PCIe/CXL模式、D2D适配器或Retimer等条款用于Chiplet互连方案选型、参数评估与设计实现也可作为学术界和工业界研究UCIe的重要参考资料。1. 解读 UCIe 1.0chiplet 互连不只是把 Die 贴在一起如果你这两年一直在跟进先进封装和 chiplet 相关的项目大概率已经发现一个问题各家自己的 die-to-die 接口五花八门放在同一个封装里能不能互连、能跑到多少 GT/s、流片前心里完全没底。Universal Chiplet Interconnect ExpressUCIe就是行业在 2022 年 2 月 24 日给出的统一答案Revision 1.0 把协议层、D2D 适配器、物理层到 sideband 和寄存器全部定死让不同工艺、不同厂家的 die 通过标准接口直接对话。这份资源正是 UCIe 1.0 规范的完整文本适合做 chiplet 架构选型、PHY 设计或者封装基板验证的工程师拿来对照查参数。它解决的核心问题很简单把 PCIe 6.0 和 CXL 的思路延伸到 die-to-die 场景同时把 raw mode 和 flit mode 的选择权交给你接下来我们一步步拆开看。2. 协议层与工作模式从 PCIe 6.0 到 Streaming 的多样选择2.1 先把五种协议模式盘清楚UCIe 1.0 的协议层最值得留意的不是它支持多少协议而是同一个物理链路上层能换成不同协议。翻开规范第二章支持的协议和模式是这么分的PCIe 6.0Raw 和 Flit、CXL 3.0 256B Flit、CXL 2.0 或 68B-Enhanced Flit Mode、Streaming 协议。PCIe 6.0 那块注意 raw mode 和 flit mode 的差异前者把 16 Byte 的 raw data 直接发给 D2D 适配器后者走 256B 的 flit 格式。CXL 3.0 的 256B Flit Mode 比较特殊规范里还细分了 Latency-Optimized 256B Flit 和 Standard 256B Flit 两种latency-optimized 版本在流控上做了裁剪时延更低。CXL 2.068B-Enhanced Flit Mode主要对应以往 CXL 2.0 的 68B 传输粒度Streaming 则完全不带 PCIe/CXL 语义直接给上层自定义协议使用。从规格表上看各模式的数据路径宽度、 flit 大小、支持的最大载荷都不同。我用一个表整理一下方便做架构选型时快速对照模式Flit/帧格式适用场景时延特征PCIe 6.0 Raw16B raw data需要透传 PCIe 语义、不关心 flit 头开销中等PCIe 6.0 Flit256B Standard FlitPCIe 6.0 原生链路对接中等偏低CXL 3.0 256B Flit256B Standard/Latency-Optimized内存语义、cache 语义扩展Latency-Optimized 最低CXL 2.0 68B Flit68B flit兼容旧 CXL 2.0 生态低Streaming任意长度流自定义芯片间数据传输取决于上层设计这里有个容易忽略的点同一份 UCIe 1.0 的 PHY 和 D2D 适配器理论上可以复用只要你把协议层换成对应的模式。我在实际方案里习惯先把上层的协议语义定下来再回头确定用哪种 flit 格式因为有些模式下流控和数据完整性机制差异很大直接影响适配器里的 buffer 设计。2.2 PCIe 6.0 的 Raw Mode 和 Flit Mode 怎么选选型这件事规范里的 2.1 节写得很清楚但实际踩过坑会有更深的体会。Raw Mode 下协议层直接把 16B 的数据作为 payload 交给 D2D 适配器适配器并不知道里面的内容是 TLP 还是 DLLP相当于一条裸管道。这有个好处如果你只是想用 UCIe 做一个内部互联上层协议不需要完全对齐 PCIe 6.0 的 flit 格式Raw Mode 可以直接绕过时延上也少一次 flit 封装。但代价是链路级的数据完整性比如 CRC 和重传很多要靠 D2D 适配器去做协议层的防护机制帮不上忙。Flit Mode 则完全按 PCIe 6.0 的 256B flit 来传输flit 内部的错误检测和重传语义都保留了。这样做的优势是软件语义完全兼容现有 PCIe 6.0 的驱动栈但对于单纯的 die-to-die 直连场景256B 的粒度反而可能带来额外的打包延迟。我在一个模拟项目 X 里做过对比时延敏感的小包传输场景下Raw Mode 平均延迟比 Flit Mode 少十几个时钟周期但链路偶然出现 bit 错误的时候Flit Mode 的重传机制让系统恢复快得多。所以没有绝对的优劣看你的业务模型更在意延迟还是可靠。CXL 3.0 的 Latency-Optimized 256B Flit 是另一个常被忽略的分支。它和 Standard 256B Flit 的区别不在于 flit 大小而在于流控更新和与物理层交互的方式做了时延收敛。如果你的目标是 CXL 类型的内存扩展建议优先评估 Latency-Optimized 版本尤其是做多 hop 的 chiplet 网络时每一跳少几个纳秒端到端积累下来很客观。2.3 协议协商的决策表一次说清该听谁的很多人以为 UCIe 的协议选择是软件配置的这在规范里其实写得很细3.3 节给了一个 decision table。链路初始化的时候D2D 适配器会根据对端能力、当前配置的协议模式、以及物理层训练结果来决定最终用哪种 flit 格式。我简单梳理一下这个决策逻辑先看角色和配置。每一边的高层软件或者硬件配置寄存器会声明希望跑的协议模式。如果两边都声明为 PCIe 6.0 Flit就走 Standard 256B Flit如果都是 CXL 3.0就有机会走 Latency-Optimized 256B Flit。再看 Physical Layer 训练结果。 在 Advanced Package 和 Standard Package 下物理层支持的最高速率不一样如果速率不足以支撑某种 flit 模式的带宽需求适配器可以降级到更小粒度的 flit 或者回退到 Raw Mode。最后看对端能力。 1.0 阶段不同厂商实现的模式子集会不一样决策表里规定了可以 fallback 的路径。我遇到的情况是两边的 PHY 都支持 32 GT/s但一方没有实现 Streaming最后 link 只好停在 PCIe 6.0 Flit 模式。这个决策表不是给人肉配置用的而是硬件状态机在上电后自动走的。你真正要做的是在设计阶段把可能用到的模式集合列清楚让软件有办法查询最终协商结果。规范 7.5 节里的寄存器会暴露这些状态后面第六章我们会细说。3. D2D 适配器关键机制CRC、重传与链路训练的配合3.1 适配器在收发路径上做了什么D2D 适配器夹在协议层和逻辑物理层中间很多人误以为它只是做协议转换。实际上它的职责比我一开始想的多很多链接初始化、flit 打包/解包、CRC 计算、重传管理、电源状态转换甚至运行时链路的 parity 检测都归它管。规范第三章把链路初始化拆成三个阶段其中最核心的是 Adapter Initialization。在这个阶段双方要通过 sideband 或者初始化报文交换 capability确认 flit 大小、CRC 算法、重传 buffer 深度这些参数。我用一句话概括它的数据路径协议层下来的一坨数据在适配器里被切成固定大小的 payload加上 header 和 CRC组成一个 flit再往下交给逻辑物理层做 lane 分配。接收方向做相反操作先看 CRC 过不过不过就触发重传请求。这一层值得研究的细节是它的可靠性模型。规范里 3.6 和 3.7 节提到 CRC 计算和 Retry Rules。链路级 retry 不是简单把整个 flit 重发一遍而是设计了一套序号管理和 ack/nak 机制。3.2 CRC 与重传 RDI/FDI 的行为差异Raw Die-to-Die InterfaceRDI和 Flit-Aware Die-to-Die InterfaceFDI拿到的适配器行为不完全一样。RDI 下适配器只负责把 raw data 切成块、加上 path CRC 就发出去接收端如果发现 CRC 错误能不能重传要看两边是否协商了 retry因为 raw 模式本身不感知 flit 边界。FDI 模式下适配器能看到 flit 边界所以可以按 flit 做完整的重传管理。从实现角度我做过的做法是对 RDI 场景默认关闭链路级 retry把可靠性交给上层协议FD 场景则依赖适配器内置的 retry buffer 处理瞬时突发错误效果会好很多。下面用一个简化的状态变换来描述适配器的工作循环# 简化版D2D Adapter 错误检测与重传逻辑逻辑示意 def adapter_tx_flow(flit): # 1. 计算 CRC 并追加到 flit 尾部 # 2. 本地缓存一份 flit用于 retry # 3. 发给逻辑物理层 pass def adapter_rx_flow(received_data): # 1. 用同样的 CRC 算法做校验 # 2. 如果校验失败记录 flit seq发 nack # 3. 如果通过提取 payload 上报协议层发 ack pass def retry_policy(timeout_list): # 关键参数重传次数上限、重传超时阈值 # 超过阈值则触发 Link Training 重新初始化 if retry_count MAX_RETRY_LIMIT: link_layer_reinit()这里逻辑很简单但有实际参数要注意CRC 多项式长度、重传 buffer 大小、以及重传超时。UCIe 1.0 里的 CRC 有多项式选择不同模式用不同多项式重传 buffer 如果开太小长 flit 突发时会直接丢包。还有一点重传机制依赖逻辑物理层的 parity 检测来辅助判断链路健康状况这个在 3.8 节有讲实际的链路误码率很低时retry 几乎不触发但一旦发生缓冲深度决定了能不能扛过错误突发。3.3 链路初始化的三阶段与训练状态机把链路训练放在适配器里讲是因为它不只属于物理层。规范里把初始化分成了三个阶段我这几年看下来真正难调的是 Stage 3Adapter Initialization。Stage 1 和 Stage 2 主要是物理层的事把 lane 对齐、时钟恢复、把电气参数训好到了 Stage 3适配器才开始互相交换配置。这个阶段如果卡住大概率不是时钟问题而是两边在 flit 格式或者流控参数上达不成一致。我一般排查时先看 Sideband 上报的 Training Status 字段在哪一跳停下来的它会告诉你当前卡在哪个 stage 的哪个子状态。如果卡在 Adapter Initialization重点检查两边协议模式声明和 CRC 算法协商结果。调试时我会构造一个最小化配置强制两边都用 PCIe 6.0 Flit Standard 256B排除其它组合的影响然后再逐步打开 CXL 或 Streaming 选项。State Machine Hierarchy 是适配器状态机的结构骨架其中有主状态比如 Disabled、Reset、Init、Active、链路电源状态L0/L1/L2、以及物理层的训练子状态。状态层级多调试仪器显示的时候经常一大串建议把每层的状态变化打点记录下来对照规范总能看到是哪一层先停了。4. 链路训练与翻车现场常见问题的定位与排查4.1 现象一Link Training 卡在 Electric Idle 无法进入 Active这条我印象最深某次做模拟项目 X 的时候Advanced Package 下死活进不了 Active 状态信号观测显示发端已经进入 Electrical Idle 状态了但收端完全发现不了。原因后来定位到是收端检测 threshold 设置过严。规范 5.12 节定义了 electrical idle 的进入/退出条件接收端的空闲检测器要有足够的 hold time否则发端进了 idle 后稍有一点电压波动就被误判为退出状态机自己也乱了。解决方法是调整 receiver 端的 electrical idle detect threshold并稍微增加滤波时间常数。在 PHY 的寄存器接口里找到对应控制位把阈值从典型值的 80% 放宽到 60% 左右重新跑训练就过了。调试时可以通过 Sideband 读 Link Training Status确认到底是哪一端进入/退出 idle 超标。4.2 现象二CRC 校验频繁失败重传风暴导致带宽腰斩链路明明能通但吞吐量不稳定抓包发现 retry 次数异常高每个 flit 都要重传。原因大概率不是 CRC 多项式选错而是链路信号完整性在某个 lane 上出了问题造成偶发 bit 翻转。UCIe 的重传机制面对这类错误是逐 flit 重传一两个 flit 出错不会崩但错误出现频率高时重传开销直接把有效带宽吃掉一半。解决方向应放在物理层而不是协议层。我会先跑一遍单 lane 的 PRBS 测试确认是哪条 lane 的误码率高再看眼图和串扰情况。曾遇到一个案例是某个 lane 的信号在封装基板上走了很长一段插损超标导致误码率升高。后来调整了走线层、加粗线宽回损和插损才达标。CRC 和重传机制在这里是兜底不能当作信号质量差的遮羞布。4.3 现象三Lane Reversal 后链路极不稳定时通时断打开 Lane Reversal 功能后链路就不稳定了。镜像交换 lane 之后时序和训练总时好时坏。原因是 Lane Reversal 不只是把 lane 顺序调换还牵扯 lane id 映射和 remapping 逻辑。如果文档里的 4.2 节 lane 编号没对应上或者 remap 表配置错位就会导致数据被错误地分配到非对应的物理 lane 上。解决方法是先把 lane reversal 关掉确认基础链路稳定后再打开。打开后还要检查 sideband 中上报的 TX/RX lane mapping table确保对端映射关系和硬件连线一致。我曾在硬件连线设计时把 lane 的物理序号从 0 还是 1 开始搞混造成整张映射表所有 lane 都错位了一个 channel。最简单的做法是先跑 link training 的低速模式让 PHY 自动完成 lane reversal detect再检查每个 lane 上训练报文是否落在正确的编号上。4.4 现象四Multi-module 配置下初始化的时序冲突多个 die 通过 UCIe 组成多模块系统时每个模块的上电时序不同造成初始化时模块间相互等待。原因在于 UCIe 1.0 的多模块初始化没有全局统一指挥各模块各自启动一等跑到一半发现需要的相邻模块还没有 Ready。解决方法是按层级做好模块间 reset 依赖链先保证所有参与初始化的模块电源稳定再用统一的 sideband 信号对它们做同步释放 reset。规范 4.7.1 节提到的多模块初始化顺序我一般这样实现主模块先完成自身的 PHY 校准再通过 sideband 广播初始化命令其余模块收到后再进入各自训练流程。必要时可以人为加一段延时避免多个模块同时抢 sideband 通道。4.5 现象五接管现有 PCIe/CXL 控制器后 UCIe 适配器不兼容拿来现成的 PCIe 6.0 控制器直接接 UCIe 适配器结果链路能初始化但业务流量跑不通。原因是 PCIe 控制器实现里通常有自己的 flit 封装逻辑而 UCIe 的 D2D 适配器在 FDI 模式下需要卸载协议层的部分 flit 处理。两边都试图封装或者解析 flit就会造成重复封装、数据语义错位。解决是在协议层与 D2D 适配器之间把职责分界明确。UCIe 规范明确协议层负责与 PCIe/CXL 有关的标准行为D2D 适配器只负责与 die-to-die 有关的链路行为不要重复封装。检查时重点看协议层送出来的 flit 是否已包含正确的头信息适配器不要再额外加自己的头部。我在实际项目中就遇到过适配器默认给所有流量再包一层头导致对端解析时 offset 全错之后我对头信息归属列了一个权责表才彻底解决。5. 逻辑物理层与电气参数把 Lane 映射和信号质量抓在手里5.1 Byte-to-Lane 映射与 Valid Framing 怎么配置逻辑物理层一方面是适配器和电气层之间的中间地带另一方面承担了字节到 lane 的映射、加扰、训练序列生成、和时钟门控等。规范 4.1.1 节详细描述了 Byte-to-Lane Mapping 的方式一条 16 lane 的链路数据会被分到 16 条物理 lane 上每一拍从所有 lane 上并行收 16 字节。问题是接收端靠什么知道每一拍从哪里开始答案就是 Valid Framing。发送端在数据的开头或结尾用额外的信号线或某种编码标注这一拍是有效的接收端对正要同步这个有效的边界然后才能正确重组字节。这个机制和传统 SerDes 的 training pattern 完全不同不是靠时钟恢复后自动字节对齐而是靠 Valid 信号作为帧同步。实际调试中我最常犯的错是把 Valid 信号的时序要求和数据信号搞混导致接收端在某一拍 y 上丢失了对齐标志整个流全部错位。规范里强调Valid 和时钟信号以及数据信号之间需要满足一定的 setup/hold 时序物理实现时要留意龙其是收发两端可能使用不同时钟域时需要做一个同步处理。Free Running Clock Mode 是另一个容易绕晕的点。这个模式下即使没有数据流量时钟信号也保持运行收端可以靠这个时钟做持续的跟踪。好处是省去了频繁的电离 idle 和唤醒过程坏处是功耗偏高。如果你是低功耗场景可以考虑把 Free Running Clock 关掉让时钟跟随数据一起门控这样动态功耗会低一些但链路重新唤醒时会引入额外延迟。5.2 Lane Reversal、Remapping 与冗余修复Die-to-die 链路在封装时可能因为绕线、层叠等原因lane 的物理顺序和逻辑顺序不一致或者出线时某些 lane 走线歪了导致信号质量不行。UCIe 的做法相当暴力也相当好用lane reversal 直接反转顺序remapping 把损坏的 lane 重映射到备用的 lane 上。规范 4.3 节里定义了数据 lane 的修复机制和时钟/track lane 的修复机制比我想的灵活很多。数据 lane repair 在初始化阶段根据训练结果确定哪些物理 lane 可用如果 lane 数不够链路可以降级到更少的有效 lane 继续工作也就是 width degrade。这部分在先进封装的场景下特别重要因为基板走线的缺陷率不可忽略有了修复机制良率能拉回来不少。我实际配置 lane repair 的经验是优先把故障 lane 修复到冗余 lane 上只有当冗余 lane 也不够时才启用 lane repealing。修复过程中发送端和接收端都必须对 remapping 结果保持同步否则接收端会在同一组数据上映射到不同的物理 lane 上。规范里有一个 Valid Repair 的实现细节链路在重映射时其实是通过 sideband 交换修复请求然后两端同时更新映射表。相对于直接硬改硬件布线软性的 remapping 确实把标称可靠性和良率都提高了。数字化描述一下常见 lane 配置的可靠性参数Lane 配置模式有效数据带宽修复后最大可用 Lane 数典型良率提升16116 数据 1 冗余16 字节/拍17中等16无冗余16 字节/拍16无818 字节/拍9高宽边耦合 64264 字节/拍66较高5.3 电气层TX/RX 均衡、封装类型与 BER 指标电气层是整个 UCIe 中物理实现最难的部分。规范第五章里明确了发射器驱动拓朴输出阻抗、去加重和均衡参数都是可配置寄存器。接收器端 Rx Termination 也分标准封装和先进封装两套需求。我们做 chiplet 芯片时发现多数信号质量问题出现在封装内部的互连通道而不是 die 本身。所以参数配置前先要搞清楚自己用的是 standard package 还是 advanced package这两类的通道预算完全不同。根据规范标准封装和高级封装支持的最高数据速率不同。标准封装下通道损耗预算更紧张数据速率多半要回退到 24 GT/s 甚至 16 GT/s高级封装如基于硅中介层或等效的高密度互连可以跑 32 GT/s。另外 Transmitter Equalization 参数通常有预设的 tap 组合比如 2-tap 或 3-tap你需要根据通道 S 参数实测来选一组不能满脑子能跑多快跑多快。我在板级测试时看到的经验是先进封装下回退一档速率往往误码率从 1e-8 直接掉到 1e-15 以下所以可靠性和峰值速率之间要权衡。接收端的 equalization 也同样重要尤其是 CTLE 增益设置。这个值太大容易放大高频噪声太小又补偿不了插损。比较务实的做法是把 TX 均衡先固定在中值扫描 RX 的 CTLE 档位在每个档位下看 PRBS 误码率或者 eye 高度做成一张二维表来选最优组合。这个先固定一个维度、扫描另一个维度的调试方法是换串扰干扰下最实用的做法。BER 要求方面UCIe 规范把 CRC 和 retry 跟误码率绑定在一起链路层能容忍一定的原始 bit 错误只要在 retry 机制可恢复的范围内。如果原始误码率过高retry 会反复触发吞吐量就下来了。我一般给自己定的实用门槛是在看 eye 的时候低速率下要求眼高至少 30% 的摆幅高速率下至少 20%低于这个阈值就建议先调整均衡而不是硬抗。6. 从寄存器视角验证 UCIe 链路软件能做什么与验证技巧6.1 通过 DVSEC 发现与管理 UCIe 链路规范第七章给了一套软件视图。UCIe 链路在 PCIe 配置空间里用 Vendor Defined CapabilityDVSEC暴露自身信息这样系统软件不需要私有的接口也能枚举和配置链路。首先在 Configuration Space 里找到 DVSEC 的 Capability ID 和 Capability Version然后读取 UCIe Link DVSEC里面记录了链路状态、支持的协议模式、以及当前协商结果。这里我最依赖的一个字段是 Link Status它直接把训练完成情况、当前速率、当前宽度和 lane 映射情况全部翻出来了。想从软件层面做实时的链路体检我会用下面这个思路把寄存器操作封装成可复现脚本# 伪代码UCIe Link 状态读取与关键字段解析 def read_ucie_link_status(pci_dev): # 对于 PCIe 配置空间做 Read解析 DVSEC 结构 # 找到 UCIe Link DVSEC 的 offset 0x10 ~ 0x2F # 其中 Link Status 寄存器 offset 0x14 之后 # 该寄存器 4:0 位代表 Link State比如 # 0x0 Disabled # 0x1 Reset # 0x2 Init # 0x3 Active # 需要做掩码提取 # state (raw 0x1F) pass def verify_link_ready(pci_dev, timeout_ms): # 循环轮询 Link Status直到状态变成 Active # 若是进入 Disabled/Fault 状态则打印错误码 # 也可以读取 Link Training StatusLTSSM 相关字段 # 判断链路是否稳定在 L0正常传输状态 pass用这套脚本做的意义在于链路训练的结果不只是 PHY 工程师能看软件工程师也能通过标准配置空间读到同一份数据两边排查时有一个共同指标。我在一次排障中发现软件读到的 Link State 是 L2低功耗状态但 PHY 侧测试仪器显示已经 Active说明是电源管理策略把链路切到低功耗挂起了与“链路没训练”不是一回事。如果没有软件侧确认我可能还要花半天去查 PHY 状态。6.2 验证时我怎么设计一套可控的复现流程拿到资源之后最容易犯的错是把整本几百页规范从头看到尾看到后面忘前面。我的阅读和验证习惯是先建立分层心智模型即协议层、D2D 适配器、逻辑物理层、电气层四个层次每读一层就写下和上一层的接口关系。然后对照寄存器章节找实际能读到哪些状态位最后挑选一个简化的测试用例走通比如强制配置成 PCIe 6.0 Flit Standard 256B速率 32 GT/s161 lane。复现时还要注意一点UCIe 的协议协商结果会受到制造工艺和封装寄生参数影响。同一个逻辑配置在不同工艺角下可能跑到 32 GT/s 时 BER 略高。所以验证流程里最好保留一个 margin 测量步骤同一个配置在慢工艺角和快工艺角各跑一遍 PRBS记录眼高和眼宽余量。我有一次在实验室里配置优化得很好但小批量样品一上机就出现偶发重传后来才发现做实验用的是一颗品质特别好的中介层片子样品的中介层没那么理想通道损耗比实验室环境多 1 dB 左右。从那以后我每次做链路验证都强制在流程里加一步用实测的 S 参数替代仿真参数重跑一遍均衡配置把仿真和实测的 gap 缩小在可控范围内。希望这份 UCIe 1.0 规范阅读指南能帮你在 chiplet 项目里少走一段弯路。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站