8b/10b下的编码/加扰和组帧
8b/10b下的编码/加扰和组帧
- 适用于链路速率为2.5GT/s和5.0GT/s
8b/10b编码
编码方式
- 将8bit的数据编码成10bit的数据
- 8bit的数据会拆分成高3位和低5位,高三位采用3b/4b编码,低5位采用5b/6b编码
- 12种特殊(COM,STP,SDP,END,EDB,PAD,SKP,FTS,IDL,k28.4,k28.6,EIE)的符号在8b/10b种需要引入一个控制字符,用于表明编码后的数据是一个控制字符而不是数据
- 当链路速度为2.5GT/s和5.0GT/s时,使用该编码
- 8b/10b在正失调(positive disparity)和负失调(negative disparity)下可能编码值不一样
一些控制码(K Codes)
- 又叫k码
- 作用
- 用于lane和link的初始化和管理
- 在Non-Flit模式下(pcie6.0新增),让DLLPs和TLPs组成帧(frame)
- 12种特殊的控制码
编码 | 符号 | 全称 | 描述 |
---|---|---|---|
K28.5 | COM | Comma | 用于lane和link初始化和管理 |
K27.7 | STP | Start TLP | Non-Flit模式:表示TLP包的开始,Flit模式:保留 |
k28.2 | SDP | Start DLLP | Non-Flit模式:表示DLLP包的开始,Flit模式:保留 |
K29.7 | END | End | Non-Flit模式:表示TLP包或者DLLP包的结束,Flit模式:保留 |
k30.7 | EDB | End Bad | Non-Flit模式:表示无效TLb包的结束,Flit模式:保留 |
k23.7 | PAD | Pad | 在Non-Flit模式用于组成帧,在Non-Flit模式和Flit模式下用于链路宽度和lane顺序的协商 |
k28.0 | SKP | Skip | 当两个通信端口的比特率不同时,用于补偿两端的差异,在Flit模式和Non-Flit模式下用法相同 |
K28.1 | FTS | Fast Train ing Sequence | Non-Flit模式,用于组成FTSOS,从L0s退出到L0时,用于快速实现符号锁定(symbol lock) |
K28.3 | IDL | Idle | 用于组成EIOS,Flit模式和Non-Flit模式下用法相同 |
K28.4 | 保留 | ||
K28.6 | 保留 | ||
K28.7 | EIE | Electrical Idle Exit | 2.5GT/s下保留,用于组成EIEOS,并且要先于FTS发送 |
编码规则
发射端
- 当发射机处于电气空闲(EI)状态后,发射机在第一次传输差分数据时允许选择任何的失调(disparity),除非另有说明.
- 在初始化失调之后,发射必须选择遵守合适的8b/10b编码规则直到下一次电气空闲状态到来
接受端
- 对于接收端而言,在检测到对端退出电气空闲状态后,初始的失调被设定为第一个符号的失调,第一个符号是用来做符号锁定(Symbol lock)
- 对方在传输差分信息的过程种,由于发生了特定数量的错误,符号锁定可能会丢失然后重新实现符号锁定, 这时接收端允许重新初始化失调.
- 接受端在初始化失调设置之后, 按照当前运行失调(running dispairty),后面所有接收到的符号都必须在8b/10b编码表中找得到
- 按照当前运行失调,如果接收端接收到的symbol在8b/10b编码表中找不到,物理层对通知数据链路层接收到的符号是无效的,并且这是一个接收端错误(Receiver Error),在Non-Flit模式下,该错误会与端口绑定起来向上报.在Flit模式下,在符号中的错误会传到FEC逻辑中去纠正
- 如果8b/10b错误或者k码在Flit的边界检测到,接收机允许发送任意8-bit的值到FEC逻辑
组帧
- 有两类类型的帧会应用到lane上,第一类由有序集(Ordered Sets,简称OS)组成;第二个在数据流中,由TLPs和DLLPs组成
- 有序集在每条lane上都会持续的发,因此如果一个link由多条lane构成,完整的有序集会同时出现所有lane上
Non-Flit模式下的数据流
- 当没有包信息或者特殊的有序集需要传输时,发射机处于逻辑空闲(Logical Idle)状态
- 发射机处于逻辑空闲状态时,必须发空闲数据(Idle data,由00h组成),空闲数据也需要经过加扰和编码
- 当接收机没有收到包或者特殊的有序集时,接收机也是处于逻辑空闲状态,并且也应该接受空闲数据
- 在传输空闲数据时, SKPOS也必须按照一定的规则持续传输
组帧规则
- TLPs组成帧必须要把STP符号放在TLP的开始,并且要把END符号或者EDB符号放在TLP的结束
- 在STP和END或者EDB符号之间,TLP最少包含18个符号.如果接收到序列,STP和END或者EDB符号之间的符号数小于18个,接收机允许将这视为一个接收端错误(可选的功能,如果检查了则必须跟port关联起来)
- DLLPs组成帧必须要把SDP符号放在DLLP的开头,并且把END符号放在DLLP的末尾
- 当TLPs,DLLPs或者特殊的符号需要发送时,这时的一个或者多个符号时间成为逻辑空闲,逻辑空闲需要发送和接受空闲数据(00h)
- 当发射机处于逻辑空闲时,空闲数据符号应该在所有lane上都传输,空闲数据会被加扰(避免差分线上出现长的0)
- 接收机必须忽略接收到的空闲数据,并且不得依赖这些数据,除了一些加扰过的特定数据序列外(比如物理层的状态机在Configuration.Idle和Recovery.Idle需要判断收到的空闲数据个数,这时就会依赖空闲数据)
- 如果链路宽度大于x1,当从逻辑空闲条件开始传输TLP时,STP符号必须放在lane0上
- 如果链路宽度大于x1,当从逻辑空闲条件开始传输DLLP时,SDP符号必须放在lane0
- 一个符号时间内,STP符号只能放在链路上一次
- 一个符号时间内,SDP符号只能放在链路上一次
- 在相同的符号时间,链路上可以出现一个STP符号和SDP符号(eg. x16 SDP(1symbol)+DLLP(6symbol)+END+STP+…)
- 链路宽带大于x4时,STP和SDP符号可以放在4*N(N是正整数),eg. x8的链路,STP和SDP符号可以放在0和4
- xN(N>=8)的链路,如果END和EDB符号放在lane k上,K不等于N-1,并且lane k+1没有跟STP符号或者SDP符号时(比如没有TLP或者DLLP需要发送时),必须在lane k+1到lane N-1上填充PAD
- eg. x8的链路,END符号或者EDB符号放在lane3,当后面没有STP或者SDP符号时,lane 4到lane 7必须用PAD填充
- EDB 符号用于标记无效 TLP 的结束
- 接收机可以检查上述规则(可选),如果接收机检查了,违反后会产生接收端错误,并且上报错误时会关联到port
加扰
- 数据流与特定模式序列(pattern)进行异或操作(XOR),特定模式序列用线性反馈移位寄存器产生(Linear Feedback Shift Register, LFSR)
- 发射机发送数据时需要先加扰然后在进行8b/10b编码(gen1/2)
- 因为8b/10b编码可以保证直流平衡,如果是先编码,在加扰可能会0和1的个数相差较大
- 接收端先进行8b/10b解码(gen1/2)然后在进行解扰
- 多lane的link,加扰函数可以用一个或者多个线性反馈移位寄存器实现
- 发送端,如果link上有多个线性反馈移位寄存器时,它们必须协同工作, 每个线性反馈移位寄存器中都要维持相同的同步值(lane与lane之间的输出偏移(skew))
- 接收端,如果link上有多个线性反馈移位寄存器时,它们必须协同工作,每个线性反馈移位寄存器需要维持相同的同步至(lane与lane之间的偏移)
- 加扰或者解扰是通过8bit的数据(D0-D7)与线性反馈移位寄存器的输出(16-bit,D0-D15)进行异或
- 加扰步骤
- 线性移位反馈寄存器的输出D15与数据的D0进行异或
- 线性移位反馈寄存器和数据寄存器串行前进
- 对数据的D1到D7按照D0的方式重复操作
- gen1/2线性移位反馈寄存器的加扰多项式为
G(x)=x^16+x^5+x^4+X^3+1
- 对于给定的初始值,后面的值都是确定的
- 数据链路层可以通知物理层禁止加扰,具体实现方式协议没做说明
加扰规则
- Flit模式和Non-Flit都需要加扰
- COM 符号初始化 LFSR
- 除SKP外的每一个符号,线性移位反馈寄存器都是串行移位,前进8次
- 除了有序集(eg.TS1,TS2,EIEOS)、合规性模式序列(Compliance Pattern)和修改过的合规性测试序列(Modified Compliance Pattern)外的所有的数据符号(D Codes)都需要加扰
- 所有特殊符号(K 码)不需要加扰
- 线性移位反馈寄存器的初始种子(即D0-D15的值)是FFFFh
- COM字符发送出去之后,发送端的线性移位反馈寄存器立即初始化
- link上某条lane收到COM符号后,立刻初始化该条lane的线性移位反馈寄存器
你好,請問 8b/10b 和 Scrambler 的功能是不是類似的?
為什麼需要同時做這2種功能呢?
Gen3 之後只使用 Scrambler, 是否說明 8b/10b 不是很有必要呢?
剛開始讀 pci,對此很困惑😖
@seruze 你好 ,
請問 8b/10b 和 Scrambler 的功能是不是類似的?
编码和加绕还是不一样的,8b/10b编码的主要功能是保持直流平衡,因为经过8b/10b编码后的数据0和1的个数比较接近,不会出现长0或长1的情况,出现长0或者长1可能会导致接收端对电平0,1的识别出现误判,而加绕主要是防止不同lane之间的干扰,比如一个x16的链路,在发相同的有续集(order set)时,如果没有加绕,这16条lane发送的数据就是一样的,更容易产生干扰,加饶之后,每条lane传输的数据就变得伪随机了,可以降低lane与lane之间的干扰。所以在tx方向,一般都是先加绕,然后进行8b/10b编码。补充:一条lane也是可以降低干扰的,这也比较好理解,如果不加扰,一条lane传输的内容完全一样,就相当于是形成了高频信号,容易受到外界或者内部干扰。
為什麼需要同時做這2種功能呢?
因为它们的作用是不一样的
Gen3 之後只使用 Scrambler, 是否說明 8b/10b 不是很有必要呢?
gen3-gen5没有采用8b/10b编码是因为8b/10b编码的效率比较低,一个8比特的数需要10比特来编码,这样在传输时会浪费到20%的带宽,对gen3以上的速率来讲,浪费太多,可能不太容易接受,所以gen3-gen5 换了更高效的编码128b/130b编码,128b/130b编码从编码方式来讲并不能维持直流平衡,所以协议换了一种加绕算法来让0,1的个数稍微平衡点,此外,为了维持0,1个数平衡,协议在很多地方都有做专门的处理,比如TS1,TS2的symbol 14-15就可以根据前面0,1个数的差别来看是作为TS的标识符还是作为直流平衡用。gen3很多有续集的定义0,1的个数基本是相等的,而且有续集通常还不需要加绕,也都是维持直流平衡。在链路训练过程中,两端交换最对的就是TS,所以为了在128b/130b编码中,对TS的很多symbol也都是进行了加绕处理,防止lane与lane之间的干扰,而在8b/10b编码下,TS没有加绕的,但是在8b/10b编码下,一定程度上也可以防止lane与lane之间的干扰,因为8b/10b编码会根据当前运行一致性(就是0,1个数的差别)来确定编码后的值,在多lane的链路上,一定程度上也可以保证每条lane传输的内容不一样
@重新开始 真是很感謝您這麼詳細的回應,我會再好好研讀這方面的資料,再次感謝您的回答,也希望您能繼續推出 pcie 的文章分享,真的很受用,謝謝:)