LLR vs. Hard Decision Demodulation

This example shows the BER performance improvement for QPSK modulation when using log-likelihood ratio (LLR) instead of hard-decision demodulation in a convolutionally coded communication link. With LLR demodulation, one can use the Viterbi decoder either in the unquantized decoding mode or the soft-decision decoding mode. Unquantized decoding, where the decoder inputs are real values, though better in terms of BER, is not practically viable. In the more practical soft-decision decoding, the demodulator output is quantized before being fed to the decoder. It is generally observed that this does not incur a significant cost in BER while significantly reducing the decoder complexity. We validate this experimentally through this example.


The first step is to set up system parameters for simulation.

  • bitsPerIter : Number of bits to simulate

  • EbNo : Information bit Eb/No in dB

  • codeRate : Code rate of convolutional encoder

  • constlen : Constraint length of encoder

  • codegenpoly : Code generator polynomial of encoder

  • tblen : Traceback depth of Viterbi decoder

M     = 4; % Modulation alphabet size for QPSK
k     = log2(M);
bitsPerIter = 1.2e4;
EbNo  = 3;

% Code properties
codeRate = 1/2;
constlen = 7;
codegenpoly  = [171 133];
tblen    = 32;
trellis  = poly2trellis(constlen, codegenpoly);

Create a rate 1/2, constraint length 7 ConvolutionalEncoderConvolutionalEncoder System object.

hConvEnc = comm.ConvolutionalEncoder(trellis);

Modulator and Channel

Create a QPSKModulatorQPSKModulator System object and two QPSKDemodulatorQPSKDemodulator System objects one each for hard-decision and LLR demodulation.

hMod = comm.QPSKModulator('BitInput',true);
hDemodHD = comm.QPSKDemodulator('BitOutput',true,...
    'DecisionMethod', 'Hard decision');
hDemodLLR = comm.QPSKDemodulator('BitOutput',true,...
    'DecisionMethod', 'Log-likelihood ratio');

Create an AWGNChannelAWGNChannel System object. The signal going into the AWGN channel is the modulated encoded signal. To achieve the required Eb/No, adjust the signal-to-noise ratio for coded bits and multi-bit symbols and set this as the the EbNo of the channel object.

hChan = comm.AWGNChannel('NoiseMethod', 'Signal to noise ratio (Eb/No)',...
    'SignalPower', 1, 'SamplesPerSymbol', 1);
adjSNR     = EbNo - 10*log10(1/codeRate) + 10*log10(k);
hChan.EbNo = adjSNR;

Viterbi Decoding

Create ViterbiDecoderViterbiDecoder System objects to act as the hard-decision, unquantized and soft-decision decoders and set the traceback depth to 'tblen'.

hVitDecHD  = comm.ViterbiDecoder(trellis, 'InputFormat', 'Hard',...
    'TracebackDepth', tblen);
hVitDecUNQANT = comm.ViterbiDecoder(trellis, ...
    'InputFormat', 'Unquantized', 'TracebackDepth', tblen);
hVitDecSD  = comm.ViterbiDecoder(trellis, 'InputFormat', 'Soft',...
  'SoftInputWordLength',3, 'TracebackDepth', tblen);

Quantization for soft-decoding

Before using a comm.ViterbiDecoder object in the soft-decision mode, the output of the comm.QPSKDemodulator object needs to be quantized. This example uses a comm.ViterbiDecoder object with a 'SoftInputWordLength' value of 3. This value is a good compromise between short wordlengths and a small BER penalty. Create a ScalarQuantizerEncoderScalarQuantizerEncoder System object with 3-bit quantization.

hScalQuant = dsp.ScalarQuantizerEncoder;
NoiseVariance = 10.^(-adjSNR/10);
hScalQuant.Partitioning = 'Unbounded';
hScalQuant.BoundaryPoints = (-1.5:0.5:1.5)/NoiseVariance;

Calculating the Error Rate

Create ErrorRateErrorRate System objects to compare the decoded bits to the original transmitted bits. The Viterbi decoder creates a delay in the output decoded bit stream equal to the traceback length. To account for this delay set the 'ReceiveDelay' property of the comm.ErrorRate objects to 'tblen'.

hErrorCalcHD  = comm.ErrorRate('ReceiveDelay', tblen);
hErrorCalcUNQUANT = comm.ErrorRate('ReceiveDelay', tblen);
hErrorCalcSD  = comm.ErrorRate('ReceiveDelay', tblen);

System Simulation

Initialize variables for storing BER results and simulate the system.

ber_HD  = zeros(3,1);
ber_UNQUANT = zeros(3,1);
ber_SD  = zeros(3,1);

% Generate 'bitsPerIter' message bits.
data = randi([0 1], bitsPerIter, 1);

% Convolutionally encode the data
encData = step(hConvEnc, data);

% Modulate the encoded data
modData = step(hMod, encData);

% Pass the modulated signal through an AWGN channel
channelOutput = step(hChan, modData);

% Hard-decision Demodulation
demodDataHD = step(hDemodHD, channelOutput);

% LLR Demodulation
demodDataLLR = step(hDemodLLR, channelOutput);

% Hard-decision decoding: Pass the demodulated data through the Viterbi
% decoder; and compute and accumulate errors
decDataHD   = step(hVitDecHD, demodDataHD);
ber_HD      = step(hErrorCalcHD, data, decDataHD);

% Unquantized decoding: Pass the demodulated data through the Viterbi
% decoder; and compute and accumulate errors
decDataUNQUANT   = step(hVitDecUNQANT, demodDataLLR);
ber_UNQUANT      = step(hErrorCalcUNQUANT, data, decDataUNQUANT);

% Soft-decision decoding: The demodulated data must pass through a
% quantizer before being fed to the Viterbi decoder. However the output
% from the demodulator must be sign-reversed before being fed to the
% quantizer. This is because in the soft-decision decoding mode, the
% comm.ViterbiDecoder object assumes that positive numbers correspond to 1s
% and negative numbers to 0s. Thus the decoding operation consists of
% feeding in the sign reversed data from the comm.PSKDemodulator object to
% the dsp.scalarQuantizerEncoder object and feeding in the output from this
% dsp.scalarQuantizerEncoder object to the comm.ViterbiDecoder. Compute and
% accumulate errors.
quantizedValue = step(hScalQuant, -demodDataLLR);
decDataSD      = step(hVitDecSD, double(quantizedValue));
ber_SD         = step(hErrorCalcSD, data, decDataSD);

Running Simulation Example

The next step simulates the above designed communications system over a range of Eb/No values by executing the driver file SIMLLRVSHD. It plots BER results as they are generated. BER results for hard-decision demodulation and LLR demodulation with unquantized and soft-decision decoding are plotted in red, blue and black respectively. A comparison of simulation results with theoretical results is also shown. We see that the BER is only slightly degraded by using soft-decision decoding instead of unquantized decoding. The gap between the BER curves for soft-decision decoding and the theoretical bound can be narrowed by increasing the number of quantizer levels. This example may take some time to compute BER results, so we have set it to run in parallel if you have the Parallel Computing Toolbox™ (PCT) installed. To obtain results over a larger range of Eb/No values, modify this example file accordingly. More statistically reliable results can be obtained by collecting more errors which can be realized faster with the parallelized simulation.

[licensePCT,~] = license( 'checkout' , 'Distrib_Computing_Toolbox');
if ( licensePCT && ~isempty(ver('distcomp')))
Starting parallel pool (parpool) using the 'local' profile ... connected to 12 workers.


The following functions are used in this example:

Was this topic helpful?