3. PCIe 事务层协议:Memory Read/Write TLP 格式、Completion 与 Non-Posted 事务、Max Payload Size (MPS) 对延迟的影响

事务层(Transaction Layer)是 PCIe 协议栈的最顶层,负责生成与解析事务层包(TLP)。对于 DMA 传输而言,Memory Read 与 Memory Write 是最核心的两种事务类型。本章将深入解析 TLP 的字段结构、Non-Posted 与 Posted 事务的差异,以及 Max Payload Size(MPS)如何直接影响传输延迟。

关键概念速览: Memory Read 属于 Non-Posted 事务,必须等待 Completion 返回数据;Memory Write 属于 Posted 事务,无需等待响应。MPS 决定了单个 TLP 能携带的最大数据载荷,直接影响链路利用率和延迟。

3.1 Memory Read TLP 格式与字段解析

Memory Read TLP 用于从目标设备(如 Endpoint 或 RC)的指定地址空间读取数据。其格式包含一个 12 字节或 16 字节的头部(Header),紧随其后的是可选的 TLP Digest(ECRC)。

字段 位宽 描述
Fmt / Type 7:0 格式与类型:Memory Read 为 0000_0000b(3DW Header, no data)或 0010_0000b(4DW Header, no data)
TC 2:0 Traffic Class:用于 QoS 区分,默认 0
TD 1 bit TLP Digest 存在标志:1 表示尾部有 ECRC
EP 1 bit 中毒标志(Poisoned):指示数据已损坏
Attr 2 bits 属性:顺序模型、No Snoop、Relaxed Ordering
Length 9:0 数据载荷长度,单位 DWord(4 字节),最大 1024 DWord
Requester ID 15:0 请求者 Bus/Device/Function 编号
Tag 7:0 事务标签,用于匹配 Completion
Address 32 / 64 bit 目标地址(3DW 为 32 位,4DW 为 64 位)
设计提示: Tag 字段在 DMA 设计中至关重要。FPGA 中的 DMA 控制器必须管理 Tag 池,确保每个未完成的 Non-Posted 请求拥有唯一 Tag,否则会导致 Completion 无法正确路由。
Memory Read TLP 格式结构 TLP Header (12 或 16 字节) Fmt/Type TC Length Requester ID Tag Address [31:2] Attr/EP/TD Data Payload (无,Memory Read 不携带数据) 可选的 TLP Digest (ECRC) — 4 字节 TLP 从发送端进入数据链路层

3.2 Memory Write TLP 格式与 Posted 事务特性

Memory Write TLP 用于向目标地址写入数据。与 Read 不同,Write 属于 Posted 事务:发送端发出 TLP 后无需等待 Completion,直接释放资源。这使得 Write 具有更低的延迟和更高的吞吐量,但也带来了可靠性风险——发送端无法直接得知写入是否成功。

特性 Memory Write (Posted) Memory Read (Non-Posted)
是否需要 Completion 否 是(必须返回 CplD)
延迟特性 低(无等待) 高(需往返)
数据流方向 请求者 → 目标 请求者 ← 目标(通过 CplD)
错误报告机制 通过 AER 或 Poisoned 位 通过 Completion 状态
典型应用 DMA 写、寄存器写 DMA 读、配置空间读
兼容性警告: 某些老旧 Root Complex 或 Switch 对 Posted 事务的流控(FC)信用量配置较小。当 DMA 写流量过大时,可能触发 FC 阻塞,导致写延迟急剧上升。设计时建议监控 FC 信用量状态。
Posted vs Non-Posted 事务流程对比 Memory Write (Posted) 发送端 接收端 MWr TLP ✗ 无 Completion 发送端立即释放资源 Memory Read (Non-Posted) 发送端 接收端 MRd TLP CplD (含数据) 发送端等待 Completion Tag 保持占用

3.3 Completion 事务:Cpl 与 CplD

