Why does the flat part of the BER curve appear after the Viterbi decoder (MatLab)? I am trying to implement convolutional codes according to this MathWorks example in MatLab 2014a.



clear; close all; clc
rng default
M = 4;                 % Modulation order
k = log2(M);            % Bits per symbol
EbNoVec = (0:20)';       % Eb/No values (dB)
numSymPerFrame = 100000;   % Number of QAM symbols per frame

modul = comm.RectangularQAMModulator(M, 'BitInput', true);
berEstSoft = zeros(size(EbNoVec)); 


trellis = poly2trellis(7,[171 133]);
tbl = 32;
rate = 1/2;

decoders = comm.ViterbiDecoder(trellis,'TracebackDepth',tbl,...
'TerminationMethod','Continuous','InputFormat','Unquantized');


for n = 1:length(EbNoVec)
    % Convert Eb/No to SNR
    snrdB = EbNoVec(n) + 10*log10(k*rate);
    % Noise variance calculation for unity average signal power.
    noiseVar = 10.^(-snrdB/10);
    % Reset the error and bit counters
    [numErrsSoft, numErrsHard, numBits] = deal(0);

    while numErrsSoft &lt; 100 &amp;&amp; numBits &lt; 1e7
        % Generate binary data and convert to symbols
        dataIn = randi([0 1], numSymPerFrame*k, 1);

        % Convolutionally encode the data
        dataEnc = convenc(dataIn, trellis);

        % QAM modulate
        txSig = step(modul, dataEnc);

        % Pass through AWGN channel
        rxSig = awgn(txSig, snrdB, 'measured');

        % Demodulate the noisy signal using hard decision (bit) and
        % soft decision (approximate LLR) approaches.       
        demods = comm.RectangularQAMDemodulator(M, 'BitOutput', true, ...
        'DecisionMethod', 'Approximate log-likelihood ratio',...
        'VarianceSource', 'Property', 'Variance', noiseVar);
        rxDataSoft = step(demods, rxSig);

        % Viterbi decode the demodulated data
        dataSoft = step(decoders, rxDataSoft);

        % Calculate the number of bit errors in the frame. Adjust for the
        % decoding delay, which is equal to the traceback depth.
        numErrsInFrameSoft = biterr(dataIn(1:end-tbl), dataSoft(tbl+1:end));

        % Increment the error and bit counters
        numErrsSoft = numErrsSoft + numErrsInFrameSoft;
        numBits = numBits + numSymPerFrame*k;

    end

    % Estimate the BER for both methods
    berEstSoft(n) = numErrsSoft/numBits;
end

semilogy(EbNoVec, berEstSoft,'-o','LineWidth', 1.5)
hold on
legend('Soft','location','best')
grid
xlabel('Eb/No (dB)')
ylabel('Bit Error Rate')


And I am confused about the obtained curve:



Why does not the BER curve decrease exponentially after the 5dB?
Have anybody faced this issue before?
while numErrsSoft &lt; 100 &amp;&amp; numBits &lt; 1e7


Nope, you can't stop after 10⁷ bits if you're after error rates &lt; 10⁻⁶. That means you expect to see less than 10 bit errors. That's not a sufficient statistic!

So, this is where I know your curve becomes unreliable, anyway.

You might still be running into some error flow due to the implementation, but I can't look inside Matlab's implementation of neither the QAM decision nor its Viterbi, so these are "meh" at best for scientific considerations about the nature of Viterbi.