Chapter 5: TLP Elements
书籍: PCI Express Technology 3.0 (MindShare Press, 2012)
页码: Book Pages 169-226 | PDF Pages 226-277
学习日期: 2026-04-13
本章概要
本章详细描述 Transaction Layer Packet (TLP) 的结构、格式和各类字段。TLP 是 PCIe 中承载事务请求和完成响应的数据包。本章涵盖 TLP 组装/拆解过程、通用 Header 格式、各类 TLP 请求(Memory/IO/Configuration/Message)以及 Completion 的格式。
5.1 包协议的优势
1. 包格式明确定义
- PCI: 传输大小不确定,无法确定有效载荷边界
- PCIe: 包有已知的大小和格式,Header 指明类型
- Header 大小固定(除了地址字段,可以是 32-bit 或 64-bit)
- 接收方在传输开始后不能暂停或提前终止
2. 帧符号定义包边界
- Gen1/Gen2 (8b/10b): 使用 Start (STP) 和 End (END) 控制符号标记包的开始和结束
- Gen3 (128b/130b): 不再使用传统的控制符号
- 任何错误/毛刺在 PCIe 中更容易识别和处理
3. CRC 保护整个包
- PCI: 每个数据阶段使用奇偶校验(边带信号)
- PCIe: 使用 CRC 验证整个包的端到端传输
- Data Link Layer 添加 Sequence Number,支持自动重传
5.2 TLP 结构
TLP 组装 (Transmit Side)
软件层 → 事务层 生成事务层数据 ↓ 添加 TLP Header ↓ 添加 Data Payload (如果有) ↓ 添加 ECRC (如果启用) ↓ 发送到 Data Link Layer 添加序列号、LCRC ↓ 发送到 Physical Layer 添加 STP、CRC、END 符号 ↓ 串行传输TLP 拆解 (Receive Side)
串行接收 ↓ Physical Layer 检测 STP/END,提取符号 8b/10b 解码 校验 CRC ↓ Data Link Layer 检查序列号 校验 LCRC 发送 ACK/NAK 丢弃/转发 TLP ↓ Transaction Layer 检查 ECRC (如果存在) 解析 Header 提取 Data Payload ↓ 软件层TLP 层次结构
┌─────────────────────────────────────────────────────┐ │ TLP Data Payload (可选) │ ├─────────────────────────────────────────────────────┤ │ TLP Header (3 DW 或 4 DW) │ │ - Format/Type │ │ - TLP Digest (可选, 1 DW) │ │ - 其他 Header 字段 │ ├─────────────────────────────────────────────────────┤ │ Data Link Layer: Seq Num + LCRC │ ├─────────────────────────────────────────────────────┤ │ Physical Layer: STP Symbol + Framing │ └─────────────────────────────────────────────────────┘5.3 通用 TLP Header 格式
TLP Header 结构 (3 DW 或 4 DW)
Byte 0 │ Format[1:0] │ Type[4:0] │ Byte 1 │ Reserved │ TC[2:0] │ Byte 2 │ Attr[1:0] │ TLP Hnd[1] │ (Hnd = Header Digest Present) Byte 3 │ TLP Type[4:0] │ Reserved │ Byte 4-7 │ Address (32-bit) or Address[31:0] (64-bit) │ Byte 8-11│ Address[63:32] (仅 64-bit 地址) │ Byte 12 │ Extended Register │ Register │ Byte 13 │ Reserved │ Byte 14-15│ Transaction ID │ ... (基于 TLP 类型不同)关键 Header 字段说明
| 字段 | 位置 | 说明 |
|---|---|---|
| Format[1:0] | Byte 0[7:6] | 00=No Data, 01=1DW Data, 10=2DW Header(64b addr), 11=3DW Header |
| Type[4:0] | Byte 0[5:0] | TLP 类型 |
| TC[2:0] | Byte 1[2:0] | Traffic Class (0-7) |
| Attr[1:0] | Byte 2[7:6] | 属性: Bit 6=RO, Bit 7=NS |
| TD | Byte 3[7] | TLP Digest 存在标志 |
| EP | Byte 3[6] | Poisoned Data (数据污染) |
| Transaction ID[15:0] | Bytes 14-15 | 唯一标识请求 |
| Length[9:0] | Bytes 7-8 (DW0) | 以 DW 为单位的长度 |
Format/Type 编码表
| Format | Type | TLP 类型 |
|---|---|---|
| 000b | 00000b | MRd (Memory Read) |
| 000b | 00001b | MRdLk (Memory Read Locked) |
| 000b | 00100b | IO Rd (IO Read) |
| 000b | 00101b | IO Wr (IO Write) |
| 000b | 01010b | Config Rd0 (Type 0) |
| 000b | 01011b | Config Wr0 (Type 0) |
| 000b | 01110b | Config Rd1 (Type 1) |
| 000b | 01111b | Config Wr1 (Type 1) |
| 100b | 10000b | Completion (Cpl) |
| 100b | 10001b | Completion with Data (CplD) |
| … | … | … |
Poisoned Data (EP)
- EP = 1 表示数据已被污染
- 接收方应标记数据不可靠
- 等同于 PCI 的 PERR#
5.4 Memory Requests
Memory Read Request (MRd)
特点: Non-Posted,需要 Completion 返回数据
Header: 3 DW (32-bit addr) 或 4 DW (64-bit addr) ↓ Address: 目标内存地址 ↓ Length: 要读取的 DW 数 (1-1024) ↓ Requester ID: 发送者的 BDF ↓ Completer 返回 CplD (Completion with Data)Memory Write Request (MWr)
特点: Posted,无需响应
Header: 3 DW 或 4 DW ↓ Address: 目标内存地址 ↓ Data Payload: 要写入的数据 ↓ ECRC: 可选3 DW vs 4 DW Header
- 3 DW: 32-bit 地址,Header 后直接是数据
- 4 DW: 64-bit 地址,低 32 位在 DW1-2,高 32 位在 DW3
5.5 IO Requests
IO Read/Write
特点: Non-Posted,需要 Completion
Header: 3 DW(IO 地址为 32-bit)
Format = 00b (No Data) 或 01b (Data Payload present) Type = IO Rd / IO Wr Address = 32-bit IO 地址 Length = 1 (IO 访问只支持单 DWORD) Requester ID = BDFIO vs Memory 区别
| 特性 | IO 请求 | Memory 请求 |
|---|---|---|
| 地址宽度 | 32-bit | 32-bit 或 64-bit |
| Length | 固定 1 DW | 1-1024 DW |
| Posted? | No | Memory Write = Yes |
| 用途 | Legacy 设备寄存器 | MMIO |
5.6 Configuration Requests
Type 0 vs Type 1
- Type 0: 访问最终设备(在目标总线上)
- Type 1: 穿过 Bridge(用于路由到下游总线)
Configuration Request Header
Format = 00b (No Data) Type = Config Rd0/Wr0 或 Config Rd1/Wr1 Address: Bus/Dev/Func + Register Number Requester ID = RC 的 BDF寄存器访问
- 寄存器号必须是 4 的倍数(DW 对齐)
- Extended Configuration Space 使用额外的高位地址
5.7 Completions
Completion 格式
无数据 Completion (Cpl):
Header: 3 DW Status: OK / UR / CRS / CA Requester ID: 响应者 Transaction ID: 匹配原始请求带数据 Completion (CplD):
Header: 3 DW Status: OK Data: 返回的数据 Byte Count: 剩余可返回字节 Lower Address: 数据所在地址Completion Status
| 状态 | 说明 | 场景 |
|---|---|---|
| OK (00b) | 成功 | 正常完成 |
| UR (01b) | Unsupported Request | 不支持的请求 |
| CRS (10b) | Completion Retry Status | 需要重试 |
| CA (11b) | Completer Abort | 终止 |
Byte Count 和 Lower Address
- Byte Count: Completer 还能返回多少字节(用于分段返回)
- Lower Address: 本次返回数据在请求地址中的起始偏移
5.8 Message Requests
Message 类型
| 消息类型 | 说明 |
|---|---|
| INTx | 传统中断消息 (Assert/Deassert INTA-D) |
| Power Management | 电源管理消息 |
| Error Signaling | 错误信号消息 |
| Locked Transaction | 锁定事务消息 |
| Slot Power Limit | 插槽功率限制消息 |
| Vendor-Defined | 厂商自定义消息 |
| LTR | Latency Tolerance Reporting |
| OBFF | Optimized Buffer Flush/Fill |
Message 路由方式
- Implicit Routing: 广播给所有设备
- Address Routing: 路由到特定地址
- ID Routing: 路由到特定 BDF
Message Header
- 3 DW Header
- 使用 Implicit Routing(大多数消息)
- Message Code 字段指明消息类型
5.9 TLP Digest (ECRC)
ECRC 保护范围
ECRC 覆盖 Header 和 Data Payload,但不包括:
- Seq Num
- LCRC
- Framing 符号
ECRC 生成
- 可选(通过 TLP Digest (TD) 位指示)
- 如果设备启用 ECRC,所有发出的 TLPs 必须包含 ECRC
ECRC 检查
- 最终目标设备检查 ECRC(端到端保护)
- Switch/ Bridge不修改ECRC(透明传输)
- 如果 ECRC 错误,报告给软件
5.10 Byte Enables
用途
指示 Data Payload 中哪些字节是有效的。
规则
- Byte Enable 位于 Header 的 Byte 8-11
- 每个 DW 有一个对应的 Byte Enable 位
- Byte Enable = 1: 对应字节有效
- Byte Enable = 0: 对应字节应被丢弃
示例
Data Payload: [0xAA, 0xBB, 0xCC, 0xDD] (1 DW) Byte Enables: 1010b → 字节 0 和字节 2 有效,字节 1 和字节 3 丢弃 → 实际数据: [0xAA, -, 0xCC, -]关键知识点速记
- TLP = Header + Data + Digest(可选)
- 3 DW Header: 32-bit 地址,无数据
- 4 DW Header: 64-bit 地址
- Format/Type 字段: 决定 TLP 类型和格式
- TD (TLP Digest): 1 = ECRC 存在
- EP (Poisoned): 1 = 数据已污染
- Memory Write: Posted,无需 Completion
- Memory Read: Non-Posted,需要 CplD
- IO/Config: Non-Posted,需要 Cpl/CplD
- Completion Status: OK/UR/CRS/CA
- ECRC: 端到端校验,Switch 不修改
- Byte Enables: 指示有效数据字节
思考题
- TLP 的 Format/Type 字段是如何编码的?为什么需要这两个字段?
- ECRC 和 LCRC 分别保护什么?它们在哪个层添加/检查?
- Poisoned Data (EP) 的实际用途是什么?和 PCI 的 PERR# 有什么关系?
- 为什么 Completion 需要 Status、Byte Count 和 Lower Address 三个字段来描述数据?
- 3 DW Header 和 4 DW Header 的区别是什么?分别在什么场景使用?
笔记结束