CPM接收机中的线性均衡器与维特比判决器:设计与仿真
简介一份面向通信与数字信号处理方向的连续相位调制CPM线性均衡器仿真资源核心采用维特比判决器完成符号判决适合正在研究CPM调制解调、均衡算法与误码率性能分析的高年级本科生、研究生及工程师快速上手。压缩包共29个文件含14个.m脚本、7个.mat数据文件、7个.asv自动保存备份及1张误码率曲线图整体仅533KB。m脚本覆盖信号调制、相位编码、信道建模、线性均衡、维特比译码及误码率统计等完整仿真链路并包含帧数据映射/解映射、升余弦脉冲整形等辅助模块便于还原收发全过程mat数据保存了不同均衡长度下的仿真结果与BER对比可直接加载运行验证。已有123人学习下载对理解线性均衡器在CPM系统中的作用机制、对比参数差异对性能的影响是一份轻量且实用的参考代码包。1. 线性均衡器在CPM接收机里到底解决什么问题CPM连续相位调制相位是连续的符号之间互相“染色”。相位累加和部分响应成型让信号天然带记忆所以接收端最理论正确的做法是让维特比判决器直接在包含信道响应的超大网格上跑最大似然序列检测。但网格状态数会随调制指数、进制数、记忆长度和信道多径延扩展呈指数级膨胀在工程上经常跑不动。于是很多接收机在维特比前面塞一个线性均衡器用少量抽头把信道冲激响应压缩到可接受范围把“信道带来的新增记忆”尽量抹平。此时维特比面对的是一个近似的、短记忆的等效信道只需要处理CPM自身的状态转移计算量一下子回到可落地的水平。这种架构不是最优解但胜在稳定和可调。频率选择性衰落不极端时线性均衡器加维特比判决器的组合几乎不损失多少误码率性能实现复杂度却低一个数量级。适合带宽受限的无线数传、遥测下行链路以及想快速把CPM解调跑上FPGA的工程场景。下面按调制、均衡、判决三条线展开最后给出一套可以在Matlab里直接复现链路和排错手法。2. CPM、线性均衡器、维特比判决器如何组成一条有效链路2.1 CPM的记忆决定了维特比网格不得不存在CPM信号在符号间隔内的相位是连续累加的相位表达式为phi(t) 2 * pi * h * sum(a_i * q(t - i * T))其中h是调制指数a_i是M进制符号q(t)是相位脉冲。q(t)持续一个符号周期时是全响应CPM持续L个符号周期时是部分响应CPM。无论哪种当前时刻的相位都依赖历史符号。维特比判决器想干的事就是把CPM看作一个网格编码调制器在状态格里找一条累计路径度量最小的符号序列。状态由两部分构成当前累积相位状态theta_n以及最近L-1个已发符号。二进制CPM、h0.5、全响应时状态数只有4个相位0、pi/2、pi、3pi/2维特比很轻松。换到h1/3、4进制、L3的部分响应CPM状态会变成几十到上百个。网格复杂度还能接受但如果再叠加一个多径信道信道本身的冲激响应也会拉长记忆接收机就不得不在网格里同时估计CPM状态和信道抽头这就不太现实了。线性均衡器在这里的角色是让信道不再捣乱。常见做法是把均衡器放在匹配滤波之后维特比之前用均衡器输出作为维特比的观测值。理论上如果均衡器能把信道完全逆掉维特比的度量计算就和AWGN加性高斯白噪声信道下的CPM解调完全一致直接用欧氏距离做分支度量即可。2.2 线性均衡器为什么不直接硬判决通信系统里很多地方是均衡完直接硬判决QPSK、16QAM都这么干。但CPM不能这么硬来。线性均衡器本质是一个线性滤波器CPM本身不是线性调制它的信息编码在相位变化路径里均衡器输出的星座图并不像QAM那样有明确的判决边界。强行在某个采样点做硬判决会把连续相位路径上的大量信息丢掉尤其在低信噪比时误码率会明显劣化。因此均衡器在这个架构里是“辅助者”不是“判决者”。它把信道的多径尾巴削短把信号恢复成近似纯CPM过AWGN信道的样子真正对符号串做决策的是维特比判决器。维特比用均衡器输出的软信息复数基带采样点计算分支度量在所有可行的相位轨迹中挑一条累计度量最小的路径。这条路径对应的符号序列就是判决结果。2.3 均衡器选型LMS还是最小二乘工程上给CPM前面配线性均衡器最常用的两种自适应算法是LMS最小均方和RLS递归最小二乘。LMS计算量小、实现简单适合训练序列较长、信道变化不太快的场景。RLS收敛快但矩阵运算算力开销大在高速FPGA上不是首选。LMS的更新公式是每个符号周期做一次% LMS自适应均衡器核心更新 for n N_taps:length(rx_filtered) x rx_filtered(n:-1:n - N_taps 1); % 构造回归向量 y(n) w * x; % 均衡器输出 e(n) d(n) - y(n); % 误差训练期用已知序列 w w mu * x * conj(e(n)); % 抽头更新 endN_taps是抽头数mu是步长d(n)是训练序列对应的理想信号。误差用的是复数共轭因为基带信号是复数的梯度的方向要取共轭。训练阶段结束后把误差切到判决反馈模式用维特比判决器的输出重构参考信号继续做判决引导的自适应跟踪。如果要求严格收敛也可以先发一段训练序列做LS最小二乘信道估计直接解维纳-霍夫方程拿到初始抽头系数再用LMS做小步长自适应微调。这样做的好处是收敛速度快坏处是实现里需要做矩阵求逆。对仿真来说两种都可以对FPGA落地来说我会优先选择纯LMS因为硬件的乘累加结构非常规整。3. 可复现的最小链路从Matlab到维特比判决器3.1 发射端与信道先把问题控制住写仿真链路之前先把参数固定。调制指数 h 取0.5二进制全响应接收端用匹配滤波器后做定时同步定时误差暂不考虑。信道用两径等增益多径延时一个符号周期。这样设置的原因是信道只引入一个符号的记忆均衡器压力不大维特比网格也不会太大方便验证整条链路是否正确。发射端核心代码% CPMod二进制全响应h0.5矩形频率脉冲 M 2; h_mod 0.5; L 1; N_symbols 4000; bits randi([0 1], N_symbols, 1); syms 2 * bits - 1; % 双极性映射 phi 0; phase zeros(N_symbols 1, 1); for k 1:N_symbols phase(k 1) mod(phase(k) pi * h_mod * syms(k), 2 * pi); endphase是每个符号结束时刻的累积相位。全响应CPM在符号周期内相位线性变化所以可以每符号只保留一个相位样点再插值也可以直接在符号率上处理。维特比判决器也按符号率工作所以仿真不需要过采样这一条链路里均衡器是符号间隔均衡器。信道加多径channel [1, 0.5]; % 两径第二径幅度0.5 rx filter(channel, 1, exp(1j * phase(2:end))); rx awgn(rx, 12, measured); % 不加噪声的信号功率为基准这里的filter是多径卷积第二径延时正好一个符号周期。注意带通信号和基带等效模型的差别基带仿真里多径系数直接乘在复数包络上不需要考虑载波。3.2 线性均衡器设计与训练抽头数和训练序列配合训练序列放在数据最前面长度取200个符号就足够。训练期目标是让均衡器输出逼近期望的CPM匹配滤波输出参考信号。参考信号怎么生成是个细节常见做法是已知训练符号生成无噪声的纯CPM匹配滤波输出作为LMS的d(n)。这样均衡器学到的是从多径信道输入到理想信号的逆映射。均衡器实现N_taps 15; % 抽头数奇数保证中心抽头 mu 0.008; w zeros(N_taps, 1); w(round(N_taps / 2)) 1; % 初始化为纯延时 train_len 200; d_train ref_signal(1:train_len); % 理想参考信号 for n N_taps:train_len x rx(n:-1:n - N_taps 1); y w * x; e d_train(n) - y; w w mu * x * conj(e); endrx是接收符号序列。mu 0.008对幅度归一化后的信号是安全值太大导致发散。训练完成后均衡器切换到判决引导模式把维特比判决出的符号重新作为参考。但仿真里更省事的做法是训练后直接固定抽头不再自适应方便排查均衡器之外的逻辑问题。抽头数15对这个两径信道偏宽但能展示一个现象抽头越多均衡器越会把噪声放大后面会看到误码率不一定变好。3.3 维特比判决器实现状态、分支度量与回溯均衡器输出y_n仍是一串复数相位样点。维特比判决器要做的是根据这些观测值在所有可能的CPM相位路径中找最可能的符号序列。二进制、h0.5、全响应时每符号的相位增量是pi/2或-pi/2所以状态量就是当前累积相位。为了消除连续相位的缠绕歧义四个状态0, pi/2, pi, 3pi/2用模2pi归一。分支度量的计算方式每个候选状态转移会生成一个理想的复数参考值exp(j * phase_candidate)它与均衡器输出的距离就是分支度量。路径度量更新后做加比选ACS操作存幸存路径最后回溯。% 维特比核心二进制 h0.5 全响应 n_states 4; path_metric zeros(n_states, 1); survivor zeros(n_states, N_symbols); % 记录每个状态每个时刻的历史符号 ref_phase [0, pi/2, pi, 3*pi/2]; for t 1:N_symbols obs y_eq(t); % 均衡器输出 new_metric inf(n_states, 1); for s 1:n_states % 每个状态有两条候选路径pi/2 或 -pi/2 for bit [0, 1] phase_candidate mod(ref_phase(s) (2*bit-1) * pi/2, 2*pi); [~, ns] min(abs(exp(1j*phase_candidate) - exp(1j*ref_phase))); % 修正需要按相位值匹配到目标状态 [~, ns] min(abs(mod(ref_phase - phase_candidate pi, 2*pi) - pi)); br_metric abs(obs - exp(1j * phase_candidate))^2; cand path_metric(s) br_metric; if cand new_metric(ns) new_metric(ns) cand; survivor(ns, t) bit; end end end path_metric new_metric; end实际代码里,状态映射要做成查找表避免每时刻算一遍min(abs(...))。维特比最耗时的部分是状态数和分支数的乘积这里每时刻要做4状态×2分支共8次复数距离计算跑几千个符号没压力。回溯长度取5到10个符号即可工程上一般取状态数的2到4倍。注意path_metric是实数度量连续累加数值不断增大符号数一多需要做归一化否则浮点精度会丢。表1给出了本小节链路的关键参数后面调参会用到参数取值说明调制指数 h0.5二进制CPM常见值记忆长度 L1全响应网格简单均衡器抽头数15奇数中心抽头初始化LMS步长 mu0.008训练期固定值训练序列长度200足够LMS收敛维特比状态数4h0.5下的相位状态回溯长度85~10范围内取中值4. 参数怎么调才不踩坑抽头、步长、回溯深度4.1 抽头数不是越多越好线性均衡器在抑制多径的同时会放大噪声这叫噪声增强效应。抽头数越少均衡器能补偿的多径扩展越短残余ISI大维特比看到的是被污染的状态转移抽头数太多噪声被放大维特比的br_metric计算的方差偏大等价于信噪比下降。对两径延时一个符号的信道7到15个抽头足够对更长延时的信道不要无脑加抽头先看信道冲激响应的有效长度。一个实操技巧画出均衡器抽头系数绝对值如果两端抽头明显比中间小许多说明抽头冗余可以减数目再训练一次。若抽头中间部位没有明显主峰说明步长太大或者参考信号生成有问题。4.2 LMS步长的量级判断LMS收敛的约束是步长小于信号功率下的最大特征值倒数严格分析要用自相关矩阵特征值。工程上更直观的判断方式mu取0.001到0.01之间。mu0.008对归一化功率的信号几乎是安全的。步长太大时均衡器的误差信号不收敛抽头系数发散维特比判决器的误码率会突然变成0.5附近。步长太小则收敛慢训练序列不够的话均衡器还没收敛就开始发数据性能差一大截。判断收敛的标准是看训练期误差e(n)的功率轨迹前50个符号快速下降后100个符号基本平坦才算训练成功。4.3 维特比回溯长度和路径度量溢出回溯深度太浅会切掉幸存路径的公共部分造成判决错误太深则浪费存储。二进制h0.5时回溯取8足够部分响应CPM建议取10到15。加性噪声较大时路径度量值会持续累加运行几万个符号后可能接近浮点的上限需要对全部状态减去同一常数这是BCJR和维特比共通的数值处理手法每100个符号做一次归一化即可。还有一个容易被忽略的是定时误差。这个链路里均衡器是符号间隔均衡器实际系统里如果定时有偏差符号间隔采样点不是最佳采样点均衡器训练会一直不收敛。常见做法是在同步完成后再开均衡器训练或者使用分数间隔均衡器T/2间隔在白噪声背景下多花一倍的抽头数换来更宽松的定时裕量。5. 用误码率、误差轨迹和相位图验证这套判决器是否真的工作验证思路分三层第一层看维特比判决出的符号序列误码率是否接近理论值第二层看均衡器误差收敛轨迹判断自适应是否正常第三层看均衡前后的相位轨迹图直观发现纬度塌缩和相位跳变问题。误码率统计最简单代码里加一段对比% 误码率统计 out_bits decoded_bits(1:end - traceback); ref_bits bits(1:length(out_bits)); ber sum(out_bits ~ ref_bits) / length(out_bits);若信噪比12dB下BER能在1e-3左右说明链路正确。如果没有均衡器直接把多径信号喂给维特比误码率至少差一个量级。误差轨迹画法% 训练期误差功率滑动平均 plot(movmean(abs(e).^2, 20));看曲线是否单调下降进入平台若震荡剧烈先降mu再训练若平台太高说明抽头数“不够”信道残余ISI没有被压下去。这里查看抽头系数的幅度分布stem(abs(w));如果除了中心抽头外的能量依然比较高说明你要么把均衡器当成纯匹配滤波器在用要么信道延误建模与实际不符。第二种情况要去核查信道滤波器的系数看channel里的路径时延和相位是不是按复数基带模型设置的。相位轨迹图是CPM链路里最直观的调试手段。画法很简单直接plot均衡器输出的实部与虚部连成一条连续曲线。正常的CPM全响应h0.5信号相位轨迹是平滑的折线每个符号间隔相位方向旋转90度。如果相位轨迹上出现突跳、螺旋折返大概率是均衡器抽头发散或者参考信号相位基准没对齐。检查参考信号生成时用的初始相位是不是0以及维特比的ref_phase是否和发射端一致。还有一个经常出问题的是训练序列和参考信号的符号对齐。LMS训练时d_train和rx之间必须严格同步不能有偏差。如果误差曲线一开始很大随后缓慢下降但误码率仍高多半是训练序列起始点偏移了半个符号。此时用互相关比对接收信号和本地参考序列的峰值位置把对齐修正后再训练一次。验证通过后的最后一个技巧是判决引导模式切换。训练结束后不要直接冻结抽头而是把维特比判决出的符号反馈回来继续更新均衡器这样在信道缓慢漂移时能持续跟踪。实际实现时要注意帧结构训练序列→数据→训练序列周期性的插入已知序列均衡器和维特比的状态都能定期校准。本文还有配套的精品资源点击获取