第三章:测试信号与码型:PRBS伪随机码、固定码型、自定义码型的选择
做误码率测试这么多年,我经常被问到同一个问题:“到底该用哪种码型来测?”
说实话,这个问题没有标准答案。不同的场景,不同的设备,甚至不同的测试目的,都会影响你的选择。今天我就把这几类码型的门道给你讲透。
3.1 为什么码型选择这么重要?
你想想看,误码率测试的本质是什么?
是拿一个已知的信号发出去,再收回来对比。如果发出去的信号本身就有问题,那测出来的误码率能信吗?
我在项目中遇到过一件事:有个同事用全“0”码型测光模块,结果误码率一直为零。他高兴坏了,觉得产品没问题。结果一上真实业务,丢包率直接爆表。为什么?因为全“0”码型没有跳变,接收端的时钟恢复电路根本没法锁定。
嗯,这就是码型选择不当的典型后果。
核心原则:测试码型必须能模拟真实业务信号的统计特性,同时要能暴露链路的潜在缺陷。
3.2 PRBS伪随机码:最通用的选择
PRBS,全称Pseudo-Random Binary Sequence。说白了,就是看起来像随机信号,但实际上是确定性的序列。
我个人习惯把PRBS叫做“万金油”码型。为什么?因为它有几个很讨喜的特点:
- 统计特性接近真实信号:0和1的分布均匀,有足够的跳变密度
- 可重复性:同样的种子能生成完全一样的序列,方便对比
- 频谱特性好:能量分布均匀,能有效激励链路的各个频段
常见的PRBS阶数
| PRBS阶数 | 序列长度 | 典型应用场景 |
|---|---|---|
| PRBS7 | 2^7 - 1 = 127 | 短距离、低速链路(如1Gbps以下) |
| PRBS15 | 2^15 - 1 = 32767 | 中速链路(如10Gbps) |
| PRBS23 | 2^23 - 1 = 8388607 | 高速链路(如25Gbps) |
| PRBS31 | 2^31 - 1 = 2147483647 | 超高速链路(如100Gbps以上) |
这里有个经验:阶数越高,序列越长,越能暴露长连“0”或长连“1”带来的问题。但代价是测试时间更长。
我的建议:如果拿不准用哪个,先从PRBS15开始。它兼顾了测试覆盖率和效率。我在调试25Gbps链路时,PRBS23和PRBS31的结果差异其实不大,但PRBS31的测试时间长了近100倍。
3.3 固定码型:简单但有效
固定码型,就是重复发送同一个固定的比特序列。比如全“0”、全“1”、或者“1010”交替。
你可能会问:这么简单的码型,有什么用?
用处大了去了。我举个例子:
- 全“0”或全“1”:用来测试链路的直流偏置特性。如果接收端有隔直电容,全“0”码型会导致电容充电,信号基线漂移。
- “1010”交替码:这是最高频率的码型,用来测试链路的带宽极限。如果链路带宽不够,这种码型的眼图会闭合得最明显。
- 特定模式:比如“00001111”,用来测试时钟恢复电路的锁定能力。
注意:固定码型不能替代PRBS。它只能暴露特定问题,不能全面评估链路质量。我曾经见过有人只用“1010”码型测完就说链路没问题,结果一上PRBS23就发现误码率高达10^-6。
3.4 自定义码型:灵活应对特殊场景
当PRBS和固定码型都不够用时,就该自定义码型上场了。
什么场景需要自定义?
- 模拟真实业务:比如你的系统传输的是视频流,那就可以构造一个包含大量连续相同像素值的码型
- 压力测试:构造最坏情况的码型,比如长连“0”后紧跟长连“1”,考验链路的瞬态响应
- 协议特定要求:某些协议有特殊的码型要求,比如8B/10B编码后的码型
下面是一个简单的Python示例,生成自定义码型:
def generate_custom_pattern(length, pattern_type='worst_case'):
"""
生成自定义测试码型
pattern_type: 'worst_case' - 最坏情况, 'realistic' - 模拟真实业务
"""
if pattern_type == 'worst_case':
# 构造长连0后跟长连1
pattern = '0' * 100 + '1' * 100
# 重复直到达到目标长度
pattern = (pattern * (length // len(pattern) + 1))[:length]
elif pattern_type == 'realistic':
# 模拟视频流:大部分是相近的像素值
import random
random.seed(42)
pattern = ''.join(['1' if random.random() > 0.4 else '0' for _ in range(length)])
return pattern
# 生成1000比特的自定义码型
test_pattern = generate_custom_pattern(1000, 'worst_case')
print(f"自定义码型前50比特: {test_pattern[:50]}")
3.5 如何选择?一张图说清楚
下面这张图是我自己总结的码型选择流程,帮你快速决策:
3.6 避坑指南:我踩过的那些坑
做误码率测试十几年,我踩过的坑不少。挑几个典型的说说:
- 坑一:PRBS阶数选太高。我曾经在10Gbps链路上用PRBS31,结果测了整整一天还没跑完一个周期。后来发现PRBS23已经能覆盖所有问题了。
- 坑二:固定码型测完就收工。有个项目,用“1010”码型测出来误码率为零,结果一上PRBS15就发现10^-8的误码率。后来查出来是链路的低频特性有问题。
- 坑三:自定义码型太随意。有次我为了模拟视频流,构造了一个全是“1”的码型。结果测出来误码率奇高,后来发现是接收端的均衡器饱和了。嗯,这其实不是链路的问题,是码型设计的问题。
总结一下:
- 日常测试:PRBS15或PRBS23,省时又全面
- 排查特定问题:固定码型,直击要害
- 模拟真实场景:自定义码型,灵活定制
- 终极方案:三种码型组合使用,互相验证
记住,没有完美的码型,只有最适合当前场景的码型。多试几种,你就能找到感觉。