☰
扩频序列设计:m序列、Walsh码与Gold序列的工程实践
2026/10/24 17:21:09 网站建设 项目流程

简介:这份文档面向通信工程、无线通信课程学习者和CDMA系统入门者,聚焦扩频通信中两类核心序列——m序列与Walsh码的原理与生成方法,帮助读者理解码分多址中扩频码的设计逻辑与正交性来源。压缩包内为1个doc文件,约355KB,集中整理了Walsh码由Hadamard矩阵重排生成的过程、64阶Walsh序列在前向链路中的信道分配与码片速率说明,并附有Matlab生成函数代码,涵盖Paley序、Walsh序及逆Walsh序的变换矩阵构造;同时讲解m序列的线性移位寄存器结构与反馈系数、起始状态对序列的影响,并延伸至Gold序列的模2加生成思路。内容还讨论了多径与小区间异步导致的实际非正交及多址干扰问题,适合作为扩频序列理论学习与仿真实现的参考。目前已有636人学习下载。

1. 正交的幻觉:为什么 Walsh 码在纸面上完美,在空口里翻车

扩频序列里有两个名字几乎绕不开:m 序列和 Walsh 码。前者靠线性移位寄存器滚出 2^n−1 的伪随机长周期,后者靠 Hadamard 矩阵的行正交性把 64 条前向信道硬生生塞进同一段频谱。教科书给它们的评价都很漂亮——正交、低互相关、抑制多址干扰。但真正在链路预算里踩过坑的人都知道,Walsh 码的正交性只在「同步」这个前提下成立,一旦多径延迟到达、邻区信号异步混入,那点正交性立刻打折,MAI 不会归零。这个反直觉的落差,恰恰是理解扩频序列设计动机的入口:正交不是物理属性,而是一个需要被工程条件兜住的约定。搞懂 m 序列怎么产生、Walsh 矩阵怎么从 Hadamard 矩阵重排出来、Gold 序列为什么要在 m 序列之上再叠一层,才能明白 CDMA 里码分多址到底「分」的是什么。下面从生成机制一路拆到矩阵重排的源码细节。

2. m 序列:n 级移位寄存器如何滚出 2^n−1 的周期

2.1 反馈系数决定序列,起始状态只决定起点

m 序列的全称是最长线性移位寄存器序列,结构上就是一个 n 级移位寄存器加一条模 2 加法的反馈抽头。每个时钟沿,寄存器整体左移一位,最右端补入的新比特由若干级输出异或得到。这里有个容易被混淆的分工:反馈系数的组合决定这条序列「是不是」m 序列、周期有多长;起始状态只决定你从这条周期序列的哪个相位开始读。换句话说,反馈多项式选错了,再怎么换初值也滚不出最长周期。

n 级寄存器最多有 2^n 种状态,全零状态是吸收态(异或永远得零),所以理论上限是 2^n−1。能跑满这个上限的反馈抽头,对应的是本原多项式。常见的实现思路是查本原多项式表,而不是现场枚举——n 稍大一点,枚举空间就爆炸了。

# n 级 m 序列发生器:taps 为本原多项式对应的反馈抽头位置(1-based) def m_sequence(n, taps, seed, length): state = seed & ((1 << n) - 1) # 截断到 n 位,防止初值越界 if state == 0: raise ValueError("全零初值是吸收态,永远输出 0") out = [] for _ in range(length): out.append(state & 1) # 取最低位作为输出码片 fb = 0 for t in taps: # 对抽头位置做模 2 加 fb ^= (state >> (t - 1)) & 1 state = (state >> 1) | (fb << (n - 1)) # 右移并回填反馈位 return out

这段逻辑里,taps就是反馈系数的位置集合,seed是起始状态,length控制输出长度。关键在最后一行:右移之后把反馈位塞进最高位,等价于「左移补反馈」的镜像写法,两种写法在文献里都常见,读别人代码时别被方向绕晕。state & 1取的是当前最低位,所以输出序列的相位和 seed 强相关——同一个本原多项式、不同 seed,得到的是同一条周期序列的不同平移。

2.2 自相关双值特性:为什么它像噪声又不像噪声

m 序列被当作伪随机噪声序列用,核心依据是它的自相关函数只有两个取值:零延迟处为 1(归一化后),其余延迟处为 −1/(2^n−1)。这个「接近零但不等于零」的旁瓣,是它和理想白噪声的区别,也是它在同步捕获里能用的原因——接收端滑动本地序列做相关,只有对齐那一刻相关峰才陡然立起来,其余位置都被压得很低。

互相关方面,同一本原多项式不同相位之间的互相关同样很低,但不同本原多项式产生的两条 m 序列之间,互相关峰值可能并不理想。这就是优选对概念的由来:并非任意两条 m 序列都适合拿来做码分多址的地址码,得挑互相关峰值满足门限的那一对。Gold 序列正是建立在这个前提上——取一对优选对,模 2 加,得到一族序列,族内任意两条的互相关都受控。

