系列文章目录
PCIe简介-部件简介
PCIe总线-背景知识
PCIe总线-PCIe体系结构(1)
PCIe总线-PCIe体系结构(2)
文章目录
- 系列文章目录
- [PCIe数据链路层(Data Link Layer)](#PCIe数据链路层(Data Link Layer))
-
- [DLLPs数据链路层包(Data Link Layer Packet)](#DLLPs数据链路层包(Data Link Layer Packet))
- [Ack/Nak协议(Ack/Nak Protocol)](#Ack/Nak协议(Ack/Nak Protocol))
PCIe数据链路层(Data Link Layer)
数据链路层主要负责链路管理,主要有三个功能:TLP错误纠正、流量控制以及电源管理。
DLLPs数据链路层包(Data Link Layer Packet)
DLLP数据包是一种在位于同一条链路的本端设备与对端设备的数据链路层之间传输的额数据包,其大小一般只有8 Bytes。如下图所示,DLLP的发送流程。
- DLLP组包(DLLP Assembly)
- 在发送方会给DLLP Core添加16 bit的CRC,用来供接收方进行校验;
- 添加完CRC之后的数据包会被送到物理层,会被加入起始符和结束符(Gen1和Gen2使用,Gen3有所改变,因为Gen3编码改变了);
- 对加完这两种字符的DLLP进行编码,通过链路上所有的通道进行差分传输。

- DLLP拆包(DLLP disassembly)
- 接收方接收到一包DLLP数据包,首先提出起始符和结束符;
- 通过CRC校验数据包是否在传输的途中发生错误;
Ack/Nak协议(Ack/Nak Protocol)
下图展示了 PCIe 链路层如何通过 "序号 + LCRC + 重传缓存 + Ack/Nak DLLP " 实现可靠传输,也就是常说的 Replay 机制。
- 对于发送测:
(1)对于来自事务层的TLP数据包都要加入序列号和LCRC,并在重传buffer中复制一份TLP。
(2)重传buffer会一直保留着TLP的副本,直到收到发送方传递过来的Ack DLLP数据包。发送方会根据这个Ack DLLP中的序列号,将这个连同之前的TLP备份全部删除; - 对于接受侧:
(1)接收方会根据LCRC判断接收到的报文是否出错,如果出错会立即返回给发送方一个Nak的报文,通知发送方重传。
(2)如果接收到的数据包是正确的,接收到会有计数器加一,直到达到阈值返回一个Ack的数据包。

下图展示了DLLP数据包的结构。DLLP包含了4 byte DLLP Type,2 byte的CRC和其他的信息。

下图展示了内存读TLP通过交换机的例子。
- 步骤1a:发起方发送一个内存读请求,并在自身的重传缓存中也保存一个请求包的副本。交换机接收这个 MRd TLP(Memory Read TLP,以后简写为 MRd TLP),并校验 LCRC 以及序列号。
步骤1b:校验未发现出错,因此交换机向发起方返回一个 Ack DLLP。作为响应,发起方将其重传缓存中保存的 MRd TLP 副本丢弃。 - 步骤2a:交换机将这个 MRd TLP 转发到正确的输出端口,使用的路由信息是这个 MRd TLP 的内存地址,在转发出去的同时,交换机会在这个输出端口的重传缓存内保存一份这个 TLP 的副本。完成方接收到这个 MRd TLP 并对其进行错误校验。
步骤2b:校验未发现出错,因此完成方向交换机返回一个 Ack DLLP。作为响应,交换机之前输出这个 TLP 的输出端口会将其重传缓存中保存的这个 MRd TLP 的副本丢弃。 - 步骤3a:作为这个请求的最终目的地,完成方将会校验 MRd TLP 中的 ECRC 字段域,这个字段域是可选的不是必需的。若校验未出错,则将这个请求呈交给设备核心层。然后根据这个请求命令中的相关信息,设备将会收集被请求的数据,发起方返回一个 CplD(Completion with Data TLP,带有数据的完成包),同时它也将在自己的重传缓存中保存这个 CplD TLP 的副本。当交换机接收到这个 CplD TLP 时将会对其进行错误校验。
步骤3b:校验未发现出错,因此交换机向完成方返回一个 Ack DLLP。作为响应,完成方将其重传缓存中保存的这个 CplD TLP 的副本清除。 - 步骤4a:交换机对这个 CplD TLP 中的发起方 ID 进行译码,并通过这个信息将 CplD TLP 路由至正确的输出端口,输出的同时在这个输出端口的重传缓存内保存 CplD TLP 的副本。当发起方接收到这个 CplD TLP 时将会对其进行错误校验。
步骤4b:校验未发现出错,因此发起方向交换机返回一个 Ack DLLP。作为响应,交换机之前输出这个 CplD TLP 的输出端口会将其重传缓存中保存的这个 CplD TLP 的副本丢弃。发起方将校验 ECRC 字段域(这个字段是可选的,不是必需的),校验未出错则将完成包里的数据向上呈交给设备核心层逻辑。

总的来说在PCIe链路上的每一级都是先缓存一份,直到收到下一级的Ack应答,才会将缓存的数据包删除。
关于流量控制和电源管理都有专门的一个章节,这里不展开了