尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Simulink AWGN信道仿真全解析:从模型搭建到BER曲线

Simulink AWGN信道仿真全解析:从模型搭建到BER曲线 简介面向通信工程与信号处理学习者的小型示例包演示如何在MATLAB/Simulink环境中搭建AWGN加性高斯白噪声信道仿真模型用于分析不同信噪比下信号的失真程度与误码率变化。压缩包共3个文件核心为Simulink模型文件.mdl、负责参数设置与仿真实例的MATLAB脚本.m以及说明文档.txt整体大小仅4KB属于轻量级入门示例。从脚本和模型可以看出内容涵盖信号源、AWGN信道、接收滤波及误码率统计等关键环节适合对照学习AWGN信道的基本仿真流程、SNR参数配置和结果分析方法。目前已有274人学习下载对刚接触Simulink通信仿真的读者具有较好的参考价值。1. 从 AWGN.rar 看起Simulink 信道仿真到底在仿什么如果你手头有一个名为 AWGN.rar 的压缩包解压后大概率是几层嵌套的文件夹里面躺着awgn_simu.mdl或.slx模型再加几个魔改过的初始化脚本。这种包在通信课程设计和工程预研里非常常见但真正能一次跑通的人不多。原因有两层一是 Simulink 里AWGN Channel模块的参数名和 MATLAB 的awgn()函数不完全一致很多人查了半天资料还对不上二是仿真结果出来后BER 曲线和理论值对不上不知道是信噪比换算错了还是信号延迟没对齐。AWGNAdditive White Gaussian Noise加性高斯白噪声是通信仿真里最基础也最绕不开的信道模型。所谓“白”指功率谱密度平坦“高斯”指幅度分布服从正态分布“加性”就是直接叠加在信号上。它解决的核心问题很简单给定一个调制信号在特定信噪比下误码率到底是多少。这个标题背后的实际需求往往是用 Simulink 搭一个可视化链路再用 MATLAB 脚本批量扫点画 BER 曲线。适合的读者是刚接触通信仿真的研究生、做物理层预研的工程师以及想验证自己编解码算法的人。接下来我按“搭模型、调参数、复现理论、排查问题”的顺序把这条链路完整走一遍。2. Simulink 里搭 AWGN 仿真链路从模块布局到符号参数2.1 最小模型结构发端、信道、收端三件套在 Simulink 里做 AWGN 信道仿真最常用的模型拓扑是伯努利二进制源 → BPSK 调制 → AWGN 信道 → 判决解调 → 误码率统计。模型用不着加均衡器或者同步器因为 AWGN 既不引入频率偏移也不引入符号间干扰链路是内存无记忆的。打开 Simulink 库浏览器依次拖入以下模块Bernoulli Binary GeneratorCommunications Toolbox生成 0/1 序列默认概率 0.5输出帧格式。BPSK Modulator Baseband把 0/1 映射为 1/-1。AWGN Channel叠加高斯噪声注意它属于 Communications Toolbox不在基本 Simulink 库。BPSK Demodulator Baseband硬判决输出 0/1。Error Rate Calculation统计误码数、误码率和总比较符号数。连接方式很简单源到调制器调制器输出进 AWGN 信道信道输出同时进入解调器和误码率模块的信号端。关键点是Error Rate Calculation模块有两个输入Tx和Rx。Tx接延迟对齐后的发送端比特不是调制前的也不是调制后的Rx接解调输出。很多人直接接调制器输出和解调器输出那统计的是星座点符号错误率虽然比例上有对应关系但和通常说的 BER 不是一回事。2.2 参数设置的四个必调项用鼠标双击 AWGN Channel 模块会看到 “Parameters” 页签。最容易被坑的是 “Mode” 下拉框默认是Signal to noise ratio (Eb/No)而不是你脑子里默认的SNR (dB)。两个模式都要求填“每个符号的比特数”或“符号周期”如果忘了填模块会按默认值抛错或悄悄改变噪声功率。下面表格给出常用模式与填法Mode需要填的参数输入含义典型场景Signal to noise ratio (Eb/No)Eb/N0 (dB)、Number of bits per symbol每比特能量与噪声功率谱密度之比BPSK 理论 BER 对比Signal to noise ratio (Es/No)Es/N0 (dB)、Input signal power每符号能量与噪声谱密度之比多进制调制常用Signal to noise ratio (SNR)SNR (dB)、Signal power、Symbol period信号功率与噪声功率之比直接对接示波器读数以 BPSK 为例Number of bits per symbol填 1Eb/N0 和 SNR 是同一个值。但如果你用的是 16QAM这一项填 4要不要做log2(4)的换算就取决于你的习惯。我一般直接在 MATLAB 脚本里计算好 Es/N0 再填入因为 Simulink 模型参数化之后批量扫点更方便。另外两个必调项是Input signal power和Symbol period。Input signal power默认是1瓦这要求前置调制器输出的信号平均功率为 1。BPSK 的 1/-1 星座点平均功率正好是 1所以通常不用改。但如果前面接了成形滤波器或者放大模块信号功率会变填错 1 会造成实际信噪比比设置值低 3dB 这种隐蔽错误。2.3 用脚本批量扫描信噪比的正确姿势手动在模块界面改 Eb/N0 再点运行只适合验证单点。要画 BER 曲线得把模型参数化。我常用的做法是在模型里把 AWGN 模块的 Eb/N0 框填成EbN0_dB这是一个由工作区注入的变量然后在 MATLAB 脚本里用sim()函数循环调用。%% 批量扫描 Eb/N0 并收集 BER EbN0_list 0:2:10; % 扫 0 到 10 dB步进 2 ber_results zeros(size(EbN0_list)); % 预分配 for idx 1:length(EbN0_list) EbN0_dB EbN0_list(idx); % 写入工作区变量 % 设置仿真停止时间为 1e5 个符号BPSK 即 1e5 比特 simOut sim(awgn_simu, StopTime, 1e5); % 模型里的 Error Rate Calculation 模块可以用 simout 输出 ber_results(idx) simOut.ber(1); % ber 信号是 [误码率, 误码数, 比较数] fprintf(Eb/N0 %.2f dB, BER %.5f\n, EbN0_dB, ber_results(idx)); end % 画图并与理论值对比 semilogy(EbN0_list, ber_results, bo-); grid on; xlabel(Eb/N0 (dB)); ylabel(BER);这段脚本里需要注意simOut.ber(1)的取法是靠 Error Rate Calculation 模块的Output data勾选为Port并把输出端口接到simout模块上。如果你只是用sim()而没配置输出结果是空的。另一个常用参数是StopTime这里写成字符串1e5表示仿真 10 万个符号。BPSK 下误码率在1e-4量级时至少要仿真 10^6 个符号才有统计意义否则 BER 曲线会是毛刺状。所以实际跑曲线时高信噪比段的 StopTime 要拉长低信噪比段可以短一点。还有一个细节sim()的返回对象在 R2016a 之后是Simulink.SimulationOutput要取信号时用simOut.ber而不是simOut.get(ber)。如果你用的是旧版本写成后者也行但新版本里两种写法都兼容。脚本里用fprintf打印进度是为了在批量跑长仿真时能随时看到跑到哪里总比干等强。3. 用 MATLAB 脚本还原 AWGN 模型等价结构与参数换算3.1awgn()函数和手动加噪的区别Simulink 里的 AWGN 模块本质上就是对调制信号加上功率受控的高斯噪声。在 MATLAB 纯代码里最省事的是直接调用awgn()函数%% BPSK 仿真的 MATLAB 代码版 M 2; % BPSK EbN0_dB 6; % 目标 Eb/N0 numBits 1e6; % 仿真比特数 data randi([0 1], numBits, 1); % 随机比特 sym 2*data - 1; % BPSK 映射0--1, 1-1 % 调用 awgn 函数注意信号是实数measured 会按实测功率施加噪声 rx awgn(sym, EbN0_dB, measured); % 硬判决 rxBit rx 0; % 统计误码 err sum(data ~ rxBit); ber err / numBits; fprintf(Eb/N0 %.2f dB, BER %.6f\n, EbN0_dB, ber);awgn(sym, EbN0_dB, measured)的含义是先把输入信号sym的实测功率作为信号功率然后按照EbN0_dB计算出加性高斯白噪声的方差并叠加。第三参数写measured时信号功率不需要自己算如果省略它函数默认信号功率为 0 dBW。这里 BPSK 信号幅度是 ±1平均功率正好为 1两种写法结果一样。但当你换成 8PSK 或 16QAM 时星座点功率不一定为 1measured能自动规避功率不匹配问题。注意awgn()里的第二个参数是 Eb/N0 还是 SNR取决于你对sym的定义。对于 BPSK一个符号携带 1 比特Eb/N0 就是 SNR。如果改成qammod生成 16QAM 符号awgn()的第二个参数仍是 SNR即 Es/N0要算 Eb/N0 需要再减去10*log10(4)。这个细节和 Simulink 模块里的 Mode 选择是同一个坑两头要对应起来。3.2 手动生成高斯噪声并验证功率有时候你需要自己加噪比如想用不同分布或想控制噪声实现层级的复杂度。手动加噪的核心公式是rx sym sqrt(No/2) * randn(size(sym))其中No是噪声功率谱密度randn生成方差为 1 的实高斯白噪声。为什么是sqrt(No/2)因为实信号的单边功率谱密度为No/2噪声总功率等于No * fs的一半在基带等效模型中你只需要把噪声方差设为No/2。%% 手动加噪精确控制噪声方差 EbN0_dB 6; EbN0 10^(EbN0_dB/10); % 线性值 Eb 1; % BPSK 每比特能量为 1 No Eb / EbN0; % 噪声单边功率谱密度 noiseVar No/2; % 实噪声方差 noise sqrt(noiseVar) * randn(numBits, 1); rx_manual sym noise; % 对比 awgn 函数的结果 rx_awgn awgn(sym, EbN0_dB, measured); fprintf(手动加噪与实际误码率: %.6f\n, sum((rx_manual0)~data)/numBits); fprintf(awgn 函数误码率: %.6f\n, sum((rx_awgn0)~data)/numBits);这段代码里的noiseVar No/2是最容易让人犹豫的行。因为有的教材写sqrt(No/2)有的写sqrt(No)区别在于信号是复数还是实数模型。BPSK 的基带信号是实数噪声分布是实高斯方差为No/2。QPSK 则是复信号同相和正交两路各加方差为No/2的实噪声叠加成复噪声方差为No此时写sqrt(No/2)*(randn1j*randn)。判断原则很简单看你的调制信号是实数列还是复数列复数列就必须拆两路。3.3 Simulink 与脚本统一定标模型里填的功率单位Simulink 的 AWGN Channel 模块内部处理噪声时同样遵循上述公式。它要求填入Input signal power的作用是不用实测信号功率直接按设定值计算。如果你把模块里的 Eb/N0 设为 6dB并把Input signal power设为 1那模块内部就执行一遍与我们手动代码完全一致的加噪操作。为了验证我习惯在模型里加一个To Workspace模块记录信道输出然后回到 MATLAB 里和awgn()的输出做互相投影对比。一个常见的工程做法是先用 MATLAB 纯代码调通链路再用 Simulink 搭模型做可视化或生成代码。两个环境的参数是同一个数学模型只是入口不同。下面的表格概括了三种做法的功率语义实现方式噪声功率计算公式需要提供的参数awgn(x, snr, measured)No x_power / 10^(snr/10)信噪比 dB 值手动randnnoiseVar No/2其中No Eb/EbN0Eb 值、Eb/N0 线性值Simulink AWGN 模块 (Eb/N0)同上但取Eb1默认Eb/N0 dB 值、每符号比特数这条对应关系是排查误差的钥匙。如果 Simulink 仿出来的 BER 和 MATLAB 代码差很大先检查是不是每符号比特数填错了。16QAM 的模块填错这个数字噪声功率会差 12 倍BER 曲线直接错几个数量级。4. 读懂仿真结果BER 曲线、理论下限和信噪比换算4.1 理论 BER 曲线怎么画仿真的最终目的通常是将实测 BER 与理论 BER 对比。BPSK 在 AWGN 下的理论误码率是0.5 * erfc(sqrt(EbN0_lin))此公式只适用于相干解调 BPSK。但在工程上我们更常用berawgn()函数它能直接给出多种调制的理论值省得每次查公式。%% 绘制理论 BER 与仿真 BER EbN0_dB 0:0.5:10; EbN0_lin 10.^(EbN0_dB/10); theory_ber 0.5 * erfc(sqrt(EbN0_lin)); % BPSK 理论值 % 把第二节扫到的仿真结果画在一起 semilogy(EbN0_dB, theory_ber, r-, LineWidth, 1.5); hold on; semilogy(EbN0_list, ber_results, bo-); legend(理论 BPSK, Simulink 仿真); xlabel(Eb/N0 (dB)); ylabel(BER); title(AWGN 信道 BPSK 误码率曲线); grid on;这段代码里最关键的是把纵轴设为对数刻度否则 BER 从10^-1到10^-5的动态范围会被“压缩”到肉眼看不见的下方。erfc是余误差函数对 BPSK 来说这是精确的数学表达不是近似。如果你画出来的仿真点整体比理论值高 0.5dB 左右先怀疑噪声功率是否多给了如果低信噪比段对齐高信噪比段却突然掉不下去那是仿真比特数不够误码率在地板附近波动。4.2 从 SNR 换算 Eb/N0 的四个参数工程里经常碰到的问题是手头只有接收机输出信噪比 SNR想和 BER 曲线对齐。换算公式是Eb/N0 (dB) SNR (dB) 10*log10(Ts) - 10*log10(Tb)或者写成Eb/N0 Es/N0 - 10*log10(log2(M))。这里M是调制进制数。对于 BPSKlog2(2)1所以 SNR 和 Eb/N0 相等。但对于 QPSKM4Eb/N0 比 Es/N0 低 3dB。实际中还有一个容易被忽略的量当信号经过升余弦滚降滤波后占用的带宽变成fs*(1alpha)此时噪声功率与采样率、滤波器带宽有关。如果你用 Simulink 的 Spectrum 模块看到噪声底抬高不要急着调模块参数先算一下等效噪声带宽。我在做 DVB-S2 仿真时习惯在脚本里先定义Es mean(abs(sym).^2)再显式计算 Es/N0最后换算 Eb/N0这样能避免把成形滤波器的 3dB 损耗算错。4.3 仿真结果异常的排查清单遇到仿真点和理论值对不上按下面的顺序查通常能解决 90% 的问题误码率比较器的Tx接入点是否经过延迟对齐。Simulink 里Error Rate Calculation的Receive delay参数默认是 0但信道模块、滤波器都会引入延迟最常见的错误是信噪比低时误码率正常信噪比高时误码率降到1e-2后不再降这就是比特序没对齐。噪声模式是否选错模块里选了SNR但要填 Eb/N0或者选了Eb/No但每符号比特数写错导致噪声功率增加10*log10(M)倍。信号功率是否等于 1Input signal power填 1但实际信号经过插值或增益后平均功率变成 0.8实际信噪比低于设定值 0.97dB。仿真数据长度是否足够BER 在1e-5时至少要跑 10^6 个符号才能看到 10 个错误否则统计抖动很大。常用经验是“目标误码率的倒数乘 20”即想看到1e-5跑2e6个比特。关于延迟对齐我提供一个小技巧把Error Rate Calculation的Receive delay设置为 1然后观察误码率是否显著变化。如果变化了说明调制器或解调器内部有固有延迟。BPSK 调制解调模块通常没有延迟但如果你加了平方根升余弦滤波器延迟就是滤波器阶数的一半。更好的办法是先用alignsignals函数在 MATLAB 里检查两路比特信号找出延迟量再回填到 Simulink 模块里。5. 把仿真当工程用三个提高 AWGN 模型可信度的技巧5.1 用 Simulink 模型参数批量跑对应关系而不是手动改在完成模型验证后我建议把整个模型封装成子系统然后用set_param直接修改模块里的参数。例如要把 AWGN 模块的 Eb/N0 改成工作区变量可以在初始化回调里写assignin(base,EbN0_dB,2)。这样你从 MATLAB 脚本每次修改base工作区的值再调用sim()就不需要每次打开模型面板。技巧是给 AWGN 模块的掩码参数分配一个变量名比如EbN0_dB然后用下面这段脚本循环调用%% 批量跑 BER 的另一种方式直接改模块参数 for nn 1:length(EbN0_list) set_param(awgn_simu/AWGN Channel, EbNo, EbN0_dB); % 将参数变量化 EbN0_dB EbN0_list(nn); % 重新赋值 simOut sim(awgn_simu); ber_results(nn) simOut.ber(1); endset_param里的第三参数EbN0_dB其实是指模块内部的字符串运行到这条命令时 Simulink 会把这个字符串当作表达式解析于是base工作区中的EbN0_dB就被读入。这种方式的优点是扫点过程中不用反复打开模型也能配合parfor并行计算提速。缺点是如果你把EbNo写错成SNR参数名不匹配会直接报错所以需要先跑一次单点确认路径。5.2 开启外部模式并在运行时观察中间量当你想看调制器输出星座点在噪声叠加前后的变化或者想看信道输出信号的频谱时打开 Simulink 的 “External” 仿真模式需要目标硬件或仿真器支持。在纯软件仿真中更实用的做法是把几个关键信号用To Workspace模块输出然后在 MATLAB 里用plot或scatter画星座图。我在调试 AWGN 模型时会先画叠加前的星座图确认调制正确再画叠加后的星座图看噪声是圆形还是菱形。圆形说明同相和正交噪声方差一致菱形说明某个支路噪声功率不对。5.3 从模型到 C 代码生成后的数值一致性检查如果 AWGN 模型最终要部署到 FPGA 或嵌入式处理器你多半需要从 Simulink 模型生成 C 代码。生成时有个隐藏坑AWGN 模块内部用了随机数生成器默认是v4种子算法每次仿真都会得到不同的噪声序列。为保证可重复性你必须在模型配置参数里把随机数种子固定或者在生成代码时用可配置的种子参数。我通常会在模型的InitFcn里调用rng(42)来固定整个仿真的全局随机数流。生成代码后用同样的输入文件跑一次对比软件仿真和硬件在环的 BER 曲线两者应在统计误差范围内一致。如果出现系统偏差多半是硬件环境里噪声生成算法被优化过了头比如把sqrt(No/2)简化成了sqrt(No)这时候用前面提到的手动加噪公式回推就能定位。以上就是围绕这个标题能展开的全部核心内容。从 Simulink 模型搭建到 MATLAB 代码复现再到参数换算和排错关键是保持对“信号功率、噪声方差、Eb/N0”三者换算的清醒。把这个关系刻在脑子里任何 AWGN 相关仿真都不会跑偏。本文还有配套的精品资源点击获取
返回列表