3. PRBS7详解:多项式x⁷+x⁶+1、生成过程、码型特性

3.1 为什么PRBS7是串行测试的"标准语言"

做高速串行测试的工程师,几乎天天跟PRBS7打交道。PCIe Gen1/Gen2、SATA、USB 3.0、千兆以太网……这些接口的物理层测试,PRBS7都是标配码型。说白了,它就是串行链路测试的"普通话"。

PRBS7的全称是7阶伪随机二进制序列(Pseudo-Random Binary Sequence of order 7)。它的周期只有127位,不像PRBS31那样长达21亿位。但正是这个"短周期"特性,让PRBS7在工程测试中非常好用——码型短,跑一轮快,调试效率高。我在项目中习惯先用PRBS7做快速眼图扫描,等链路基本调通再上PRBS31做压力测试。

为什么是7阶?因为7级移位寄存器能生成的序列长度刚好是2⁷-1=127位,这个长度不长也不短,既能覆盖足够的码型变化,又不会让测试时间拖得太长。你想想看,要是每次跑测试都要等几分钟才出一个结果,那调试效率得多低。

3.2 多项式x⁷+x⁶+1的数学含义

PRBS7的核心是它的本原多项式:x⁷+x⁶+1。这个多项式决定了序列的生成方式。从数学上讲,它满足三个条件:不可约、本原、最大周期。但我做测试工程师这么多年,说实话,每次拿到一个新接口,我第一个关心的不是多项式能不能约分,而是——抽头位置对不对。

多项式x⁷+x⁶+1的指数7和6,对应的就是LFSR(线性反馈移位寄存器)的抽头位置。指数7代表最高位(第7级寄存器),指数6代表第6级。常数项1代表反馈路径直接连接到第1级的输入端,没有额外的抽头。这三个位置——第7级、第6级、第1级——构成了完整的反馈网络。

关键概念:本原多项式是生成最大周期LFSR序列的"密码本"。只有用本原多项式,才能让移位寄存器遍历除全0外的所有状态,输出周期最长的伪随机序列。x⁷+x⁶+1就是一个标准的7阶本原多项式。

有个参数大家经常搞混——阶数和级数。7阶多项式对应7级移位寄存器,序列周期是2⁷-1=127位。我遇到过有人把"7阶"说成"7位序列",那差远了。127位周期和7位周期,完全是两个概念。

3.3 PRBS7的LFSR生成结构

下面这张图是PRBS7的LFSR电路结构。7个D触发器(寄存器)串联,第6级和第7级的输出通过异或门反馈到第1级。每次时钟上升沿,数据向右移一位,反馈值写入第1级。

PRBS7 LFSR生成结构 (x⁷+x⁶+1) R1 R2 R3 R4 R5 R6 R7 ⊕ OUT 反馈路径 (R6 + R7) 💡 初始值:通常设为全1 (0x7F),避免全0死锁。每个时钟周期,7个寄存器同时右移,反馈值写入R1。 📌 输出序列周期:2⁷−1 = 127位。包含了除全0外所有7位二进制组合。

生成过程其实不复杂。每个时钟周期,所有寄存器同时更新:R1得到反馈值(R6⊕R7),R2得到R1原来的值,R3得到R2原来的值……依次类推,R7得到R6原来的值。输出通常从R7的Q端取出。如果初始值设成全1(0x7F),那输出的第一位就是1。

用Python实现PRBS7生成器也就十几行代码:

def prbs7(seed=0x7F, n_bits=127):
    """生成PRBS7序列,初始值默认全1"""
    lfsr = seed & 0x7F          # 只保留低7位
    bits = []
    for _ in range(n_bits):
        out = (lfsr >> 6) & 1    # 从R7(bit6)输出
        bits.append(out)
        feedback = ((lfsr >> 6) ^ (lfsr >> 5)) & 1  # R7 XOR R6
        lfsr = ((lfsr << 1) | feedback) & 0x7F       # 左移 + 反馈
    return bits

# 生成127位PRBS7
seq = prbs7()
print(''.join(str(b) for b in seq[:32]))  # 前32位

这段代码模拟的就是上面那张图。我习惯在调试测试系统时先用Python验证一遍LFSR行为,确认无误再烧到FPGA或ATE里跑,省得在硬件上反复试错。

3.4 码型特性分析

PRBS7的127位序列有哪些工程上关心的特性?我列了几个核心参数:

参数 数值 工程意义
序列周期 127 bits 测试一轮快,适合快速眼图扫描
最大连续1 7 考验CDR锁相环的保持能力
最大连续0 6 考验AC耦合电容的放电时间
直流失衡 +1 bit(65个1, 62个0) 几乎直流平衡,适合AC耦合通道
自相关主峰 127 尖锐的自相关峰,便于同步锁定
自相关旁峰 -1 旁瓣极低,码间干扰小

游程分布是另一个重要指标。PRBS7的游程分布完全符合理论预期:

  • 1位游程(单个0或1):占总游程数的1/2
  • 2位游程:占1/4
  • 3位游程:占1/8
  • ……以此类推,直到7位游程

这个特性让PRBS7能模拟真实数据中的各种码型变化,但又不像真实数据那样不可控。我经常跟团队里的年轻人说:"PRBS7就是串行链路的'体检套餐'——该测的项目都覆盖了,而且结果可重复、可对比。"

工程小窍门:用PRBS7测试时,记得在接收端先做同步。因为PRBS7周期短,接收端的LFSR只要连续锁对7个bit就能进入同步状态。这也是PRBS7比PRBS31更容易上手的原因之一——同步快,调试反馈周期短。

3.5 实际测试中的注意事项

PRBS7虽然简单,但在实际测试中也有不少坑。我挑几个最常见的说说:

⚠️ 避坑指南 - 我踩过的三个PRBS7的坑

  1. 初始值全0导致输出全0:我曾经在调试一块FPGA的PRBS7发生器时,发现输出端一直是0,折腾了两小时才发现是初始值寄存器没初始化,默认全0。LFSR在全0状态下会永久锁死,输出永远不会变化。
  2. 连续7个1导致CDR漂移:有一次测6Gbps链路,眼图一直张不开。后来发现是PRBS7的连续7个1让CDR锁相环产生了漂移,把采样点偏了。解决办法是在接收端加均衡器,或者在码型中插入同步头。
  3. 误把多项式顺序搞反:有人把x⁷+x⁶+1看成"抽头在bit7和bit6",但在代码里对应的是右移还是左移,容易搞反。我的经验是——画一遍LFSR结构图,标清楚每个寄存器的位置,再写代码就不容易错了。

另外一个容易被忽略的点:PRBS7的频谱在直流附近有能量抬升。虽然它的直流失衡只有1个bit(127位中65个1、62个0),但如果你用的是AC耦合通道,这个微小的不平衡会在长周期上积累成基线漂移。我建议在跑BER测试前,先用示波器看一段时间的波形底部,确认没有明显的基线晃动。

说到眼图,PRBS7跑出来的眼图和PRBS31还是有区别的。PRBS7的抖动分布偏向于"窄而高",因为它的低频分量少;PRBS31则更接近真实数据的抖动分布。所以我的测试习惯是:先用PRBS7做快速调试和功能验证,再用PRBS31做最终的合规性测试。各取所长,效率最高。

好了,PRBS7的核心内容就这些。从多项式到生成结构,从码型特性到实际避坑,覆盖了我在项目中积累的大部分经验。记住一句话:PRBS7是串行测试的"万用表"——简单、可靠、够用,但也要知道它什么时候该用、什么时候该换别的工具。