关注我,追更更多通信仿真代码!
文章目录
摘要
本文基于 MATLAB 通信工具箱搭建了完整的卷积编码与维特比译码仿真链路,系统对比了 4‑QAM 与 16‑QAM 调制下硬判决、软判决译码及不同回溯深度的误码率性能。仿真结果表明:软判决相比硬判决可获得约 2~3 dB 编码增益;回溯深度取约束长度的 4~5 倍即可接近最优性能;编码系统在低信噪比下性能略逊于未编码系统,但随着信噪比升高优势逐渐显现。上述结论为实际系统中卷积码参数选取提供了参考依据。。
一、引言
- 在数字通信中,信道噪声与干扰不可避免导致传输差错。信道编码通过添加冗余信息使接收端具备纠错能力,从而有效降低误码率。卷积码是一种具有"记忆"特性的编码方式,其输出不仅取决于当前输入,还与历史输入相关。维特比算法(Viterbi Algorithm)是卷积码的最大似然译码算法,通过在网格图上搜索最短路径实现最优译码。
- 根据分支度量采用的距离类型,维特比译码分为硬判决(使用汉明距离)与软判决(使用欧氏距离)。软判决保留接收信号的幅度信息,能显著提升性能,但实现复杂度较高。本文利用 MATLAB 通信工具箱的编码、译码和调制解调功能,搭建了完整的仿真系统,通过蒙特卡洛仿真评估不同配置下的误码率性能,并分析各参数的影响。
二、系统原理
2.1 卷积码编码

2.2 维特比译码算法


2.3 QAM 调制与软解调


三、仿真系统设计
3.1 系统架构

3.2 仿真图分析

可以看到:
- 软判决的普适优越性:无论在哪种调制下,软判决均优于硬判决,因其保留了可靠性度量,使译码路径选择更准确。
- 编码后对系统性能提升的有效性:可以看出在信噪比低的时候,未经编码的系统信噪比 反而优于 经过编码的系统。这是因为卷积码具有记忆性,一个译码错误会导致该时刻及其后续若干时刻的连续错误,在低SNR环境下,"犯错随机化"的未编码系统反而优于"固执回溯"的编码系统。当snr变大后,可以看出,经过码的系统的误码率性能明显优于未经过编码的系统,这说明了编码的性能优势。
- 增加回溯深度可以提升ber性能,但对于 K=7 的卷积码,深度取 32(约 4.6已足够,继续增加仅增加延迟和存储,性能提升有限。
- 本文采用系统函数进行的vitb译码,自己实现译码算法的代码,可见往期的文章【第【97】期--卷积码编码与Viterbi译码原理及仿真实现 --MATLAB完整代码】
3.3 部分代码
c
function results = ECC_single(config)
% 打印仿真配置信息(开始)
fprintf('========== ECC_single 仿真启动 ==========\n');
fprintf('调制阶数 M = %d\n', config.M);
fprintf('回溯深度 = %d\n', config.tracebackDepth);
fprintf('每帧符号数 = %d\n', config.numSymPerFrame);
fprintf('帧数 = %d\n', config.numFrame);
fprintf('SNR 点数 = %d\n', length(config.snrdBvec));
fprintf('编码使能 = %d\n', config.codingEnabled);
fprintf('-----------------------------------------\n');
% Extract parameters for readability
M = config.M;
k = log2(M); % 每个符号对应的比特数
trellis = config.trellis;
tracebackDepth = config.tracebackDepth;
snrdBvec = config.snrdBvec;
numFrame = config.numFrame;
numSymPerFrame = config.numSymPerFrame;
codingEnabled = config.codingEnabled;
berHard = zeros(size(snrdBvec));
berSoft = zeros(size(snrdBvec));
parfor n = 1:length(snrdBvec)
snrdB = snrdBvec(n);
noiseVar = 10^(-snrdB/10); % 噪声方差(单边带)
% 打印当前 SNR 点开始信息(parfor 内输出顺序可能不固定)
fprintf('SNR = %.2f dB:开始处理...\n', snrdB);
[numErrsSoft, numErrsHard, numBits] = deal(0);
for nn = 1:numFrame
% 1. 生成随机数据比特
dataIn = randi([0 1], numSymPerFrame * k, 1);
% 2. 卷积编码(若使能)
if codingEnabled
dataEnc = convenc(dataIn, trellis);
else
dataEnc = dataIn;
end
% 3. 调制(QAM,Gray映射,比特输入,单位平均功率)
txSig = qammod(dataEnc, M, 'gray', ...
'InputType', 'bit', 'UnitAveragePower', true);
% 4. 通过 AWGN 信道
rxSig = awgn(txSig, snrdB, 'measured');
% 5. 解调 与 维特比译码
if codingEnabled
% --- 硬判决分支 ---
% 解调为比特(硬判决)
rxDataHard = qamdemod(rxSig, M, 'gray', ...
'OutputType', 'bit', 'UnitAveragePower', true);
% 维特比译码(硬判决)
decodedHard = vitdec(rxDataHard, trellis, tracebackDepth, 'cont', 'hard');
% --- 软判决分支 ---
% 解调为近似 LLR(软信息),需提供噪声方差
rxDataSoft = qamdemod(rxSig, M, 'gray', ...
'OutputType', 'approxllr', 'UnitAveragePower', true, ...
'NoiseVariance', noiseVar);
% 维特比译码(软判决,未量化)
decodedSoft = vitdec(rxDataSoft, trellis, tracebackDepth, 'cont', 'unquant');
% 计算误比特数(需扣除维特比延迟引起的尾部比特)
errsHard = biterr(dataIn(1:end-tracebackDepth), decodedHard(tracebackDepth+1:end));
errsSoft = biterr(dataIn(1:end-tracebackDepth), decodedSoft(tracebackDepth+1:end));
else
% 无编码分支:直接解调为比特
rxData = qamdemod(rxSig, M, 'gray', ...
'OutputType', 'bit', 'UnitAveragePower', true);
errsHard = biterr(dataIn, rxData);
errsSoft = errsHard; % 无编码时软硬判决相同
end
% 累加错误数
numErrsHard = numErrsHard + errsHard;
numErrsSoft = numErrsSoft + errsSoft;
% 累计有效比特数(硬/软判决一致,因为有编码时都要扣除回溯深度)
if codingEnabled
bitsInFrame = length(dataIn) - tracebackDepth;
else
bitsInFrame = length(dataIn);
end
numBits = numBits + bitsInFrame;
end
% 计算该 SNR 点的 BER
berHard(n) = numErrsHard / numBits;
berSoft(n) = numErrsSoft / numBits;
% 打印该 SNR 点完成信息
fprintf('SNR = %.2f dB 完成:硬判决 BER = %.2e,软判决 BER = %.2e\n', ...
snrdB, berHard(n), berSoft(n));
end
% 填充结果结构体
results.berHard = berHard;
results.berSoft = berSoft;
results.snrdBvec = snrdBvec;
% 仿真结束打印
fprintf('========== ECC_single 仿真结束 ==========\n');
end
四 总结
本文基于 MATLAB 通信工具箱搭建了完整的卷积编码与维特比译码仿真链路,系统对比了 4‑QAM 与 16‑QAM 调制下硬判决、软判决译码及不同回溯深度的误码率性能。仿真结果表明:软判决相比硬判决可获得约 2~3 dB 编码增益;回溯深度取约束长度的 4~5 倍即可接近最优性能;编码系统在低信噪比下性能略逊于未编码系统,但随着信噪比升高优势逐渐显现。上述结论为实际系统中卷积码参数选取提供了参考依据。