前言
8B/10B,也叫做8字节/10字节或8B10B。8B/10B方式最初由IBM公司于1983年发明并应用于ESCON(200M互连系统),由Al Widmer和Peter Franaszek在IBM的刊物“研究与开发”发表。
一、基本知识
8b/10b编码的特性之一是保证DC 平衡。
采用8b/10b编码方式,可使得发送的“0”、“1”数量保持基本一致,连续的“1”或“0”不超过5位,即每5个连续的“1”或“0”后必须插入一位“0”或“1”,从而保证信号DC平衡,它就是说,在链路超时时不致发生DC失调。通过8b/10b编码,可以保证传输的数据串在接收端能够被正确复原,除此之外,利用一些特殊的代码( 在PCI-Express总线中为K码) ,可以帮助接收端进行还原的工作,并且可以在早期发现数据位的传输错误,抑制错误继续发生。
8b/10b编码是目前许多高速串行总线采用的编码机制,如 USB3.0、1394b、Serial ATA、PCI Express、Infini-band、Fiber Channel、RapidIO等总线或网络等。
8B/10B编码是目前高速串行通信中经常用到的一种编码方式。直观的理解就是把8bit数据编码成10bit来传输,为什么要引入这种机制呢?其根本目的是“直流平衡(DC Balance)”。当高速串行流的逻辑1或逻辑0有多个位没有产生变化时,信号的转换就会因为电压位阶的关系而造成信号错误,直流平衡的最大好处便是可以克服以上问题。
将8bit编码成10bit后,10B中0和1的位数只可能出现3种情况:
1.有5个0和5个1 ; // Disparity = 0 ; (不均等性)
2.有6个0和4个1 ; // Disparity = +2 ;(计算规则:0的个数减去1的个数。而RD(极性偏差或者运行不一致) ,如果1的个数比0多,那么是RD = +1;如果0的个数比1多,那么是RD= -1。此外,这里,6个0 并不是说会出现0000001111或者1111110000 这样的序列, 因为这样的序列已经被剔除出去。但是可以出现1010001001这样的,6个0和4个1的序列。连续5个0(0000011111、0000010111等)和5个1(1111100000)的序列,只有在控制码中存在)
3.有4个0和6个1 ; // Disparity = -2 ;
这样引出了一个新术语“不均等性(Disparity)”,就是1的位数和0的位数的差值,根据上面3种情况就有对应的3个Disparity 0、-2、+2。
二、工作原理
1.原理讲解
8bit原始数据会分成两部分,其低5位会进行5B/6B编码,高3位则进行3B/4B编码,这两种映射关系在当时已经成为了一个标准化的表格。人们喜欢把8bit数据表示成Dx.y的形式,其x=5LSB(least significant bit最低有效位),y=3MSB(most significant bit最高有效位)。
8b/10b编码是将一组连续的8位数据分解成两组数据,一组3位,一组5位,经过编码后分别成为一组4位的代码和一组6位的代码,从而组成一组10位的数据发送出去。相反,解码是将1组10位的输入数据经过变换得到8位数据位。
数据值可以统一的表示为DX.Y或KX.Y:
其中D表示为数据代码,
K表示为特殊的命令代码,
X表示输入的原始数据的低5位EDCBA,
Y 表示输入的原始数据的高3位HGF。
例如一个8bit数据101 10101,x=10101(21) y=101(5),现在我们就把这8bit数据写成D21.5,明白了吧!
Dx.y形式在进行5B/6B和3B/4B编码中表示更直观,下面我们来看看两张编码表:
对于8bit数据,它在表中的位序为HGFEDCBA,即H为最高位,A为最低位,EDCBA经过5B/6B编码为abcdei,HGF经过3B/4B编码为fghj。传送10bit编码的顺序为abcdeifghj。
![8B/10B编码 <wbr>详解zz](https://img8.php1.cn/3cdc5/1e70e/807/1002630fdb427b6c.jpeg)
† 3B/4B使用K.x.7
![8B/10B编码 <wbr>详解zz](https://img8.php1.cn/3cdc5/1e70e/807/214b310ab9d4a7a7.jpeg)
† 对于D.x.7&#xff0c;当和5B/6B组合时D.x.P7和D.x.A7编码必须选择一个来避免连续的5个0或1。遇上连续5个0或1的情况下使用“逗号码”来进行校准。D.x.A7用在x&#61;17 x&#61;18 x&#61;20当RD&#61;-1时&#xff0c;x&#61;11 x&#61;13 x&#61;14 当RD&#61;&#43;1时。当x&#61;23 x&#61;27 x&#61;29 x&#61;30时&#xff0c;使用K.x.7进行编码。其他情况下x.A7码不能被使用&#xff0c;他将会导致和其他“逗号序列”产生冲突。
‡ 候补编码K.x.y允许K.28.1 K.28.5 K.28.7作为“逗号码”来保证数据流中的唯一性。
你们也许注意到了表中有个RD标志&#xff0c;它是Running Disparity的缩写&#xff0c;它的目的就是保持8B/10B编码中的直流平衡。它跟上面提到的Disparity其实是一样的意思&#xff0c;&#43;1用来表示1比0多&#xff0c;-1用来表示0比1多&#xff0c;-1是它的初始化状态。下面我们来看一张表来加深理解&#xff1a;
RD的全称为RunningDisparity&#xff0c;简称为RD&#xff0c;由于数据流不断从发送端向接收端传输&#xff0c;前面已发送数据的不一致性累积产生的状态称为“运行不一致”&#xff0c;RD会出现“&#43;1”和“-1”两种状态&#xff0c;“&#43;1”表示正极性&#xff0c;即位“1”比位“0”多&#xff1b;“-1”表示负极性&#xff0c;即位“0”比位“1”多&#xff0c;当前RD计算方式为&#xff1a;
RD &#61; Number(1) – Number(0) &#43; Number&#xff08;past&#xff09;
RD的初始值为“-1”&#xff0c;下一状态RD的值依赖于当前的RD值以及当前6B或者4B码的极性&#xff0c;根据当前RD的值&#xff0c;决定5b/6b,3b/4b的映射方式。
![8B/10B编码 <wbr>详解zz](https://img8.php1.cn/3cdc5/1e70e/807/344f561d08962357.jpeg)
上面我们提到的“逗号码”和“逗号序列”&#xff0c;其实都是当初在规划8B/10B编码机制的时候&#xff0c;所谓的控制代码&#xff08;Control Characters&#xff09;的其中之一。8B/10B标准中使用了12个特殊的控制代码&#xff0c;他们能在数据中被发送&#xff0c;还可以组合成各种“原语”。
![8B/10B编码 <wbr>详解zz](https://img8.php1.cn/3cdc5/1e70e/807/e1cdcc74513d57c3.jpeg)
† 在控制代码中&#xff0c;K.28.1 K.28.5 K.28.7 是逗号序列&#xff0c;逗号序列是用来校准用的&#xff0c;如果K.28.7没有被使用&#xff0c;序列0011111 或者 1100000 是不会出现在任何编码中的。
‡ 在实际编码中如果K.28.7可以被使用&#xff0c;一种更复杂的校准规范需要†被使用&#xff0c;它们能组合成各种“原语”&#xff0c;在任何情况下多个K.28.7序列不允许被同时使用&#xff0c;它将导致不可探测的逗号序列。
当CurrentRD&#61;&#61;-1时&#xff0c;表示之前传输的数据中“0”的个数多于“1”的个数.
经过8b/10b编码后&#xff0c;连续的“1”和“0”的个数基本上不会超过5bit&#xff0c;只有在使用K码时&#xff0c;才会出现连续的5个0或1&#xff1a;
![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy8wZllIZzAxU0N2T2w5clUyckdpY2cwZzlHQ3dadVpxb3dGZ0pGblNSamNGdURYY3djWjQ0VTJhdW5SeVRpYWxJT0lpYjFGV0NHZGFkdkFtTnp1VFBXb1pGUS82NDA?x-oss-process&#61;image/format,png)
总结