热度 11
2013-10-8 17:36
11693 次阅读|
9 个评论
8B10B 编解码及 FPGA 实现 王敏志 概述 在使用 ALTERA 的高速串行接口时, GXB 模块里硬件实现了 8B10B 编码,用户只是“傻瓜”式的使用,笔者也一直没有弄清楚。网上搜索了一些学习资料,结合参考文献希望能够对其进行消化。另外, ALTERA 现在已经提供 8B10B IP ,用户可以直接使用,不过有时候为了代码可移植性需要自己写代码实现 8B10B 编解码,笔者希望在这方面也做些实践。 8B10B 编码概念 基本概念网上可以轻易找到答案,简单的说就是将 8bit 数据转换成 10bit 数据,显然这个转换过程有 20% 的开销,大部分公开资料提出 8B10B 编码的开销是 25% ,我同意开销大于 20% ,因为码流中必然存在一些控制码,但是为何是 25% 而不是 24% 或者 26% 呢? 为什么要使用 8B10B 编码呢?是因为 8B10B 编码的特性之一就是保证直流平衡,即编码后二进制数据流中“ 0 ”和“ 1 ”的数量基本保持一致,因为我们知道当高速串行流的逻辑 1 和逻辑 0 有多个位没有产生变化时(即所谓的长连 0 和长连 1 ),信号的转换就会因为电压位阶的关系而造成信号错误,直流平衡最大好处就是可以克服这个问题。 8B10B 编码是怎么做到 DC 平衡的呢?转换的时候,连续的“ 0 ”或者“ 1 ”数量不超过 5 位,即每 5 个连续的“ 0 ”或者“ 1 ”后必须插入一位“ 1 ”或者“ 0 ”,从而保证信号 DC 平衡。这样可以保证串行数据可以在接收端被正确复原,同时利用一些特殊代码( K 码)也可以帮助接收端进行复原工作,且可以在早期发现数据位传输错误,抑制错误继续发生。 通过以上解释,那么一个 8bit 的二进制位流,变成 10bit 后, 10B 中 0 和 1 的位数只可能出现下面 3 种可能情况: {C} l 有 5 个 0 和 5 个 1 {C} l 有 6 个 0 和 4 个 1 {C} l 有 4 个 0 和 6 个 1 这样就引出一个新的名词“不均等性”,即 Disparity 。就是 1 的位数和 0 的位数的差值,根据上述 3 种情况,那么就有 3 种 Disparity ,即 0 、 -2 、 +2 。 8B10B 编码工作原理 图 1 : 8B10B 编码器逻辑设计原理框图 如图 1 所示, 8bit ( HGFEDCBA , H 是 MSB , A 是 LSB )原始数据会被分成两部分,低 5bit 进行 5B6B 编码,高 3bit 则进行 3B4B 编码,这已成约定俗成的标准,所以 8bit 数据( 0 到 255 )也被表示为 D x. y 的形式,其中 x 就是低 5bit 对应的十进制数值,而 y 就是高 3bit 对应的十进制数值。例如 8bit 数“ 101 10101 ”,即十进制数 181 ,这时候按照上述划分原则 x=10101 ( 21 ), y=101 ( 5 ),所示这个数被表示为 D 21.5 。这叫 Code Notation 。 Running Disparity Running Disparity 缩写成 RD ,有正和负之分,即 RD+ 和 RD- 。有时候也认为 RD- = -1 , RD+ = +1 ,所以 Running Disparity 只有两种状态,而 -1 是其初始状态。根据上述“不均等性”定义, 8-Bit 码有 3 种 Disparity ,那么又是如何计算出 Running Disparity 呢? 根据参考 的描述,如果每个 5B6B 和 3B4B 码中“ 1 ”和“ 0 ”的数目不相等,那么就有两种码流可能来进行传输,一种是“ 1 ”比“ 0 ”多 2 个,另外一种就是直接取反从而“ 1 ”比“ 0 ”少 2 个。到底采取哪一种,编码原则根据当前的 Running Disparity 信号(也即图 1 中的 RD in )来选择。很明显,当 5B6B 和 3B4B 码中“ 1 ”和“ 0 ”的数目相等的时候,由于 Disparity 没有改变,所以这里似乎没有选择。但是这时候的编码原则如下: {C} l 如果 6-Bit 子块为“ 000111 ”,那么 6-Bit 子块结束 RD 为正 {C} l 如果 4-Bit 子块为“ 0011 ”,那么 4-Bit 子块结束 RD 为正 {C} l 如果 6-Bit 子块为“ 111000 ”,那么 6-Bit 子块结束 RD 为负 {C} l 如果 4-Bit 子块为“ 1100 ”,那么 4-Bit 子块结束 RD 为负 总的计算 Running Disparity 的原则如图 2 所示: 图 2 :计算 Running Disparity 规则 需要注意的是 ALTERA 高速接口里 8B10B 模块的 Running Disparity 是基于 10bit 的子块计算出来的。 10B 被分为 2 块,一个 6bit 子块( abcdei )和一个 4bit 子块( fghj ),如图 3 所示。 图 3 : 10-Bit Grouping of 6-Bit 4-Bit Sub-Blocks 6-Bit 子块的起始 Running Disparity 等于上一个 10-Bit 码的结尾 Running Disparity 。而 4-Bit 子块的 Running Disparity 等于 6-Bit 子块结尾的 Running Disparity 。 4-Bit 子块结尾的 Running Disparity 等于 10-Bit 码的 Running Disparity 。如图 4 所示。 图 4 : Running Disparity between Sub-Blocks ALTERA 给出的计算 Running Disparity 规则如下所示(如果条件不符合,那么子块结尾的 Running Disparity 与子块开头的一样),与上述参考 的内容相符,注意和图 2 比较。 {C} l 满足下列条件,子块结尾的当前 Running Disparity 为正 {C} n 子块中“ 1 ”比“ 0 ”多 {C} n 6-Bit 子块为 6’b000111 {C} n 4-Bit 子块为 4’b0011 {C} l 满足下列条件,子块结尾的当前 Running Disparity 为负 {C} n 子块中“ 1 ”比“ 0 ”少 {C} n 6-Bit 子块为 6’b111000 {C} n 4-Bit 子块为 4’b1100 数据编码表 参考 将 8B10B 数据码表分成两部分,即 5B6B 码和 3B4B 码表。 图 5 : 5B6B 数据码表 图 6 : 3B4B 数据码表 D .x.7 有两种选择(即初始码 D.x.P7 或者可选码 D.x.A7 ),编码器根据与 5B6B 编码组合是否产生 5 个连续“ 1 ”或者“ 0 ”来选择对应的码。序列中如果出现 5 个相同的位,使用逗号码( comma code )来进行同步。当 RD=-1 的时候,只有 x=17 、 x=18 和 x=20 时使用 D.x.A7 。当 RD=+1 的时候,只有 x=11 、 x=13 和 x=14 是才使用 D.x.A7 。当 x=23 、 x=27 、 x=29 和 x=30 时控制码 K.x.7 也使用 A7 这个码型。其他任何 K 码都不能使用 x.A7 码型,否则会有可能导致序列中逗号码对不齐(即导致逗号码漏检)。 只有 K.28.1 、 K.28.5 和 K.28.7 可以作为“ comma ”码,因为控制码 K.x.y 的可选编码使得其 Disparity 为 0 ,而且数据 bit 流中找不到这种编码。 控制码表 图 7 :控制码 在控制代码中, K.28.1 K.28.5 K.28.7 是逗号序列,逗号序列是用来同步的(即用来 8B10B 比特流字节对齐),如果 K.28.7 没有被使用,序列 0011111 或者 1100000 是不会出现在任何数据编码中的。 如果 K.28.7 被用于实际编码,一种比 中提到的更复杂的同步码型需要被定义使用。组合成 K.28.7 的码与其它码容易组合成其它的逗号码,两个相邻码就有可能变成相交码,从而导致对齐错误。在任何情况下多个 K.28.7 序列不允许被同时使用,它将导致不可测的误对齐逗号序列。 所谓控制码,是比特流中的 10B 没有对应的 8B 数据字节,通俗讲就是这些码不属于上述图 5 和图 6 组合成的数据中。这些码用于底层控制功能。 ALTERA 的 GXB 链接建立之前一般都要发 IDLE 码,链接建立以后对了使得接收端能对齐数据字节边界还要在发数据的同时发送一些控制码,一般都是发送 K28.5 (即十六进制的 BC )。 另外,下面这句话应该如何理解: K.28.7 is the only comma symbol that cannot be the result of a single bit error in the data stream. 在 FPGA 中实现 8B10B 编解码 ALTERA 不但提供 8B10B 的 IP ,而且还提供 Verilog 编写的 8B10B 源代码。图 8 是一个具体应用,将数据先进行 8B10B 编码,然后并转传输出。 图 8 :应用实例 分析及结论 深入了解了什么 8B10B 编码,解码的过程与编码相逆,通过 ALTERA 提供源代码可以进一步学习解码的具体过程。 参考 Stratix GX Device Handbook http://en.wikipedia.org/wiki/8B10B