8b/10b编码详解

1、8b/10b编码简介

8B/10B 编码是 1983 年由 IBM 公司的 Al Widmer 和 Peter Franaszek 所提出的数据传输编码标准,目前已经被广泛应用到高速串行总线。8B/10B 编码将待发送的 8 位数据转换成 10 位代码组,其目的是保证直流平衡,以及足够密集的电平转换。

在这些高速收发器的接收端需要通过 CDR 技术去恢复时钟与数据的相位关系,在这个过程中需要不断地检测数据边沿和数据中心,从而调整时钟和数据的相位,因此需要保证接收的数据不断变化,从而给 CDR 提供足够多的待检测数据边沿。

另外,高速接口电路一般采用交流耦合方式进行连接,在交流耦合电路中的信号线会接电容(隔直通交)。如果传输的数据在一段时间内全是 1 或全是 0,那么这段时间传输的信号可以等效成直流信号,会产生直流偏移,在通过电容时,有可能解码错误。

因此,通过 8B/10B 编码,保证编码后的数据在一定时间内 0 的个数与 1 的个数保持相等。

2、8b/10b编码原理

8B/10B 编码的原理是将 8 位数据编码成 10 位数据,编码后的数据中 0 和 1 的个数相等,以保证数据的直流平衡。

当中 8bit 的原始数据可以分为两部分:低位的 5bit EDCBA(设其十进制数值为X),高位的 3bit HGF(设其十进制数值为Y),则该 8bit 数据可以记为 D.X.Y。 比如待编码数据为 110_00011,高 3 位数据的十进制为 6,低 5 位的十进制数据为 3,则 D.3.6 就表示 110_00011。

编码时,低 5bit 原数据 EDCBA 经过 5B/6B 编码成为 6bit 码 abcdei,高 3bit 原数据 HGF 经 3B/4B 成为 4bit 码 fghj,最后再将两部分组合起来形成一个 10bit 码 abcdeifghj,如下图所示:

图 1 编码示意图

另外,8B/10B 编码中还用到 12 个控制字符,他们可以作为传输中帧起始、帧结束、传输空闲等状态标识,与数据字符的记法类似,控制字符一般记为 K.X.Y。 8bit 数据有 256 种,加上 12 种控制字符,总共有 268 种。10bit 数据有 1024 种,可以从 1024 种状态中选取 256 种 0 和 1 个数相等的数据作为编码结果,在从剩下的数据中选取 12 个作为控制字符,即常见的 K码。

8B/10B 编码中将 K28.1、K28.5 和 K28.7 作为 K 码的控制字符,称为“comma”。在任意数据组合中,comma 只作为控制字符出现,而在数据部分不会出现,因此可以用 comma 字符指示帧的开始和结束标志,或用来修正和数据流对齐的控制字符。

3、8b/10b编码表

我们首先要搞清楚三个概念:

  • 编码对照表:用来对原始数据进行编码的查找表,在对原始 8bit 数据进行编码时,不需要进行一系列复杂的算法运算(自己推算也可),而是直接从查找表上去查找 8bit 原始数据对应的 10bit 编码数据。
  • Paired disparity:成对差异即“1”的个数和“0”的个数相差 2 个(完美平衡除外)。不论是 5B/6B编码还是 3B/4B 编码,最终编码后的数据“1”和“0”的个数对比只有三种情况,第一种是“1”的个数比“0”的个数多 2 个,第二种是“0”的个数比“1”的个数多 2 个,第三种是“1”的个数和“0”的个数一样多。其中“1”的个数和“0”的个数一样多又称之为完美平衡,在完美平衡的状态下是不需要进行补偿的,只不过由于完美平衡的编码数量无法满足所有数据的编码需求,因此完美平衡实际是无法做到的。

5位数据总共有32种状态,编码结果有6位数据,0和1数量相等的只有000_111、001_011…、110_001、111_000等20种状态。其中000_111和111_000存在三个连续相同的状态,并没有被使用。导致编码后0和1数据相等的结果就只有18种状态,并不能满足输入5位数据的32种数据状态,3B4B编码也有同样的问题。此时设计编码的人提出,一次编码如果不能保证编码结果0和1个数相等,那么可以让连续两次编码结果的0和1相等,也能满足要求。

  • Running disparity:运行不一致,在上文的 Paired disparity 中已经说过编码后的数据“1”的个数和“0”的个数不可能做到一直完美平衡(因为只有少数数据编码后是完美平衡,大多数数据编码后是成对差异的),要么“1”的个数比“0”多,要么反之。我们称这种“0”“ 1”个数差为“极性偏差”,用 RD 表示,当“1”的个数比“0”多的时候 RD 的值为“+1”,反过来 RD 的值为“-1”。

如果编码结果的1和0个数相等,称为平衡编码,此时RD的数值保持不变。如果编码结果1和0个数不等,称为非平衡编码,此时RD的数值翻转,下次编码采用RD对应数值的编码作为编码结果。

搞清楚这三个概念后,我们就可以开始进行 8B/10B 编码了。8B/10B 编码是由 5B/6B 编码和 3B/4B 编码组成的,编码的过程是先进行 5B/6B 编码,再进行 3B/4B 编码,最后将两部分编码结果组合成 10bit 编码。在编码的过程中,RD 的数值会不断翻转,每次编码的起始 RD 都是上次编码结果的 RD。

