Skip to content

Commit b95cabc

Browse files
committed
Added RNTI scrambling for PDCCH.
1 parent 29c5e08 commit b95cabc

4 files changed

Lines changed: 415 additions & 8 deletions

File tree

PDCCH_decoder.m

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
function a_hat = PDCCH_decoder(f_tilde, A, L, min_sum)
1+
function a_hat = PDCCH_decoder(f_tilde, A, L, min_sum, RNTI)
22
% PDCCH_DECODER Physical Downlink Control Channel (PDCCH) polar decoder from 3GPP New
33
% Radio, as specified in Section 7.3 of TS 38.212 v1.0.1...
44
% http://www.3gpp.org/ftp/TSG_RAN/WG1_RL1/TSGR1_AH/NR_AH_1709/Docs/R1-1716928.zip
@@ -23,6 +23,10 @@
2323
% better error correction capability than the min-sum, but it has higher
2424
% complexity.
2525
%
26+
% RNTI should be a binary row vector comprising 16 bits, each having the
27+
% value 0 or 1. If this parameter is omitted, then ones(1,16) will be
28+
% used for the RNTI.
29+
%
2630
% a_hat will be a binary row vector comprising A number of bits, each
2731
% having the value 0 or 1.
2832
%
@@ -39,6 +43,13 @@
3943

4044
addpath 'components'
4145

46+
if nargin == 4
47+
RNTI = ones(1,16);
48+
end
49+
if length(RNTI) ~= 16
50+
error('RNTI length should be 16');
51+
end
52+
4253
E = length(f_tilde);
4354

4455
% The CRC polynomial used in 3GPP PBCH and PDCCH channel is
@@ -72,7 +83,5 @@
7283
% Get the 3GPP information bit pattern.
7384
info_bit_pattern = get_3GPP_info_bit_pattern(K, Q_N, rate_matching_pattern, mode);
7485

75-
% NEED TO ADD RNTI SCRAMBLING
76-
7786
% Perform Distributed-CRC-Aided polar decoding.
78-
a_hat = DCA_polar_decoder(f_tilde,crc_polynomial_pattern,crc_interleaver_pattern,info_bit_pattern,rate_matching_pattern,mode,L,min_sum,P2);
87+
a_hat = DSCA_polar_decoder(f_tilde,crc_polynomial_pattern,RNTI,crc_interleaver_pattern,info_bit_pattern,rate_matching_pattern,mode,L,min_sum,P2);

PDCCH_encoder.m

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
function f = PDCCH_encoder(a, E)
1+
function f = PDCCH_encoder(a, E, RNTI)
22
% PDCCH_ENCODER Physical Downlink Control Channel (PDCCH) polar encoder from 3GPP New
33
% Radio, as specified in Section 7.3 of TS 38.212 v1.0.1...
44
% http://www.3gpp.org/ftp/TSG_RAN/WG1_RL1/TSGR1_AH/NR_AH_1709/Docs/R1-1716928.zip
@@ -11,6 +11,10 @@
1111
% E should be an integer scalar. It specifies the number of bits in the
1212
% encoded bit sequence, where E should greater than A.
1313
%
14+
% RNTI should be a binary row vector comprising 16 bits, each having the
15+
% value 0 or 1. If this parameter is omitted, then ones(1,16) will be
16+
% used for the RNTI.
17+
%
1418
% f will be a binary row vector comprising E number of bits, each having
1519
% the value 0 or 1.
1620
%
@@ -27,6 +31,14 @@
2731

2832
addpath 'components'
2933

34+
if nargin == 2
35+
RNTI = ones(1,16);
36+
end
37+
if length(RNTI) ~= 16
38+
error('RNTI length should be 16');
39+
end
40+
41+
3042
A = length(a);
3143

3244
% The CRC polynomial used in 3GPP PBCH and PDCCH channel is
@@ -53,7 +65,5 @@
5365
% Get the 3GPP information bit pattern.
5466
info_bit_pattern = get_3GPP_info_bit_pattern(K, Q_N, rate_matching_pattern, mode);
5567

56-
% NEED TO ADD RNTI SCRAMBLING
57-
5868
% Perform Distributed-CRC-Aided polar encoding.
59-
f = DCA_polar_encoder(a,crc_polynomial_pattern,crc_interleaver_pattern,info_bit_pattern,rate_matching_pattern);
69+
f = DSCA_polar_encoder(a,crc_polynomial_pattern, RNTI, crc_interleaver_pattern,info_bit_pattern,rate_matching_pattern);

components/DSCA_polar_decoder.m

Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
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

Comments
 (0)