点击进入高速收发器系列文章导航界面
前文讲解了8B10B的原理,8B10B的开销比较大,每传输10位数据,就需要发送2位无效数据。为了减小8B10B编码的开销,同时保留编码方案的优点,提出了64B66B编码。
64B66B编码与8B10B编码方式有本质区别,8B10B编码可以从码表中获取一个数据编码结果,而64B66B在发送前需要通过白噪声对数据加扰,在接收数据时也要先对数据解扰。
用户在实际使用时,GTX的64B66B编码会比8B10B更简单,因为64B66B会提供控制帧和数据帧,相比8B10B会简单一点点。
1、64B66B编码原理
下图是万兆网的数据编码框图,将两个32位的TXD数据拼接为64位,然后经过加扰(Scrambling)来保证零一均衡,避免直流失调和时钟恢复困难。
之后在64位数据之前加入2位的同步头(Sync header),用来指示后面的64位数据是数据帧还是控制帧,用户每发送64位数据,高速收发器需要传输64位数据和2位同步头。
变速器(Gearbox)可以看成一个深度为64位的存储器,每个用户时钟输入64位数据,高速收发器在一个用户时钟内也只能发送64位编码后的数据,就会导致每个时钟会有2位数据没有被发送,暂存在变速器(Gearbox)。
经过32个时钟后,变速器(Gearbox)就会存满64位数据,用户下个时钟周期需要暂停输入数据,高速收发器在下个时钟将变速器(Gearbox)的64位数据发送,之后用户就可以继续输入需要发送的数据了,就这样循环往复。
编码过程是由加扰器(Scrambling)完成的,因此相同的数据经过加扰后会得到不同的数据,编码后的数据是不能预测的。
2位同步头有两个作用,可以用来指示帧类型,接收端也可以根据同步头来实现数据对齐,同步头只有2’b01和2’b10两种取值,其余两种为无效取值。
当同步头为2’b01时,表示后面的64位数据是纯数据,不包含任何控制字符,如下图所示。
如果同步头为2’b10,则表示后面的64位数据是控制帧,可能是起始帧,也可能是结束帧,如下图所示,注意同步码后面的第一字节数据表示控制帧的类型,根据该数据的值确定该帧数据内容。
下图是上面几种帧的一些格式,D表示数据,C表示空闲字符(7位数据),S表示帧起始字符,T表示帧结束字符。其中当同步码为2’b01时,8字节全部为数据。64B66B编码的起始帧有两种格式,一种是起始位位于第一个字节,对应的类型字符为8’h78,另一种是起始位位于第五字节,对应的类型字符为8’h33。
由于用户每次可以传输任意字节数据,导致停止位可能出现在数据的任何字节,因此结束帧会有8种类型,类型字符不相同,接收端可以根据结束帧的类型判断这帧有多少有效数据。
下表是这些控制字符的具体取值,比如起始位S的取值是8’hfb,停止位T的取值是8’hfd,空闲字符C为8’h07。
加扰和解扰一般使用的表达式为X58+X19+1,这部分内容可以在后续的示例工程中直接获取,也比较简单,实现方式与M序列类似。
2、GTX的64B66B编码发送原理
前面讲解了64B66B的原理,从此开始讲解GTX相关内容,首先需要明确GTX内部不能对待发送数据加扰,也不能对接收的数据解扰,需要用户在FPGA逻辑中自己完成加扰和解扰。
由下图可知,8B10B经过蓝色走线后到达FIFO,而64B66B编码只经过了一个TX Gearbox,并没有经过什么编码模块,因此加扰和解扰相关操作需要用户在IP外部自己完成。
TX Gearbox的作用就是前文所说的变速器,工作方式如下图所示,下图把用户数据位宽设置成32位,并且PCS每次也只能传输32位数据,两个时钟才能发送一个64位数据。
因此需要两个时钟用户才能发送64位数据,第一个时钟向GTX发送2位同步码和32位数据,变速箱先发送2位同步码和高30位数据,第2位数据留在TX Gearbox中。第二个时钟用户发送剩余32位数据,TX Gearbox需要先把上个时钟剩余2位数据发送,然后发送本次接收的高30位数据,最后还是会剩余2位数据。
因此每经过2个时钟,TX Gearbox中就会增加2位数据,当经过64个时钟后,TX Gearbox中存在64位数据,与一个用户数据位宽一致。后两个时钟周期用户不能往GTX发送数据,TX Gearbox会将内部64位数据发送出去,完成清空。
在使用64B66B编码时,一般用户端口位宽使用64位,会更方便,原理都是一样的。
上述会有一个问题,Gearbox如何知道是否该清除内部数据,用户怎么知道何时停止发送数据呢?这就需要一个计数器,GTX内部可以提供这个计数器,用户也可以向GTX提供计数器,但是后续GTH等高速收发器都不支持内部计数器的方案,因此在使用时还是推荐使用外部计数器,与其他收发器统一。
下图是使用外部计数器的框图,使用64B66B编码传输数据,需要用到几个信号。其中TXDATA[63:0]是用户待发送64位数据,TXHEADER[2:0]用来传输2位同步码,最高位不使用,接地即可。
TXSEQUENCE[6:0]是用户向GTX提供的外部计数器,使用64B66B编码时,计数器的取值范围是[0,32],TXSEQUENCE[6]接地处理。使用64B67B编码时,计数器取值范围是[0,66]。
下表是64B66B编码不同数据位宽下,用户数据停止发送数据的时钟周期数。TX_DATA_WIDTH表示用户数据位宽,与用户时钟(TXUSRCLK2)对齐。TX_INT_DATAWIDTH表示PCS内部传输并行数据位宽,可以理解成TX Gearbox输出数据位宽,与TXUSRCLK对齐。
TX_DATA_WIDTH与TX_INT_DATAWIDTH相同时,计数器必须每两个用户时钟递增一次,数据暂停两个用户时钟周期。
TX_DATA_WIDTH是TX_INT_DATAWIDTH两倍时,计数器每个用户时钟递增一次,数据暂停1个时钟周期,有效数据传输在下一个用户时钟恢复。几个用户时钟能把TX Gearbox内部数据清空,用户就需要暂停几个时钟周期。
下图表示使用外部计数器,用户数据位宽为64位,PCS内部传输并行数据位宽为4字节,使用64B66B编码的时序图,当计数器计数到32时,用户数据停止发送,Dd数据持续到计数器等于0之后才能变化。
GTX还支持内部计数器模式,虽然GTH不支持该模式,但既然存在,还是讲解一下吧,对应框图如下所示,与图9相比减少了TXSEQUENCE[6:0]信号,增加了TXSTARTSEQ和TXGEARBOXREADY。
TXSTARTSEQ用来指示复位后的第一个有效字节数据。初始为低电平,高速收发器复位完成之后,用户开始传输第一个数据时拉高,之后可以保持为任意值。
TXGEARBOXREADY其实就是内部计数器计数到固定数值后,用来告诉用户暂停发送数据的一个信号。
当内部计数器计数到固定数值后,如果用户数据位宽(TX_DATA_WIDTH)等于PCS传输数据位宽(TX_INT_DATAWIDT),TXGEARBOXREADY会拉低三个时钟,如果用户数据位宽是PCS传输数据位宽两倍,TXGEARBOXREADY会拉低两个时钟。
注意TXGEARBOXREADY拉低的第一个时钟用户可以向GTX发送数据,从拉低的第二个时钟开始,用户数据需要保持不变,直到TXGEARBOXREADY拉高为止。如下图所示,TXGEARBOXREADY拉低之后第一个时钟,用户数据依旧变化,TXGEARBOXREADY拉高一个时钟后,用户数据才开始变化。
关于发送通道的64B66B编码相关内容就讲解完毕了,涉及到的信号也比较少,主要就是变速箱的计数器外置和内置,也比较简单。
3、GTX的64B66B编码接收原理
GTX的接收通道也有一个RX Gearbox把接收的66位数据转换位2位同步头和64位数据输出给用户,下图中红色走线是使用64B66B编码信号的路径,蓝色是不使用64B66B是的路径。
注意接收通道内部是没有解扰器的,需要用户在GTX外部自己解扰。
GTX使用64B66B编码时,接收端与用户端口信号连接如下图所示,包含数据信号RXDATA、数据有效指示信号RXDATAVALID、同步头RXHEADER[2:0]、同步头有效指示信号RXHEADRVALID、RXSTARTOFSEQ、滑块对齐信号RXGEARBOXSLIP。
输出数据和同步头及有效指示信号的含义都很清晰,相关时序如下图所示,有效指示信号为高电平时,对应数据是有效的。下图中PCS在每个用户时钟只能传输64位数据,但每个时钟需要输出2位同步头和64位数据RXDATA,共66位数据,因此没经过32个时钟Gearbox就需要先缓存64位数据,此时不输出数据,才能维持这种数据差。
理解下图RX Gearbox工作原理就会变得很简单,下图中用户端口和PCS内部数据的位宽均为32位,每两个时钟周期才能输出一个64位数据。
在第N个时钟时,Gearbox内部存满了64位数据。该时钟输出第1个64位用户数据,首先输出2位同步码、32位数据,同时接收PCS传输来的32位数据,这个时钟过后Gearbox内部还有60位数据。第N+1个时钟Gearbox依旧需要接收32位数据,同时输出剩下的32位数据,不输出同步码,两个时钟完成一个64位数据输出。
在第N+2和第N+3时钟内,Gearbox需要输出第2个64位数据,经过一番操作,内部剩下60位数据。由此可知,经过64个时钟之后,Gearbox内部数据将被清空,需要暂停一个时钟输出数据来补充数据。
接收通道的Gearbox只能使用内部计数器,RXSTARTOFSEQ为高电平表示内部计数器的值为0,但用户对内部计数器的取值其实并不太关心,用户需要确定转换的起始位置,来保证输出并行数据的正确性,即输出数据对齐。
GTX的8B10B编码在接收端通过设置检测K码来实现字节对齐,但64B66B的接收通道并不提供对齐功能的,需要用户通过拉高RXGEARBOXSLIP信号和检测同步头的状态实现手动对齐,与ISERDES的手动对齐比较像,关于为什么要对齐,可以点击查看ISERDES的讲解,原理一致。
在正常传输数据时,同步码有2’b01和2’b10两种取值,且控制帧(同步码为2’b10)不会连续多字节出现。
对齐策略一般如下,在复位成功后,首先检测到同步码状态。如果同步码出现2’b00或2’b11,以及连续多个时钟周期出现控制帧(2’b10),把RXGEARBOXSLIP信号拉高一个时钟周期,调整输出数据转换的起始位置。经过32个时钟后再次对检测同步码状态(因为需要等待调整位置成功且转换完成之后在判断),如果同步码依旧出现之前的状态,则重复以上操作。
如果同步码连续多个时钟周期都正常,表示输出数据对齐成功,此时RXDATA输出的数据是正确数据,之后如果再次出现错误同步码,依旧需要重新对齐,这部分内容可以在官方示例工程中查看(示例工程写的繁琐,建议自己写,可以参考ISERDES工程)。
关于这部分对齐内容,官方手册有一个状态机讲解,涉及过于复杂,没必要,可以看下最后这张时序图。在复位之后,同步头多次无效,RXGEARBOXSLIP被拉高多次,直到连续多个时钟检测到正确同步头为止,最后block_sync拉高表示对齐完成。
到此GTX的64B66B的相关原理就讲解完毕了,如果有了前文关于GTX的一些基础,IP的其余设置与8B10B基本一致。所以后续配置IP还是比较简单,用户使用64B66B接收数据的难度回会8B10B低很多。
本文涉及的框图基本来源于手册,需要手册的在后台回复”xilinx手册”(不包括引号)即可,在64B66B文件夹和GTX文件夹即可找到本文相关手册。
如果对文章内容理解有疑惑或者对代码不理解,可以在评论区或者后台留言,看到后均会回复!
如果本文对您有帮助,还请多多点赞👍、评论💬和收藏⭐!您的支持是我更新的最大动力!将持续更新工程!