第三讲:事务层基础——TLP包结构、类型与寻址

这一讲咱们进入PCIe最核心的部分——事务层。说白了,事务层就是决定“谁给谁发什么数据”的那一层。TLP(Transaction Layer Packet)就是咱们在总线上跑来跑去的消息信封。我个人习惯先把信封拆开看明白,再去理解整个通信流程。

TLP包长什么样?

每个TLP都有固定的头部格式。你想想看,就像快递单子上有发件人、收件人、物品类型、重量一样。TLP头部里最关键的几个字段我列在这里:

字段宽度含义
Fmt2 bit头部格式:有无数据载荷、是否带地址
Type5 bit事务类型:MRd、MWr、Cpl、CplD 等
Length10 bit数据载荷的DW数(1 DW = 4 字节)
Requester ID16 bit发起者总线号+设备号+功能号
Tag8 bit事务标签,用于匹配请求与完成
Address/Address+Attr32或64 bit目标地址+属性(如PCIe存储域控制位)

我自己记的一个小技巧: 先看Fmt和Type就能知道这是个什么包。比如Fmt=2'b00是没数据的请求,Fmt=2'b01是带数据的请求,Fmt=2'b10是完成包,等等。

四种基本事务类型:MRd、MWr、Cpl、CplD

PCIe的事务类型其实不少,但日常工作里80%的场景就是这四种。我在调设备驱动时几乎天天跟它们打交道。

  • MRd(Memory Read):读存储器请求,不带数据载荷。发起者发出去,等着对方回数据。
  • MWr(Memory Write):写存储器请求,带数据载荷。写出去后一般不期望回复。
  • Cpl(Completion without Data):不带数据的完成包。比如读写完成但不需要回数据的情况,或者异常终止。
  • CplD(Completion with Data):带数据的完成包。MRd的响应就靠它了。

嗯,这里要注意一点:MWr虽然不期望回复,但PCIe规范要求接收方必须在内部保证写入顺序(PCIe ordering规则)。我曾经在项目里遇到过接收端缓冲区不够深,MWr包被阻塞导致后续读请求超时……后来加了一级FIFO才解决。

地址与属性

TLP里的地址字段支持32位(传统PCI兼容)和64位(PCIe增强)。属性字段主要控制缓存一致性、no-snoop、relaxed ordering等。

属性位名称作用
Attr[2]No Snoop1表示不需要缓存一致性探测,适合高性能流式写
Attr[1]Relaxed Ordering1表示允许乱序完成,提升性能但需要软件谨慎使用
Attr[0]ID-Based Ordering用于区分不同Requester ID的事务

我曾经踩过的坑: 在某个DMA驱动里,我把No Snoop设成了1,结果CPU写了一遍数据后,DMA读到的是旧值。因为CPU的写缓存还没刷新到内存,而No Snoop跳过了缓存一致性的同步。后来我改成先做写屏障,或者干脆关掉No Snoop才稳定。

事务层整体流程(一张图看懂)

TLP事务层交互流程 发起者 (Requester) 接收者 (Completer) MRd (无数据) CplD (带数据) MWr (带数据,无回复) 事务匹配关键点 Requester ID + Tag 唯一匹配对 Cpl/CplD返回 MWr可以带No Snoop标记,跳过缓存一致性问题,但需软件保证数据可见性。 示例:GPU发起MRd读取系统内存地址0xF0000000 → 内存控制器返回CplD Tag=0x3A,Requester ID=Bus:Dev:Fn=0x01:0x00:0x00

我总结的几个实用点

  • MWr无回复,别死等: 你发完MWr,设备端可能因为buffer满而用Flow Control(FC)信用量拒绝,但不会给你回一个包。所以设计上要小心,我曾经在某个FPGA原型里,写寄存器后没等FC就下一笔,结果丢数据了。
  • MRd的Tag不能重复: 每个待处理的读请求必须有一个独一无二的Tag,否则返回的CplD你分不清是谁的。我记得有一次代码里Tag循环复用太快,导致匹配错误,数据全乱套了。
  • CplD的Length必须和MRd的Length一致: 如果读请求是4DW,那返回的CplD必须刚好4DW,不能多不能少,而且首地址要对应。

核心一句话: TLP就是PCIe通信的基本单元。你只要掌握了MRd/MWr/Cpl/CplD四种类型,加上地址和Tag的匹配规则,就已经能理解90%的事务层行为了。

一点课后小心得

我在做PCIe分析仪解码的时候,经常看到工程师盯着TLP头部的Hex值发呆。其实你只要把Fmt和Type拆出来,剩下的就是读地址、写地址、返回数据而已。别被那一长串16进制吓住,抓住这几个关键字段就通了。