2. PRBS基本原理:伪随机二进制序列的定义、生成多项式
提起误码率测试,PRBS 是绕不开的核心工具。说白了,它就是一段“看起来像随机噪声、实际上有规律可循”的二进制序列。我最早接触这东西是在测 10G 光模块的时候,当时看着示波器上密密麻麻的码型,以为真是随机噪声——后来才发现,其实人家是有“家谱”的。这一章,我们就来把它说透。
2.1 什么是伪随机二进制序列?
伪随机二进制序列,英文全称 Pseudo Random Binary Sequence,缩写 PRBS。它的核心特征就四个字:伪 和 随机。你想想看,真正的随机序列没法重复验证,但测试需要可复现。所以工程师们想了个办法:用一个确定性的算法生成一串看起来随机的比特流。
关键点:PRBS 的“伪”指生成算法确定,“随机”指统计特性接近真随机(平衡性、游程分布等)。
我在项目中遇到过一件事:有同事直接用自带的随机数发生器做抖动测试,结果下一次跑出来的码型完全不同,根本没法复现定位。后来改用标准 PRBS7,问题瞬间解决。这就是“伪”的价值——你可以在世界上任何一台仪器上产生完全相同的序列。
2.2 生成多项式——LFSR 的灵魂
PRBS 的生成靠的是线性反馈移位寄存器,也就是 LFSR。它的本质是一个递归公式,用生成多项式来描述。举个例子,PRBS7 的多项式是 x^7 + x^6 + 1。这里的指数只代表 taps 的位置,所谓 tap,就是反馈抽头。
嗯,多项式写法里那个 +1 并不是普通加法,在GF(2)域里它代表异或(XOR)。我个人习惯画 LFSR 图的时候,把每个 D 触发器标上序号,然后把 taps 位引出来做 XOR 再反馈到输入端。这样一目了然。
| 阶数 | 常用多项式 | 序列长度(周期) | 典型应用 |
|---|---|---|---|
| PRBS7 | x7 + x6 + 1 | 27 − 1 = 127 | 千兆以太网、SDH/SONET |
| PRBS9 | x9 + x5 + 1 | 29 − 1 = 511 | 千兆以太网短距离 |
| PRBS11 | x11 + x9 + 1 | 211 − 1 = 2047 | 背板测试 |
| PRBS15 | x15 + x14 + 1 | 215 − 1 = 32767 | USB 3.0、SATA |
| PRBS23 | x23 + x18 + 1 | 223 − 1 = 8388607 | 高密度光模块 |
| PRBS31 | x31 + x28 + 1 | 231 − 1 = 2147483647 | 最苛刻的误码测试 |
你可能会问:为什么阶数越高周期越长?其实很简单,n 阶 LFSR 最多有 2n 种状态,但全零状态会“锁死”序列,所以最大周期就是 2n − 1。我曾经在调试一款 56G PAM4 芯片时,误用 PRBS23 发现跑不出完整周期——因为信号速率太高,采样深度不够。后来换成 PRBS15 就覆盖了。选型这件事,得看你的测试目标和设备能力。
2.3 从多项式到代码:手写 PRBS 生成器
光讲理论不过瘾,我直接给你一段 Python 代码。这段代码生成 PRBS7 的 127 个比特,你可以扔到任何环境里跑。
def prbs7(seed=0b1000000, length=127):
"""
生成 PRBS7 序列(多项式 x^7 + x^6 + 1)
seed: 初始值,不能为全 0
length: 输出比特数(默认完整周期 127)
"""
lfsr = seed
bits = []
for _ in range(length):
# 输出最低位
bit = lfsr & 1
bits.append(bit)
# 计算反馈:tap7 (bit 7) 和 tap6 (bit 6) 异或
feedback = ((lfsr >> 6) ^ (lfsr >> 5)) & 1
lfsr = (lfsr >> 1) | (feedback << 6)
return bits
seq = prbs7()
print(''.join(str(b) for b in seq))
# 输出示例:1111111 1000010 0110010 0100010 1101101 0111001 111...(共127位)
技巧:如果想让 LFSR 跑得更高效,可以用 mask 和 tap 做掩码运算,避免逐位移位。我在 FPGA 里写 Verilog 时就是这么干的,一个时钟就能算出一位。
2.4 为什么叫“伪随机”?看统计特性
真正合格的 PRBS 必须通过随机性测试。最简单的两个指标:平衡性(1 和 0 的数量差不超过 1)和 游程分布(相同比特连续出现的长度分布)。我记得有一次,自己写的 PRBS 生成器因为忘记处理全零种子,导致序列里全是 0,平衡性直接崩了。嗯,这里要提醒你——种子不能是全 0,否则 LFSR 永远出不来了。
常见陷阱:多阶 PRBS 的初始种子(seed)如果设置不当,可能导致序列周期变短或重复。标准做法是只允许除全 0 外的任意值。我习惯用 0b100...0 作为初始种子,这样最安全。
2.5 一张图看懂 LFSR 生成原理
下面我画了一张 PRBS7 的 LFSR 结构图。你可以看到 7 个寄存器串联,tap 从第 6 级(索引从 0 开始)和第 5 级引出,经过 XOR 后反馈到最前面。
结合这张图再看代码,思路就很清晰了:每次时钟上升沿,所有寄存器右移一位,同时根据 tap 位的异或结果填入最高位。输出的比特就是最低位(FF0 的输出),当然也可以从任意一级取出——但为了保持同步,行业里通常取 FF0 作为输出。
2.6 小结
PRBS 的本质就是用 LFSR 实现一个可重复的“伪随机”序列。生成多项式决定了抽头位置和序列长度。记住三点:种子别全零、多项式要本原、阶数按需选。这些基本功打牢了,后面注入、捕获、定位才能搞得明白。