1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
function [detected_data, errors, output_decoder_c, input_upper_u] = TurboDecode( input_decoder_c, data, turbo_iterations, decoder_type, code_interleaver, pun_pattern, tail_pattern, g1, nsc_flag1, g2, nsc_flag2, varargin )
% TurboDecode decodes a received sequence that was encoded by a binary turbo code.
% If input_decoder_c has multiple rows, then multiple codewords will be decoded (one for each row).
%
% The calling syntax is:
% [detected_data, errors, output_decoder_c, [output_decoder_u] ] =
% TurboDecode( input_decoder_c, data, turbo_iterations, decoder_type, ...
% code_interleaver, pun_pattern, tail_pattern, g1, nsc_flag1, g2, ...
% nsc_flag2, [input_decoder_u] )
%
% detected_data = a row vector containing the detected data
% errors = a column vector containing the number of errors per
% iteration for all the codewords.
% output_decoder_c = the extrinsic information of the code bits
% output_decoder_u = the extrinsic information of the systematic bits (optional)
%
% input_decoder_c = the decoder input, in the form of bit LLRs
% this could have multiple rows if the data is longer
% than the interleaver
% data = the row vector of data bits (used to count errors and for early halting of iterative decoding)
% turbo_iterations = the number of turbo iterations
% decoder_type = the decoder type
% = 0 For linear-log-MAP algorithm, i.e. correction function is a straght line.
% = 1 For max-log-MAP algorithm (i.e. max*(x,y) = max(x,y) ), i.e. correction function = 0.
% = 2 For Constant-log-MAP algorithm, i.e. correction function is a constant.
% = 3 For log-MAP, correction factor from small nonuniform table and interpolation.
% = 4 For log-MAP, correction factor uses C function calls.
% code_interleaver = the turbo interleaver
% pun_pattern = the puncturing pattern for all but the tail
% tail_pattern = the puncturing pattern just for the tail
% g1 = the first generator polynomial
% nsc_flag1 = 0 if first encoder is RSC and 1 if NSC
% g2 = the second generator polynomial
% nsc_flag2 = 0 if second encoder is RSC and 1 if NSC
% [input_decoder_u] = the a priori information about systematic bits (optional input)
%
% Copyright (C) 2005-2006, Matthew C. Valenti
%
% Last updated on Apr. 23, 2006
%
% Function TurboDecode is part of the Iterative Solutions Coded Modulation
% Library (ISCML).
%
% The Iterative Solutions Coded Modulation Library is free software;
% you can redistribute it and/or modify it under the terms of
% the GNU Lesser General Public License as published by the
% Free Software Foundation; either version 2.1 of the License,
% or (at your option) any later version.
%
% This library is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
% Lesser General Public License for more details.
%
% You should have received a copy of the GNU Lesser General Public
% License along with this library; if not, write to the Free Software
% Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
% determine some parameters
[N1,K1] = size( g1 );
[N2,K2] = size( g2 );
% check interleaver length against data length
K_data = length( data );
K_interleaver = length( code_interleaver );
if ( rem( K_data, K_interleaver ) )
error( 'The data length needs to be an integer multiple of the interleaver length' );
end
number_codewords = K_data/K_interleaver;
data_bits_per_frame = K_data/number_codewords;
data = reshape( data, K_interleaver, number_codewords)';
% intialize error counter
errors = zeros( turbo_iterations, 1 );
if ( length(varargin) >= 1 )
input_upper_u = varargin{1};
else
input_upper_u = zeros( number_codewords, data_bits_per_frame );
end
% loop over each received frame
for codeword_index=1:number_codewords
% depuncture and split
depunctured_output = Depuncture( input_decoder_c(codeword_index,:), pun_pattern, tail_pattern );
input_upper_c = reshape( depunctured_output(1:N1,:), 1, N1*length(depunctured_output) );
input_lower_c = reshape( depunctured_output(N1+1:N1+N2,:), 1, N2*length(depunctured_output) );
% decode
for turbo_iter=1:turbo_iterations
% fprintf( 'Turbo iteration = %d\n', turbo_iter );
% Pass through upper decoder
[output_upper_u output_upper_c] = SisoDecode( input_upper_u(codeword_index,:), input_upper_c, g1, nsc_flag1, decoder_type );
% Interleave and extract extrinsic information
input_lower_u = Interleave( output_upper_u - input_upper_u(codeword_index,:), code_interleaver );
% Pass through lower decoder
[output_lower_u output_lower_c] = SisoDecode( input_lower_u, input_lower_c, g2, nsc_flag2, decoder_type );
% count errors
detected_data(codeword_index,:) = Deinterleave( (sign(output_lower_u)+1)/2, code_interleaver );
error_positions = xor( detected_data(codeword_index,:), data(codeword_index,:) );
% exit if all the errors are corrected
temp_errors = sum(error_positions);
% for debugging
% fprintf( 'Codeword: %d, Iteration: %d, Errors: %d\n', codeword_index, turbo_iter, temp_errors );
if (temp_errors==0)
break;
else
errors(turbo_iter) = temp_errors + errors(turbo_iter);
% Interleave and extract extrinsic information
input_upper_u(codeword_index,:) = Deinterleave( output_lower_u - input_lower_u, code_interleaver );
end
end
% Combine output_c and puncture
% convert to matrices (each row is from one row of the generator)
upper_reshaped = [ reshape( output_upper_c, N1, length(output_upper_c)/N1 ) ];
lower_reshaped = [ reshape( output_lower_c, N2, length(output_lower_c)/N2 ) ];
% parallel concatenate
unpunctured_word = [upper_reshaped
lower_reshaped];
% repuncture
output_decoder_c( codeword_index,:) = Puncture( unpunctured_word, pun_pattern, tail_pattern );
end
detected_data = reshape( detected_data', 1, K_data);
|