Viterbi Decoder MATLAB Source Code for Convolutional Encoder

This section presents the MATLAB source code for a Viterbi decoder, specifically designed for a convolutional encoder with a constraint length of 5.

Specifications of Convolutional Encoder

The convolutional encoder used in this example has the following characteristics:

  • Convolutional Encoder: (3, 1, 4)
  • Coding Rate: 1/3
  • Constraint Length: 5
  • Output Bit Length: 3
  • Message Bit Length: 1
  • Maximal Memory Order / No. of Memory Elements: 4
  • Generator Polynomials: 25 (octal), 33 (octal), 37 (octal)

Specifications of Viterbi Decoder

The Viterbi decoder is configured as follows:

  • Codeword Length: 20
  • Coding Rate: 1/3
  • Constraint Length: 5
  • Trace Back Length: 20
  • Quantization Levels: Two (Hard decision type)
  • Generator Polynomials: 25 (octal), 33 (octal), 37 (octal)

This Viterbi decoder is specifically designed to work with the convolutional encoder described above. For more details, refer to the basics of convolutional encoders and the Convolutional Encoder MATLAB Code.

Viterbi MATLAB Code

function [dec_op]=viterbi_decoder(rcvd)
%Concatenate three consecutive bits of received encoded sequence to
%Make up a symbol
input=[];
for j=1:3:length(rcvd)
    input=[ input (rcvd(j)* 2^2) + (rcvd(j+1) * 2^1) + (rcvd(j+2) * 2^0)];
end

%%Initialize Ouput Table
Output_Table = [
    ... 0 0 7;
    ... 1 7 0;
    ... 2 3 4;
    ... 3 4 3;
    ... 4 5 2;
    ... 5 2 5;
    ... 6 6 1;
    ... 7 1 6;
    ... 7 3 4;
    ... 8 4 3;
    ... 9 0 7;
    ... 10 7 0;
    ... 11 6 1;
    ... 12 1 6;
    ... 13 5 2;
    ... 14 2 5];

%%Initialize Next-State(Ouput State) Table
Next_State   =[
    ... 0 0   8;
    ... 1 0 8;
    ... 2 1 9;
    ... 3 1 9;
    ... 4 2 10;
    ... 5 2 10;
    ... 6 3 11;
    ... 7 3 11;
    ... 8 4 12;
    ... 9 4 12;
    ... 10 5 13;
    ... 11 5 13;
    ... 12 6 14;
    ... 13 6 14;
    ... 14 7 15;
    ... 15 7 15];

%%%Updating the arrays
State_Hist(1:16, 1:10)=55; %STATE HISTORY array
aem(1:16, 1:6)=0; %ACCUMULATED ERROR METRIC (AEM) array

%%%%%%%%%Transition Table For Trace Back%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Transition_Table    =   [
    ... 0 55 55 55 55 55 55 55 1 55 55 55 55 55 55 55;
    ... 0 55 55 55 55 55 55 55 1 55 55 55 55 55 55 55;...
    ... 55 0 55 55 55 55 55 55 55 1 55 55 55 55 55 55;...
    ... 55 0 55 55 55 55 55 55 55 1 55 55 55 55 55 55;...
    ... 55 55 0 55 55 55 55 55 55 55 1 55 55 55 55 55;...
    ... 55 55 0 55 55 55 55 55 55 55 1 55 55 55 55 55;...
    ... 55 55 55 0 55 55 55 55 55 55 55 1 55 55 55 55;...
    ... 55 55 55 0 55 55 55 55 55 55 55 1 55 55 55 55;...
    ... 55 55 55 55 0 55 55 55 55 55 55 55 1 55 55 55;...
    ... 55 55 55 55 0 55 55 55 55 55 55 55 1 55 55 55;...
    ... 55 55 55 55 55 0 55 55 55 55 55 55 55 1 55 55;...
    ... 55 55 55 55 55 0 55 55 55 55 55 55 55 1 55 55;...
    ... 55 55 55 55 55 55 0 55 55 55 55 55 55 55 1 55;...
    ... 55 55 55 55 55 55 0 55 55 55 55 55 55 55 1 55;...
    ... 55 55 55 55 55 55 55 0 55 55 55 55 55 55 55 1;...
    ... 55 55 55 55 55 55 55 0 55 55 55 55 55 55 55 1];