上次8B/10B编码结果的RD数值将用作本次5B/6B编码的起始RD,而3B/4B编码的起始RD等于上次5B/6B编码结果的RD,3B/4B编码结果的RD作为本次8B/10B编码的RD。

对应的编码状态跳转如下图所示:

图 2 编码状态跳转示意图

3.1 5B/6B 编码表

图 3 5B/6B 编码表

5bit 的数据位宽一共对应 32 个原始数据,所以在上图的 5B/6B 编码中一共拥有 0~31 个原始数据,其中“EDCBA”表示原始数据,“abcdei”表示编码后的数据。表中可以看到绝大多数数据都是有两个编码对应的,在实际使用的时候根据 RD 的值来选择其中一个编码使用;还有一部分数据后面是携带标记符号的,如 D.23、D.27、D.29、D.30,这些带标记符号的既是原始数据又是控制编码的一部分,主要用于 K.x.7。其中还有一个 K28 比较特殊,这是一个独立的控制编码不与数据复用,主要用于控制编码 K.28.y。

3.2 3B/4B 编码表

图 4 3B/4B 编码表

在 3B/4B 编码当中大家要注意的是数字 7 有两种编码,分别是 D.x.P7 和 D.x.A7,为什么要用两种编码方式呢?

主要是避免出现连续的 5 个“0”或“1”,例如当 RD 为 1 时对 D(11,7) 进行编码,其中 11 编码后的数值是 110100 而 7 就只能使用 D.x.A7 这种编码规则了,如果使用 D.x.P7 的编码规则,最后编码数据就成了 1101000001,可以看到出现了连续的 5 个“0”。因此大家在编码的时候一定要选择合适的编码规则。

在控制码的编码表中可以看到 K.x.1、 K.x.5、 K.x.7 这三个控制码被特殊标记了,这三个特殊编码会和上文 5B/6B 编码中提到的 K28 连用,组成 K.28.1、K.28.5 和 K.28.7 三个特殊编码,这三个特殊编码是会出现连续 5 个“0”或“1”的,这种特殊码又称之为“comma symbols”。它们不会出现在数据负荷部分,并且只要出现就一定是控制码,通常用它们作为帧的开始和结束标志,或者数据流对齐的控制字符。

除了K.28.1、K.28.5 和 K.28.7 这三个特殊编码外还要注意上文 5B/6B 编码中提到的 D.23、D.27、D.29、D.30 这几个特殊数值,在控制码中他们只能和 K.x.7 连用组成 K.23.7、K.27.7、K.29.7、K.30.7 这四个特殊控制码。原因和数字 7 的两套编码规则一样,避免出现连续的 5 个“0”或“1”。

完整的控制码编码表如下:

图 5 控制码编码示意图

4、8b/10b编码实例

XilinxUG476手册的附录有所有 8B/10B 编码数据的结果, 以及对应的RD值。这里以手册中的数据为例,对 8B/10B 编码进行实例分析。

问题一

请问 D.8.3 的 8B/10B 编码结果是多少?

第一个原始数据在进行编码的时候是默认 RD 为“-1”。D.8 的 5B/6B 编码结果为 111001,5B/6B 编码完成后,RD 翻转变为 1。将 RD=1 作为 D.x.3 的 3B/4B 编码起始 RD,根据查表得编码结果为 0011,再次将 RD 翻转,作为本次 8B/10B 编码结果的 RD。因此起始 RD=-1 的编码结果为 111001_0011。

与正确答案一致,编码结果为 111001_0011:

图 6 D.8.3 的 8B/10B 编码结果

问题二

当前 RD=1,则 K.28.5、D.2.6、D.23.4 的编码结果依次是多少,且最终的 RD 是多少?

首先 RD=1 时,查得 k.28 编码结果为 110000,这是不平衡编码,RD 的最终结果会翻转,RD=-1;K.x.5 的3B/4B编码是 0101,这是平衡编码,因此 RD 不变,等于 -1。

因此 D.2.6 的起始 RD=-1,首先 D.2 的 5B/6B 编码结果为 101101,RD 翻转变为 1。D.x.6 的 3B/4B 编码结果为 0110,由于 D.x.6 是平衡编码,因此 RD 保持不变,等于 1。故 D.2.6 的编码结果为 101101_0110,RD 最终为 1。

最后,D.23.4 的起始 RD=1,D.23.4 的 5B6B 编码结果为 000101,RD 翻转为 -1。之后 D.x.4 的编码结果为 1101,RD 的极性再次翻转为 1。

所以 K.28.5、D.2.6、D.23.4 的编码结果依次是 110000_0101、101101_0110、000101_1101,RD 的最终取值为 1。 D.2.6、D.23.4的手册查表结果如下图所示,与上述计算结果保持相同,证明编码规则没有问题。

图 7 D.2.6 的 8B/10B 编码结果
图 8 D.23.4 的 8B/10B 编码结果

8b/10b编码详解
https://yao-jiangyu.github.io/8b10b/
作者
小姚
发布于
2025年2月5日
许可协议