第三章:测试信号与码型: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 如何选择?一张图说清楚

下面这张图是我自己总结的码型选择流程,帮你快速决策:

码型选择决策流程图 开始选择码型 测试目的是什么? 直流/偏置特性 全面链路评估 模拟真实业务 固定码型 PRBS伪随机码 自定义码型 建议:优先使用PRBS15或PRBS23 特殊需求时辅以固定码型或自定义码型

3.6 避坑指南:我踩过的那些坑

做误码率测试十几年,我踩过的坑不少。挑几个典型的说说:

  • 坑一:PRBS阶数选太高。我曾经在10Gbps链路上用PRBS31,结果测了整整一天还没跑完一个周期。后来发现PRBS23已经能覆盖所有问题了。
  • 坑二:固定码型测完就收工。有个项目,用“1010”码型测出来误码率为零,结果一上PRBS15就发现10^-8的误码率。后来查出来是链路的低频特性有问题。
  • 坑三:自定义码型太随意。有次我为了模拟视频流,构造了一个全是“1”的码型。结果测出来误码率奇高,后来发现是接收端的均衡器饱和了。嗯,这其实不是链路的问题,是码型设计的问题。

总结一下:

  • 日常测试:PRBS15或PRBS23,省时又全面
  • 排查特定问题:固定码型,直击要害
  • 模拟真实场景:自定义码型,灵活定制
  • 终极方案:三种码型组合使用,互相验证

记住,没有完美的码型,只有最适合当前场景的码型。多试几种,你就能找到感觉。

专注资料整理