【PCIe 6.0】PCIe Flit 打包解包规则


🔥点击查看精选 PCIe 系列文章🔥
🔥点击进入【芯片设计验证】社区,查看更多精彩内容🔥


📢 声明

  • 🥭 作者主页:【MangoPapa的CSDN主页】。
  • ⚠️ 本文首发于CSDN,转载或引用请注明出处 https://mangopapa.blog.csdn.net/article/details/128940275
  • ⚠️ 本文为非盈利性质,目的为 个人学习记录知识分享。因个人能力受限,存在协议解读不正确的可能。若您参考本文进行产品设计或进行其他事项并造成了不良后果,本人不承担相关法律责任。
  • ⚠️ 若本文所采用图片或相关引用侵犯了您的合法权益,请联系我进行删除。
  • 😄 欢迎大家指出文章错误,欢迎同行与我交流 ~
  • 📧 邮箱:mangopapa@yeah.net
  • 💬 直达博主:loveic_lovelife(搜索或点击扫码)




1. PCIe 6.0 Flit 概述


  PCIe Flit Mode 时,以 Flit 为最小单位进行 Packets 传输。

  PCIe 6.0 Flit 由 236B TLP + 6B DLP + 8B CRC + 6B FEC 共 256B 组成,在物理层的逻辑子层进行 Flit 打包及解包(Packing / Unpacking)。Flit 格式如下图所示。

在这里插入图片描述

▲图 1:PCIe Flit Format

  PCIe Flit Packing 流程如图 2 所示。先从 Transaction Layer 及 Data Link Layer 拿到待传输的 TLP 及 DLLP 并按一定规则填充到 TLP Bytes 及 DLP Bytes,然后基于 236B TLP Bytes 及 6B DLP Bytes 计算出 8B CRC,最后三者作为输入计算出 6B ECC。至此,完整的 Flit 打包完毕。

在这里插入图片描述

▲图 2:PCIe Flit 打包流程(图左)

  PCIe Flit Unpacking 流程如图 3 所示,其是 Flit Packing 的逆过程。


在这里插入图片描述

▲图 3:PCIe Flit Unpacking 流程(图左)

  Flit Packing、Unpacking 过程中,CRC 及 ECC Bytes 长度固定且计算较为成熟,按照既定规则去算去填充/解析即可,比较新的是 TLP 及 DLP Bytes 填充/解析。打包解包过程中涉及到 TLP 的切片、拼接及 NOP 规划填充,涉及 DLP 中的 Flit 状态指示、新的 Ack/Nak 机制、新的 Flow Control DLLP 等等,都需要花些精力去研究。



2. TLP Bytes


  我们知道,PCIe 的 DLLP、CRC 及 FEC 均为定长,但不同类型、不同载荷的 TLP 长度是不定的,需要根据具体长度对 TLP 进行切片或者将多个 TLP 拼接。

  PCIe TLP 填充到 Flit TLP Bytes 时,有几条常规情况下的规则:

  • 同一 TLP 可以放到多笔 Flit 中。 比如 TLP0 Size 超出 236B,那么只能对其进行拆分,放到多笔 Flit 中进行发送;比如 TLP1 Size 为 16B,前 8B 位于 Flit0 TLP Bytes 的末尾,后 8B 位于 Flit1 TLP Bytes 的起首。无论那种情况,均需确保被拆分的 TLP 位于前后相邻的 Flit 中。

  • 一笔 Flit 中可以填充多笔 TLP。 TLP Size 大小不一,在 236B TLP Bytes 范围内,允许填充多笔 TLP。注意,填充 TLP 的最大数目是有要求的,即每 Half-Flit 中的 TLP 数目不能超过 8,相关讨论见:《讨论:为什么每 Half-Flit 中的 TLP 数目不能超过 8 个?》 。对于接收端而言,若接收端在 Half-Flit 中检测到了超过 8 笔 TLP,可以记录并上报错误。

  • TLP 在 Flit 内的起始位置不受限于任何边界约束。 PCIe Webinar Q&A 中是这么说的,但这么说并不严谨,这么说容易被曲解为 TLP 可以在 TLP Bytes 中任一 Byte 位置起始。考虑到 TLP 和 NOP Size 均为 DW 整数倍,TLP 的起始位置只可能出现在 DW Boundary 上。如果某 TLP 之前为 NOP,还需确保 TLP 起始位置 4DW 边界对齐。

  • 当 Transaction Layer 没有 TLP 要传输时,填充 NOP TLP(1DW)。一旦开始插入 NOP TLP,在下一 4DW Boundary 之前的 TLP Bytes 均需填充 NOP。也就是说,NOP 之后的 TLP 要求 4DW 边界对齐,即边界对齐的 4DW 之内,可以全部为 TLP,可以全部为 NOP,可以为 TLP -> NOP,但不允许出现 NOP -> TLP 的转换。


  还有一些 TLP 出粗情况下的必要但不太常用的规则:

  • Nullified 或 Poisoned TLP 问题。

    • 如果当前 Flit 最后一笔 TLP 为 Poisoned 或 Nullified TLP,需要通过 DLP Bytes 发送 Flit_Marker,通过 Flit_Marker 中的 Flit_Statue 将该 TLP 标记为 Posioned 或 Nullified(作用同 Non-Flit Mode 时的 EDB)。若某 Poisoned / Nullfied TLP 跨过当前 Flit 延续到了下一 Flit,这两笔 Flit 的 Flit_Marker 中 Flit_Status 都要对 Poisoned 或 Nullified 状态进行指示。

    • 接收端接收到 Nullfied 状态的 TLP 后,将其作废,并释放其早前占用的 Credits。

    • 若发送端发送 TLP 过程中发现某 TLP Nullfied 或 Poisoned,当前 Flit 中该 TLP 之后的 TLP Bytes 全部填充 NOP TLP。

  • 其他。 我们看到一条补充一条。

