第【122】期--卷积编码与维特比译码在 M‑QAM 系统中的性能仿真研究--matlab完整代码

关注我,追更更多通信仿真代码!

文章目录

    • 摘要
    • 一、引言
    • 二、系统原理
      • [2.1 卷积码编码](#2.1 卷积码编码)
      • [2.2 维特比译码算法](#2.2 维特比译码算法)
      • [2.3 QAM 调制与软解调](#2.3 QAM 调制与软解调)
    • 三、仿真系统设计
      • [3.1 系统架构](#3.1 系统架构)
      • [3.2 仿真图分析](#3.2 仿真图分析)
      • [3.3 部分代码](#3.3 部分代码)
    • [四 总结](#四 总结)

摘要

本文基于 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 倍即可接近最优性能;编码系统在低信噪比下性能略逊于未编码系统,但随着信噪比升高优势逐渐显现。上述结论为实际系统中卷积码参数选取提供了参考依据。

相关推荐
weixin_307779133 天前
一维无粘 Burgers 方程的激波形成问题:MacCormack 格式求解
c++·算法·matlab
Evand J3 天前
【MATLAB例程,图像滤波5】 反谐波均值滑动窗口滤波(CHMF)图像降噪与质量评价,附代码下载链接
图像处理·算法·计算机视觉·matlab·均值算法·滑动窗口滤波·均值滑动
分享资料3 天前
Matlab脚本调用Python脚本方法
matlab
slandarer3 天前
MATLAB | 绘图复刻 (二十七) | 多子图堆叠面积图
数学建模·matlab
机器学习之心4 天前
基于BiGRU-Attention的轴承剩余寿命预测(MATLAB实现):从振动信号到RUL曲线的完整闭环
数据结构·算法·matlab·轴承剩余寿命预测·振动信号·bigru-attention
Evand J5 天前
【MATLAB代码,车联网8】MPC网联车辆节能跟驰控制:速度跟踪、间距约束与能耗优化。MATLAB完整代码订阅专栏后可直接查看
matlab·代码·车联网·mpc·车辆·网联·网联技术
我找到地球的支点啦6 天前
Matlab系列(009) 一CRC循环冗余校验详解
开发语言·数据结构·算法·matlab·信息与通信
吃好睡好便好9 天前
查找函数的使用
学习·算法·matlab·生活·查找函数
chhttty9 天前
Design Verifier检查:整型数溢出检查与修复
matlab·simulink