提示:判断一条序列是不是 m 序列,别只看周期长度,还要验证它在一个周期内 0 和 1 的个数差 1、游程分布符合预期。周期对但统计特性不对,多半是反馈抽头选成了非本原多项式。

3. Walsh 码:Hadamard 矩阵到 Walsh 矩阵的重排逻辑

3.1 正交性来自矩阵行,不来自生成公式

Walsh 码的正交性根源在 Hadamard 矩阵:一个由 +1 和 −1 构成的方阵,任意两行内积为零。直接把 Hadamard 矩阵的行拿来当扩频码,其实已经正交了,那为什么还要「重排」?因为 Hadamard 矩阵的自然行序(也叫 Paley 序)下,相邻行的交变次数(符号翻转次数)并不随行号单调增长。而实际系统关心的是「序号小的码,交变次数少」——交变次数少意味着码片变化慢,对载波同步误差和滤波失真更宽容。Walsh 序就是把行按交变次数重新排列,让 W0 全为 +1、W1 交变一次、W2 交变两次……依次递增。

这个重排不是随便排的,它对应一个确定的置换。源码里用三个矩阵把这条链路拆得很清楚:Hp是 Paley 序矩阵,Wg是 Walsh 序矩阵,Hm是逆 Walsh 序矩阵,Ep、Eg、Em则是记录置换关系的变换矩阵。理解这段代码的关键,是看懂「用位操作算出行号映射」这件事。

3.2 源码拆解:位操作如何完成行号置换

function X = walshf1(N) N = ceil(log2(N)); H = hadamard(2^N); % 生成 2^N 阶 Hadamard 矩阵(Paley 序) Hp = zeros(2^N); Ep = zeros(2^N); Wg = zeros(2^N); Eg = zeros(2^N); E = eye(2^N); % 第一段:把 H 的行按 Paley 序映射到 Hp for n = 1:2^N p = 0; for i = 1:N p = bitset(p, i, bitget(n-1, N-i+1)); % 位序反转 end Hp(p+1, :) = H(n, :); Ep(p+1, :) = E(n, :); end % 第二段:按交变次数规则把 Hp 重排成 Walsh 序 Wg for n = 1:2^N g = 0; g = bitset(g, N, bitget(n-1, N)); % 最高位直接继承 for i = 2:N if bitget(n-1, N-i+1) == 0 g = bitset(g, N-i+1, bitget(g, N-i+2)); else g = bitset(g, N-i+1, 1 - bitget(g, N-i+2)); end end Wg(g+1, :) = Hp(n, :); Eg(g+1, :) = Ep(n, :); end % 第三段:再反转一次位序,得到逆 Walsh 序 Hm for n = 1:2^N m = 0; for i = 1:N m = bitset(m, i, bitget(n-1, N-i+1)); end Hm(m+1, :) = Wg(n, :); Em(m+1, :) = Eg(n, :); end X = Wg; % 返回 Walsh 序矩阵

第一段的bitset(p, i, bitget(n-1, N-i+1))做的是位序反转:把行号 n−1 的二进制位从高到低倒过来写。这一步把 Hadamard 矩阵的自然行序转成 Paley 序,Ep同步记录这个置换,方便后续反查「Walsh 序第 k 行对应原始第几行」。第二段是核心:g的每一位由前一位(更高位)和当前输入位共同决定,规则是「输入位为 0 则继承,为 1 则取反」。这实际上是在按 Gray 码的思路累加交变次数——相邻 Walsh 序行号之间只差一个符号翻转位置,所以交变次数单调递增。第三段再反转一次位序,得到逆 Walsh 序,Hm和Em是给需要反向映射的场景准备的。

参数上,N进来先被ceil(log2(N))规整成 2 的幂次,所以传 64 得到 64 阶,传 60 也会被抬到 64 阶。X = Wg是最终返回的 Walsh 序矩阵,行号从 1 开始对应 W0 到 W(2^N−1)。如果只想要矩阵不关心置换关系,Ep、Eg、Em可以省掉,但排查「某个 W 码对应哪条原始 Hadamard 行」时,这三个矩阵就是后悔药。

3.3 64 阶 Walsh 与前向信道的对应关系

CDMA 前向链路用 64 阶 Walsh 序列,每个 W 序列固定分配给一种前向物理信道,W0 到 W63 一共 64 条,码片速率 1.2288 Mc/s。这个数字不是随手定的:1.2288 Mc/s 的码片速率配合 64 阶正交码,正好把一条 1.25 MHz 带宽的载波切成 64 个正交子信道,每个子信道承载一路低速业务或控制信息。码分多址的「分」,在前向链路上分的就是这 64 条 Walsh 码——基站侧所有信道同时发射,靠码的正交性在接收端解扩时彼此分离。

但这里埋着第 1 章说的那个坑:正交性要求所有 Walsh 码在接收端严格码片对齐。基站发出去的 64 路信号在时间上是同步的,可一旦经过多径信道,某条路径延迟了几个码片到达,它携带的 Walsh 码和本地解扩用的 Walsh 码就不再逐位对齐,内积不再为零,MAI 就漏进来了。邻区信号更是完全异步,正交性从源头上就不成立。所以实际系统里 Walsh 码负责的是「同小区同步信道之间的正交」,跨小区和抗多径得靠别的机制兜底。

