LJgibbs · 2022年01月25日

PCIe扫盲——物理层逻辑部分基础(一、二、三)

写在前面

笔者在工作中需要包个 PCIe wrapper,正在努力飞快学习 PCIe ing.
本文系转载,略做格式调整与增加解释(使用斜体表示),转自:
http://blog.chinaaet.com/justlxy/p/5100053328

转载正文

物理层逻辑部分基础(一)

首先,回顾一下,之前看了很多遍的PCIe的Layer结构图:
image.png
PCIe中的物理层主要完成编解码(8b/10b for Gen1&Gen2,128b/130b for Gen3 and later)、扰码与解扰码、串并转换、差分发送与接收、链路训练等功能。其中链路训练主要通过物理层包Ordered Sets来实现。

PCIe Spec将物理层分为两个部分——逻辑子层和电气子层,如下图所示:
image.png
如上图所示,PCIe物理层实现了一对收发差分对,因此可以实现全双工的通信方式。需要注意的是,PCIe Spec只是规定了物理层需要实现的功能、性能与参数等,至于如何实现这些却并没有明确的说明。也就是说,厂商可以根据自己的需要和实际情况,来设计PCIe的物理层。下面将以Mindshare书中的例子来简要的介绍PCIe的物理层逻辑部分,可能会与其他的厂商的设备的物理层实现方式有所差异,但是设计的目标和最终的功能是基本一致的。

物理层逻辑子层的发送端部分的结构图如下图所示:
image.png
在进行8b/10b编码之前,Mux会对来自数据链路层的数据中插入一些内容,如用于标记包边界或者Ordered Sets的控制字符和数据字符。为了区分这些字符,Mux为其对应上一个D/K#位(Data or Kontrol)。

注:图中还包含了Gen3的一些实现,不过这里只介绍Gen1 & Gen2,并不会介绍Gen3。如果大家感兴趣的,可以去阅读Mindshare的书籍或者参考PCIe Gen3的Spec。

Byte Striping将来自Mux的并行数据按照一定的规则(后面会详细地说)分配到各个Lane上去。随后进行扰码(Scrambler)、8b/10b编码、串行化(Serializer),然后是差分发送对。

其中扰码器(Scrambler)是基于伪随机码(Pesudo-Random)的异或逻辑(XOR),由于是伪随机码,所以只要发送端和接收端采用相同的算法和种子,接收端便可以轻松地恢复出数据。但是,如果发送端和接收端由于某些原因导致其节拍不一致了,此时便会产生错误,因此Gen1和Gen2的扰码器(Scrambler)会周期性地被复位。

注:关于8b/10b的原理和作用,在我之前的博文中有所介绍。所以接下来的文章中不会重复介绍这些内容,但是会简要地介绍PCIe中的8b/10b的实现细节和要点。之前的文章地址为:http://blog.chinaaet.com/justlxy/p/5100052814

物理层逻辑子层的接收端部分的结构图如下图所示:
image.png
由于PCIe采用的是一种Embeded Clock(借助8b/10b)机制,因此接收端在接收到数据流时,首先要从中恢复出时钟信号,这正是通过CDR逻辑来实现的。如上图所示,接收端的逻辑基本上都是与发送端相对应的相反的操作。这里就不在详细地介绍了。

物理层逻辑部分基础(二)

上一篇文章中提到了Mux会对来自数据链路层的数据(TLP&DLLP)插入一些控制字符,如下图所示。当然,这些控制字符只用于物理层之间的传输,接收端的设备的物理层接收到这些数据后,会将这些控制字符去除,在往上传到其数据链路层。
image.png
当然,除了STP、SDP和END之外,还有一些其他的控制字符,如EDB(前面的文章详细介绍过)、SKIP、COM等。如下图所示:
image.png
前面的文章中提到过Ordered Sets,其主要用于链路训练等。

每一个Ordered Set都是按照DW对齐的(即四个字节),且Ordered Set开头也是一个叫做Comma(COM)的K字符(控制字符),随后包含一些K字符或者D字符(数据字符)。

对于只有一个Lane的PCIe设备来说,Byte Striping并没有什么卵用,其主要用于多个Lane的数据流分配。

x1(一个Lane)和x8(8个Lane)的例子分别如下两张图所示:
image.png
Mult-lane 规则

除此之外,还有一些其他的规则,主要是针对Mult-Lane的,对于一个Lane并没有什么影响:
image.png
x4(4个Lane)需要遵循以下的规则:

  • STP and SDP characters are always sent on Lane 0.
  • END and EDB characters are always sent on Lane 3.
  • When an ordered set such as the SKIP is sent, it must appear on all lanes simultaneously.
  • When Logical Idles are transmitted, they must be sent on all lanes simultaneously.
  • Any violation of these rules may be reported as a Receiver Error to the Data Link Layer.