Completion 是 Non-Posted 事务的响应。对于 Memory Read,目标设备必须返回 Completion with Data (CplD)。Completion 头部包含与请求对应的 Requester ID 和 Tag,以及完成状态(Successful Completion / Unsupported Request / Completer Abort 等)。

  • Cpl(Completion without Data): 用于 I/O 或 Configuration 写完成,不携带数据。
  • CplD(Completion with Data): 用于 Memory Read 完成,携带请求的数据载荷。
  • Split Completion: 当目标无法立即响应时,可先返回 Cpl(状态为“成功”但无数据),稍后再发送 CplD。此机制在复杂系统中会增加延迟不确定性。
延迟分析: 一次 Memory Read 的完整延迟 = TLP 发送延迟 + 目标处理延迟 + CplD 返回延迟。在 FPGA DMA 设计中,目标处理延迟通常包括:地址译码、数据读取、内部总线仲裁。实测表明,典型 FPGA Endpoint 的 Read 延迟在 200 ns ~ 2 μs 之间,取决于 MPS 和内部 FIFO 深度。

3.4 Max Payload Size (MPS) 对延迟的影响

MPS 是 PCIe 链路层协商的参数,定义了单个 TLP 能携带的最大数据载荷(以字节为单位)。常见 MPS 值为 128 B、256 B、512 B、1024 B、2048 B、4096 B。MPS 对 DMA 传输延迟有显著影响:

MPS 值 单 TLP 最大数据 延迟特性 适用场景
128 B 128 字节 低延迟(小包快速发出) 控制寄存器、小数据块
256 B 256 字节 中等延迟 通用 DMA
512 B 512 字节 较高延迟(需等待数据填满) 大数据流、视频传输
1024 B 1024 字节 高延迟(首字节延迟增加) 高性能计算、批量数据
2048 B / 4096 B 2048 / 4096 字节 最高延迟(需大缓冲区) NVMe、GPU 通信

MPS 对延迟的影响机制:

  • 首字节延迟(First Byte Latency): 发送端必须等待数据累积到 MPS 大小才能封装 TLP。MPS 越大,首字节等待时间越长。
  • 链路利用率: 大 MPS 减少 TLP 头部开销(每 TLP 固定 12~16 字节头部),提升有效带宽,但牺牲单次延迟。
  • 流控信用量: 大 MPS 需要更多的接收端缓冲区信用量。如果信用量不足,发送端会被迫等待,增加延迟。
MPS 对延迟与带宽的影响趋势 128B 256B 512B 1024B 2048B 4096B 低 高 延迟 / 带宽 延迟 带宽 MPS 增大 → 延迟上升,带宽趋近饱和 设计需在延迟与吞吐量之间权衡
设计建议: 在 FPGA DMA 中,建议根据应用场景动态配置 MPS。对于延迟敏感的控制类 DMA,使用 128 B 或 256 B;对于吞吐量优先的批量数据传输,使用 1024 B 或更大。同时,确保 Root Complex 和 Switch 支持所选的 MPS 值,否则链路会协商到最低公共值。

3.5 事务层协议对 DMA 延迟的综合影响

综合来看,事务层的三个关键因素共同决定了 DMA 传输的延迟特性:

  1. 事务类型: Memory Write(Posted)延迟低于 Memory Read(Non-Posted),因为后者需要等待 Completion 往返。
  2. TLP 头部开销: 每 TLP 固定 12~16 字节头部,小数据包时开销占比高,降低有效带宽。
  3. MPS 与数据对齐: MPS 越大,单 TLP 承载数据越多,但首字节延迟增加。数据地址未对齐时,可能触发额外的 TLP 拆分,进一步增加延迟。
实测数据参考: 在 Gen3 x8 链路上,使用 256 B MPS 进行 4 KB DMA Read,典型延迟约为 1.2 μs(包含 TLP 发送 + 目标处理 + CplD 返回)。将 MPS 提升至 1024 B 后,延迟增加至 1.8 μs,但有效带宽从 5.2 GB/s 提升至 6.8 GB/s。设计者必须根据系统需求做出权衡。
DMA Read 延迟分解(事务层视角) 总延迟 = TLP 发送 + 目标处理 + CplD 返回 TLP 发送 目标处理(地址译码 + 数据读取) CplD 返回 受 MPS 影响 受内部总线频率影响 受链路速率影响