一 . 前言
PCIe总线的的接收端链路上没有时钟,因此获取时钟的办法是通过接收到发送端发过来的报文信息(内部嵌入有时钟信息的数据流)中来获取时钟信息,将此过程称之为bit lock,同理symbol lock表示PCIe链路上获取开始训练的标记符COM字符的过程。
每条 lane 的 symbol lock 过程, 也即是:每 条 lane完成了COM字符鉴定过程。
symbol lock:通过Oerdered-Sets中的COM,找到symbol0,此过程只在link training,进recovery和退出L0s时发FTS阶段完成。
对Serdes传输协议有了解的同学都知道,如何在Serdes接收到的茫茫的bit流中找到边界是一件最基础的事情,然后才能谈数据传输。
我们举个例子,下面是Serdes接收端收到的bit流,你可能会疑惑,这里面都是啥?
.......
011111010101010010101010000010101010101101001100101010010101010110101010101010101010101001001001010101011010110110101110100111010
011010010101010000010101011111010100101101001100101010010101010110101010101010101010101001001001010101011010110110101110100111010
011111010101010010000010101010101101001010101100101010010101010110101010101010101010101001001001010101011010110110101110100111010
011100101010100001010101101001100101010010101001010101101010101110101010101010101010101001001001010101011010110110101110100111010
.......
假设我们直接通过Serdes去传输我们想要的数据,那么对于接收端而言,它并不知道数据是什么时候开始,因为发送端没有告诉它什么时候开始。显而易见,发送端需要和接收端约定好一个特殊的标志。
于是自然而然,我们就会想,用什么标志合适呢?假设我们用0101101001011010为标志(也就是5A5A),可行吗?
答案显然是不可行,因为你没法确保数据中是否恰好包含5A5A。假如数据中也包含5A5A,那就彻底错位了。当然这是一个概率问题。
那么,最好的办法就是无论对于标志位还是数据本身,我们都按照一定的长度L切割开来,而且每段长度内,都需要符合一定的规律,这样接收端就可以根据预先约定好的规则验证接收数据流的正确性。
于是,在Serdes的通信中,引入了编码(Encode),对于接收端而言,就需要解码(Decode)。
二. 数据编码
上面举例子列举的数据流其实就是128b/130b编码的例子。
在这个编码中,每130bit的数据我们姑且称之为编码单元,在PCIe的概念里8bit为一个Symbol(这里注意:对于Gen1/2速率,每一个symbol 含有10 bits, 而对于Gen3/4/5速率,每个symbol 含有8bits ),所以该编码单元里包含16个Symbol。剩下的2bit为Sync Header。这里面Sync Header只允许为01或者10.
- 如果是01开始,那后面就会是控制字(Order Set)
- 如果是10开始,那后面就是数据本身
【实际应用】在链路建立链接的过程中,都会有Link Training的过程,在这个过程中,会一直发送Order Sets,所以对于接收端而言,每隔一个130bit长度就预期会收到01开头的控制字。
所以,对于Serdes接收端,我们只需要在茫茫bit流中不断的按照130bit为间隔,寻找是否连续的130bit都是01开头,那么这就是Symbol Lock了。
那么,为什么是8个130bit呢?这也是概率问题。考虑本身的链路误码率(1E-12),在链路训练阶段,恰好8个130bit都是以01开头,却并不是真正Symbol Lock的概率已经微乎其微。
所以,8b10b编码或者64b66b编码也都是类似原理。