📄 harqdematch.m
字号:
function [code_bits] = HarqDematch( channel_streams, X_RV, N_IR, N_TTI, B )
% HarqDematch reassembles B UMTS turbo codewords from B*P received HSDPA streams
%
% The calling syntax is:
% [code_bits] = HarqDematch( channel_streams, X_RV, N_IR, N_TTI )
%
% code_bits = the reassembled, received turbo codewords (input to decoder)
% could be multiple rows if a long data sequence was
% segmented into multiple turbo codewords
%
% channel_streams = B*P by U matrix containing bits received over the channel
% where U=960 for QPSK and U=1920 for 16-QAM
% and B is the number of turbo codewords.
% X_RV = The redundancy version (an integer from 0 to 7).
% N_IR = Size of the virtual IR buffer
% N_TTI = Length of each unpunctured turbo codeword
% B = the number of turbo codewords
%
% Copyright (C) 2005, Matthew C. Valenti
%
% Last updated on June 21, 2006
%
% Function HarqDematch 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
% sanity checks
if ( rem( N_TTI, 3 ) )
error( 'N_TTI must be a multiple of 3' );
elseif ( N_IR < N_TTI/3 )
error( 'N_IR is not large enough' );
end
% interleaver pattern for physical channel (table 7)
p_interleaver = [0 20 10 5 15 25 3 13 23 8 18 28 1 11 21 6 16 26 4 14 24 19 9 29 12 2 7 22 27 17];
R2 = 32;
C2 = 30;
% determine parameters
[P_total,U] = size( channel_streams );
% number physical channels per codeword
P = P_total/B;
number_codewords = B; % an alias
% determine modulation from U.
if (U == 960)
modulation = 0; % QPSK
elseif (U == 1920)
modulation = 1; % QAM
else
error( 'U must be either 960 or 1920' );
end
N_data = P*U;
% Based on X_RV and modulation, determine the Redundancy Version and other parameters
if (modulation == 0)
% QPSK
U = 960;
r_max = 4;
N_row = 2;
LUT = [1 0
0 0
1 1
0 1
1 2
0 2
1 3
0 3];
s = LUT(X_RV+1,1);
r = LUT(X_RV+1,2);
else
% 16-QAM
U = 1920;
r_max = 2;
N_row = 4;
LUT = [1 0 0
0 0 0
1 1 1
0 1 1
1 0 1
1 0 2
1 0 3
1 1 0];
s = LUT(X_RV+1,1);
r = LUT(X_RV+1,2);
b = LUT(X_RV+1,3);
end
% virtual IR buffer should not be larger than input word
if ( N_IR > N_TTI )
N_IR = N_TTI;
end
% some more parameters
delta_N = N_IR - N_TTI;
N_sys = N_TTI/3;
% Figure out N_p1 and N_p2
N_p1 = floor( (N_IR - N_sys)/2 );
N_p2 = ceil( (N_IR - N_sys)/2 );
% more parameter
if (s==1)
N_t_sys = min( N_sys, N_data );
else
N_t_sys = max( N_data - (N_p1+N_p2), 0 );
end
N_t_p1 = floor( (N_data - N_t_sys)/2 );
N_t_p2 = ceil( (N_data-N_t_sys)/2 );
% loop over each turbo codeword
for codeword_index=1:number_codewords
% the channel streams just for this codeword
temp_channel_streams = channel_streams( (P*(codeword_index-1)+1):P*codeword_index, : );
% Deinterleave
if (modulation == 0) % QPSK
% Deinterleave each physical channel
for p_count=1:P
% write into matrix column-by-column
y_prime = reshape( temp_channel_streams( p_count, : ), R2, C2 );
% inter-column permutations
y(:,p_interleaver+1) = y_prime;
% read out matrix row-by-row
temp_channel_streams( p_count, : ) = reshape( y', 1, U );
end
else % QAM
% Each physical channel must be deinterleaved twice
for p_count=1:P
% split into two streams
w_prime = reshape( temp_channel_streams(p_count,:), 4, U/4 );
z(1,:) = reshape( w_prime(1:2,:), 1, U/2 );
z(2,:) = reshape( w_prime(3:4,:), 1, U/2 );
% deinterleave each substream
for substream=1:2
% write into matrix column-by-column
y_prime = reshape( z(substream,:), R2, C2 );
% inter-column permutations
y(:,p_interleaver+1) = y_prime;
% read out matrix row-by-row
z_prime( substream, : ) = reshape( y', 1, U/2 );
end
% Constellation re-arrangement
if (b==0)
w_prime(1:2,:) = reshape( z_prime(1,:), 2, U/4 );
w_prime(3:4,:) = reshape( z_prime(2,:), 2, U/4 );
elseif (b==1)
% swap MSB with LSB
w_prime(1:2,:) = reshape( z_prime(2,:), 2, U/4 );
w_prime(3:4,:) = reshape( z_prime(1,:), 2, U/4 );
elseif (b==2)
% Inversion of LSB
w_prime(1:2,:) = reshape( z_prime(1,:), 2, U/4 );
% w_prime(3:4,:) = not( reshape( z_prime(2,:), 2, U/4 ) );
w_prime(3:4,:) = -reshape( z_prime(2,:), 2, U/4 );
else
% swap then invert LSB
w_prime(1:2,:) = - reshape( z_prime(2,:), 2, U/4 );
% w_prime(3:4,:) = not( reshape( z_prime(1,:), 2, U/4 ) );
w_prime(3:4,:) = reshape( z_prime(1,:), 2, U/4 );
end
% reassemble
temp_channel_streams( p_count, : ) = reshape( w_prime, 1, U );
end
end
% Reverse the physical channel segmentation
w = reshape( temp_channel_streams', 1, N_data);
% Decollect the bits
[systematic_t, parity_1_t, parity_2_t] = BitDecollection( w, N_row, s, N_TTI, N_IR );
% Second Rate Dematching
% depuncture systematic stream
X_i = N_sys;
e_plus = N_sys;
e_minus = abs( N_sys - N_t_sys );
e_ini = mod( X_i - floor( r*e_plus/r_max ) - 1, e_plus)+1;
systematic = RateDematch( systematic_t, X_i, e_ini, e_plus, e_minus );
% depuncture first parity stream
X_i = N_p1;
e_plus = 2*N_p1;
e_minus = 2*abs( N_p1 - N_t_p1 );
e_ini = mod( X_i - floor( r*e_plus/r_max ) - 1, e_plus)+1;
parity_1 = RateDematch( parity_1_t, X_i, e_ini, e_plus, e_minus );
% depuncture second parity stream
X_i = N_p2;
e_plus = N_p2;
e_minus = abs( N_p2 - N_t_p2 );
e_ini = mod( X_i - floor( r*e_plus/r_max ) - 1, e_plus)+1;
parity_2 = RateDematch( parity_2_t, X_i, e_ini, e_plus, e_minus );
% First Rate Dematching
X_i = N_sys;
e_ini = X_i;
% The systematic stream is never punctured
streams(1,:) = systematic;
% only need first rate matching if IR buffer smaller than the encoder output
if ( N_IR < N_TTI )
% depuncture first parity stream
% Correction 6-21-2006
% e_plus = X_i;
% e_minus = abs( floor( delta_N/2 ) );
e_plus = 2*X_i;
e_minus = 2*abs( floor( delta_N/2 ) );
streams(2,:) = RateDematch( parity_1, X_i, e_ini, e_plus, e_minus );
% depuncture second parity stream
% Correction 6-21-2006
% e_plus = 2*X_i;
% e_minus = 2*abs( ceil( delta_N/2 ) );
e_plus = X_i;
e_minus = abs( ceil( delta_N/2 ) );
streams(3,:) = RateDematch( parity_2, X_i, e_ini, e_plus, e_minus );
else
streams(2,:) = parity_1;
streams(3,:) = parity_2;
end
% Bit Deseparation
code_bits( codeword_index, :) = reshape( streams, 1, 3*X_i );
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -