4. 伪随机码生成与特性:m序列、Gold序列、Kasami序列的生成与自/互相关特性

各位同学,咱们今天聊聊扩频通信的“灵魂”——伪随机码。说白了,没有这些码,卫星通信的抗干扰能力就是一句空话。我当年刚入行时,总觉得这玩意儿就是一堆0和1,直到在项目中吃过亏,才明白码选得好不好,直接决定了系统能扛住多大的干扰。

伪随机码,英文叫PN码,它看起来像随机噪声,但实际上是确定的、可重复生成的。卫星通信里,我们用它来扩展信号带宽,让信号“藏”在噪声里。今天我就带大家手撸三种最经典的序列:m序列、Gold序列、Kasami序列。咱们不光讲理论,还要看它们在实际中怎么用。

核心知识点速览:

  • m序列:最长线性反馈移位寄存器序列,自相关特性极好,但互相关不够理想。
  • Gold序列:由两个m序列优选对模2加生成,互相关特性大幅改善,码数量多。
  • Kasami序列:由m序列及其采样序列模2加生成,互相关特性比Gold序列更好,但码数量少。
伪随机码生成与特性知识体系 伪随机码 (PN码) m序列 Gold序列 Kasami序列 自相关好 互相关差 互相关好 码数量多 互相关最优 码数量少 测距 同步 CDMA 抗干扰 低截获 多址

4.1 m序列:最基础的伪随机码

m序列,全称是最长线性反馈移位寄存器序列。为什么叫“最长”?因为n级移位寄存器,最多能产生2ⁿ-1个非全零状态,这就是它的周期。我习惯叫它“老祖宗”,因为后面讲的Gold和Kasami,都是从它变出来的。

生成原理:

说白了,就是一组寄存器,加上一些反馈抽头,然后不停地移位。反馈抽头的位置由本原多项式决定。举个例子,一个3级m序列,本原多项式是x³ + x + 1,对应的抽头就是第3级和第1级。

// 3级m序列生成示例 (本原多项式: x³ + x + 1)
// 初始状态: [1, 0, 0]
reg [2:0] shift_reg = 3'b100;
for (int i = 0; i < 7; i++) begin
    // 输出当前最高位
    pn_out[i] = shift_reg[2];
    // 计算反馈: 抽头位置 2 和 0
    feedback = shift_reg[2] ^ shift_reg[0];
    // 移位
    shift_reg = {shift_reg[1:0], feedback};
end
// 输出序列: 1 0 0 1 0 1 1 (周期7)

我的经验:选本原多项式时,别光看理论。我曾在项目中用了一个看似完美的本原多项式,结果在FPGA上跑出来自相关旁瓣偏高。后来查了半天,发现是抽头太多导致组合逻辑延迟太大,时序没收敛。所以,实际工程中,我建议优先选抽头少的本原多项式,比如三抽头或五抽头的。

自相关特性:

m序列的自相关函数,在零偏移时是峰值(等于周期N),在其他偏移时是-1/N。这个特性非常漂亮,就像一把“梳子”,只有对齐了才能梳到头。我当年做捕获算法时,就是利用这个特性来寻找信号起始点的。

互相关特性:

但m序列的互相关就不那么理想了。不同本原多项式生成的m序列,互相关值可能很高。我记得有一次做多用户系统,两个m序列的互相关峰值达到了周期的一半,直接把用户间的干扰拉爆了。所以,m序列更适合单用户或少量用户的场景。

4.2 Gold序列:互相关问题的解决方案

Gold序列的出现,就是为了解决m序列互相关差的问题。它的生成方法很简单:找一对“优选对”的m序列,然后模2加。什么叫优选对?就是两个m序列的互相关函数只有三个值:-1、-t(n)、t(n)-2,其中t(n) = 2^{(n+1)/2} + 1(n为奇数)。

我个人的习惯是,在需要大量码序列的CDMA系统中,首选Gold序列。比如GPS的C/A码,用的就是Gold序列。为什么?因为Gold序列的码数量多,n级寄存器能生成2ⁿ+1个Gold序列,而m序列只有φ(2ⁿ-1)/n个。

