马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
1、8B/10B编码是什么? 简单来说,8B/10B编码就是将原本是8bits的数据,按照一定的规则扩展编码到10bits。8B10B编码是1983年由IBM公司提出的传输编码标准,通常用于高速收发器中,以太网、JESD204B、SATA等接口协议都使用了这个编码规则。
原本用8bits就能表示的数据现在要用10bits来表示,那肯定就会造成一定程度的浪费,也就是我们所说的 “编码开销” ,对接收端来说,它接收的10位数据只有8位是有效的,2位是相对无效的,所以它的编码开销是 2/10*100% = 20% 。存在编码开销也就是意味着传输带宽的浪费,那么8B/10B编码究竟有什么好处,以至于我们能容忍20%的编码开销也要使用它呢?
8B/10B编码最大的好处是直流平衡(DC平衡),8B/10B编码可以保证编码后的数据在一定时间内0的个数与1的个数保持相等。
对于高速信号的处理,可以使用直流耦合和交流耦合,若要实现远距离通讯或者光通讯,则只能使用交流耦合的方式。在交流耦合电路中的信号线会接电容(隔直通交),电容特性是 “隔直通交” ,如果数据流中长时间没有电平翻转,那么必然会将其视为直流被阻断造成极性偏差,也就是电势差不满足高低电平的判断阈值,进而造成对接收电平信号的误判,进而导致接收数据出错,如下图所示。
8B/10B编码另一个好处是有助于恢复时钟。在这些高速收发器的接收端需要通过CDR技术去恢复时钟与数据的相位关系,在这个过程中需要不断的检测数据边沿和数据中心,从而调整时钟和数据的相位,因此需要保证接收的数据需要不断的变化,从而给CDR提供足够多的待检测数据边沿。
2、8B/10B编码的规则 8B/10B编码就是把8位数据编码成10位数据,8位共有256种状态,而10位数据有1024种状态,可以从1024种状态中选取256种0和1个数相等的数据作为编码结果。再从剩下的数据中选取12个作为控制字符,即常见的K码。
假设原始8位数据从高到低用HGFEDCBA表示,8B/10B编码将8位数据分成高3位HGF和低5位EDCBA两个子组。然后经过5B/6B编码,将低5位EDCBA映射成abcdei;高3位经过3B/4B编码,映射成fghj,最后合成abcdeifghj发送。发送时由于是小端模式,a先发送。其对应关系如下图所示:
将低5位EDCBA按其十进制数值记为x,将高3位按其十进制数值记为y,将原始8bit数据记为D.x.y。
此外在8B/10B编码中,还需用到12种控制字符,用来标识传输数据的开始和结束,传输空闲等状态,按照上述规则,将控制字符记为K.x.y,例如常见的K.28.5。
5位数据总共有32种状态,编码结果有6位数据,0和1数量相等的只有000_111、001_011…、110_001、111_000等20种状态。其中000_111和111_000存在三个连续相同的状态,并没有被使用。导致编码后0和1数据相等的结果就只有18种状态,并不能满足输入5位数据的32种数据状态,3B4B编码也有同样的问题。
既然不能保证5个0/5个1,那就要么保证4个0/6个1,或者6个0/4个1呗。假设第一次传输的是4个0/6个1,那么只要保证下一次传输的是6个0/4个1,这样把两次传输当做一个整体来看,0和1的个数就还是一样多的,一样可以保证直流平衡。
需要注意的是,某些8位数据是可以有5个0/5个的10位编码的,如果上一次编码的结果是4个0/6个1,然后下一个数据又是5个0/5个1,那么就把6个0/4个1的编码往后顺延即可。5B/6B的编码规则如下:
其中的RD = -1(RD,Running Disparity,极性偏差)表示的是上一次的编码结果是1的个数比0的个数少,所以这次编码对应的1要比0多,例如D.00在RD = -1时的编码是100111,1的个数就比0的个数多(因为RD = -1意味着上一次的1的个数比0的个数少,要保证直流平衡)。RD = 1的情况类似。
3B/4B的编码和5B/6B的编码规则是一样的,其具体的对应关系如下:
因为8B10B编码大多用于异步串行通信,接收方需要识别数据的帧头、帧尾这些控制信息,从而完成数据的对齐、同步等等。因此8B10B编码有12个控制字符,通常称为K码(comma),这些控制字符的编码结果是唯一的,不会与数据编码的结果重复。下表就是12个控制字符的编码。
K码的编码结果是唯一的,不会与数据编码有重复。如下图所示,在数据流中不同的K码充当不同的角色,在数据恢复时,我们可以通过寻找K28.7来实现字节对齐,识别到K28.1准备接收数据,并在这不同阶段可以产生不同的状态信号。
3、两个例子 Xilinx的UG476手册的附录有所有8B10B编码数据的结果,可以作为参考使用。
(1)D1.6表示的数据是什么?它的8B/10B编码是多少?
6表示高3位即110,1表示低5位即00001,所以这个数据是110_00001。编码结果可以查表,但是因为没有指定上一次RD的值,所以可能的结果有两种:
RD = 1:100010 0110
RD = -1:011101 0110
(2)假设初始RD = -1,总线上依次传输 K.28.5、K.28.5、D.1.7、D.3.5、K.28.1、K.28.1 的编码结果依次是多少,RD又是如何变化的?
4、GTX的8B/10B编码 GTX的8B/10B编码默认是打开了,如果你开了这个功能以后在调试时不需要使用,可以把它Bypass掉,如下:
勾选了以后,可以通过给TX8B10BBYPASS赋值来给对应字节的8B/10B功能旁路掉,比如TX8B10BBYPASS[0]赋值1,表示第0个字节就不使用8B/10B了。使用旁路功能时,必须要把8B/10B功能先打开,也就是说如果你都没开,那自然谈不上旁路。8B/10B功能依靠端口TX8B10BEN,高电平有效。这两个端口的具体使用方式如下:
在使用旁路功能时,因为编码后的数据比编码前的数据会多两位,所以需要填充,填充可以使用这两个端口:TXCHARDISPMODE 和 TXCHARDISPVAL,这两个端口都是8bits,每个bit对应一个字节,填充规则如下:
在不使用旁路功能的时候,这两个端口的值可以用来控制运行一致性,也就是前面说的RD,规则如下:
正常来讲,我们还是希望RD由8B/10B编码器来实现,所以一般把这两个值设定为2‘b00。
在发送数据时,需要通过1bi来指定是数据还是K码,端口TXCHARISK可以完成这个工作,仍然是1bit对应1个字节,高电平有效。当使用8B/10B的旁路功能时,把TXCHARISK置0即可。
看完了TX端的8B/10B编码,再来看看RX端的8B/10B解码,二者在使用上非常类似,所以只讲一些有区别的地方。RX端的8B/10B解码器可以检查两种错误:
8B/10B解码器包括特殊字符(K字符)经常用于控制功能。当RXDATA检测到位K字符时,解码器驱动RXCHARISK为高电平。
如果DEC_PCOMMA_DETECT被使能,当RXDATA接收到正8B/10B comma,RXCHARISCOMMA为高电平。如果DEC_MCOMMA_DETECT被使能,当RXDATA接收到负8B/10B comma,RXCHARISCOMMA为高电平。
5、Verilog实现 尽管用逻辑也能实现8B/10B的编码和解码,但似乎有点复杂了。因为输入和输出是有对应关系的,所以最简单的实现方法就是查找表,用查找表实现的Verilog代码很简单,但是写ROM的初值就比较麻烦了,所以我这边就暂时不写了。
|