1+ function a_hat = DSCA_polar_decoder(e_tilde , crc_polynomial_pattern , crc_scrambling_pattern , crc_interleaver_pattern , info_bit_pattern , rate_matching_pattern , mode , L , min_sum , P2 )
2+ % DSCA_POLAR_DECODER Distributed-and-Scrambled-CRC-Aided (DSCA) polar decoder.
3+ % a_hat = DSCA_POLAR_DECODER(e_tilde, crc_polynomial_pattern, crc_interleaver_pattern, info_bit_pattern, rate_matching_pattern, mode, L, min_sum, P2)
4+ % decodes the encoded LLR sequence e_tilde, in order to obtain the
5+ % recovered information bit sequence a_hat.
6+ %
7+ % e_tilde should be a real row vector comprising E number of Logarithmic
8+ % Likelihood Ratios (LLRS), each having a value obtained as LLR =
9+ % ln(P(bit=0)/P(bit=1)).
10+ %
11+ % crc_polynomial_pattern should be a binary row vector comprising P+1
12+ % number of bits, each having the value 0 or 1. These bits parameterise a
13+ % Cyclic Redundancy Check (CRC) comprising P bits. Each bit provides the
14+ % coefficient of the corresponding element in the CRC generator
15+ % polynomial. From left to right, the bits provide the coefficients for
16+ % the elements D^P, D^P-1, D^P-2, ..., D^2, D, 1.
17+ %
18+ % crc_scrambling_pattern should be a binary row vector, with each element
19+ % having the value 0 or 1. This vector is right-aligned with the
20+ % vector of CRC bits (before CRC interleaving in the encoder), then
21+ % applied using XOR operations.
22+ %
23+ % crc_interleaver_pattern should be a row vector comprising K number of
24+ % integers, each having a unique value in the range 1 to K. Each integer
25+ % identifies which one of the K information or CRC bits provides the
26+ % corresponding bit in the input to the polar encoder kernal.
27+ %
28+ % info_bit_pattern should be a row vector comprising N number of logical
29+ % elements, each having the value true or false. The number of elements
30+ % in info_bit_pattern having the value true should be K, where K = A+P.
31+ % These elements having the value true identify the positions of the
32+ % information and CRC bits within the input to the polar encoder kernal.
33+ %
34+ % rate_matching_pattern should be a row vector comprising E number of
35+ % integers, each having a value in the range 1 to N. Each integer
36+ % identifies which one of the N outputs from the polar encoder kernal
37+ % provides the corresponding bit in the encoded bit sequence e.
38+ %
39+ % mode should have the value 'repetition', 'puncturing' or 'shortening'.
40+ % This specifies how the rate matching has been achieved. 'repetition'
41+ % indicates that some outputs of the polar encoder kernal are repeated in
42+ % the encoded bit sequence two or more times. 'puncturing' and
43+ % 'shortening' indicate that some outputs of the polar encoder kernal
44+ % have been excluded from the encoded bit sequence. In the case of
45+ % 'puncturing' these excluded bits could have values of 0 or 1. In the
46+ % case of 'shortening' these excluded bits are guaranteed to have values
47+ % of 0.
48+ %
49+ % L should be a scalar integer. It specifies the list size to use during
50+ % Successive Cancellation List (SCL) decoding.
51+ %
52+ % min_sum shoular be a scalar logical. If it is true, then the SCL
53+ % decoding process will be completed using the min-sum approximation.
54+ % Otherwise, the log-sum-product will be used. The log-sum-product gives
55+ % better error correction capability than the min-sum, but it has higher
56+ % complexity.
57+ %
58+ % P2 should be a scalar integer. Although the CRC has P bits, only
59+ % P-min(P2,log2(L)) of these are used for error detection. The remaining
60+ % min(P2,log2(L)) of the CRC bits are used to improve error correction.
61+ % So the CRC needs to be min(P2,log2(L)) number of bits longer than CRCs
62+ % used in other codes, in order to achieve the same error detection
63+ % capability.
64+ %
65+ % a_hat will normally be a binary row vector comprising A number of bits,
66+ % each having the value 0 or 1. However, in cases where the CRC check
67+ % fails, a_hat will be an empty vector.
68+ %
69+ % See also DSCA_POLAR_ENCODER
70+ %
71+ % Copyright © 2017 Robert G. Maunder. This program is free software: you
72+ % can redistribute it and/or modify it under the terms of the GNU General
73+ % Public License as published by the Free Software Foundation, either
74+ % version 3 of the License, or (at your option) any later version. This
75+ % program is distributed in the hope that it will be useful, but WITHOUT
76+ % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
77+ % FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
78+ % more details.
79+
80+ E = length(e_tilde );
81+ N = length(info_bit_pattern );
82+ K = length(crc_interleaver_pattern );
83+ P = length(crc_polynomial_pattern )-1 ;
84+ A = K - P ;
85+
86+ if log2(N ) ~= round(log2(N ))
87+ error(' N should be a power of 2' );
88+ end
89+ if sum(info_bit_pattern ) ~= K
90+ error(' info_bit_pattern should contain K number of ones.' );
91+ end
92+ if max(rate_matching_pattern ) > N
93+ error(' rate_matching_pattern is not compatible with N' );
94+ end
95+ if strcmp(mode ,' repetition' )
96+ if E < N
97+ error(' mode is not compatible with E' );
98+ end
99+ elseif strcmp(mode ,' puncturing' )
100+ if E >= N
101+ error(' mode is not compatible with E' );
102+ end
103+ elseif strcmp(mode ,' shortening' )
104+ if E >= N
105+ error(' mode is not compatible with E' );
106+ end
107+ else
108+ error(' Unsupported mode' );
109+ end
110+ if P < length(crc_scrambling_pattern )
111+ error(' polar_3gpp_matlab:UnsupportedBlockLength' ,' P should be no less than the length of the scrambing pattern' );
112+ end
113+
114+ % This global variable is used by the minstar and phi functions.
115+ global approx_minstar
116+ approx_minstar= min_sum ;
117+
118+ %% Characterise the interleaved CRC
119+
120+ % Get the CRC generator matrix, which has dimensions A by P.
121+ G_P = get_crc_generator_matrix(A ,crc_polynomial_pattern );
122+
123+ % Extende the CRC generator matrix by append an identity matrix to
124+ % represent the CRC bits, giving dimenstions K by P.
125+ G_P2 = [G_P ;eye(P )];
126+
127+ % Interleave the rows of the extended CRC generator matrix, according to
128+ % the CRC interleaver.
129+ G_P3 = G_P2(crc_interleaver_pattern ,: );
130+
131+ % Determine where the last 1-valued bit appears in each column. When the
132+ % SCL decoding process reaches the corresponding interleaved CRC bit, we
133+ % will terminate the decoding process if all list entries have failed the
134+ % checks assocated with at least one of this or the preceeding CRC bits.
135+ last_one_index = zeros(1 ,P );
136+ for p = 1 : P
137+ last_one_index(p ) = find(G_P3(: ,p ) == 1 , 1 , ' last' );
138+ end
139+
140+ % Extend the scrambling pattern to match the length of the CRC
141+ extended_crc_scrambling_pattern = [zeros(1 ,P - length(crc_scrambling_pattern )), crc_scrambling_pattern ];
142+
143+ %% Rate matching
144+ if strcmp(mode ,' repetition' )
145+ % LLRs for repeated bits are added together.
146+ d_tilde = zeros(1 ,N );
147+ for i= 1 : E
148+ d_tilde(rate_matching_pattern(i )) = d_tilde(rate_matching_pattern(i )) + e_tilde(i );
149+ end
150+ else
151+ if strcmp(mode ,' puncturing' )
152+ % Zero valued LLRs are used for punctured bits, because the decoder
153+ % doesn't know if they have values of 0 or 1.
154+ d_tilde = zeros(1 ,N );
155+ elseif strcmp(mode ,' shortening' )
156+ % Infinite valued LLRs are used for shortened bits, because the
157+ % decoder knows that they have values of 0.
158+ d_tilde = inf(1 ,N );
159+ else
160+ error(' Unknown rate matching mode' );
161+ end
162+
163+ d_tilde(rate_matching_pattern ) = e_tilde ;
164+ end
165+
166+ %% Perform the SCL polar decoder kernal operation.
167+ % This is achieved according to the algorithm described in
168+ % http://ieeexplore.ieee.org/abstract/document/7114328/
169+
170+ global bits % Matrix to store bit throughout the polar code graph
171+ global bits_updated % Matrix to identify which bits in the polar code graph have been calculated so far
172+ global llrs % Matrix to store LLRs throughout the polar code graph
173+ global llrs_updated % Matrix to identify which LLRs in the polar code graph have been calculated so far
174+
175+ bits = zeros(N , log2(N )+1 ); % Initialse all bits to zero. The left-most column corresponds to the decoded information, CRC and frozen bits
176+ bits_updated = [~info_bit_pattern ' ,false(N ,log2(N ))]; % The zero values that have initialised the frozen bits are known to be correct
177+ llrs = [zeros(N ,log2(N )),d_tilde ' ]; % Initialse the LLRs. The right-most column corresponds to the received LLRS
178+ llrs_updated = [false(N ,log2(N )),true(N ,1 )]; % The received LLRs have been updated.
179+
180+ PM = zeros(1 ,1 ,1 ); % Initialise the path metrics
181+ L_prime = 1 ; % Initialise the list size to 1. This will grow as the decoding proceeds
182+
183+ % We will calculate the CRC checksums alongside the SCL decoding process.
184+ crc_checksums = zeros(P ,1 );
185+ % We will keep track of whether any of the checks associated with the CRC
186+ % bits have failed.
187+ crc_okay = true ;
188+ % We need a counter to keep track of which information or CRC bit we are
189+ % working on.
190+ i2= 1 ;
191+ % We will return an empty vector if all list entries have failed the checks
192+ % assocated with at least one of the CRC bits.
193+ a_hat = [];
194+
195+ % Consider each bit in turn
196+ for i = 1 : N
197+ % Make recursive function calls to perform the XOR, g and f functions
198+ % necessary to obtain the corresponding LLR
199+ update_llr(i ,1 );
200+
201+ if info_bit_pattern(i ) == 0 % Frozen bit
202+ PM = phi(PM , llrs(i ,1 ,: ), 0 );
203+ else % Information or CRC bit
204+ % Double the list size, using 0-valued bits for the first half and 1-valued bits for the other half
205+ PM = cat(3 ,phi(PM , llrs(i ,1 ,: ), 0 ), phi(PM , llrs(i ,1 ,: ), 1 ));
206+ llrs = cat(3 ,llrs ,llrs );
207+ bits = cat(3 ,bits ,bits );
208+ bits(i ,1 ,1 : L_prime ) = 0 ;
209+ bits(i ,1 ,L_prime + 1 : 2 * L_prime ) = 1 ;
210+ bits_updated(i ,1 ) = true ;
211+
212+ % We use the interleaved CRC generator matrix to update the CRC
213+ % check sums whenever an information or CRC bit adopts a value of
214+ % 1.
215+ crc_checksums = cat(3 ,crc_checksums ,mod(crc_checksums + repmat(G_P3(i2 ,: )' ,[1 1 L_prime ]),2 ));
216+ % We need to keep track of whether any of the checks associated
217+ % with the previous CRC bits have failed.
218+ crc_okay = cat(3 ,crc_okay ,crc_okay );
219+
220+ % If the list size has grown above L, then we need to find and keep only the best L entries in the list
221+ L_prime = size(bits ,3 );
222+ if L_prime > L
223+ [~ ,max_indices ] = sort(PM ,3 );
224+ PM = PM(: ,: ,max_indices(1 : L ));
225+ bits = bits(: ,: ,max_indices(1 : L ));
226+ llrs = llrs(: ,: ,max_indices(1 : L ));
227+ crc_checksums = crc_checksums(: ,: ,max_indices(1 : L ));
228+ crc_okay = crc_okay(: ,: ,max_indices(1 : L ));
229+ L_prime = L ;
230+ end
231+
232+ % We check the corresponding CRC checksums whenever we reach the
233+ % last 1-valued bit in a column of the interleaved CRC generator
234+ % matrix.
235+ check_crc_bits = find(last_one_index == i2 );
236+ for crc_bit_index = 1 : length(check_crc_bits )
237+ for list_index = 1 : L_prime
238+ % The checksum should equal the value of the corresponding
239+ % CRC scrambling pattern bit. If not, then the CRC
240+ % check has failed. Note that we should not prune these
241+ % entries from the list, even though we know that they will
242+ % fail the CRC. We should continue the decoding of this
243+ % list entries, otherwise we will damage the error
244+ % detection capability of the CRC.
245+ if crc_checksums(check_crc_bits(crc_bit_index ),1 ,list_index ) ~= extended_crc_scrambling_pattern(check_crc_bits(crc_bit_index ))
246+ % We keep track of the failing check.
247+ crc_okay(1 ,1 ,list_index ) = false ;
248+ end
249+ end
250+ end
251+
252+ % We terminate the decoding process if all list entries have failed
253+ % the checks assocated with at least one of this or the preceeding
254+ % CRC bits.
255+ if ~any(crc_okay )
256+ return ;
257+ end
258+
259+ % Increment the counter of information and CRC bits
260+ i2 = i2 + 1 ;
261+ end
262+ end
263+
264+ %% Information bit extraction
265+
266+ % We use the list entry with a passing CRC that has the best metric. But we
267+ % only consider the best min(L,2^P2) entries in the list, to avoid
268+ % degrading the CRC's error detection capability.
269+ [~ ,max_indices ] = sort(PM ,3 );
270+ b_hat = zeros(1 ,K );
271+ for list_index = 1 : min(L ,2 ^ P2 )
272+ % Consider the next best list entry.
273+
274+ % We already checked the CRC during the SCL decoding process.
275+ if crc_okay(max_indices(list_index ))
276+ u_hat = bits(: ,1 ,max_indices(list_index ))' ;
277+
278+ % Extract the information bits from the output of the polar decoder
279+ % kernal.
280+ c_hat = u_hat(info_bit_pattern );
281+
282+ % Deinlterleave the information and CRC bits.
283+ b_hat(crc_interleaver_pattern ) = c_hat ;
284+
285+ % Remove the CRC and output the information bits.
286+ a_hat = b_hat(1 : end - P );
287+ return ;
288+ end
289+ end
290+ end
0 commit comments