PCIe系列专题之四:4.1 物理层数据流解析
一、故事前传
前面的文章针对PCIe的一部分内容已经做了解析。
较为详细解释请见之前的文章:
1. PCIe技术概述;
2.0~2.8 PCIe Transaction layer事务层详细解析;
3.0~3.2 PCIe数据链路层详细解析;
4.0 PCIe物理层结构解析;
二、物理层数据流
上一篇文章中,我们有提到"DLLP和TLP从数据链路层到达物理层后,物理层会在其两端分别加上Start和End标识,主要是方便接收端找到DLLP和TLP的边界"。
上面说到的Start和End标识,是物理层定义的控制字符中的两种。由于Gen1&Gen2 (8b/10b编码)与Gen3 (128b/130b编码)在物理层中的数据编码原理不同,物理层对Gen1&Gen2 与Gen3定义的控制字符也不同。同样,不同数据编码也造就了不同的数据流格式。所以,接下来我们对Gen1&Gen2和Gen3的数据流分开解析。
由于与SATA专题介绍的8b/10b编码原理类似,PCIe专题中将不再阐述8b/10b编码,感兴趣的话请参考:
1. Gen1&Gen2数据流
物理层针对Gen1&Gen2定义的控制字符主要有以下几类:
控制字符 | 说明 |
STP | =Start TLP, 代表TLP起始标志 |
SDP | =Start DLLP, 代表DLLP起始标志 |
END | TLP/DLLP结束标志 |
EDB | =End Bad, 无效TLP结束标志 |
SKP | =Skip,用于补偿PCIe链路中的延时 |
COM | =Comma,将PCIe链路Scramble用的LFSR值初始化 |
IDL | =Idle,PCIe链路进入Electrical Idle标识 |
PAD | 数据流中的填充字符,无实际含义 |
除了上述的控制字符之外,还需要特别介绍一下Ordered Sets。Ordered Sets不是TLP/DLLP,可以把Ordered Sets当做是Lane管家,比如Link Tranining,Link电源管理等。在Gen1&Gen2中,以COM控制字符开头,所有的Lane必须同时发送Ordered Sets。具体类型如下表:
Ordered Set(OS) | 说明 |
TS1OS/TS2OS | 用在Link Training |
EIOS | Electrical Idle, 在传输结束之前发送该序列,让PCIe链路进入空闲状态。 |
FTSOS | 告知PCIe链路从低功耗状态(L0s)进入正常工作状态(L0) |
SOS | SKP OS, 用于时钟补偿 |
EIEOS | Exit Electrical Idle, PCIe链路退出空闲状态 |
无规矩不成方圆!说了控制字符和Ordered Set,该说一下物理层中Gen1和Gen2数据流的一些规则了。
如果PCIe链路从Logical Idle之后开始数据流的传输时,STP和SDP必须放在Lane0;
如果不是从Logical Idle之后开始数据流传输,STP和SDP可以放在Lane0,4,8等;
在PCIe x2链路中,END/EDB放在Lane1,其他链路中放在Lane3,7,11等;
DLLP数据包长度为8个字符, SDP+6字符+END;
一个数据包结束之后,其他的数据包还没Ready, 这个时候需要PAD字符补位到最后一个Lane;
当数据包传输结束,所有Lane发送Logical Idle字符“idle(00)”;
所有的Lane同时发送Ordered Sets.
我们来看一下PCIe Gen2 x8的数据流,数据流里面包含了两个TLP,一个DLLP:
对照前面提到的数据流规则,上面这个例子就完全符合;
大家来找茬1:
看看下面PCIe Gen2 x8的数据流有何错误,可以在文章底部简要作答哈~
2. Gen3数据流
在Gen3中,数据编码舍弃了原来8b/10b编码,而采用更加有效的128b/130b编码。这也改变了Gen3数据流的模式。
当Gen1&Gen2采用了8b/10b编码时,数据包前后会加上控制符STP/SDP和END,格式如下:
而在Gen3采用128b/130b编码时,引入了一个新的概念: "块"(Block);
一个Block(130bits)= 2-bit Sync字段 + 16Bytes(128bits)
其中,Sync字段有两个定义:
a, Sync字段=01, 代表是数据块(Data Block);
b, Sync字段=10,代表是序列块(Ordered Set Block).
物理层对Gen3 数据块定义了5个字符(Token), 类似于Gen1&Gen2中的控制字符:
Token | 大小 | 说明 |
STP | 4 Bytes | =Start TLP,代表TLP开始标识 |
SDP | 2 Bytes | =Start DLLP,代表DLLP开始标识 |
IDL | 1 Bytes | =Logical Idle, 空闲状态 |
EDS | 4 Bytes | 数据流结束标识 |
EDB | 4 Bytes | 无效数据流标识 |
上述Tokens结构图如下:
此外,Gen3 Orderder Set的定义与Gen1/2基本一致。
我们接下来看几个PCIe Gen3 x8数据流的例子:
(1) 数据可以跨数据块(Block)传输
下面这幅图中的信息需要注意几点:
STP在Idle之后必须从Lane0开始;
一个数据块=2-bit Sync+ Byte0~15;
一个数据块中未传完的数据可以在下一个数据块中接着传输,不用再发送STP Token;
(2) 无效数据块传输
在上一个数据流的基础上,我们假设第二个TLP传输的过程中LCRC错误。那么TLP末端就会被加上EDB字段,表明此TLP已无效。
(3) 序列块(Order Set Block) SOS传输
针对序列块SOS(SKP OS)有以下几个规则:
SOS前面的数据块必须以EDS作为结束标志;
每个Lane要同时发送SOS,SOS大小一般为16Bytes(12 SKP + 1 SKP_END + 3 Scarmble数据)
如果在SOS之后需要继续数据传输,必须已数据块开始。
大家来找茬2:
看看下面PCIe Gen3 x8的数据流有何错误,可以在文章底部简要作答哈~