释义:

  • Nullified,作用同 Non-Flit Mode 时的 EDB,常用于 Switch Cut-Through Mode。TLP 边收边发,收到最后发现 TLP 有问题,就得通过 EDB 来告知下游设备将其作废。
  • Poisoned,Switch 转发 TLP 过程中发现 Data Payload 出错,但又不得不继续传递该 TLP,则将 TLP Header 中的 EP 位置一,告知下游数据出错。


3. DLP Bytes


  DLP Bytes 共 6B,按照作用可以分为两部分:

  • DLP[0:1]。该部分有以下作用:
    • 指示当前及前一 Flit 的类型(IDLE, NOP 或 Payload Flit)。
    • 指示 DLP[2:5] 中 DLLP Payload 的类型(DLLP Payload 或 Optimized_Update_FC/Flit_Marker)。
    • Flit 粒度 Ack/Nak 机制的实现。
  • DLP[2:4]。该部分为 DLLP Payload,携带了 PCIe DLLP,比如 Flow Control DLLP、Flit_Marker 及其他 Vendor 自定义的 DLLP 等。

  虽然一个 Flit 中的 DLP Bytes 远少于 TLP Bytes,但为了准备这 6B DLP 而下的功夫却要比 236B TLP 多。



4. CRC Bytes


  CRC Bytes 共 8B,由 236B TLP + 6B DLP 作为输入计算得到。



5. ECC Bytes


  FEC 是指前向纠错,ECC 是指算出来的纠错码。PCIe Flit Mode 采用 3 路交织的方式对 236B TLP + 6B DLP + 8B CRC 进行计算。



6. 参考


  1. PCI Express 6.0 Base Spec


— END —

🔥 精选往期 PCIe 协议系列文章🔥


⬆️ 返回顶部 ⬆️

### PCIe 6.0硬件设计规范和指导 #### 设计目标与特点 PCIe 6.0作为最新的高速串行计算机扩展总线标准,在性能上实现了显著提升。其主要特点是支持更高的数据传输速率,达到每秒64千兆字节(GT/s),并引入了前向纠错(FEC)机制来提高信号完整性[^4]。 #### 协议层改进 为了实现更高效的数据传输,PCIe 6.0采用了全新的FLIT (Flow Control Unit)编码方式替代传统的8b/10b或128b/130b编码方案。这种变化不仅提高了有效载荷比例,还增强了链路管理能力,使得系统能够更好地处理错误情况下的恢复操作[^3]。 #### 物理层优化 在物理层面,PCIe 6.0继续沿用了差分对形式的电气接口设计,但对其参数进行了细致调整以适应更高频率的操作环境。具体来说,包括但不限于降低抖动容忍度、增加预加重系数范围等措施,从而确保即使是在极端条件下也能维持稳定可靠的通信连接。 #### 参考设计方案建议 对于希望基于此版本构建产品的工程师而言,官方提供了详尽的设计指南文档供参考。这些资料覆盖了从原理图绘制到PCB布局布线等多个方面的重要考量因素,并给出了具体的实施步骤和技术要点说明。 ```python # Python代码示例:模拟简单的PCIe配置空间读取功能 class PCIEConfigSpace: def __init__(self, base_address): self.base_address = base_address def read_register(self, offset): # 假设这里有一个函数可以访问内存映射I/O区域 value = memory_read(self.base_address + offset) return value config_space = PCIEConfigSpace(0xCF8) vendor_id = config_space.read_register(0x00) # 获取Vendor ID寄存器值 device_id = config_space.read_register(0x02) # 获取Device ID寄存器值 print(f"Vendor ID: {hex(vendor_id)}, Device ID: {hex(device_id)}") ```
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MangoPapa

请作者喝瓶可乐吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值