主要内容

对 16-QAM 信号使用前向纠错

此示例对对 16-QAM 信号使用脉冲整形示例进行了扩展,以展示使用前向纠错 (FEC) 编码时误码率 (BER) 性能的改进。

此示例说明如何使用由基带调制器、信道、解调器、脉冲整形、升余弦滤波和纠错组成的通信链路处理二进制数据流。

建立仿真框架

在此示例中,为了实现更准确的 BER 估计,要处理的位数相比对 16-QAM 信号使用脉冲整形示例中使用的值有所增加。其他仿真变量与该示例中的设置一致。

为具有升余弦滤波和 AWGN 信道的 16-QAM 调制方案定义仿真参数。

M = 16;            % Modulation order
k = log2(M);       % Bits per symbol
numBits = k*2.5e5; % Total bits to process
sps = 4;           % Samples per symbol (oversampling factor)
filtlen = 10;      % Filter length in symbols
rolloff = 0.25;    % Filter rolloff factor

生成随机数据

rng 函数设置为其默认状态或任何静态种子值,以便示例产生可复现的结果。然后,使用 randi 函数生成随机二进制数据。

rng default;                     % Default random number generator
dataIn = randi([0 1],numBits,1); % Generate vector of binary data

应用卷积编码

为了校正由含噪信道引起的错误,在发射前对数据应用卷积编码,并对收到的数据应用 Viterbi 解码。解码器使用硬决策算法,这意味着收到的每个数据位都解释为 01

使用 poly2trellis 函数为 2/3 码率的码定义卷积编码网格。定义的网格表示 convenc 函数用于对二进制向量 dataIn 进行编码的卷积码。

constrlen = [5 4];          % Code constraint length
genpoly = [23 35 0; 0 5 13] % Generator polynomials
genpoly = 2×3

    23    35     0
     0     5    13

tPoly = poly2trellis(constrlen,genpoly);
codeRate = 2/3;

使用 tPoly 网格对输入数据进行编码。

dataEnc = convenc(dataIn,tPoly);

调制数据

使用 bit2int 函数将 k 元组编码的二进制数据转换为整数值。

dataSymbolsIn = bit2int(dataEnc,k);

使用 qammod 函数应用 16-QAM 调制。

dataMod = qammod(dataSymbolsIn,M);

应用升余弦滤波

使用 rcosdesign 函数创建一个 RRC 滤波器。

rrcFilter = rcosdesign(rolloff,filtlen,sps);

使用 upfirdn 函数按过采样因子对信号进行上采样并应用 RRC 滤波器。upfirdn 函数会在上采样信号末尾填充零,以刷新滤波器。然后,该函数应用该滤波器。

txSignal = upfirdn(dataMod,rrcFilter,sps,1);

应用 AWGN 信道

使用每符号的位数、每符号的采样数、码率和 convertSNR 函数将每比特能量与噪声功率谱密度之比 (EbNo) 转换为 SNR 值,以供 awgn 函数使用。将 Eb/N0 转换为 SNR 时,必须考虑每符号的信息位数。在不应用 FEC 的情况下,每个符号对应 k 个位。在应用 FEC 后,每个符号对应 (k × codeRate) 个信息位。对于此示例中使用的 2/3 码率和 16-QAM 发射,三个符号对应 12 个编码位和 8 个未编码(信息)位。

EbNo = 10;
snr = convertSNR(EbNo,'ebno', ...
    samplespersymbol=sps, ...
    bitspersymbol=k,CodingRate=codeRate);

使滤波后的信号通过 AWGN 信道。

rxSignal = awgn(txSignal,snr,'measured');

接收和解调信号

使用 RRC 滤波器对接收的信号进行滤波。删除信号的一部分以考虑滤波器延迟。

rxFiltSignal = ...
    upfirdn(rxSignal,rrcFilter,1,sps);       % Downsample and filter
rxFiltSignal = ...
    rxFiltSignal(filtlen + 1:end - filtlen); % Account for delay

使用 qamdemod 函数对接收的滤波信号进行解调。

dataSymbOut = qamdemod(rxFiltSignal,M);

应用 Viterbi 解码

使用 int2bit 函数将恢复的整数符号转换为二进制数据。

codedDataOut = int2bit(dataSymbOut,k); % Return data in column vector

使用针对硬决策和连续运算模式配置的 vitdec 函数对卷积编码数据进行解码。当重复调用解码器时(如循环接收数据帧时),连续运算模式保留内部状态。连续运算模式还会给系统引入延迟。尽管此示例不使用循环,但为了说明如何补偿此解码运算中的延迟,使用了 'cont' 模式。

traceBack = 16;                      % Decoding traceback length
numCodeWords = ...
    floor(length(codedDataOut)*2/3); % Number of complete codewords
dataOut = ...
    vitdec(codedDataOut(1:numCodeWords*3/2), ...
    tPoly,traceBack,'cont','hard');  % Decode data

计算系统 BER

发射和接收 RRC 滤波器引入的延迟已在恢复的数据中考虑,但解码器延迟尚未考虑在内。Viterbi 解码器的连续运算模式会产生延迟,其持续时间(以位为单位)等于回溯长度 traceBack 乘以在编码器处的输入流数。对于此示例中使用的 2/3 码率,编码器有两个输入流,因此延迟为 2×traceBack 个位。因此,解码向量 dataOut 中的前 2×traceBack 个位为零。计算 BER 时,丢弃 dataOut 中的前 2×traceBack 个位和原始向量 dataIn 中的后 2×traceBack 个位。

使用 biterr 函数通过比较 dataIndataOut 来计算错误数和 BER。对于相同的 10 dB Eb/N0,当处理链中包含 FEC 时,发生的错误更少。

decDelay = 2*traceBack;              % Decoder delay, in bits
[numErrors,ber] = ...
   biterr(dataIn(1:end - decDelay),dataOut(decDelay + 1:end));       
fprintf('\nThe bit error rate is %5.2e, based on %d errors.\n', ...
    ber,numErrors)
The bit error rate is 6.40e-05, based on 64 errors.

关于延迟的更多信息

此示例中的解码运算会产生延迟,导致解码器的输出滞后于输入。示例中未明确出现时序信息,且延迟的长度取决于所执行的具体运算。延迟发生在各种通信系统运算中,包括卷积解码、卷积交织和解交织、均衡和滤波。要了解特定函数或运算引起的延迟的持续时间,请参阅这些函数或运算的具体文档。有关延迟的详细信息,请参阅Delays of Convolutional InterleaversFading Channels

另请参阅

函数

主题