作者:Zhang Cheng,AMD工程师;文章来源:AMD开发者社区
在数字通信中,8B10B 编码能够实现出色的直流平衡(DC-Balance)和丰富的边沿跳变,便于接收端时钟恢复,但代价是需要付出 20% 的额外带宽开销——每传输 8 位有效数据就要占用 10 位的线路带宽。
为了在保证功能的同时降低这一开销,64B66B 编码应运而生。它不再对数据本身做查表替换,而是在每 64 位数据前添加一个 2 位的帧头(Header):用 "01" 和 "10" 两种组合来区分数据块与控制块。由于这两种帧头本身一定包含一次 0→1 或 1→0 的跳变,因此每 66 位至少能保证一次强制翻转,同时带宽开销从 20% 大幅降低到约 3%(2/64)。
不过,仅靠帧头的跳变并不足以解决数据段的问题。设想一种极端情况:当负载数据为连续 64 个 "1" 或连续 64 个 "0" 时,若其恰好与相同电平的帧头相接,串行链路上最多可能出现连续 65 个相同逻辑电平。这种长连 "0" 或长连 "1" 会导致直流失衡,并使接收端难以恢复时钟。
为降低这种情况出现的概率并让串行数据在统计上更接近随机分布,64B66B 编码在帧头之后引入了一个关键步骤——加扰(Scrambling)与解扰(Descrambling)。发送端通过一个自同步扰码器(通常采用生成多项式 𝐺(𝑥)=𝑥58+𝑥39+1)对 64 位数据进行加扰,打散原始数据中的规律性,从而抑制长连 "0" 和 "1" 出现;接收端再用相同的多项式还原出原始数据。
下面将以Xilinx的Aurora 64B66B IP为例,分析64B66B加扰和解扰的过程。
首先,基于VCK190生成一个Aurora64B66B的IP,然后产生example design,综合完成后打开schematic。
对比上面两张图片可以看出:在发送(TX)通路中,并行数据在进入 GTY 之前会先经过加扰(Scrambling)处理;而在接收(RX)通路中,GTY 输出的并行数据则需先经过解扰(Descrambling)还原,再送往下一级逻辑。
- 加扰

- 解扰

64B/66B 编码标准中的数据加扰和解扰的计算,都是基于自同步线性反馈移位寄存器(LFSR),对应多项式:𝐺(𝑥)= 𝑥58+𝑥39+1,以下面表格中的加扰运算代码为例:
- DATA_IN是原始数据
- SCRAMBLED_DATA_OUT是加扰后的数据
- Scrambler是LFSR的种子,初始值为58'h155_5555_5555_5555


以加扰为例,每当输入数据或 LFSR 状态变化时,串行处理 64 个 bit,取 LFSR 的第 39位(poly[38])和第 58位(poly[57])作为反馈,与输入数据 XOR 得到加扰 bit。将加扰 bit 移入 LFSR 低位(自同步特性)依次处理下一个 bit,LFSR 在循环内串行移位 64 次。在时钟上升沿,若 DATA_VALID_IN 有效,将本周期的加扰结果 tempData 锁存到输出,将更新后的 LFSR 状态 poly 写回 scrambler,供下一周期使用。若 DATA_VALID_IN 无效:LFSR 冻结,输出保持(数据流暂停时 LFSR 不推进)。
加扰和解扰的详细计算过程可参考下表:

加扰和解扰的运算过程是通过组合逻辑实现的,原因是加扰和解扰的当前输出和下一拍状态,都是由“本拍输入 + 本拍初始的状态”直接算出来的,不需要按位逐拍寄存中间结果。如果通过时序逻辑来实现的话,则至少需要一个USER_CLK的64倍时钟。假设USER_CLK的时钟为100MHz,要保持相同吞吐率(每个 USER_CLK 周期输出 64 bit),串行时序实现确实需要在一个 USER_CLK 周期内完成 64 次运算,那控制加扰和解扰计算的时钟频率至少要6400MHz,这个频率在FPGA内部几乎是无法实现Timing收敛的。当然组合逻辑也有代价的,在综合后会产生大量的LUT5和LUT3,也会导致时序压力变大。
此外,Aurora IP的加扰和解扰都是通过RTL实现的,这是因为大部分的GT(比如7系列的GTX和GTH、US/US+系列的GTH和GTY)内部都没有集成硬件的加扰和解扰模块。而在Versal系列的GTY中,集成了硬件的加解扰模块,在timing紧张的情况下可作为替代方案,具体使用方法可参考AM002。