// Gold序列生成示例 (n=5, 优选对)
// m序列1: 本原多项式 x⁵ + x² + 1
// m序列2: 本原多项式 x⁵ + x⁴ + x³ + x² + 1
reg [4:0] m1 = 5'b10000;
reg [4:0] m2 = 5'b10000;
for (int i = 0; i < 31; i++) begin
    // 分别生成两个m序列的当前位
    bit1 = m1[4];
    bit2 = m2[4];
    // Gold序列 = 模2加
    gold_out[i] = bit1 ^ bit2;
    // 更新m1
    fb1 = m1[4] ^ m1[1];  // 抽头: 4, 1
    m1 = {m1[3:0], fb1};
    // 更新m2
    fb2 = m2[4] ^ m2[3] ^ m2[2] ^ m2[1];  // 抽头: 4,3,2,1
    m2 = {m2[3:0], fb2};
end

关键特性对比:

特性 m序列 Gold序列 Kasami序列
周期 2ⁿ - 1 2ⁿ - 1 2ⁿ - 1
码数量 φ(2ⁿ-1)/n 2ⁿ + 1 2^(n/2) (小集) 或 2^(n/2)+1 (大集)
自相关峰值 N (周期) N N
互相关最大值 较高 (可达周期一半) t(n) = 2^{(n+1)/2}+1 s(n) = 2^{(n+2)/2}+1 (小集)
典型应用 单用户、测距 CDMA、多址接入 低截获、抗干扰要求极高

避坑指南:我曾经在选Gold序列的优选对时,偷懒用了网上随便找的一组多项式。结果仿真时互相关特性没问题,一上硬件,发现两个序列的互相关峰值比理论值高了3dB。后来排查发现,是移位寄存器的初始状态没选对,导致生成的序列不是完整的周期。所以,我建议你们在生成Gold序列时,一定要验证两个m序列是否真的是优选对,并且初始状态不能全零。

4.3 Kasami序列:互相关特性的极致优化

Kasami序列,是伪随机码家族里互相关特性最好的。它分为小集和大集两种。小集Kasami序列的互相关最大值只有2^{(n+2)/2}+1,比Gold序列的t(n)还要小。说白了,就是用户间的干扰更低了。

生成方法也不复杂:先有一个m序列a,然后对a进行采样(每隔2^(n/2)+1位取一个),得到序列b。然后把a和b的循环移位版本模2加,就得到Kasami序列。嗯,这里要注意,n必须是偶数。

// Kasami序列生成示例 (n=6, 小集)
// m序列a: 本原多项式 x⁶ + x + 1
// 采样间隔: 2^(n/2) + 1 = 2³ + 1 = 9
reg [5:0] m_a = 6'b100000;
reg [5:0] m_b;
// 先生成完整的m序列a (周期63)
for (int i = 0; i < 63; i++) begin
    a_seq[i] = m_a[5];
    fb_a = m_a[5] ^ m_a[0];
    m_a = {m_a[4:0], fb_a};
end
// 对a序列进行9倍采样得到b序列
for (int i = 0; i < 63; i++) begin
    b_seq[i] = a_seq[(i * 9) % 63];
end
// Kasami序列 = a 与 b的循环移位 模2加
for (int shift = 0; shift < 63; shift++) begin
    for (int i = 0; i < 63; i++) begin
        kasami_out[shift][i] = a_seq[i] ^ b_seq[(i + shift) % 63];
    end
end

我为什么说Kasami序列是极致优化?因为它的互相关值非常接近理论下限——Welch界。我在做低截获概率通信系统时,就用了Kasami序列。当时测试结果出来,多用户干扰比用Gold序列低了将近2dB,效果很明显。

但Kasami序列也有缺点:码数量少。小集只有2^(n/2)个序列,大集也只有2^(n/2)+1个。所以,它更适合用户数量少、但抗干扰要求极高的场景,比如军事通信或深空探测。

4.4 三种序列的工程选型建议

好了,三种序列都讲完了。你可能会问:那我到底该用哪个?我个人的经验是这样的:

  • 单用户、测距、同步:用m序列。自相关好,实现简单,一个寄存器就搞定。
  • 多用户CDMA、码分多址:用Gold序列。码数量多,互相关可控,是工程中最常用的。
  • 低截获、抗干扰要求极高:用Kasami序列。互相关最优,但码数量少,适合用户少的场景。

我的一个小技巧:在做系统仿真时,别只看理论互相关值。我建议你把实际的信道模型(多径、多普勒)加进去,看看互相关在衰落信道下的表现。有时候理论值很漂亮,但一遇到多径,互相关旁瓣就抬高了。这时候,你可能需要结合Rake接收机来抑制多径干扰。

最后,我想说一句:伪随机码的选择,没有绝对的“最好”,只有“最合适”。你想想看,你的系统有多少用户?信道环境怎么样?抗干扰要求多高?把这些想清楚了,自然就知道该选哪种序列了。


公众号:蓝海资料掘金营,微信deep3321