%%%find the length of input
lim=length(input); %number of time cycles
State_Hist(1,1)=0; %%Initialze the starting state at t1 = 0;

%%%%%%%%%LOOP FOR NUMBER OF TIME UNITS%%%%%%%%%%%%%%%%
%%Loop L1 Start
for t=1:1:lim
    t;
    temp_state=[];%vector to store possible states at an instant
    temp_metric=[];%vector to store metrics of possible states
    temp_parent=[];%vector to store parent states of possible states

    %%%%%%%%%%%%%LOOP FOR NUMBER OF STATES %%%Loop L2 Start
    for i=1:16
        in=input(t);
        %%check if the present state is valid or not
        if( State_Hist(i,t)==55)  %if the statement is true than its an invalid state
            %%Do Nothing
        else
            NS_a   =   Next_State(i,2) +   1;  %%Next possible state 1
            NS_b   =   Next_State(i,3) +   1;  %%Next possible state 2
            OP_a   =   Output_Table(i,2);  %%Possible output 1
            OP_b   =   Output_Table(i,3);  %%Possible output 1
            CS     =   i   -   1;  %%Current State
            M_a    =   hamm_dist(OP_a,in); %%Branch Metric for NS_a
            M_b    =   hamm_dist(OP_b,in); %%Branch Metric for NS_a

            Flag = 0;  %Flag to indicate redundant states

            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            %%%%%%%%CHECKING FOR REDUNDANT STATES%%%%%%%%%%
            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            for k=1:1:length(temp_state)
                %check redundant next states

                %if next possible state-1 redundant
                if(temp_state(1,k)==NS_a)
                    Flag=1;

                    %ADD-COMPARE-SELECT Operation
                    %em_c: error metric of current state
                    %em_r: error metric of redundant state
                    em_c=M_a + aem(i,t);
                    em_r=temp_metric(1,k) + aem(temp_parent(1, k)+1,t);

                    if( em_c< em_r)%compare the two error metrics
                        State_Hist(NS_a,t+1)=CS;%select state with low AEM
                        temp_metric(1,k)=M_a;
                        temp_parent(1,k)=CS;
                    end
                end

                %if next possible state-2 redundant
                if(temp_state(1,k)==NS_b)
                    indicator=1;
                    em_c=M_b + aem(i,t);
                    em_r=temp_metric(1,k) + aem(temp_parent(1, k)+1,t);

                    if( em_c < em_r)%compare the two error metrics
                        State_Hist(NS_b,t+1)=CS;%select state with low AEM
                        temp_metric(1,k)=M_b;
                        temp_parent(1,k)=CS;
                    end
                end
            end
            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            %%%%%%%%       END                   %%%%%%%%%%
            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

            %if none of the 2 possible states are redundant
            if(Flag == 0)
                %update state history table
                State_Hist(NS_a,t+1)   =   CS;
                State_Hist(NS_b,t+1)   =   CS;

                %update the temp vectors accordingly
                temp_state    =   [temp_state NS_a NS_b];
                temp_parent   =   [temp_parent CS CS];
                temp_metric   =   [temp_metric M_a M_b];
            end
        end
    end %%loop L2 i.e State loop ends here

    %Update the AEMs (accumulative error metrics) for all states for
    %current instant 't'
    for h=1:1:length(temp_state)
        x1  =   temp_state(1,h);    %finding  the temp_state
        x2  =   temp_parent(1,h)    +   1;   %finnding the parent_state of the present temp state
        aem(x1,t+1) =   temp_metric(1,h)    +   aem(x2,t);
    end
end %%loop for l1 i.e time ends here

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                       T R A C E - B A C K                                 %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

slm = min(aem(:, 21));
slm_loc =find( aem(:, 21)==slm );
sseq(21) = (slm_loc(1)-1);

for t=20:-1:1
    sseq(t) = State_Hist(sseq(t+1) + 1,t+1);
end

dec_op=[];
for k =1 : 20
    dec_op(k) = Transition_Table(sseq(k)+1, sseq(k+1)+1);
end