I am encoding and decoding a randomly generated bitstream of data using a [5 7] convolutional code. For the decoding part I am using a Viterbi Decoder and trying both HDD and SDD. However, my results for HDD seem incorrect as the BER exceeds the theoretical upper bound that I have calculated. I used a bitstream of 100,000 bits. Any help as to why this is happening? I know that SDD is superior to HDD but shouldn't HDD also be below the Upper Bound? Here are the results:



Here is my function for Viterbi Decoding using HDD:

function decodedBits = viterbiDecoderAWGN_HARD(receivedBits, L, k, n, G)
    % Viterbi Decoder for a (2,1) convolutional code
    % receivedBits: Received bit sequence
    % L: Constraint length
    % k: Number of input bits (always 1 for a rate 1/2 code)
    % n: Number of output bits (always 2 for a rate 1/2 code)
    % G: Generator matrix in octal form

    % Generate Trellis structure
    [nextState, outputTable] = generateTrellis(L, k, n, G);

    numStates = 2^(L-1);
    numInputs = 2^k; % Always 2 for binary
    numSteps = length(receivedBits) / n;

    % Initialize path metrics and survivors
    pathMetrics = inf(numStates, numSteps+1);
    pathMetrics(1,1) = 0; % Start state assumed to be 0
    survivors = zeros(numStates, numSteps);
    % Convert BPSK symbols to binary digits for hard decision
    hardDecisionBits = receivedBits > 0; % Convert to 0s and 1s based on the threshold

    % Viterbi algorithm
    for step = 1:numSteps
        receivedSymbol = hardDecisionBits((step-1)*n+1:step*n);
        for currentState = 0:(numStates-1)
            for inputBit = 0:(numInputs-1)
                next = nextState(currentState+1, inputBit+1);
                encodedSymbol = de2bi(outputTable(currentState+1, inputBit+1), n, 'left-msb');
                hammingDistance = sum(xor(encodedSymbol, receivedSymbol));
                metric = pathMetrics(currentState+1, step) + hammingDistance;
                if metric < pathMetrics(next+1, step+1)
                    pathMetrics(next+1, step+1) = metric;
                    survivors(next+1, step) = currentState+1; % MATLAB indexing

    % Traceback
    decodedBits = zeros(1, numSteps);
    [~, currentState] = min(pathMetrics(:, end)); % Finding the end state with the lowest metric
    for step = numSteps:-1:1
        decodedBits(step) = find([nextState(survivors(currentState, step),:)+1] == currentState, 1) - 1;
        currentState = survivors(currentState, step);

I am sure that the Trellis is being generated correctly so there is no problem there. Any ideas?

  • $\begingroup$ Where does the upper bound come from? And: your curves seem a bit too wiggly, have you really tried with enough sufficiently random data and sufficiently independently random noise? $\endgroup$ Commented Mar 22 at 12:28
  • $\begingroup$ It's a union bound. It comes from the transfer function once I sent its derivative with respect to N equal to zero. Yes, at high SNR they do become a bit wiggly but I guess 100k bits should suffice. In terms of randomness I generate 999990 bits randomly and then append 10 zeros for termination. I ran the simulation many times and with different sized input arrays and still the BER for HDD always exceeds the bounds. $\endgroup$ Commented Mar 22 at 12:34
  • $\begingroup$ I mean, 100k bits when your BER is in the order of 0.5·10⁻⁴ is of course pretty questionable, but point taken, that's not the part of the curve you're worried about. I'm not sure how you calculate the Union Bound – the usual problem with the union bound is that it's an infinite sum, and truncation turns it to be something that isn't quite a bound any more (but I doubt that should be leading what we see here). $\endgroup$ Commented Mar 22 at 12:43
  • 2
    $\begingroup$ @MarcusMüller I used a million bits and got smoother curves albeit after a long time of waiting but thanks for that suggestion. However, the problem with HDD still persists! If you want I can share the calculations for the Upper Bound... $\endgroup$ Commented Mar 22 at 18:02

1 Answer 1


Are you accounting for quantization noise in your calculation of the bound when decoding with HDD?

One-bit representation is a special case anyway, but the quantization noise has an impact, generally. For the special case of one-bit quantizers, as SNR increases it is increasingly likely that hard decision errors amplify the noise and by larger amounts compared to AWGN variance. That is, a hard decision error most likely happens with the noise barely crossing the zero threshold. The hard decision "amplifies" the noise that caused the threshold crossing by quantizing to +1 or -1, even though the unquantized value was very close to zero (but slightly over the boundary). The likelihood of large amplification from close-to-zero to +1 or -1 becomes worse for higher SNR (i.e. rarer HD errors).

  • $\begingroup$ I actually used the same bound for both and your answer makes me think that might not be ideal. Thank you! $\endgroup$ Commented Mar 24 at 12:03
  • $\begingroup$ Glad it was helpful. As I noted, the single-bit quantizer has more nuance than multi-bit. Assuming you did your union bound from min-distance error events (e.g. from pair-state trellis or other analysis of the CC), you can approximate the effects of multi-bit quantization by adding the quantizer variance to the noise variance. Then, lower the number of bits to see how it changes as you get near 1 bit. For multi-bit quantizers, the AWGN plus quantization error still has largely Gaussian tails. $\endgroup$
    – vml
    Commented Mar 24 at 18:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.