SC-FDMA与SC-DFE的MATLAB仿真:从IFDMA映射到判决反馈均衡
发布时间:2026/9/16 14:16:49 锦皓数字建站

简介这套MATLAB仿真代码围绕IFDMA交织频分多址与SC-FDMA单载波频分多址两种多址接入技术展开完整实现了SC-DFE判决反馈均衡器的建模与仿真可帮助通信专业学生或研究人员直观理解4G LTE上行链路中降低峰均比、抑制符号间干扰的核心原理。压缩包共12个文件其中9个.m脚本为仿真主体覆盖信号生成、子载波映射、瑞利衰落信道模拟、DFE均衡及误码率统计等模块另有.mat数据文件保存中间结果PDF文档与txt说明则提供SC-FDMA/SCFDE相关背景与PAPR对比参考整体包体仅52KB轻量易用。这套代码在CSDN上已有604人学习浏览适用于课程设计、毕业设计或无线通信算法验证等场景。通过运行代码读者可以对比理想信道与多径信道下的星座图、计算BER曲线并修改DFE抽头系数、反馈阶数等参数观察均衡器对系统性能的改善效果进而掌握从发射端处理到接收端均衡的完整仿真链路。1. 为什么 SC-FDMA 仿真要单独做而不是拿 OFDM 直接套做 LTE 物理层或者卫星/无线自组网的上行链路设计时直接沿用 OFDM 的仿真链路往往会踩坑同样的信道下面OFDM 的峰均比PAPR在高功率放大器前让发射机不得不多留功率回退而终端侧的功放成本又最敏感。SC-FDMA 通过 DFT 扩展把多载波信号变回类单载波特性的发射波形LTE 上行选它就是冲着低 PAPR 去的。可一旦进入频率选择性衰落信道单载波系统又必须靠均衡把符间干扰压下去于是就有了 SC-DFE 这类带判决反馈的均衡器。标题里同时出现 IFDMA、SC-FDMA 和 SC-DFE核心并不是再画一遍 OFDM 框图而是要在 MATLAB 里把「IFDMA 的子载波交织映射 频域线性均衡 判决反馈消除残余干扰」整条链路搭起来并且给出可以直接改参数跑 BER 的仿真脚本。目标读者是通信物理层算法工程师、链路级仿真开发者和做毕业设计的学生。了解一段信号怎么在频域被扩展、怎么映射、怎么均衡比拿到一个封装好的黑盒函数更有用。下文就从发射链路开始逐步写到 SC-DFE 的实现和调参。2. IFDMA/SC-FDMA 发射链路DFT 扩展与子载波映射2.1 从单载波到多载波的桥DFT-s-OFDMSC-FDMA 在 IEEE 文档里经常写成 DFT-spread OFDMDFT-s-OFDM。发射端流程相对固定先把一段调制符号QPSK、16QAM 等做 M 点离散傅里叶变换DFT这个操作把时域符号序列变换成频域表示然后把这 M 个频域分量映射到 N 个子载波中的 M 个位置上其余位置补零接着做 N 点 IFFT 回到时域加上循环前缀CP后发射。为什么中间要插一次 DFTOFDM 的实质是把数据符号直接放到 N 个频域子载波上IFFT 后时域波形服从高斯分布峰值较大。而 SC-FDMA 先用 DFT 将数据符号变换成频域值再映射到子载波相当于对发送符号做了一次预编码最终时域信号仍然由所有 M 个数据符号共同叠加产生它的包络起伏远小于普通 OFDM。MATLAB 仿真时只需两条变换就能完全体现这个差别不需要引入射频前端。2.2 IFDMA 映射等间隔子载波是怎么产生低 PAPR 的子载波映射方式常见两种集中式LFDMA把 M 个频域样本连续放在一段子载波上交织式IFDMA把 M 个频域样本等间隔地放在 N 个子载波上间隔为 N/M。标题中的 IFDMA 即指交织式映射它的时域信号有很强的重复结构把输入的 M 个时域符号直接复制 N/M 次再乘一个小区特定的相位序列就可以得到时域发射信号。正因为时域波形近似重复信号包络的峰均比明显低于映射到连续频带的方式。LTE 上行常用的是集中式也叫 Localized但 IFDMA 在仿真中有它的独特价值它能更直观地展示 SC-FDMA 的低 PAPR 特性也便于分析子载波间隔对均衡器性能的影响。在 MATLAB 里IFDMA 映射用矩阵索引就能实现核心是找对频域位置。2.3 MATLAB 发射机实现从数据符号到发射波形下面给出一段可独立运行的 SC-FDMA 发射机脚本默认采用 IFDMA 映射。这段代码直接对应前面的流程参数放在开头方便后续更换成 LFDMA 或者改变调制方式。% SC-FDMA 发射机 (IFDMA 映射) % 参数定义 M 64; % DFT 长度即每块数据符号数 N 256; % IFFT 长度即总子载波数 modOrder 16; % 16QAM cpLen N/8; % 循环前缀长度 32 % 随机生成 M 个调制符号 dataBits randi([0 1], M*log2(modOrder), 1); dataSym qammod(dataBits, modOrder, InputType, bit); % M 点 DFT 扩展 X_freq fft(dataSym, M); % 逐块做 DFT % 映射到 N 个子载波IFDMA 等间隔放置 mapIdx 1 : N/M : N; % 1, 5, 9, ... X_all zeros(N, 1); X_all(mapIdx) X_freq; % N 点 IFFT 回到时域 s_time ifft(X_all, N) * sqrt(N/M); % 归一化保证平均功率 % 加循环前缀 s_cp [s_time(end-cpLen1 : end); s_time(:)];逻辑说明dataSym是调制后的时域符号块fft(dataSym, M)把它变换到频域得到 M 个频域分量。mapIdx采用等间隔索引间隔为N/M4这就是 IFDMA。ifft(X_all, N)之后乘上sqrt(N/M)是为了补偿因子载波补零带来的功率损失使得发射信号的平均功率与原始dataSym一致。如果改成 LFDMA只需把mapIdx换成连续索引例如1:M其他部分可以不动。参数说明M 是每块数据符号数决定了发射信号的符号速率N 是 IFFT 长度对应系统总带宽调制阶数越高单位带宽效率越高但在相同信噪比下误码率也越高。CP 长度cpLen必须大于信道时延扩展否则会产生块间干扰。2.4 如何检查代码正确性仿真的第一步不是立刻加信道而是先确认发射信号是否合理。把s_cp做一次 PSD 估计可以看到 IFDMA 信号的频谱近似于单载波信号带有重叠的频带边缘再用 PAPR 统计函数计算互补累积分布函数CCDF理论上应比同参数 OFDM 低 24 dB。如果看到包含大量零频点的稀疏频谱说明映射索引写错了。另外要注意DFT 和 IFFT 长度不一致时MATLAB 的ifft函数会默认按 IFFT 点数归一化。我们在代码里手动乘了sqrt(N/M)而不是依赖其他工具函数因为后面接信道均衡时容易把缩放因子混到信道估计里。养成显式归一化的习惯后续调试会省很多时间。3. 接收端的频域线性均衡从 FDE 到 MMSE 系数计算3.1 接收信号模型与信道矩阵的频域表示发射信号经过多径信道后接收端先去掉循环前缀再对每个 SC-FDMA 块做 N 点 FFT得到频域接收向量Y(f)。因为循环前缀足够长时域线性卷积可以看成循环卷积频域上每个子载波位置乘上信道频响H(f)再加上噪声W(f)。对应关系写出来是Y(f) H(f) * X(f) W(f)这里的X(f)是映射后的频域信号其中只有 IFDMA 所指的那些子载波上有值。均衡的输入是Y(f)在映射位置的取值即Y(mapIdx)。在 MATLAB 中信道频响H由信道的时域冲激响应做 FFT 得到。如果不知道信道就需要用导频估计这里先假设信道已估计直接给出H。3.2 频域线性均衡的两种系数ZF 与 MMSE最简单的均衡是零迫ZF把每个频点上的接收值除以信道频响。实现起来只有一句Y(mapIdx) ./ H(mapIdx)。问题在于深衰落频点上噪声被放得很大符号信噪比会明显下降。实际工程中更常用 MMSE 准则它同时考虑信道幅度和噪声方差系数为C_MMSE(f) conj(H(f)) / (|H(f)|^2 1/SNR)这个公式里的 SNR 是每符号信噪比对于调制阶数和码率不同的系统需要换算。MMSE 均衡在低信噪比时偏向抑制噪声高信噪比时接近 ZF。3.3 MATLAB 代码MMSE 频域均衡与解映射下面给出接收端从 FFT 到均衡输出的完整代码它可以直接接在第 2 章发射机代码后面。% 接收端假设经过多径信道并已知信道频响 % h 多径信道冲激响应列向量噪声功率为 sigma2 snrLinear 10^(snr_dB/10); % 由仿真参数给出 N0 1 / snrLinear; % 噪声功率谱密度归一化 % 去 CP 并 FFT r_cp awgn(s_cp, snr_dB, measured); % 发射信号过 AWGN信道此处简化 r_block r_cp(cpLen1 : end); % 去掉 CP Y_freq fft(r_block, N); % 频域接收信号 % 信道频响与子载波一一对应 H_ch fft(h, N); % N 点信道频响 % 抽取映射位置的信道与接收值 Y_used Y_freq(mapIdx); H_used H_ch(mapIdx); % MMSE 频域均衡系数 C_mmse conj(H_used) ./ (abs(H_used).^2 N0); X_est_freq C_mmse .* Y_used; % M 点 IDFT 回到时域符号 X_est ifft(X_est_freq, M) * sqrt(N/M); % 注意缩放要匹配发射端归一化逻辑说明awgn在归一化功率信号上按snr_dB添加噪声方便与后面 BER 曲线对应。H_ch是理想信道频响实际仿真中应当用 LS 或 MMSE 信道估计得到。C_mmse中N0是以信号功率归一化为 1 计算的噪声方差。X_est已经是消除信道影响的时域符号但仍然带有小幅残余干扰需要送入判决器。如果直接做 QAM 判决得到的 BER 曲线在无 ISI 信道下应与理想 AWGN 曲线重叠。3.4 线性均衡的局限噪声增强与残余 ISIMMSE 均衡在块长度 M 较大的情况下会把频率选择性信道的补偿做得比较干净但它默认了每个频点独立均衡没有利用符号之间的相关性。当信道频响存在深衰落且 SNR 较低时MMSE 仍然会放大部分频段噪声导致判决前的等效信噪比低于理论值。改善办法就是引入判决反馈把已判决符号的干扰从接收信号中减掉。下表给出 ZF 与 MMSE 的对比方便决定何时升级到 SC-DFE。均衡方式是否放大噪声实现复杂度适用场景ZF 频域均衡严重最低信道平坦、高 SNR 或教学演示MMSE 频域均衡中等低一般链路仿真作为基线MMSEDFESC-DFE较弱中高频率选择性较强、要求较低误码率从表中能看出线性均衡在信道深凹陷处损失了过多信噪比。SC-DFE 的核心思路是用前馈部分做线性均衡再用反馈部分去抵消残余符号间干扰理论上能接近匹配滤波界的性能。4. SC-DFE 均衡器是如何把判决反馈搬到频域的MATLAB 实现4.1 判决反馈均衡的原理回顾传统时域 DFE 包含前馈滤波器和反馈滤波器。前馈滤波器对接收信号做线性滤波反馈滤波器则从判决符号中构造干扰估计然后从前馈输出中减去。因为反馈的是无噪的判决符号它可以有效消除已判决符号对当前符号的干扰而不像线性均衡那样放大噪声。问题是在多载波/频域系统中符号分布在不同频率上单纯时域反馈会带来较高复杂度。SC-FDMA 的均衡可以在频域做前馈在时域做反馈。接收端先对映射位置的频域信号做加权合并前馈然后 IFFT 回时域反馈部分则利用时域判决结果做循环卷积预测再从信号中减去。由于 SC-FDMA 每个块只有 M 个符号反馈滤波器长度可以控制在 M 量级比纯时域均衡容易迭代。4.2 频域 SC-DFE前馈系数与反馈系数怎么算一个实用的实现方式是推导 MMSE-DFE 的前馈矩阵使得最后真正放到 MATLAB 里的是一组频域系数和一组时域反馈系数。常见的做法是把信道频响、噪声方差和判决符号的协方差代入 HMMSE 推导得到前馈滤波器的频域表达式反馈滤波器则通过在时域上对原始信道卷积与前馈响应做残差估计得到。为了不引入矩阵求逆的复杂推导下面给出一种更容易理解和调试的迭代法先用 MMSE 频域均衡得到初始符号估计做硬判决然后把判决符号重新编码成 SC-FDMA 发射波形经由已知信道后与接收信号比较得到残余干扰再将残余干扰反馈回频域修正估计值。这样每一轮迭代都会提升判决正确率等效于 DFE 的反馈过程。4.3 MATLAB 代码迭代 SC-DFE 实现这段代码可以把第 3 章的 MMSE 均衡结果作为初始迭代点然后执行 23 次反馈修正。% SC-DFE 迭代均衡 % 输入Y_freq 频域接收信号H_ch 信道频响mapIdx 映射索引 % 输入M, N, cpLen, modOrder, snrLinear N0 1 / snrLinear; % 初始 MMSE 均衡 Y_used Y_freq(mapIdx); H_used H_ch(mapIdx); C_mmse conj(H_used) ./ (abs(H_used).^2 N0); X_est_freq C_mmse .* Y_used; X_est ifft(X_est_freq, M) * sqrt(N/M); % 迭代反馈 numIter 3; for iter 1:numIter % 硬判决星座点归一化到与发射相同刻度 x_det qamdemod(X_est, modOrder, OutputType, bit); x_slice qammod(x_det, modOrder, InputType, bit); % 重建经过信道的接收信号无噪声 x_tx_freq fft(x_slice, M); X_tx_all zeros(N, 1); X_tx_all(mapIdx) x_tx_freq; s_rebuild ifft(X_tx_all, N) * sqrt(N/M); r_rebuild_freq fft(s_rebuild, N) .* H_ch; % 计算残余干扰含 MMSE 均衡器影响 Y_used_rebuild r_rebuild_freq(mapIdx); residual_freq Y_used - C_mmse .* Y_used_rebuild; % 将残余干扰补偿回去 X_est_freq C_mmse .* Y_used residual_freq; X_est ifft(X_est_freq, M) * sqrt(N/M); end逻辑说明第一次进入迭代时X_est与 MMSE 结果一致。之后每一轮把判决符号重新做发射机操作得到对应的接收频域信号Y_used_rebuild再用原始接收信号减去重建信号乘以均衡系数后的部分得到残余项。把残余项加回到均衡输出相当于先用反馈消除已判符号的干扰。这个迭代方法虽然没有严格的矩阵 DFE 推导但能复现 DFE 的“反馈纠正”行为重要的是不会引入数值上的矩阵病态问题。需要说明的是当判决错误较多时反馈也可能把错误传播下去因此迭代次数不宜超过 3。参数说明numIter对应 DFE 的反馈次数并不是越多越好。在低信噪比区域错误的判决会污染反馈导致性能反而低于 MMSE。经验上 2 次迭代已经能获得大部分增益仿真时可以通过berSNR曲线对比不同numIter的表现。qammod与qamdemod使用相同的InputType能够保证判决后的复数值与发射端映射一致这是误差平稳的前提。4.4 反馈结构与抽头长度对仿真结果的影响上面的迭代方法里反馈是通过完整的发射机重建完成的相当于反馈滤波器覆盖了整个数据块。如果信道频响变化较慢也可以只构造前几个符号的反馈但那样需要显式设计时域反馈抽头复杂度会上升。实际工程中的 SC-DFE 常使用 Cholesky 分解来设计前后的线性变换代码里会用dlyap或chol求解。对普通链路级仿真我一般先把迭代次数固定为 2再分别看线性均衡和 DFE 的 BER如果两者差异小于 0.5 dB说明信道还不够恶劣或者反馈长度不足。下表列出常用 SC-DFE 参数范围在 MATLAB 仿真中可直接作为初值参数取值范围说明迭代次数13超过 3 次错误传播风险增大DFT 长度 M641024与调制阶数、带宽相关子载波总数 NM 的整数倍倍数越大频谱效率越低CP 长度N/16N/4需大于信道时延扩展调制方式QPSK/16QAM/64QAM高阶调制对残差更敏感5. 完整仿真代码与 BER/PAPR 对照实验5.1 把发射机、信道、接收机合并成一个脚本实际做仿真时不要把所有代码堆到一个文件里建议把发射机、信道、线性均衡、SC-DFE 分别写成函数再用一个主脚本循环 SNR。这样便于更换 QAM 调制阶数或信道模型。下面给出一个主循环的核心结构假设前面的函数已经放到同一目录。% 主仿真脚本SC-FDMA MMSE vs SC-DFE snrVec 0:2:16; berMmse zeros(size(snrVec)); berDfe zeros(size(snrVec)); for k 1:length(snrVec) % 生成一个块的数据仿真多次取平均 errMmse 0; errDfe 0; totalBits 0; for blk 1:100 % 每信噪比跑 100 块 % 发射机 [txBlock, dataBits] scfdma_tx(M, N, modOrder, cpLen); % 信道此处使用固定 3 径信道 h [1 0.5 0.2]; % 多径抽头系数 noiseVar 1 / 10^(snrVec(k)/10); rBlock add_channel(txBlock, h, cpLen, noiseVar); % 接收均衡 yMmse scfdma_mmse_rx(rBlock, h, cpLen, M, N, noiseVar); yDfe scfdma_dfe_rx(rBlock, h, cpLen, M, N, modOrder, noiseVar, 2); % 判决并统计误码 [~, bHatMmse] qamdemod(yMmse, modOrder, OutputType, bit); [~, bHatDfe] qamdemod(yDfe, modOrder, OutputType, bit); errMmse errMmse sum(bHatMmse ~ dataBits); errDfe errDfe sum(bHatDfe ~ dataBits); totalBits totalBits length(dataBits); end berMmse(k) errMmse / totalBits; berDfe(k) errDfe / totalBits; end semilogy(snrVec, berMmse, o-, snrVec, berDfe, s-); legend(MMSE-FDE, SC-DFE (2 iter));说明scfdma_tx、scfdma_mmse_rx、scfdma_dfe_rx分别对应前文代码封装的函数。主循环里噪声功率noiseVar是每个符号的噪声方差假设信号归一化平均功率为 1。add_channel函数内部完成线性卷积加噪声并保证每块加了 CP具体实现可以先把发射块补零做线性卷积再切掉多余点。这样每个 SNR 点循环 100 块总误码数至少几百比特时 BER 才可信信噪比高时可能需要更多块否则曲线底部波动很大。5.2 仿真参数与典型结果解读建议的仿真参数如下参数设置说明M128DFT 长度N512子载波数IFDMA 间隔为 4调制16QAM每符号 4 bit信道3 径等功率时延模拟频率选择性SNR 范围016 dB观察 10^-2~10^-4 BERSC-DFE 迭代2反馈修正两次在 3 径信道下MMSE 均衡在 16QAM 中会有明显的错误平层因为某些频点接近零陷线性均衡无法完全消除噪声增强。SC-DFE 曲线通常会比 MMSE 好 12 dB 左右尤其在中高信噪比区域错误平层会被压低。如果曲线在 14 dB 以上出现拐弯多半是反馈迭代中判决错误导致的传播需要减少迭代或者改善初始线性均衡性能。5.3 PAPR 对照实验验证 IFDMA 的标签效果除了 BER还要做一个 PAPR 的 CCDF 对照。操作是分别用 IFDMA 和 OFDM 生成大量信号块统计每块时域波形的峰值功率与平均功率之比画出 CCDF 曲线。MATLAB 中可以计算s_cp的PAPR_vec再与相同参数下 OFDM 信号对比。IFDMA 在 CCDF0.1 处通常低 23 dB。这个实验不仅验证了前文理论也让仿真代码有更直观的输出。5.4 把 SC-DFE 扩展到导频辅助信道估计上面代码假设理想信道已知。真实仿真要加入导频在每个资源块中插入若干已知符号接收端通过 LS 估计得到H_used。SC-DFE 对信道估计误差比较敏感尤其是反馈重建时用了错误的频偏会导致干扰抵消不完全。建议先做理想信道估计跑通链路后再替换为 LS 或 MMSE 估计并观察性能退化。6. 几个容易踩的坑同步、信道估计与均衡器抽头设置6.1 时域同步不准时SC-DFE 反馈符号全是错的SC-FDMA 接收端去 CP 的位置如果偏移了几个采样点频域信号会引入额外相位旋转而且这个旋转与子载波索引成正比。IFDMA 因为子载波间隔是均匀稀疏的相位旋转在映射位置可能变化更快让 MMSE 系数按H_used计算时不准确。做法是先用导频相关做粗同步再在频域用单抽头相位估计做补偿。同步偏差超过 CP 的 1/4 时SC-DFE 的反馈不仅没增益还会显著恶化。6.2 信道估计误差对 MMSE 系数的影响MMSE 公式里的abs(H_used).^2 N0包含噪声方差N0如果N0估计偏小加权系数偏向放大噪声估计偏大则偏向保留干扰。更隐蔽的问题是H_used本身有估计误差那么C_mmse会产生偏差。SC-DFE 里反馈重建又用同一个信道频响等于把误差放大了两倍。建议在仿真脚本里给信道估计加上一个复高斯误差例如H_est H_true 0.01*randn(size(H_true))观察 BER 是否迅速抬高。6.3 反馈迭代次数不是越大越好前面提到numIter超过 3 之后错误传播会抵消掉理论增益。有一种抗争方式是只在判决可靠性高的符号上使用反馈即设置一个阈值当 MMSE 输出距离星座点较远时不参与重建。简单的做法是把迭代次数降到 1对比所有符号都反馈的版本能发现中低 SNR 下阈值判决更稳。如果计算资源允许可以在每轮迭代后统计与上次判决不同的符号数发现大于 5% 就提前终止防止无谓的错误扩散。6.4 用残差信号验证均衡器是否收敛不要只盯着 BER 曲线。一个快速验证手段是计算均衡器输出与理想符号之间的均方误差公式为MSE mean(abs(X_est - x_slice).^2)。在线性均衡和 SC-DFE 迭代过程中打印每一轮的 MSE 数值正确实现的反馈会把 MSE 逐步压低。如果第二轮 MSE 高于第一轮说明反馈滤波器符号符号方向做反了需要将残余项减去而非加上。这个检查在 DEBUG 阶段比 BER 更有用因为 BER 需要积累大量统计MSE 则对一个数据块就能看出趋势。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。