如下图所示:
image.png
对于x8、x16、x32需要遵循以下的规则:

  • STP/SDP characters are always sent on Lane 0 when transmission starts after a period during which Logical Idles are transmitted. After that, they may only be sent on Lane numbers divisible by 4 when sending back‐to‐back packets (Lane 4, 8, 12, etc.).
  • END/EDB characters are sent on Lane numbers divisible by 4 and then minus one (Lane 3, 7, 11, etc.).
  • If a packet doesn’t end on the last Lane of the Link and there are no more packets ready to go, PAD Symbols are used as filler on the remaining lane numbers. Logical Idle can’t be used for this purpose because it must appear on all Lanes at the same time.
  • Ordered sets must be sent on all lanes simultaneously.
  • Similarly, logical idles must be sent on all lanes when they are used.
  • Any violation of these rules may be reported as a Receiver Error to the Data Link Layer.

x8的例子如下图所示:
image.png
扰码器

发送端的扰码器(Scrambler)有一个16-bit的线性反馈寄存器(LFSR,Linear Feedback Shift Register),其实现了以下这个多项式:
image.png
具体的功能框图如下图所示:
image.png
关于扰码器(Scrambler)还需要遵循以下这些规则:

  • 不同的Lane的扰码器必须是同步操作的;
  • 扰码器只对TLP和DLLP中的D字符(数据字符)以及逻辑空闲字符(00H,Logical Idle)作用,并不作用于K字符(控制字符)和Ordered Set中的D字符(如TS1、TS2等);
  • 兼容性测试字符(Compliance Pattern Characters)并不被扰码;
  • COM字符(一种控制字符,不会被扰码)可用于使发送端和接收端的扰码器中的LFSR同时被初始化为FFFFH;
  • 扰码器默认时被使能的,但是PCIe Spec允许将其临时禁止,以用于测试用途。

K字符(控制字符)

PCIe中用到的K字符(控制字符)如下表所示:
image.png
其对应的8b/10b编码如下表所示:
image.png
注:其中PAD字符主要用于Mult-Lane中,当一个包的长度比较短,有的Lane可能就没有数据可以发了,这时候可以用PAD字符来填充。如本文的x8的例子所示。

Ordered Sets主要用于链路管理(Link Management)功能。对于Gen1和Gen2的PCIe来说,所有的Ordered Set都以COM作为开头。

Ordered Sets是在每个Lane上同步发送的,即每一个Lane都会同时的发送相同的Ordered Sets,因此,Ordered Sets也可以被用于Lane De-skewing。

除了链路训练之外,Ordered Sets还被用于时钟容差补偿(Clock Tolerance Compensation,CTC)以及更改链路功耗状态(Changing Link Power States)等。

注:关于CTC,可以参考PCIe Base Spec V2.0第4.2.7节相关内容。后续也会单独写一篇博文,来详细地介绍弹性缓存(Elastic Buffer)与CTC。

对应的,主要有以下几种Ordered Sets:

TS1 and TS2 Ordered Set (TS1OS/TS2OS)、
Electrical Idle Ordered Set (EIOS)、
FTS Ordered Set (FTSOS)、
SKP Ordered Set (SOS)和
Electrical Idle Exit Ordered Set (EIEOS)。

注:关于链路管理以及Ordered Sets等详细内容,会在后续的博文中介绍。

物理层逻辑部分基础(三)

这一篇文章来继续聊一聊接收端物理层逻辑子层的实现细节。回顾一下之前的那张图片:
image.png
其中的一个Lane的具体逻辑如下图所示:
image.png
其中,Rx Clock Recovery从输入的串行数据流中提取出Rx Clock

当Rx Clock稳定在Tx Clock的频率上(Rx Clock locked on to the Tx Clock Freq)时,我们就称接收端取得了Bit Lock。

如果链路(Link)处于低功耗状态(比如L0s或者L1)时,接收端此时会失去同步(即Losing Bit Lock)。

为了避免物理层认为这是一个错误(异常),发送端会发送一个电气空闲命令集(Electrical Idle Ordered Sets,EIOS)通知接收端,即将进入低功耗状态。此时,接收端会临时关闭(De-gate)其输入。

注:这里的关闭(De-gate)并非是直接关闭输入端口,只是暂时不对输入端口上的数据进行处理。

当发送端需要唤醒链路(Link)时,会首先发送一定数量的FTS Ordered Sets,并重新取得Bit Lock和Symbol Lock。

接收端的链路De-Skew逻辑如下图所示:
image.png
Gen1和Gen2的PCIe采用COM字符来进行De-Skew,如果COM没有同时出现在每个Lane上,那么先到达的COM会被延时一会,以实现Lane的同步。很显然,这种机制只能校正比较小的Skew,也就是说Lane-to-Lane的Skew有一个最大值,超出这个最大值,De-Skew也无能为力了。如下表所示:
image.png
接收端的8b/10b解码器结构如下图所示:
image.png
以下情况,被认为是编码冲突(Code Violation),即该字符在传输过程中发生了错误:
image.png
关于解扰码器(Descrambler)和Byte Un-striping都比较简单了,这里就不在详细地介绍了。具体可以参考PCIe Spec的相关内容。

版权声明

版权声明:本文为 AET 博主「Felix」的原创文章,转载请附上原文出处链接及本声明。

原文链接:http://blog.chinaaet.com/justlxy/p/5100053328

转载自:知乎
作者:Felix

推荐阅读

更多招聘及面经请关注FPGA的逻辑
推荐阅读
关注数
10604
内容数
561
FPGA Logic 二三事
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息