前言
本系列不会从零讲PCIe,也不会照搬规范条款,标准文档已经够厚,这里更像是一份工程师视角下的PCIe手边笔记 , 以更简洁的方式记录PCIe的关键点。
TLP包
由于PCIe-DMA的实现始终在事务层通过TLP包完成,因此深入理解TLP包的构成至关重要。
TLP包所在位置
在PCIe协议的传输层中,TLP包的结构相较于链路层与物理层的报文而言,最为简单清晰。

TLP的结构
TLP的结构与以太网帧类似,主要由头、数据载荷(Payload)和可选的ECRC构成。我们的关注重点在于包头,因为数据载荷即待传输的数据,而ECRC则为可选校验字段。

TLP包类型
在多种TLP包类型中,开发DMA主要涉及以下三种:
- • MRd:内存读请求
- • MWr:内存写请求
- • CPLD:完成包
鉴于现代PCIe设备普遍采用MMIO技术,IO类型的TLP已被MRd/MWr包所替代,因此无需关注。

TLP请求分为Posted(带发布)和Non-Posted(非带发布)两类。Posted请求类似于发送普通邮件,发出后无需等待确认;因此这类操作没有响应。而非Posted请求则类似于寄送挂号信,必须收到对方的签收回执才算完成;因此Requester会等待Completer返回一个完成包(CpLD)。具体来说,MWr是Posted请求,故无返回;而MRd是Non-Posted请求,因此Requester会等待Completer返回CpLD。

TLP包头的结构

Fmt和Type
FMT字段决定了TLP包头格式与内容:
- • FMT[0] : 指定包头大小。
0代表3DW(用于32位地址),1代表4DW(用于64位地址)。 - • FMT[1] : 指示是否包含数据载荷(Payload)。
0表示无载荷(如MRd),1表示有载荷(如MWr)。 - • FMT[2] : 用于指示是否含有扩展头部,这是PCIe 3.0末期及PCIe 4.0的功能。通常可忽略并默认置
0。
Type是一个5比特宽的字段,用于定义TLP包的类型。在DMA相关开发中,仅需关注以下两种核心类型的编码:
- • 内存读写请求(MRd/MWr):
5'b0_0000 - • 带数据的完成包(CplD):
5'b0_1010

TC[2:0]
Traffic Class(TC)字段实现了PCIe的QoS功能,通过此3比特字段可为TLP指定优先级。其默认值 000b(TC0)提供基本服务,而更高的类别(TC1-TC7,如 111b 代表TC7)则用于实现差异化的服务质量。通过合理配置TC,可以优先保障关键数据的传输延迟与带宽。
Attr[2]
ID Based Ordering (IDO)
IDO是PCIe中一种基于BDF号实现保序的机制,赛灵思设备虽不支持,但其设计思想值得了解。它与网络系统中“保序”概念类似。
核心前提:不同Requester ID(发起者)或Completer ID(完成者)的TLP包之间几乎不存在数据依赖。因为设备A通常不关心设备B的通信进度。
实现机制:基于上述前提,IDO允许switch等组件识别出这些独立的TLP流,并让它们互相“超车”。这使得设备B的数据包可以绕过因故阻塞的设备A的数据包继续传输,从而显著提升链路利用率和系统整体性能。
TH
PCIe高级功能,它允许设备在发送内存访问请求(TLP)时,附加一个“提示”,告诉CPU/系统这个数据应该被如何处理或缓存,从而优化系统性能,降低访问延迟并缓解流量拥堵。赛灵思不支持
TD
是否添加ECRC
- • 0:忽略ECRC
- • 1:添加ECRC
EP
为1 表示错包,需要丢弃
Attr[1:0]
Attr[1]:Relaxed Ordering(宽松排序)
该比特位用于控制是否启用宽松排序机制:
- • 值为 0:表示强制顺序执行(Strong Ordering)。TLP必须严格按照发送顺序被处理,若先发的TLP因资源未就绪(如等待目标内存释放)而阻塞,后续TLP即使资源就绪也不得执行,必须等待。
- • 值为 1:表示启用宽松排序。此时若某个TLP因等待资源而阻塞,后续不属于同一数据流、且资源就绪的其他TLP可以被允许越过它先执行,从而有效缓解因强排序引起的阻塞问题,提升总线利用率。
Attr[0]:No Snoop(缓存一致性控制)
该比特位用于控制是否启用缓存一致性嗅探(Snoop)机制:
- • 值为 0:启用嗅探,系统会维护CPU缓存与PCIe设备访问之间的一致性。CPU与内存之间的Cache会监听PCIe访问,将频繁操作的数据缓存在Cache中。若CPU读取数据时在Cache中命中,则可直接读取,避免访问内存,从而降低访问延迟。
- • 值为 1:关闭嗅探。在大流量或大数据传输场景中,由于数据局部性差,Cache命中率很低,此时建议关闭嗅探。这样可以避免不必要的缓存一致性监听开销,减少系统资源占用,提升传输效率。
AT
Address Type(物理地址虚拟地址转换)
该字段用于标识TLP中地址的转换状态,具体编码如下:
- • 00 = Default / Untranslated默认未转换地址,TLP中直接使用物理地址,不涉及地址转换服务(ATS)。
- • 01 = Translation Request地址转换请求。TLP中包含的是虚拟地址(VA),请求接收方将其转换为物理地址(PA)。该功能需上位机软件及相应驱动支持,并遵循《Address Translation Services》规范定义的转换流程。
- • 10 = Translated地址已转换。TLP中提供的地址为经ATS转换后的最终映射地址,可直接用于访问目标内存或设备。
- • 11 = Reserved保留值,暂未定义用途,不应在正常传输中使用。
Length
该字段以DW为单位,指示TLP数据载荷(Payload)的长度。
- • 对于MWr、CplD及MSG等包含Payload的TLP包,此字段有效。
- • 编码规则:值**
0**代表最大长度 1024 DW,其余值1–1023则直接对应实际的DW数量。
Last/First DW Byte Enables
Bit 7 = 1: Byte 3 in DW is valid; otherwise not
Bit 6 = 1: Byte 2 in DW is valid; otherwise not
Bit 5 = 1: Byte 1 in DW is valid; otherwise not
Bit 4 = 1: Byte 0 in DW is valid; otherwise not

写在最后
TLP是PCIe事务层的核心。无论是读写请求、完成包还是中断消息,最终都以TLP的形式在链路上传输。理解TLP结构,就等于理解了PCIe通信的语言。
- • Fmt / Type 决定了TLP的语法和语义;
- • Attr、TC、TH、TD 描述了TLP的优先级与传输属性;
- • Length、Byte Enables 则定义了数据的边界与有效性。
对FPGA开发者而言,真正的挑战不在于背下这些字段的定义,而在于如何在工程实现中正确生成和解析它们。只有在波形里看到完整的TLP流、在ILA上确认每个字段的作用,PCIe的复杂才会变得清晰可控。
评论区
登录后即可参与讨论
立即登录