4. Gold 序列:为什么要在 m 序列之上再叠一层模 2 加

4.1 优选对模 2 加,换来的是一整族可控互相关的码

单条 m 序列的互相关特性依赖优选对,可选数量有限。Gold 序列的做法是:取一对周期和速率相同的 m 序列优选对,把其中一条循环移位后与另一条模 2 加,移位量取遍一个周期,就得到一族序列。族内任意两条序列的互相关峰值被限制在一个三值集合内,不会随码数量增加而恶化。这个性质对码分多址至关重要——地址码数量要够多,同时任意两条地址码之间的干扰要可控,Gold 序列正好卡在这个平衡点上。

从实现角度看,Gold 序列发生器就是两个并行的 m 序列发生器加一个模 2 加法器,移位量通过改变其中一条序列的初值(相位)来选。硬件代价比单独维护一张大码表低得多,这也是它在实际系统里被广泛采用的原因之一。

4.2 m 序列、Walsh、Gold 三者的分工

把三者放在一起看,分工其实很清楚:m 序列提供长周期、类噪声的伪随机特性,适合做扰码和同步;Walsh 码提供严格正交的行集合,适合做信道化,把同一小区的多路信号分开;Gold 序列提供数量足够、互相关受控的码族,适合做地址码,区分不同用户或不同小区。很多系统里这三者是叠加使用的——先 Walsh 信道化,再加扰码,扰码往往就来自 m 序列或 Gold 序列。理解这个分层,比单独记住每个序列的定义有用得多。

序列核心性质典型角色关键约束
m 序列周期 2^n−1,双值自相关扰码、同步、PN 生成反馈抽头须为本原多项式
Walsh 码行间严格正交前向信道化依赖码片级同步
Gold 序列族内互相关三值受控地址码、区分用户/小区需先有 m 序列优选对

5. 避坑与排查:扩频序列实现里最容易翻车的几处

5.1 现象:m 序列周期对,但统计特性不对

原因多半是反馈抽头选成了非本原多项式,寄存器跑进了一个短循环。解决方式是拿本原多项式表核对抽头位置,或者直接验证一个周期内 1 的个数是否为 2^(n−1),不对就换抽头。

5.2 现象:Walsh 矩阵生成后某两行内积不为零

先查阶数是否被ceil(log2(N))悄悄抬过——传了非 2 的幂次,矩阵维度变了,行号对应关系全乱。再查重排循环里bitset的位序方向,N-i+1和i写反会导致置换错位,矩阵看着像那么回事,正交性却崩了。

5.3 现象:仿真里 MAI 明明该为零却压不下去

检查多径模型是否引入了非整数码片延迟。只要延迟不是码片周期的整数倍,Walsh 码的正交性就破了,这时候该看的是接收端有没有做多用户检测或均衡,而不是回头怀疑矩阵生成代码。

5.4 现象:Gold 序列互相关峰值超标

大概率是两条源 m 序列不构成优选对。优选对的互相关峰值有明确门限,随便拿两条 m 序列模 2 加,族内互相关可能远超预期。换优选对,或者退一步用别的码族。

注意:Walsh 序和逆 Walsh 序的矩阵不要混用。Wg和Hm行序不同,拿Hm的行号去索引信道,解扩出来的结果是错的,而且错得很隐蔽——因为矩阵本身仍然正交。

6. 设计取舍:正交是约定,不是物理定律

回到最开始那个落差。Walsh 码的设计动机,是在同步前提下用最小的实现代价换取信道间的完全正交——Hadamard 矩阵天然存在,重排只是行序调整,硬件上就是查表和异或,代价极低。这个取舍成立的条件写得很清楚:码片对齐。一旦条件不满足,正交性不是「减弱」,而是从根上不成立,因为内积为零的推导每一步都依赖逐位对齐。

m 序列的取舍在另一头:用线性反馈换长周期和低自相关旁瓣,代价是互相关特性依赖本原多项式和优选对的挑选,不能随便组合。Gold 序列则是在 m 序列的基础上,用「多一条移位序列加一个模 2 加法器」的代价,换来一整族互相关受控的码,把地址码数量的问题一次性解决。三者没有谁更先进,只有各自兜住了哪一段工程约束。

验证一套扩频序列实现是否可信,我一般会走三步:先验单条序列的周期和统计特性,再验矩阵行间内积是否严格为零,最后把序列丢进带多径和异步邻区的链路模型里看 MAI 的实际量级。前两步过不了是代码问题,第三步过不了是模型问题,两者别混为一谈。源码里那三个置换矩阵Ep、Eg、Em看着冗余,真到排查行号映射对不上的时候,就是唯一的后悔药——从那以后我每次改 Walsh 重排逻辑,都强制把这三个矩阵打出来对一遍行号,再谈性能。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询