Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
promise
OpenXG-RAN
Commits
5cf8d93a
Commit
5cf8d93a
authored
May 17, 2018
by
Guy De Souza
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
NR Polar imports
parent
313cab3d
Changes
29
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
4816 additions
and
0 deletions
+4816
-0
openair1/PHY/CODING/TESTBENCH/polartest.c
openair1/PHY/CODING/TESTBENCH/polartest.c
+194
-0
openair1/PHY/CODING/nrPolar_init.c
openair1/PHY/CODING/nrPolar_init.c
+54
-0
openair1/PHY/CODING/nrPolar_tools/.gitkeep
openair1/PHY/CODING/nrPolar_tools/.gitkeep
+0
-0
openair1/PHY/CODING/nrPolar_tools/get_3GPP_info_bit_pattern.c
...air1/PHY/CODING/nrPolar_tools/get_3GPP_info_bit_pattern.c
+200
-0
openair1/PHY/CODING/nrPolar_tools/get_PC_bit_pattern.c
openair1/PHY/CODING/nrPolar_tools/get_PC_bit_pattern.c
+259
-0
openair1/PHY/CODING/nrPolar_tools/get_crc_generator_matrix.c
openair1/PHY/CODING/nrPolar_tools/get_crc_generator_matrix.c
+79
-0
openair1/PHY/CODING/nrPolar_tools/main_pucch.c
openair1/PHY/CODING/nrPolar_tools/main_pucch.c
+39
-0
openair1/PHY/CODING/nrPolar_tools/nr_bitwise_operations.c
openair1/PHY/CODING/nrPolar_tools/nr_bitwise_operations.c
+16
-0
openair1/PHY/CODING/nrPolar_tools/nr_crc_byte.c
openair1/PHY/CODING/nrPolar_tools/nr_crc_byte.c
+374
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_bit_insertion.c
openair1/PHY/CODING/nrPolar_tools/nr_polar_bit_insertion.c
+31
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_bit_insertion_2.c
openair1/PHY/CODING/nrPolar_tools/nr_polar_bit_insertion_2.c
+63
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_channel_interleaver_pattern.c
...DING/nrPolar_tools/nr_polar_channel_interleaver_pattern.c
+42
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_crc.c
openair1/PHY/CODING/nrPolar_tools/nr_polar_crc.c
+46
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
+254
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c
openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c
+115
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
+112
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
+56
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_info_bit_pattern.c
...air1/PHY/CODING/nrPolar_tools/nr_polar_info_bit_pattern.c
+110
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_interleave.c
openair1/PHY/CODING/nrPolar_tools/nr_polar_interleave.c
+37
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_kernal_operation.c
...air1/PHY/CODING/nrPolar_tools/nr_polar_kernal_operation.c
+23
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_kronecker_power_matrices.c
.../CODING/nrPolar_tools/nr_polar_kronecker_power_matrices.c
+2064
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c
...air1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c
+160
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_output_length.c
openair1/PHY/CODING/nrPolar_tools/nr_polar_output_length.c
+25
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h
openair1/PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h
+42
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_plot.m
openair1/PHY/CODING/nrPolar_tools/nr_polar_plot.m
+0
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_pucch_defs.h
openair1/PHY/CODING/nrPolar_tools/nr_polar_pucch_defs.h
+28
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_rate_match.c
openair1/PHY/CODING/nrPolar_tools/nr_polar_rate_match.c
+64
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_sequence_pattern.c
...air1/PHY/CODING/nrPolar_tools/nr_polar_sequence_pattern.c
+19
-0
openair1/PHY/CODING/nrPolar_tools/nr_pucch_encoder.c
openair1/PHY/CODING/nrPolar_tools/nr_pucch_encoder.c
+310
-0
No files found.
openair1/PHY/CODING/TESTBENCH/polartest.c
0 → 100644
View file @
5cf8d93a
#include <math.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "SIMULATION/TOOLS/defs.h"
int
main
(
int
argc
,
char
*
argv
[])
{
//Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.)
time_stats_t
timeEncoder
,
timeDecoder
;
opp_enabled
=
1
;
cpu_freq_GHz
=
get_cpu_freq_GHz
();
reset_meas
(
&
timeEncoder
);
reset_meas
(
&
timeDecoder
);
randominit
(
0
);
//Default simulation values (Aim for iterations = 1000000.)
int
itr
,
iterations
=
1000
,
arguments
,
polarMessageType
=
1
;
//0=DCI, 1=PBCH, 2=UCI
double
SNRstart
=
-
20
.
0
,
SNRstop
=
20
.
0
,
SNRinc
=
0
.
5
;
//dB
double
SNR
,
SNR_lin
;
int16_t
nBitError
=
0
;
// -1 = Decoding failed (All list entries have failed the CRC checks).
int8_t
decoderState
=
0
,
blockErrorState
=
0
;
//0 = Success, -1 = Decoding failed, 1 = Block Error.
uint16_t
testLength
,
coderLength
,
blockErrorCumulative
=
0
,
bitErrorCumulative
=
0
;
double
timeEncoderCumulative
=
0
,
timeDecoderCumulative
=
0
;
uint8_t
decoderListSize
=
8
,
pathMetricAppr
=
0
;
//0 --> eq. (8a) and (11b), 1 --> eq. (9) and (12)
while
((
arguments
=
getopt
(
argc
,
argv
,
"s:d:f:m:i:l:a:"
))
!=
-
1
)
switch
(
arguments
)
{
case
's'
:
SNRstart
=
atof
(
optarg
);
printf
(
"SNRstart = %f
\n
"
,
SNRstart
);
break
;
case
'd'
:
SNRinc
=
atof
(
optarg
);
break
;
case
'f'
:
SNRstop
=
atof
(
optarg
);
break
;
case
'm'
:
polarMessageType
=
atoi
(
optarg
);
break
;
case
'i'
:
iterations
=
atoi
(
optarg
);
break
;
case
'l'
:
decoderListSize
=
(
uint8_t
)
atoi
(
optarg
);
break
;
case
'a'
:
pathMetricAppr
=
(
uint8_t
)
atoi
(
optarg
);
break
;
default:
perror
(
"[polartest.c] Problem at argument parsing with getopt"
);
abort
();
}
if
(
polarMessageType
==
0
)
{
//DCI
//testLength = ;
//coderLength = ;
}
else
if
(
polarMessageType
==
1
)
{
//PBCH
testLength
=
NR_POLAR_PBCH_PAYLOAD_BITS
;
coderLength
=
NR_POLAR_PBCH_E
;
}
else
if
(
polarMessageType
==
2
)
{
//UCI
//testLength = ;
//coderLength = ;
}
//Logging
time_t
currentTime
;
time
(
&
currentTime
);
char
fileName
[
512
],
currentTimeInfo
[
25
];
sprintf
(
fileName
,
"./polartestResults/_ListSize_%d_pmAppr_%d_Payload_%d_Itr_%d"
,
decoderListSize
,
pathMetricAppr
,
testLength
,
iterations
);
strftime
(
currentTimeInfo
,
25
,
"_%Y-%m-%d-%H-%M-%S.csv"
,
localtime
(
&
currentTime
));
strcat
(
fileName
,
currentTimeInfo
);
//Create "./polartestResults" folder if it doesn't already exist.
struct
stat
folder
=
{
0
};
if
(
stat
(
"./polartestResults"
,
&
folder
)
==
-
1
)
mkdir
(
"./polartestResults"
,
S_IRWXU
|
S_IRWXO
);
FILE
*
logFile
;
logFile
=
fopen
(
fileName
,
"w"
);
if
(
logFile
==
NULL
)
{
fprintf
(
stderr
,
"[polartest.c] Problem creating file %s with fopen
\n
"
,
fileName
);
exit
(
-
1
);
}
fprintf
(
logFile
,
",SNR,nBitError,blockErrorState,t_encoder[us],t_decoder[us]
\n
"
);
uint8_t
*
testInput
=
malloc
(
sizeof
(
uint8_t
)
*
testLength
);
//generate randomly
uint8_t
*
encoderOutput
=
malloc
(
sizeof
(
uint8_t
)
*
coderLength
);
double
*
modulatedInput
=
malloc
(
sizeof
(
double
)
*
coderLength
);
//channel input
double
*
channelOutput
=
malloc
(
sizeof
(
double
)
*
coderLength
);
//add noise
uint8_t
*
estimatedOutput
=
malloc
(
sizeof
(
uint8_t
)
*
testLength
);
//decoder output
t_nrPolar_params
nrPolar_params
;
nr_polar_init
(
&
nrPolar_params
,
polarMessageType
);
// We assume no a priori knowledge available about the payload.
double
aPrioriArray
[
nrPolar_params
.
payloadBits
];
for
(
int
i
=
0
;
i
<
nrPolar_params
.
payloadBits
;
i
++
)
aPrioriArray
[
i
]
=
NAN
;
for
(
SNR
=
SNRstart
;
SNR
<=
SNRstop
;
SNR
+=
SNRinc
)
{
SNR_lin
=
pow
(
10
,
SNR
/
10
);
for
(
itr
=
1
;
itr
<=
iterations
;
itr
++
)
{
for
(
int
i
=
0
;
i
<
testLength
;
i
++
)
testInput
[
i
]
=
(
uint8_t
)
(
rand
()
%
2
);
start_meas
(
&
timeEncoder
);
polar_encoder
(
testInput
,
encoderOutput
,
&
nrPolar_params
);
stop_meas
(
&
timeEncoder
);
//BPSK modulation
for
(
int
i
=
0
;
i
<
coderLength
;
i
++
)
{
if
(
encoderOutput
[
i
]
==
0
)
modulatedInput
[
i
]
=
1
/
sqrt
(
2
);
else
modulatedInput
[
i
]
=
(
-
1
)
/
sqrt
(
2
);
channelOutput
[
i
]
=
modulatedInput
[
i
]
+
(
gaussdouble
(
0
.
0
,
1
.
0
)
*
(
1
/
sqrt
(
2
*
SNR_lin
)));
}
start_meas
(
&
timeDecoder
);
decoderState
=
polar_decoder
(
channelOutput
,
estimatedOutput
,
&
nrPolar_params
,
decoderListSize
,
aPrioriArray
,
pathMetricAppr
);
stop_meas
(
&
timeDecoder
);
//calculate errors
if
(
decoderState
==-
1
)
{
blockErrorState
=-
1
;
nBitError
=-
1
;
}
else
{
for
(
int
i
=
0
;
i
<
testLength
;
i
++
){
if
(
estimatedOutput
[
i
]
!=
testInput
[
i
])
nBitError
++
;
}
if
(
nBitError
>
0
)
blockErrorState
=
1
;
}
//Iteration times are in microseconds.
timeEncoderCumulative
+=
(
timeEncoder
.
diff_now
/
(
cpu_freq_GHz
*
1000
.
0
));
timeDecoderCumulative
+=
(
timeDecoder
.
diff_now
/
(
cpu_freq_GHz
*
1000
.
0
));
fprintf
(
logFile
,
",%f,%d,%d,%f,%f
\n
"
,
SNR
,
nBitError
,
blockErrorState
,
(
timeEncoder
.
diff_now
/
(
cpu_freq_GHz
*
1000
.
0
)),
(
timeDecoder
.
diff_now
/
(
cpu_freq_GHz
*
1000
.
0
)));
if
(
nBitError
<
0
)
{
blockErrorCumulative
++
;
bitErrorCumulative
+=
testLength
;
}
else
{
blockErrorCumulative
+=
blockErrorState
;
bitErrorCumulative
+=
nBitError
;
}
decoderState
=
0
;
nBitError
=
0
;
blockErrorState
=
0
;
}
//Calculate error statistics for the SNR.
printf
(
"[ListSize=%d, Appr=%d] SNR=%+8.3f, BLER=%9.6f, BER=%12.9f, t_Encoder=%9.3fus, t_Decoder=%9.3fus
\n
"
,
decoderListSize
,
pathMetricAppr
,
SNR
,
((
double
)
blockErrorCumulative
/
iterations
),
((
double
)
bitErrorCumulative
/
(
iterations
*
testLength
)),
(
timeEncoderCumulative
/
iterations
),
timeDecoderCumulative
/
iterations
);
blockErrorCumulative
=
0
;
bitErrorCumulative
=
0
;
timeEncoderCumulative
=
0
;
timeDecoderCumulative
=
0
;
}
print_meas
(
&
timeEncoder
,
"polar_encoder"
,
NULL
,
NULL
);
print_meas
(
&
timeDecoder
,
"polar_decoder"
,
NULL
,
NULL
);
fclose
(
logFile
);
free
(
testInput
);
free
(
encoderOutput
);
free
(
modulatedInput
);
free
(
channelOutput
);
free
(
estimatedOutput
);
return
(
0
);
}
openair1/PHY/CODING/nrPolar_init.c
0 → 100644
View file @
5cf8d93a
#include "nrPolar_tools/nr_polar_defs.h"
#include "nrPolar_tools/nr_polar_pbch_defs.h"
void
nr_polar_init
(
t_nrPolar_params
*
polarParams
,
int
messageType
)
{
if
(
messageType
==
0
)
{
//DCI
}
else
if
(
messageType
==
1
)
{
//PBCH
polarParams
->
n_max
=
NR_POLAR_PBCH_N_MAX
;
polarParams
->
i_il
=
NR_POLAR_PBCH_I_IL
;
polarParams
->
n_pc
=
NR_POLAR_PBCH_N_PC
;
polarParams
->
n_pc_wm
=
NR_POLAR_PBCH_N_PC_WM
;
polarParams
->
i_bil
=
NR_POLAR_PBCH_I_BIL
;
polarParams
->
payloadBits
=
NR_POLAR_PBCH_PAYLOAD_BITS
;
polarParams
->
encoderLength
=
NR_POLAR_PBCH_E
;
polarParams
->
crcParityBits
=
NR_POLAR_PBCH_CRC_PARITY_BITS
;
polarParams
->
crcCorrectionBits
=
NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS
;
polarParams
->
K
=
polarParams
->
payloadBits
+
polarParams
->
crcParityBits
;
// Number of bits to encode.
polarParams
->
N
=
nr_polar_output_length
(
polarParams
->
K
,
polarParams
->
encoderLength
,
polarParams
->
n_max
);
polarParams
->
n
=
log2
(
polarParams
->
N
);
polarParams
->
crc_generator_matrix
=
crc24c_generator_matrix
(
polarParams
->
payloadBits
);
polarParams
->
G_N
=
nr_polar_kronecker_power_matrices
(
polarParams
->
n
);
}
else
if
(
messageType
==
2
)
{
//UCI
}
polarParams
->
Q_0_Nminus1
=
nr_polar_sequence_pattern
(
polarParams
->
n
);
polarParams
->
interleaving_pattern
=
(
uint16_t
*
)
malloc
(
sizeof
(
uint16_t
)
*
polarParams
->
K
);
nr_polar_interleaving_pattern
(
polarParams
->
K
,
polarParams
->
i_il
,
polarParams
->
interleaving_pattern
);
polarParams
->
rate_matching_pattern
=
(
uint16_t
*
)
malloc
(
sizeof
(
uint16_t
)
*
polarParams
->
encoderLength
);
uint16_t
*
J
=
malloc
(
sizeof
(
uint16_t
)
*
polarParams
->
N
);
nr_polar_rate_matching_pattern
(
polarParams
->
rate_matching_pattern
,
J
,
nr_polar_subblock_interleaver_pattern
,
polarParams
->
K
,
polarParams
->
N
,
polarParams
->
encoderLength
);
polarParams
->
information_bit_pattern
=
malloc
(
sizeof
(
uint8_t
)
*
polarParams
->
N
);
polarParams
->
Q_I_N
=
malloc
(
sizeof
(
int16_t
)
*
(
polarParams
->
K
+
polarParams
->
n_pc
));
polarParams
->
Q_F_N
=
malloc
(
sizeof
(
int16_t
)
*
(
polarParams
->
N
+
1
));
// Last element shows the final array index assigned a value.
polarParams
->
Q_PC_N
=
malloc
(
sizeof
(
int16_t
)
*
(
polarParams
->
n_pc
));
for
(
int
i
=
0
;
i
<=
polarParams
->
N
;
i
++
)
polarParams
->
Q_F_N
[
i
]
=
-
1
;
// Empty array.
nr_polar_info_bit_pattern
(
polarParams
->
information_bit_pattern
,
polarParams
->
Q_I_N
,
polarParams
->
Q_F_N
,
J
,
polarParams
->
Q_0_Nminus1
,
polarParams
->
K
,
polarParams
->
N
,
polarParams
->
encoderLength
,
polarParams
->
n_pc
);
polarParams
->
channel_interleaver_pattern
=
malloc
(
sizeof
(
uint16_t
)
*
polarParams
->
encoderLength
);
nr_polar_channel_interleaver_pattern
(
polarParams
->
channel_interleaver_pattern
,
polarParams
->
i_bil
,
polarParams
->
encoderLength
);
free
(
J
);
}
openair1/PHY/CODING/nrPolar_tools/.gitkeep
0 → 100644
View file @
5cf8d93a
openair1/PHY/CODING/nrPolar_tools/get_3GPP_info_bit_pattern.c
0 → 100644
View file @
5cf8d93a
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
void
get_3GPP_info_bit_pattern
(
uint16_t
K
,
uint16_t
n_PC
,
uint16_t
Q_N_length
,
uint8_t
E_r
,
uint8_t
*
P
,
uint16_t
*
Q_N
,
uint8_t
**
info_bit_pattern
)
{
// GET_3GPP_INFO_BIT_PATTERN Obtain the 3GPP information bit pattern,
// according to Section 5.4.1.1 of 3GPP TS 38.212
//
// I should be an integer scalar. It specifies the number of bits in the
// information, CRC and PC bit sequence. It should be no greater than N or E.
//
// Q_N should be a row vector comprising N number of unique integers in the
// range 1 to N. Each successive element of Q_N provides the index of the
// next most reliable input to the polar encoder kernal, where the first
// element of Q_N gives the index of the least reliable bit and the last
// element gives the index of the most reliable bit.
//
// rate_matching_pattern should be a vector comprising E_r number of
// integers, each having a value in the range 1 to N. Each integer
// identifies which one of the N outputs from the polar encoder kernal
// provides the corresponding bit in the encoded bit sequence e.
//
// mode should have the value 'repetition', 'puncturing' or 'shortening'.
// This specifies how the rate matching has been achieved. 'repetition'
// indicates that some outputs of the polar encoder kernal are repeated in
// the encoded bit sequence two or more times. 'puncturing' and
// 'shortening' indicate that some outputs of the polar encoder kernal
// have been excluded from the encoded bit sequence. In the case of
// 'puncturing' these excluded bits could have values of 0 or 1. In the
// case of 'shortening' these excluded bits are guaranteed to have values
// of 0.
//
// info_bit_pattern will be a vector comprising N number of logical
// elements, each having the value true or false. The number of elements
// in info_bit_pattern having the value true will be I. These elements
// having the value true identify the positions of the information and
// CRC bits within the input to the polar encoder kernal. The
// information bit arrangement can be achieved according to
// u(info_bit_pattern) = a.
int
I
=
K
+
n_PC
;
if
(
I
>
Q_N_length
)
//I=K+n_PC
{
fprintf
(
stderr
,
"I=K+n_PC should be no greater than N."
);
exit
(
-
1
);
}
if
(
I
>
E_r
)
{
fprintf
(
stderr
,
"I=K+n_PC should be no greater than E."
);
exit
(
-
1
);
}
//This is how the rate matching is described in TS 38.212
int
J
[
Q_N_length
];
int
i
,
j
;
for
(
j
=
0
;
j
<
Q_N_length
;
j
++
)
{
i
=
floor
(
32
*
(
double
)
j
/
Q_N_length
);
J
[
j
]
=
P
[
i
]
*
(
Q_N_length
/
32
)
+
(
j
%
(
Q_N_length
/
32
));
}
//Q_Ftmp_N = [];
int
Q_Ftmp_N_length
=
Q_N_length
-
E_r
;
if
(
E_r
<
Q_N_length
)
{
if
((
double
)(
I
)
/
E_r
<=
(
double
)
7
/
16
)
// puncturing
{
//Q_Ftmp_N_length = Q_Ftmp_N_length + N-E;
if
(
E_r
>=
(
double
)
3
*
Q_N_length
/
4
)
{
//Q_Ftmp_N = [Q_Ftmp_N,0:ceil(3*N/4-E/2)-1];
Q_Ftmp_N_length
=
Q_Ftmp_N_length
+
ceil
(
3
*
Q_N_length
/
4
-
(
double
)
E_r
/
2
);
}
else
{
//Q_Ftmp_N = [Q_Ftmp_N,0:ceil(9*N/16-E/4)-1];
Q_Ftmp_N_length
=
Q_Ftmp_N_length
+
ceil
(
9
*
Q_N_length
/
16
-
(
double
)
E_r
/
4
);
}
}
}
int
*
Q_Ftmp_N
=
(
int
*
)
malloc
(
sizeof
(
int
)
*
Q_Ftmp_N_length
);
if
(
Q_Ftmp_N
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
if
(
E_r
<
Q_N_length
)
{
if
((
double
)
I
/
E_r
<=
7
/
16
)
// puncturing
{
for
(
j
=
0
;
j
<
Q_N_length
-
E_r
;
j
++
)
{
Q_Ftmp_N
[
j
]
=
J
[
j
];
}
if
(
E_r
>=
3
*
Q_N_length
/
4
)
{
for
(
j
=
0
;
j
<
ceil
(
3
*
Q_N_length
/
4
-
(
double
)
E_r
/
2
);
j
++
)
{
Q_Ftmp_N
[
Q_N_length
-
E_r
+
1
+
j
]
=
j
;
}
}
else
{
for
(
j
=
0
;
j
<
ceil
(
9
*
Q_N_length
/
16
-
(
double
)
E_r
/
4
);
j
++
)
{
Q_Ftmp_N
[
Q_N_length
-
E_r
+
1
+
j
]
=
j
;
}
}
}
else
// shortening
{
for
(
j
=
E_r
;
j
<
Q_N_length
;
j
++
)
{
Q_Ftmp_N
[
j
-
E_r
]
=
J
[
j
];
}
}
}
//Q_Itmp_N = setdiff(Q_N-1,Q_Ftmp_N,'stable'); // -1 because TS 38.212 assumes that indices start at 0, not 1 like in Matlab
int
Q_Itmp_N_length
=
Q_N_length
;
int
Q_Itmp_N_common
[
Q_N_length
];
for
(
i
=
0
;
i
<
Q_N_length
;
i
++
)
{
Q_Itmp_N_common
[
i
]
=
0
;
//1 if in common, otherwise 0
for
(
j
=
0
;
j
<
Q_Ftmp_N_length
;
j
++
)
{
if
((
int
)
Q_N
[
i
]
==
Q_Ftmp_N
[
j
])
{
Q_Itmp_N_common
[
i
]
=
1
;
Q_Itmp_N_length
--
;
break
;
}
}
}
free
(
Q_Ftmp_N
);
if
(
Q_Itmp_N_length
<
I
)
{
fprintf
(
stderr
,
"Too many pre-frozen bits."
);
exit
(
-
1
);
}
int
*
Q_Itmp_N
=
(
int
*
)
malloc
(
sizeof
(
int
)
*
Q_Itmp_N_length
);
if
(
Q_Itmp_N
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
j
=
0
;
for
(
i
=
0
;
i
<
Q_N_length
;
i
++
)
{
if
(
!
Q_Itmp_N_common
[
i
])
//if not commonc
{
Q_Itmp_N
[
j
]
=
(
int
)
Q_N
[
i
];
j
++
;
}
}
int
*
Q_I_N
=
(
int
*
)
malloc
(
sizeof
(
int
)
*
(
I
));
if
(
Q_I_N
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
//Q_I_N=Q_Itmp_N(end-I+1:end);
for
(
j
=
Q_Itmp_N_length
-
(
I
);
j
<
Q_Itmp_N_length
;
j
++
)
{
Q_I_N
[
j
-
(
Q_Itmp_N_length
-
(
I
))]
=
Q_Itmp_N
[
j
];
}
free
(
Q_Itmp_N
);
//info_bit_pattern(Q_I_N+1) = true;
*
info_bit_pattern
=
(
uint8_t
*
)
malloc
(
sizeof
(
uint8_t
)
*
Q_N_length
);
if
(
*
info_bit_pattern
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
for
(
j
=
0
;
j
<
Q_N_length
;
j
++
)
{
(
*
info_bit_pattern
)[
j
]
=
0
;
for
(
i
=
0
;
i
<
I
;
i
++
)
{
if
(
Q_I_N
[
i
]
==
j
)
{
(
*
info_bit_pattern
)[
j
]
=
1
;
break
;
}
}
}
free
(
Q_I_N
);
}
openair1/PHY/CODING/nrPolar_tools/get_PC_bit_pattern.c
0 → 100644
View file @
5cf8d93a
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
void
get_PC_bit_pattern
(
uint16_t
Q_N_length
,
uint16_t
n_PC
,
uint8_t
n_PC_wm
,
uint16_t
*
Q_N
,
uint8_t
*
info_bit_pattern
,
uint8_t
**
PC_bit_pattern
)
{
// GET_PC_BIT_PATTERN Obtain the Parity Check (PC) bit pattern,
// according to Section 5.3.1.2 of 3GPP TS 38.212
//
// info_bit_pattern should be a vector comprising N number of logical
// elements, each having the value true or false. The number of elements
// in info_bit_pattern having the value true should be I, where
// I = A+P+n_PC. These elements having the value true identify the
// positions of the information, CRC and PC bits within the input to the
// polar encoder kernal.
//
// Q_N should be a row vector comprising N number of unique integers in the
// range 1 to N. Each successive element of Q_N provides the index of the
// next most reliable input to the polar encoder kernal, where the first
// element of Q_N gives the index of the least reliable bit and the last
// element gives the index of the most reliable bit.
//
// n_PC should be an integer scalar. It specifies the number of PC bits to
// use, where n_PC should be no greater than I.
//
// n_PC_wm should be an integer scalar. It specifies the number of PC bits
// that occupy some of the most reliable positions at the input to the
// polar encoder kernal. The remaining n_PC-n_PC_wm PC bits occupy some of
// the least reliable positions at the input to the polar encoder kernal.
// n_PC_wm should be no greater than n_PC.
//
// PC_bit_pattern will be a vector comprising N number of logical
// elements, each having the value true or false. The number of elements
// in PC_bit_pattern having the value true will be n_PC.
// These elements having the value true identify the positions of the
// PC bits within the input to the polar encoder kernal.
//N = length(info_bit_pattern); -> Q_N_length
//I = sum(info_bit_pattern);
int
totInfoBit
=
0
;
int
j
,
i
;
for
(
j
=
0
;
j
<
Q_N_length
;
j
++
)
{
if
(
info_bit_pattern
[
j
])
totInfoBit
++
;
}
if
(
n_PC
>
totInfoBit
)
{
fprintf
(
stderr
,
"n_PC should be no greater than totInfoBit."
);
exit
(
-
1
);
}
if
(
n_PC_wm
>
n_PC
)
{
fprintf
(
stderr
,
"n_PC_wm should be no greater than n_PC."
);
exit
(
-
1
);
}
//Q_I = 1:N;
int
*
Q_I
=
(
int
*
)
malloc
(
sizeof
(
int
)
*
Q_N_length
);
if
(
Q_I
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
for
(
j
=
0
;
j
<
Q_N_length
;
j
++
)
{
Q_I
[
j
]
=
j
+
1
;
}
//Q_N_I = intersect(Q_N, Q_I(info_bit_pattern), 'stable');
int
Q_N_I_length
=
0
;
int
*
Q_N_common
=
(
int
*
)
malloc
(
sizeof
(
int
)
*
Q_N_length
);
if
(
Q_N_common
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
for
(
j
=
0
;
j
<
Q_N_length
;
j
++
)
//init
{
Q_N_common
[
j
]
=
0
;
}
for
(
j
=
0
;
j
<
Q_N_length
;
j
++
)
//look in Q_I
{
if
(
info_bit_pattern
[
j
])
{
//Q_I(info_bit_pattern)
for
(
i
=
0
;
i
<
Q_N_length
;
i
++
)
//look in Q_N
{
if
(
Q_N
[
i
]
+
1
==
Q_I
[
j
])
{
Q_N_common
[
i
]
=
1
;
Q_N_I_length
++
;
break
;
}
}
}
}
free
(
Q_I
);
int
*
Q_N_I
=
(
int
*
)
malloc
(
sizeof
(
int
)
*
Q_N_I_length
);
if
(
Q_N_I
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
i
=
0
;
for
(
j
=
0
;
j
<
Q_N_length
;
j
++
)
{
if
(
Q_N_common
[
j
])
{
Q_N_I
[
i
]
=
Q_N
[
j
]
+
1
;
i
++
;
}
}
free
(
Q_N_common
);
//int G_N = get_G_N(N);
//int w_g = sum(G_N,2);
//useless, I do this
int
*
w_g
=
(
int
*
)
malloc
(
sizeof
(
int
)
*
Q_N_length
);
if
(
w_g
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
w_g
[
0
]
=
1
;
w_g
[
1
]
=
2
;
int
counter
=
2
;
int
n
=
log2
(
Q_N_length
);
for
(
i
=
0
;
i
<
n
-
1
;
i
++
)
//n=log2(N)
{
for
(
j
=
0
;
j
<
counter
;
j
++
)
{
w_g
[
counter
+
j
]
=
w_g
[
j
]
*
2
;
}
counter
=
counter
*
2
;
}
//Q_tilde_N_I = Q_N_I(n_PC+1:end); % This is what it says in TS 38.212
int
*
Q_tilde_N_I
=
(
int
*
)
malloc
(
sizeof
(
int
)
*
(
Q_N_I_length
-
n_PC
));
if
(
Q_tilde_N_I
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
int
*
Q_tilde_N_I_flip
=
(
int
*
)
malloc
(
sizeof
(
int
)
*
(
Q_N_I_length
-
n_PC
));
if
(
Q_tilde_N_I_flip
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
for
(
i
=
0
;
i
<
Q_N_I_length
-
n_PC
;
i
++
)
{
Q_tilde_N_I
[
i
]
=
Q_N_I
[
n_PC
+
i
];
//Q_tilde_N_I_flip = fliplr(Q_tilde_N_I);
Q_tilde_N_I_flip
[
Q_N_I_length
-
n_PC
-
i
-
1
]
=
Q_tilde_N_I
[
i
];
}
//%Q_tilde_N_I = Q_N_I(n_PC-n_PC_wm+1:end); % I think that this would be slightly more elegant
//[w_g_sorted, indices] = sort(w_g(Q_tilde_N_I_flip));
int
*
w_g_sorted
=
(
int
*
)
malloc
(
sizeof
(
int
)
*
(
Q_N_I_length
-
n_PC
));
if
(
w_g_sorted
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
int
*
indices
=
(
int
*
)
malloc
(
sizeof
(
int
)
*
(
Q_N_I_length
-
n_PC
));
if
(
indices
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
for
(
i
=
0
;
i
<
Q_N_I_length
-
n_PC
;
i
++
)
{
w_g_sorted
[
i
]
=
w_g
[
Q_tilde_N_I_flip
[
i
]
-
1
];
// w_g(Q_tilde_N_I_flip), yet to sort
indices
[
i
]
=
i
;
}
free
(
Q_tilde_N_I
);
free
(
w_g
);
//bubble sort
int
tempToSwap
=
0
;
for
(
i
=
0
;
i
<
(
Q_N_I_length
-
n_PC
)
-
1
;
i
++
)
{
for
(
j
=
0
;
j
<
(
Q_N_I_length
-
n_PC
)
-
i
-
1
;
j
++
)
{
if
(
w_g_sorted
[
j
]
>
w_g_sorted
[
j
+
1
])
//then swap
{
tempToSwap
=
w_g_sorted
[
j
];
w_g_sorted
[
j
]
=
w_g_sorted
[
j
+
1
];
w_g_sorted
[
j
+
1
]
=
tempToSwap
;
tempToSwap
=
indices
[
j
];
indices
[
j
]
=
indices
[
j
+
1
];
indices
[
j
+
1
]
=
tempToSwap
;
}
}
}
free
(
w_g_sorted
);
//Q_N_PC = [Q_N_I(1:n_PC-n_PC_wm), Q_tilde_N_I_flip(indices(1:n_PC_wm))];
int
*
Q_N_PC
=
(
int
*
)
malloc
(
sizeof
(
int
)
*
(
n_PC
));
if
(
Q_N_PC
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
for
(
i
=
0
;
i
<
n_PC
-
n_PC_wm
;
i
++
)
{
Q_N_PC
[
i
]
=
Q_N_I
[
i
];
//Q_N_PC = [Q_N_I(1:n_PC-n_PC_wm), ...
}
free
(
Q_N_I
);
for
(
i
=
0
;
i
<
n_PC_wm
;
i
++
)
{
Q_N_PC
[
n_PC
-
n_PC_wm
+
i
]
=
Q_tilde_N_I_flip
[
indices
[
i
]];
//... Q_tilde_N_I_flip(indices(1:n_PC_wm))];
}
free
(
Q_tilde_N_I_flip
);
free
(
indices
);
//PC_bit_pattern = false(1,N);
//PC_bit_pattern(Q_N_PC) = true;
*
PC_bit_pattern
=
(
uint8_t
*
)
malloc
(
sizeof
(
uint8_t
)
*
(
Q_N_length
));
if
(
*
PC_bit_pattern
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
for
(
i
=
0
;
i
<
Q_N_length
;
i
++
)
{
(
*
PC_bit_pattern
)[
i
]
=
0
;
for
(
j
=
0
;
j
<
n_PC
;
j
++
)
{
if
(
Q_N_PC
[
j
]
-
1
==
i
)
{
(
*
PC_bit_pattern
)[
i
]
=
1
;
break
;
}
}
}
//free(Q_I);
//free(Q_N_common);
//free(Q_N_I);
//free(w_g);
//free(Q_tilde_N_I);
//free(Q_tilde_N_I_flip);
//free(w_g_sorted);
//free(indices);
free
(
Q_N_PC
);
}
openair1/PHY/CODING/nrPolar_tools/get_crc_generator_matrix.c
0 → 100644
View file @
5cf8d93a
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
void
get_crc_generator_matrix
(
uint8_t
A
,
uint8_t
P
,
uint8_t
*
crc_polynomial_pattern
,
uint8_t
***
G_P
)
{
// GET_CRC_GENERATOR_MATRIX Obtain a Cyclic Redudancy Check (CRC) generator
// matrix.
//
// A should be an integer scalar. It specifies the number of bits in the
// information bit sequence.
//
// crc_polynomial_pattern should be a binary row vector comprising P+1
// number of bits, each having the value 0 or 1. These bits parameterise a
// Cyclic Redundancy Check (CRC) comprising P bits. Each bit provides the
// coefficient of the corresponding element in the CRC generator
// polynomial. From left to right, the bits provide the coefficients for
// the elements D^P, D^P-1, D^P-2, ..., D^2, D, 1.
//
// G_P will be a K by P binary matrix. The CRC bits can be generated
// according to mod(a*G_P,2).
*
G_P
=
(
uint8_t
**
)
malloc
(
A
*
sizeof
(
uint8_t
*
));
if
(
*
G_P
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
int
i
,
j
;
for
(
i
=
0
;
i
<
A
;
i
++
)
{
(
*
G_P
)[
i
]
=
(
uint8_t
*
)
malloc
(
P
*
sizeof
(
uint8_t
));
if
((
*
G_P
)[
i
]
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
}
if
(
A
>
0
)
{
//G_P(end,:) = crc_polynomial_pattern(2:end);
for
(
i
=
0
;
i
<
P
;
i
++
)
{
(
*
G_P
)[
A
-
1
][
i
]
=
crc_polynomial_pattern
[
i
+
1
];
}
//for k = A-1:-1:1
// G_P(k,:) = xor([G_P(k+1,2:end),0],G_P(k+1,1)*crc_polynomial_pattern(2:end));
//end
for
(
j
=
A
-
2
;
j
>-
1
;
j
--
)
{
for
(
i
=
0
;
i
<
P
;
i
++
)
{
(
*
G_P
)[
j
][
i
]
=
0
;
//init with zeros
}
for
(
i
=
1
;
i
<
P
;
i
++
)
{
if
(
(
*
G_P
)[
j
+
1
][
i
]
!=
(
(
*
G_P
)[
j
+
1
][
0
])
*
crc_polynomial_pattern
[
i
])
//xor
(
*
G_P
)[
j
][
i
-
1
]
=
1
;
}
if
(
0
!=
(
(
*
G_P
)[
j
+
1
][
0
])
*
crc_polynomial_pattern
[
P
])
//xor
(
*
G_P
)[
j
][
P
-
1
]
=
1
;
}
}
printf
(
"G_P=
\n
"
);
for
(
i
=
0
;
i
<
A
;
i
++
)
{
for
(
j
=
0
;
j
<
P
;
j
++
)
{
printf
(
"%i "
,
(
int
)(
*
G_P
)[
i
][
j
]);
}
printf
(
"
\n
"
);
}
}
openair1/PHY/CODING/nrPolar_tools/main_pucch.c
0 → 100644
View file @
5cf8d93a
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "nr_polar_defs.h"
#include "nr_polar_pucch_defs.h"
void
PUCCH_encoder
(
uint8_t
a
[],
uint8_t
A
,
uint8_t
G
,
uint16_t
*
E_r
,
uint8_t
**
f
);
int
main
()
{
uint16_t
E_r
;
uint8_t
*
f
;
uint8_t
A
=
32
;
//16, 32, 64, 128, 256, 512, 1024 Payload length
uint8_t
G
=
54
;
//, 108, 216, 432, 864, 1728, 3456, 6912, 13824}; encoded block length
uint8_t
j
;
uint8_t
*
a
=
(
uint8_t
*
)
malloc
(
sizeof
(
uint8_t
)
*
A
);
if
(
a
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
printf
(
"DEBUG: Send "
);
for
(
j
=
0
;
j
<
A
;
j
++
)
//create the message to encode
{
//a[j]=rand()%2;
a
[
j
]
=
1
;
// ONLY ONES FOR TEST, otherwise random
printf
(
"%i"
,
a
[
j
]);
}
printf
(
"
\n
"
);
PUCCH_encoder
(
a
,
A
,
G
,
&
E_r
,
&
f
);
return
0
;
}
openair1/PHY/CODING/nrPolar_tools/nr_bitwise_operations.c
0 → 100644
View file @
5cf8d93a
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void
nr_byte2bit
(
uint8_t
*
array
,
uint8_t
arraySize
,
uint8_t
*
bitArray
){
//First 2 parameters are in bytes.
for
(
int
i
=
0
;
i
<
arraySize
;
i
++
){
bitArray
[(
7
+
(
i
*
8
))]
=
(
array
[
i
]
>>
0
&
0x01
);
bitArray
[(
6
+
(
i
*
8
))]
=
(
array
[
i
]
>>
1
&
0x01
);
bitArray
[(
5
+
(
i
*
8
))]
=
(
array
[
i
]
>>
2
&
0x01
);
bitArray
[(
4
+
(
i
*
8
))]
=
(
array
[
i
]
>>
3
&
0x01
);
bitArray
[(
3
+
(
i
*
8
))]
=
(
array
[
i
]
>>
4
&
0x01
);
bitArray
[(
2
+
(
i
*
8
))]
=
(
array
[
i
]
>>
5
&
0x01
);
bitArray
[(
1
+
(
i
*
8
))]
=
(
array
[
i
]
>>
6
&
0x01
);
bitArray
[
(
i
*
8
)
]
=
(
array
[
i
]
>>
7
&
0x01
);
}
}
openair1/PHY/CODING/nrPolar_tools/nr_crc_byte.c
0 → 100644
View file @
5cf8d93a
This diff is collapsed.
Click to expand it.
openair1/PHY/CODING/nrPolar_tools/nr_polar_bit_insertion.c
0 → 100644
View file @
5cf8d93a
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void
nr_polar_bit_insertion
(
uint8_t
*
input
,
uint8_t
*
output
,
uint16_t
N
,
uint16_t
K
,
uint16_t
*
Q_I_N
,
uint16_t
*
Q_PC_N
,
uint8_t
n_PC
){
uint16_t
k
=
0
;
uint8_t
flag
;
if
(
n_PC
>
0
)
{
/*
*
*/
}
else
{
for
(
int
n
=
0
;
n
<=
N
-
1
;
n
++
)
{
flag
=
0
;
for
(
int
m
=
0
;
m
<=
(
K
+
n_PC
)
-
1
;
m
++
)
{
if
(
n
==
Q_I_N
[
m
])
{
flag
=
1
;
break
;
}
}
if
(
flag
)
{
// n ϵ Q_I_N
output
[
n
]
=
input
[
k
];
k
++
;
}
else
{
output
[
n
]
=
0
;
}
}
}
}
openair1/PHY/CODING/nrPolar_tools/nr_polar_bit_insertion_2.c
0 → 100644
View file @
5cf8d93a
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
void
nr_polar_bit_insertion_2
(
uint8_t
*
u
,
uint8_t
*
b
,
uint8_t
*
info_bit_pattern
,
uint8_t
*
PC_bit_pattern
,
uint16_t
N
)
{
int
PC_circular_buffer_length
=
5
;
int
i
,
j
;
int
k
=
0
;
int
*
y
=
(
int
*
)
malloc
(
sizeof
(
int
)
*
PC_circular_buffer_length
);
if
(
y
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
for
(
i
=
0
;
i
<
PC_circular_buffer_length
;
i
++
)
{
y
[
i
]
=
0
;
}
int
tempToShift
;
//for n=0:N-1
printf
(
"u = "
);
for
(
i
=
0
;
i
<
N
;
i
++
)
{
//y = [y(2:end),y(1)];
tempToShift
=
y
[
0
];
for
(
j
=
0
;
j
<
PC_circular_buffer_length
-
1
;
j
++
)
{
y
[
j
]
=
y
[
j
+
1
];
}
y
[
PC_circular_buffer_length
-
1
]
=
tempToShift
;
//if info_bit_pattern(n+1)
// if PC_bit_pattern(n+1)
// u(n+1) = y(1);
// else
// u(n+1) = b(k+1);
// k=k+1;
// y(1) = xor(y(1),u(n+1));
if
(
info_bit_pattern
[
i
])
{
if
(
PC_bit_pattern
[
i
])
{
u
[
i
]
=
y
[
1
];
}
else
{
u
[
i
]
=
b
[
k
];
k
++
;
y
[
1
]
=
(
y
[
1
]
!=
u
[
i
]);
}
}
else
{
u
[
i
]
=
0
;
}
printf
(
"%i "
,
u
[
i
]);
}
free
(
y
);
}
openair1/PHY/CODING/nrPolar_tools/nr_polar_channel_interleaver_pattern.c
0 → 100644
View file @
5cf8d93a
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void
nr_polar_channel_interleaver_pattern
(
uint16_t
*
cip
,
uint8_t
I_BIL
,
uint16_t
E
){
if
(
I_BIL
==
1
)
{
uint16_t
T
=
0
,
k
;
while
(
((
T
/
2
)
*
(
T
+
1
))
<
E
)
T
++
;
int16_t
**
v
=
malloc
(
T
*
sizeof
(
*
v
));
for
(
int
i
=
0
;
i
<=
T
-
1
;
i
++
)
v
[
i
]
=
malloc
((
T
-
i
)
*
sizeof
(
*
(
v
[
i
])));
k
=
0
;
for
(
int
i
=
0
;
i
<=
T
-
1
;
i
++
)
{
for
(
int
j
=
0
;
j
<=
(
T
-
1
)
-
i
;
j
++
)
{
if
(
k
<
E
)
{
v
[
i
][
j
]
=
k
;
}
else
{
v
[
i
][
j
]
=
(
-
1
);
}
k
++
;
}
}
k
=
0
;
for
(
int
j
=
0
;
j
<=
T
-
1
;
j
++
)
{
for
(
int
i
=
0
;
i
<=
(
T
-
1
)
-
j
;
i
++
)
{
if
(
v
[
i
][
j
]
!=
(
-
1
)
)
{
cip
[
k
]
=
v
[
i
][
j
];
k
++
;
}
}
}
for
(
int
i
=
0
;
i
<=
T
-
1
;
i
++
)
free
(
v
[
i
]);
free
(
v
);
}
else
{
for
(
int
i
=
0
;
i
<=
E
-
1
;
i
++
)
cip
[
i
]
=
i
;
}
}
openair1/PHY/CODING/nrPolar_tools/nr_polar_crc.c
0 → 100644
View file @
5cf8d93a
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
void
nr_polar_crc
(
uint8_t
*
a
,
uint8_t
A
,
uint8_t
P
,
uint8_t
**
G_P
,
uint8_t
**
b
)
{
int
i
,
j
;
int
*
temp_b
=
(
int
*
)
malloc
(
sizeof
(
int
)
*
P
);
if
(
temp_b
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
printf
(
"temp = "
);
for
(
i
=
0
;
i
<
P
;
i
++
)
{
temp_b
[
i
]
=
0
;
for
(
j
=
0
;
j
<
A
;
j
++
)
{
temp_b
[
i
]
=
temp_b
[
i
]
+
a
[
j
]
*
G_P
[
j
][
i
];
}
temp_b
[
i
]
=
temp_b
[
i
]
%
2
;
printf
(
"%i "
,
temp_b
[
i
]);
}
*
b
=
(
uint8_t
*
)
malloc
(
sizeof
(
uint8_t
)
*
(
A
+
P
));
if
(
*
b
==
NULL
)
{
fprintf
(
stderr
,
"malloc failed
\n
"
);
exit
(
-
1
);
}
printf
(
"
\n
b = "
);
for
(
i
=
0
;
i
<
A
;
i
++
)
{
(
*
b
)[
i
]
=
a
[
i
];
printf
(
"%i"
,
(
*
b
)[
i
]);
}
for
(
i
=
A
;
i
<
A
+
P
;
i
++
)
{
(
*
b
)[
i
]
=
temp_b
[
i
-
A
];
printf
(
"%i"
,
(
*
b
)[
i
]);
}
free
(
temp_b
);
}
openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
0 → 100644
View file @
5cf8d93a
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
/*
* Return values:
* 0 --> Success
* -1 --> All list entries have failed the CRC checks
*/
int8_t
polar_decoder
(
double
*
input
,
uint8_t
*
output
,
t_nrPolar_params
*
polarParams
,
uint8_t
listSize
,
double
*
aPrioriPayload
,
uint8_t
pathMetricAppr
){
uint8_t
***
bit
=
nr_alloc_uint8_t_3D_array
(
polarParams
->
N
,
(
polarParams
->
n
+
1
),
2
*
listSize
);
uint8_t
**
bitUpdated
=
nr_alloc_uint8_t_2D_array
(
polarParams
->
N
,
(
polarParams
->
n
+
1
));
//0=False, 1=True
uint8_t
**
llrUpdated
=
nr_alloc_uint8_t_2D_array
(
polarParams
->
N
,
(
polarParams
->
n
+
1
));
//0=False, 1=True
double
***
llr
=
nr_alloc_double_3D_array
(
polarParams
->
N
,
(
polarParams
->
n
+
1
),
2
*
listSize
);
uint8_t
**
crcChecksum
=
nr_alloc_uint8_t_2D_array
(
polarParams
->
crcParityBits
,
2
*
listSize
);
double
*
pathMetric
=
malloc
(
sizeof
(
double
)
*
(
2
*
listSize
));
uint8_t
*
crcState
=
malloc
(
sizeof
(
uint8_t
)
*
(
2
*
listSize
));
//0=False, 1=True
for
(
int
i
=
0
;
i
<
(
2
*
listSize
);
i
++
)
{
pathMetric
[
i
]
=
0
;
crcState
[
i
]
=
1
;
}
for
(
int
i
=
0
;
i
<
polarParams
->
N
;
i
++
)
{
llrUpdated
[
i
][
polarParams
->
n
]
=
1
;
bitUpdated
[
i
][
0
]
=
((
polarParams
->
information_bit_pattern
[
i
]
+
1
)
%
2
);
}
uint8_t
**
crc_generator_matrix
=
crc24c_generator_matrix
(
polarParams
->
payloadBits
);
//G_P
uint8_t
**
extended_crc_generator_matrix
=
malloc
(
polarParams
->
K
*
sizeof
(
uint8_t
*
));
//G_P3
uint8_t
**
tempECGM
=
malloc
(
polarParams
->
K
*
sizeof
(
uint8_t
*
));
//G_P2
for
(
int
i
=
0
;
i
<
polarParams
->
K
;
i
++
){
extended_crc_generator_matrix
[
i
]
=
malloc
(
polarParams
->
crcParityBits
*
sizeof
(
uint8_t
));
tempECGM
[
i
]
=
malloc
(
polarParams
->
crcParityBits
*
sizeof
(
uint8_t
));
}
for
(
int
i
=
0
;
i
<
polarParams
->
payloadBits
;
i
++
)
{
for
(
int
j
=
0
;
j
<
polarParams
->
crcParityBits
;
j
++
)
{
tempECGM
[
i
][
j
]
=
crc_generator_matrix
[
i
][
j
];
}
}
for
(
int
i
=
polarParams
->
payloadBits
;
i
<
polarParams
->
K
;
i
++
)
{
for
(
int
j
=
0
;
j
<
polarParams
->
crcParityBits
;
j
++
)
{
if
(
(
i
-
polarParams
->
payloadBits
)
==
j
){
tempECGM
[
i
][
j
]
=
1
;
}
else
{
tempECGM
[
i
][
j
]
=
0
;
}
}
}
for
(
int
i
=
0
;
i
<
polarParams
->
K
;
i
++
)
{
for
(
int
j
=
0
;
j
<
polarParams
->
crcParityBits
;
j
++
)
{
extended_crc_generator_matrix
[
i
][
j
]
=
tempECGM
[
polarParams
->
interleaving_pattern
[
i
]][
j
];
}
}
//The index of the last 1-valued bit that appears in each column.
uint16_t
last1ind
[
polarParams
->
crcParityBits
];
for
(
int
j
=
0
;
j
<
polarParams
->
crcParityBits
;
j
++
)
{
for
(
int
i
=
0
;
i
<
polarParams
->
K
;
i
++
)
{
if
(
extended_crc_generator_matrix
[
i
][
j
]
==
1
)
last1ind
[
j
]
=
i
;
}
}
double
*
d_tilde
=
malloc
(
sizeof
(
double
)
*
polarParams
->
N
);
nr_polar_rate_matching
(
input
,
d_tilde
,
polarParams
->
rate_matching_pattern
,
polarParams
->
K
,
polarParams
->
N
,
polarParams
->
encoderLength
);
for
(
int
j
=
0
;
j
<
polarParams
->
N
;
j
++
)
llr
[
j
][
polarParams
->
n
][
0
]
=
d_tilde
[
j
];
/*
* SCL polar decoder.
*/
uint32_t
nonFrozenBit
=
0
;
uint8_t
currentListSize
=
1
;
uint8_t
decoderIterationCheck
=
0
;
int16_t
checkCrcBits
=-
1
;
uint8_t
listIndex
[
2
*
listSize
],
copyIndex
;
for
(
uint16_t
currentBit
=
0
;
currentBit
<
polarParams
->
N
;
currentBit
++
){
updateLLR
(
llr
,
llrUpdated
,
bit
,
bitUpdated
,
currentListSize
,
currentBit
,
0
,
polarParams
->
N
,
(
polarParams
->
n
+
1
),
pathMetricAppr
);
if
(
polarParams
->
information_bit_pattern
[
currentBit
]
==
0
)
{
//Frozen bit.
updatePathMetric
(
pathMetric
,
llr
,
currentListSize
,
0
,
currentBit
,
pathMetricAppr
);
//approximation=0 --> 11b, approximation=1 --> 12
}
else
{
//Information or CRC bit.
if
(
(
polarParams
->
interleaving_pattern
[
nonFrozenBit
]
<=
polarParams
->
payloadBits
)
&&
(
aPrioriPayload
[
polarParams
->
interleaving_pattern
[
nonFrozenBit
]]
==
0
)
)
{
//Information bit with known value of "0".
updatePathMetric
(
pathMetric
,
llr
,
currentListSize
,
0
,
currentBit
,
pathMetricAppr
);
bitUpdated
[
currentBit
][
0
]
=
1
;
//0=False, 1=True
}
else
if
(
(
polarParams
->
interleaving_pattern
[
nonFrozenBit
]
<=
polarParams
->
payloadBits
)
&&
(
aPrioriPayload
[
polarParams
->
interleaving_pattern
[
nonFrozenBit
]]
==
1
)
)
{
//Information bit with known value of "1".
updatePathMetric
(
pathMetric
,
llr
,
currentListSize
,
1
,
currentBit
,
pathMetricAppr
);
for
(
uint8_t
i
=
0
;
i
<
currentListSize
;
i
++
)
bit
[
currentBit
][
0
][
i
]
=
1
;
bitUpdated
[
currentBit
][
0
]
=
1
;
updateCrcChecksum
(
crcChecksum
,
extended_crc_generator_matrix
,
currentListSize
,
nonFrozenBit
,
polarParams
->
crcParityBits
);
}
else
{
updatePathMetric2
(
pathMetric
,
llr
,
currentListSize
,
currentBit
,
pathMetricAppr
);
for
(
int
i
=
0
;
i
<
currentListSize
;
i
++
)
{
for
(
int
j
=
0
;
j
<
polarParams
->
N
;
j
++
)
{
for
(
int
k
=
0
;
k
<
(
polarParams
->
n
+
1
);
k
++
)
{
bit
[
j
][
k
][
i
+
currentListSize
]
=
bit
[
j
][
k
][
i
];
llr
[
j
][
k
][
i
+
currentListSize
]
=
llr
[
j
][
k
][
i
];}}}
for
(
int
i
=
0
;
i
<
currentListSize
;
i
++
)
{
bit
[
currentBit
][
0
][
i
]
=
0
;
crcState
[
i
+
currentListSize
]
=
crcState
[
i
];
}
for
(
int
i
=
currentListSize
;
i
<
2
*
currentListSize
;
i
++
)
bit
[
currentBit
][
0
][
i
]
=
1
;
bitUpdated
[
currentBit
][
0
]
=
1
;
updateCrcChecksum2
(
crcChecksum
,
extended_crc_generator_matrix
,
currentListSize
,
nonFrozenBit
,
polarParams
->
crcParityBits
);
currentListSize
*=
2
;
//Keep only the best "listSize" number of entries.
if
(
currentListSize
>
listSize
)
{
for
(
uint8_t
i
=
0
;
i
<
2
*
listSize
;
i
++
)
listIndex
[
i
]
=
i
;
nr_sort_asc_double_1D_array_ind
(
pathMetric
,
listIndex
,
currentListSize
);
//sort listIndex[listSize, ..., 2*listSize-1] in descending order.
uint8_t
swaps
,
tempInd
;
for
(
uint8_t
i
=
0
;
i
<
listSize
;
i
++
)
{
swaps
=
0
;
for
(
uint8_t
j
=
listSize
;
j
<
(
2
*
listSize
-
i
)
-
1
;
j
++
)
{
if
(
listIndex
[
j
+
1
]
>
listIndex
[
j
])
{
tempInd
=
listIndex
[
j
];
listIndex
[
j
]
=
listIndex
[
j
+
1
];
listIndex
[
j
+
1
]
=
tempInd
;
swaps
++
;
}
}
if
(
swaps
==
0
)
break
;
}
//First, backup the best "listSize" number of entries.
for
(
int
k
=
(
listSize
-
1
);
k
>
0
;
k
--
)
{
for
(
int
i
=
0
;
i
<
polarParams
->
N
;
i
++
)
{
for
(
int
j
=
0
;
j
<
(
polarParams
->
n
+
1
);
j
++
)
{
bit
[
i
][
j
][
listIndex
[(
2
*
listSize
-
1
)
-
k
]]
=
bit
[
i
][
j
][
listIndex
[
k
]];
llr
[
i
][
j
][
listIndex
[(
2
*
listSize
-
1
)
-
k
]]
=
llr
[
i
][
j
][
listIndex
[
k
]];
}
}
}
for
(
int
k
=
(
listSize
-
1
);
k
>
0
;
k
--
)
{
for
(
int
i
=
0
;
i
<
polarParams
->
crcParityBits
;
i
++
)
{
crcChecksum
[
i
][
listIndex
[(
2
*
listSize
-
1
)
-
k
]]
=
crcChecksum
[
i
][
listIndex
[
k
]];
}
}
for
(
int
k
=
(
listSize
-
1
);
k
>
0
;
k
--
)
crcState
[
listIndex
[(
2
*
listSize
-
1
)
-
k
]]
=
crcState
[
listIndex
[
k
]];
//Copy the best "listSize" number of entries to the first indices.
for
(
int
k
=
0
;
k
<
listSize
;
k
++
)
{
if
(
k
>
listIndex
[
k
])
{
copyIndex
=
listIndex
[(
2
*
listSize
-
1
)
-
k
];
}
else
{
//Use the backup.
copyIndex
=
listIndex
[
k
];
}
for
(
int
i
=
0
;
i
<
polarParams
->
N
;
i
++
)
{
for
(
int
j
=
0
;
j
<
(
polarParams
->
n
+
1
);
j
++
)
{
bit
[
i
][
j
][
k
]
=
bit
[
i
][
j
][
copyIndex
];
llr
[
i
][
j
][
k
]
=
llr
[
i
][
j
][
copyIndex
];
}
}
}
for
(
int
k
=
0
;
k
<
listSize
;
k
++
)
{
if
(
k
>
listIndex
[
k
])
{
copyIndex
=
listIndex
[(
2
*
listSize
-
1
)
-
k
];
}
else
{
//Use the backup.
copyIndex
=
listIndex
[
k
];
}
for
(
int
i
=
0
;
i
<
polarParams
->
crcParityBits
;
i
++
)
{
crcChecksum
[
i
][
k
]
=
crcChecksum
[
i
][
copyIndex
];
}
}
for
(
int
k
=
0
;
k
<
listSize
;
k
++
)
{
if
(
k
>
listIndex
[
k
])
{
copyIndex
=
listIndex
[(
2
*
listSize
-
1
)
-
k
];
}
else
{
//Use the backup.
copyIndex
=
listIndex
[
k
];
}
crcState
[
k
]
=
crcState
[
copyIndex
];
}
currentListSize
=
listSize
;
}
}
for
(
int
i
=
0
;
i
<
polarParams
->
crcParityBits
;
i
++
)
{
if
(
last1ind
[
i
]
==
nonFrozenBit
)
{
checkCrcBits
=
i
;
break
;
}
}
if
(
checkCrcBits
>
(
-
1
)
)
{
for
(
uint8_t
i
=
0
;
i
<
currentListSize
;
i
++
)
{
if
(
crcChecksum
[
checkCrcBits
][
i
]
==
1
)
{
crcState
[
i
]
=
0
;
//0=False, 1=True
}
}
}
for
(
uint8_t
i
=
0
;
i
<
currentListSize
;
i
++
)
decoderIterationCheck
+=
crcState
[
i
];
if
(
decoderIterationCheck
==
0
)
{
//perror("[SCL polar decoder] All list entries have failed the CRC checks.");
free
(
crc_generator_matrix
);
free
(
d_tilde
);
free
(
pathMetric
);
nr_free_uint8_t_3D_array
(
bit
,
polarParams
->
N
,
(
polarParams
->
n
+
1
));
nr_free_double_3D_array
(
llr
,
polarParams
->
N
,
(
polarParams
->
n
+
1
));
nr_free_uint8_t_2D_array
(
crcChecksum
,
polarParams
->
crcParityBits
);
return
(
-
1
);
}
nonFrozenBit
++
;
decoderIterationCheck
=
0
;
checkCrcBits
=-
1
;
}
}
for
(
uint8_t
i
=
0
;
i
<
2
*
listSize
;
i
++
)
listIndex
[
i
]
=
i
;
nr_sort_asc_double_1D_array_ind
(
pathMetric
,
listIndex
,
currentListSize
);
uint8_t
*
nr_polar_uHat
=
malloc
(
sizeof
(
uint8_t
)
*
polarParams
->
N
);
uint8_t
*
nr_polar_cHat
=
malloc
(
sizeof
(
uint8_t
)
*
polarParams
->
K
);
uint8_t
*
nr_polar_bHat
=
malloc
(
sizeof
(
uint8_t
)
*
polarParams
->
K
);
for
(
uint8_t
i
=
0
;
i
<
fmin
(
listSize
,
(
pow
(
2
,
polarParams
->
crcCorrectionBits
))
);
i
++
)
{
if
(
crcState
[
listIndex
[
i
]]
==
1
)
{
for
(
int
j
=
0
;
j
<
polarParams
->
N
;
j
++
)
nr_polar_uHat
[
j
]
=
bit
[
j
][
0
][
listIndex
[
i
]];
//Extract the information bits (û to ĉ)
nr_polar_info_bit_extraction
(
nr_polar_uHat
,
nr_polar_cHat
,
polarParams
->
information_bit_pattern
,
polarParams
->
N
);
//Deinterleaving (ĉ to b)
nr_polar_deinterleaver
(
nr_polar_cHat
,
nr_polar_bHat
,
polarParams
->
interleaving_pattern
,
polarParams
->
K
);
//Remove the CRC (â)
for
(
int
j
=
0
;
j
<
polarParams
->
payloadBits
;
j
++
)
output
[
j
]
=
nr_polar_bHat
[
j
];
break
;
}
}
free
(
crc_generator_matrix
);
free
(
d_tilde
);
free
(
pathMetric
);
free
(
nr_polar_uHat
);
free
(
nr_polar_cHat
);
free
(
nr_polar_bHat
);
nr_free_uint8_t_3D_array
(
bit
,
polarParams
->
N
,
(
polarParams
->
n
+
1
));
nr_free_double_3D_array
(
llr
,
polarParams
->
N
,
(
polarParams
->
n
+
1
));
nr_free_uint8_t_2D_array
(
crcChecksum
,
polarParams
->
crcParityBits
);
return
(
0
);
}
openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c
0 → 100644
View file @
5cf8d93a
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void
updateLLR
(
double
***
llr
,
uint8_t
**
llrU
,
uint8_t
***
bit
,
uint8_t
**
bitU
,
uint8_t
listSize
,
uint16_t
row
,
uint16_t
col
,
uint16_t
xlen
,
uint8_t
ylen
,
uint8_t
approximation
)
{
uint16_t
offset
=
(
xlen
/
(
pow
(
2
,(
ylen
-
col
-
1
))));
for
(
uint8_t
i
=
0
;
i
<
listSize
;
i
++
)
{
if
((
(
row
)
%
(
2
*
offset
)
)
>=
offset
)
{
if
(
bitU
[
row
-
offset
][
col
]
==
0
)
updateBit
(
bit
,
bitU
,
listSize
,
(
row
-
offset
),
col
,
xlen
,
ylen
);
if
(
llrU
[
row
-
offset
][
col
+
1
]
==
0
)
updateLLR
(
llr
,
llrU
,
bit
,
bitU
,
listSize
,
(
row
-
offset
),
(
col
+
1
),
xlen
,
ylen
,
approximation
);
if
(
llrU
[
row
][
col
+
1
]
==
0
)
updateLLR
(
llr
,
llrU
,
bit
,
bitU
,
listSize
,
row
,
(
col
+
1
),
xlen
,
ylen
,
approximation
);
llr
[
row
][
col
][
i
]
=
(
pow
((
-
1
),
bit
[
row
-
offset
][
col
][
i
])
*
llr
[
row
-
offset
][
col
+
1
][
i
])
+
llr
[
row
][
col
+
1
][
i
];
}
else
{
if
(
llrU
[
row
][
col
+
1
]
==
0
)
updateLLR
(
llr
,
llrU
,
bit
,
bitU
,
listSize
,
row
,
(
col
+
1
),
xlen
,
ylen
,
approximation
);
if
(
llrU
[
row
+
offset
][
col
+
1
]
==
0
)
updateLLR
(
llr
,
llrU
,
bit
,
bitU
,
listSize
,
(
row
+
offset
),
(
col
+
1
),
xlen
,
ylen
,
approximation
);
computeLLR
(
llr
,
row
,
col
,
i
,
offset
,
approximation
);
}
}
llrU
[
row
][
col
]
=
1
;
}
void
updateBit
(
uint8_t
***
bit
,
uint8_t
**
bitU
,
uint8_t
listSize
,
uint16_t
row
,
uint16_t
col
,
uint16_t
xlen
,
uint8_t
ylen
)
{
uint16_t
offset
=
(
xlen
/
(
pow
(
2
,(
ylen
-
col
)))
);
for
(
uint8_t
i
=
0
;
i
<
listSize
;
i
++
)
{
if
((
(
row
)
%
(
2
*
offset
)
)
>=
offset
)
{
if
(
bitU
[
row
][
col
-
1
]
==
0
)
updateBit
(
bit
,
bitU
,
listSize
,
row
,
(
col
-
1
),
xlen
,
ylen
);
bit
[
row
][
col
][
i
]
=
bit
[
row
][
col
-
1
][
i
];
}
else
{
if
(
bitU
[
row
][
col
-
1
]
==
0
)
updateBit
(
bit
,
bitU
,
listSize
,
row
,
(
col
-
1
),
xlen
,
ylen
);
if
(
bitU
[
row
+
offset
][
col
-
1
]
==
0
)
updateBit
(
bit
,
bitU
,
listSize
,
(
row
+
offset
),
(
col
-
1
),
xlen
,
ylen
);
bit
[
row
][
col
][
i
]
=
(
(
bit
[
row
][
col
-
1
][
i
]
+
bit
[
row
+
offset
][
col
-
1
][
i
])
%
2
);
}
}
bitU
[
row
][
col
]
=
1
;
}
void
updatePathMetric
(
double
*
pathMetric
,
double
***
llr
,
uint8_t
listSize
,
uint8_t
bitValue
,
uint16_t
row
,
uint8_t
approximation
)
{
if
(
approximation
)
{
//eq. (12)
for
(
uint8_t
i
=
0
;
i
<
listSize
;
i
++
)
{
if
((
2
*
bitValue
)
!=
(
1
-
copysign
(
1
.
0
,
llr
[
row
][
0
][
i
])
))
pathMetric
[
i
]
+=
fabs
(
llr
[
row
][
0
][
i
]);
}
}
else
{
//eq. (11b)
int8_t
multiplier
=
(
2
*
bitValue
)
-
1
;
for
(
uint8_t
i
=
0
;
i
<
listSize
;
i
++
)
pathMetric
[
i
]
+=
log
(
1
+
exp
(
multiplier
*
llr
[
row
][
0
][
i
])
)
;
}
}
void
updatePathMetric2
(
double
*
pathMetric
,
double
***
llr
,
uint8_t
listSize
,
uint16_t
row
,
uint8_t
appr
)
{
double
*
tempPM
=
malloc
(
sizeof
(
double
)
*
listSize
);
for
(
int
i
=
0
;
i
<
listSize
;
i
++
)
tempPM
[
i
]
=
pathMetric
[
i
];
uint8_t
bitValue
=
0
;
if
(
appr
)
{
//eq. (12)
for
(
uint8_t
i
=
0
;
i
<
listSize
;
i
++
)
{
if
((
2
*
bitValue
)
!=
(
1
-
copysign
(
1
.
0
,
llr
[
row
][
0
][
i
])))
pathMetric
[
i
]
+=
fabs
(
llr
[
row
][
0
][
i
]);
}
}
else
{
//eq. (11b)
int8_t
multiplier
=
(
2
*
bitValue
)
-
1
;
for
(
uint8_t
i
=
0
;
i
<
listSize
;
i
++
)
pathMetric
[
i
]
+=
log
(
1
+
exp
(
multiplier
*
llr
[
row
][
0
][
i
]));
}
bitValue
=
1
;
if
(
appr
)
{
//eq. (12)
for
(
uint8_t
i
=
listSize
;
i
<
2
*
listSize
;
i
++
)
{
if
((
2
*
bitValue
)
!=
(
1
-
copysign
(
1
.
0
,
llr
[
row
][
0
][(
i
-
listSize
)])))
pathMetric
[
i
]
=
tempPM
[(
i
-
listSize
)]
+
fabs
(
llr
[
row
][
0
][(
i
-
listSize
)]);
}
}
else
{
//eq. (11b)
int8_t
multiplier
=
(
2
*
bitValue
)
-
1
;
for
(
uint8_t
i
=
listSize
;
i
<
2
*
listSize
;
i
++
)
pathMetric
[
i
]
=
tempPM
[(
i
-
listSize
)]
+
log
(
1
+
exp
(
multiplier
*
llr
[
row
][
0
][(
i
-
listSize
)]));
}
free
(
tempPM
);
}
void
computeLLR
(
double
***
llr
,
uint16_t
row
,
uint16_t
col
,
uint8_t
i
,
uint16_t
offset
,
uint8_t
approximation
)
{
double
a
=
llr
[
row
][
col
+
1
][
i
];
double
absA
=
fabs
(
a
);
double
b
=
llr
[
row
+
offset
][
col
+
1
][
i
];
double
absB
=
fabs
(
b
);
if
(
approximation
||
isinf
(
absA
)
||
isinf
(
absB
))
{
//eq. (9)
llr
[
row
][
col
][
i
]
=
copysign
(
1
.
0
,
a
)
*
copysign
(
1
.
0
,
b
)
*
fmin
(
absA
,
absB
);
}
else
{
//eq. (8a)
llr
[
row
][
col
][
i
]
=
log
((
exp
(
a
+
b
)
+
1
)
/
(
exp
(
a
)
+
exp
(
b
)));
}
}
void
updateCrcChecksum
(
uint8_t
**
crcChecksum
,
uint8_t
**
crcGen
,
uint8_t
listSize
,
uint32_t
i2
,
uint8_t
len
)
{
for
(
uint8_t
i
=
0
;
i
<
listSize
;
i
++
)
{
for
(
uint8_t
j
=
0
;
j
<
len
;
j
++
)
{
crcChecksum
[
j
][
i
]
=
(
(
crcChecksum
[
j
][
i
]
+
crcGen
[
i2
][
j
])
%
2
);
}
}
}
void
updateCrcChecksum2
(
uint8_t
**
crcChecksum
,
uint8_t
**
crcGen
,
uint8_t
listSize
,
uint32_t
i2
,
uint8_t
len
)
{
for
(
uint8_t
i
=
0
;
i
<
listSize
;
i
++
)
{
for
(
uint8_t
j
=
0
;
j
<
len
;
j
++
)
{
crcChecksum
[
j
][
i
+
listSize
]
=
(
(
crcChecksum
[
j
][
i
]
+
crcGen
[
i2
][
j
])
%
2
);
}
}
}
openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
0 → 100644
View file @
5cf8d93a
#ifndef __NR_POLAR_DEFS__H__
#define __NR_POLAR_DEFS__H__
#include <math.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
static
const
uint8_t
nr_polar_subblock_interleaver_pattern
[
32
]
=
{
0
,
1
,
2
,
4
,
3
,
5
,
6
,
7
,
8
,
16
,
9
,
17
,
10
,
18
,
11
,
19
,
12
,
20
,
13
,
21
,
14
,
22
,
15
,
23
,
24
,
25
,
26
,
28
,
27
,
29
,
30
,
31
};
typedef
struct
nrPolar_params
{
uint8_t
n_max
;
uint8_t
i_il
;
uint8_t
n_pc
;
uint8_t
n_pc_wm
;
uint8_t
i_bil
;
uint16_t
payloadBits
;
uint16_t
encoderLength
;
uint8_t
crcParityBits
;
uint8_t
crcCorrectionBits
;
uint16_t
K
;
uint16_t
N
;
uint8_t
n
;
uint16_t
*
interleaving_pattern
;
uint16_t
*
rate_matching_pattern
;
uint16_t
*
Q_0_Nminus1
;
int16_t
*
Q_I_N
;
int16_t
*
Q_F_N
;
int16_t
*
Q_PC_N
;
uint8_t
*
information_bit_pattern
;
uint16_t
*
channel_interleaver_pattern
;
uint8_t
**
crc_generator_matrix
;
//G_P
uint8_t
**
G_N
;
}
t_nrPolar_params
;
void
polar_encoder
(
uint8_t
*
input
,
uint8_t
*
channel_input
,
t_nrPolar_params
*
polarParams
);
int8_t
polar_decoder
(
double
*
input
,
uint8_t
*
output
,
t_nrPolar_params
*
polarParams
,
uint8_t
listSize
,
double
*
aPrioriPayload
,
uint8_t
pathMetricAppr
);
void
nr_polar_init
(
t_nrPolar_params
*
polarParams
,
int
messageType
);
uint8_t
**
nr_polar_kronecker_power_matrices
(
uint8_t
n
);
uint16_t
*
nr_polar_sequence_pattern
(
uint8_t
n
);
uint32_t
nr_polar_output_length
(
uint16_t
K
,
uint16_t
E
,
uint8_t
n_max
);
void
nr_polar_channel_interleaver_pattern
(
uint16_t
*
cip
,
uint8_t
I_BIL
,
uint16_t
E
);
void
nr_polar_rate_matching_pattern
(
uint16_t
*
rmp
,
uint16_t
*
J
,
uint8_t
*
P_i_
,
uint16_t
K
,
uint16_t
N
,
uint16_t
E
);
void
nr_polar_rate_matching
(
double
*
input
,
double
*
output
,
uint16_t
*
rmp
,
uint16_t
K
,
uint16_t
N
,
uint16_t
E
);
void
nr_polar_rate_matcher
(
uint8_t
*
input
,
unsigned
char
*
output
,
uint16_t
*
pattern
,
uint16_t
size
);
void
nr_polar_interleaving_pattern
(
uint16_t
K
,
uint8_t
I_IL
,
uint16_t
*
PI_k_
);
void
nr_polar_interleaver
(
uint8_t
*
input
,
uint8_t
*
output
,
uint16_t
*
pattern
,
uint16_t
size
);
void
nr_polar_deinterleaver
(
uint8_t
*
input
,
uint8_t
*
output
,
uint16_t
*
pattern
,
uint16_t
size
);
void
nr_polar_info_bit_pattern
(
uint8_t
*
ibp
,
uint16_t
*
Q_I_N
,
int16_t
*
Q_F_N
,
uint16_t
*
J
,
uint16_t
*
Q_0_Nminus1
,
uint16_t
K
,
uint16_t
N
,
uint16_t
E
,
uint8_t
n_PC
);
void
nr_polar_info_bit_extraction
(
uint8_t
*
input
,
uint8_t
*
output
,
uint8_t
*
pattern
,
uint16_t
size
);
void
nr_byte2bit
(
uint8_t
*
array
,
uint8_t
arraySize
,
uint8_t
*
bitArray
);
void
nr_polar_bit_insertion
(
uint8_t
*
input
,
uint8_t
*
output
,
uint16_t
N
,
uint16_t
K
,
uint16_t
*
Q_I_N
,
uint16_t
*
Q_PC_N
,
uint8_t
n_PC
);
void
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D
(
uint8_t
*
matrix1
,
uint8_t
**
matrix2
,
uint8_t
*
output
,
uint16_t
row
,
uint16_t
col
);
uint8_t
***
nr_alloc_uint8_t_3D_array
(
uint16_t
xlen
,
uint16_t
ylen
,
uint16_t
zlen
);
uint8_t
**
nr_alloc_uint8_t_2D_array
(
uint16_t
xlen
,
uint16_t
ylen
);
double
***
nr_alloc_double_3D_array
(
uint16_t
xlen
,
uint16_t
ylen
,
uint16_t
zlen
);
void
nr_free_uint8_t_3D_array
(
uint8_t
***
input
,
uint16_t
xlen
,
uint16_t
ylen
);
void
nr_free_uint8_t_2D_array
(
uint8_t
**
input
,
uint16_t
xlen
);
void
nr_free_double_3D_array
(
double
***
input
,
uint16_t
xlen
,
uint16_t
ylen
);
void
updateLLR
(
double
***
llr
,
uint8_t
**
llrU
,
uint8_t
***
bit
,
uint8_t
**
bitU
,
uint8_t
listSize
,
uint16_t
row
,
uint16_t
col
,
uint16_t
xlen
,
uint8_t
ylen
,
uint8_t
approximation
);
void
updateBit
(
uint8_t
***
bit
,
uint8_t
**
bitU
,
uint8_t
listSize
,
uint16_t
row
,
uint16_t
col
,
uint16_t
xlen
,
uint8_t
ylen
);
void
updatePathMetric
(
double
*
pathMetric
,
double
***
llr
,
uint8_t
listSize
,
uint8_t
bitValue
,
uint16_t
row
,
uint8_t
approximation
);
void
updatePathMetric2
(
double
*
pathMetric
,
double
***
llr
,
uint8_t
listSize
,
uint16_t
row
,
uint8_t
approximation
);
void
computeLLR
(
double
***
llr
,
uint16_t
row
,
uint16_t
col
,
uint8_t
i
,
uint16_t
offset
,
uint8_t
approximation
);
void
updateCrcChecksum
(
uint8_t
**
crcChecksum
,
uint8_t
**
crcGen
,
uint8_t
listSize
,
uint32_t
i2
,
uint8_t
len
);
void
updateCrcChecksum2
(
uint8_t
**
crcChecksum
,
uint8_t
**
crcGen
,
uint8_t
listSize
,
uint32_t
i2
,
uint8_t
len
);
void
nr_sort_asc_double_1D_array_ind
(
double
*
matrix
,
uint8_t
*
ind
,
uint8_t
len
);
#endif
openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
0 → 100644
View file @
5cf8d93a
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
void
polar_encoder
(
uint8_t
*
input
,
uint8_t
*
channel_input
,
t_nrPolar_params
*
polarParams
){
/*//Create the Transport Block.
unsigned int payload=0xb3f02c82;
uint8_t pbchTransportBlockSize = ( polarParams->K / (8*sizeof(uint8_t)) );
uint8_t *pbchTransportBlock = malloc(pbchTransportBlockSize);
memcpy(pbchTransportBlock,&payload,sizeof(payload));
//Attach CRC to the Transport Block. (a to b)
uint32_t crc = crc24c(&payload, NR_POLAR_PBCH_PAYLOAD_BITS)>>8;
pbchTransportBlock[NR_POLAR_PBCH_PAYLOAD_BITS>>3] = ((uint8_t*)&crc)[2];
pbchTransportBlock[1+(NR_POLAR_PBCH_PAYLOAD_BITS>>3)] = ((uint8_t*)&crc)[1];
pbchTransportBlock[2+(NR_POLAR_PBCH_PAYLOAD_BITS>>3)] = ((uint8_t*)&crc)[0];*/
/*
* Bytewise operations
*/
//Calculate CRC.
uint8_t
*
nr_polar_crc
=
malloc
(
sizeof
(
uint8_t
)
*
polarParams
->
crcParityBits
);
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D
(
input
,
polarParams
->
crc_generator_matrix
,
nr_polar_crc
,
polarParams
->
payloadBits
,
polarParams
->
crcParityBits
);
for
(
uint8_t
i
=
0
;
i
<
polarParams
->
crcParityBits
;
i
++
)
nr_polar_crc
[
i
]
=
(
nr_polar_crc
[
i
]
%
2
);
//Attach CRC to the Transport Block. (a to b)
uint8_t
*
nr_polar_b
=
malloc
(
sizeof
(
uint8_t
)
*
polarParams
->
K
);
for
(
uint16_t
i
=
0
;
i
<
polarParams
->
payloadBits
;
i
++
)
nr_polar_b
[
i
]
=
input
[
i
];
for
(
uint16_t
i
=
polarParams
->
payloadBits
;
i
<
polarParams
->
K
;
i
++
)
nr_polar_b
[
i
]
=
nr_polar_crc
[
i
-
(
polarParams
->
payloadBits
)];
//Interleaving (c to c')
uint8_t
*
nr_polar_cPrime
=
malloc
(
sizeof
(
uint8_t
)
*
polarParams
->
K
);
nr_polar_interleaver
(
nr_polar_b
,
nr_polar_cPrime
,
polarParams
->
interleaving_pattern
,
polarParams
->
K
);
//Bit insertion (c' to u)
uint8_t
*
nr_polar_u
=
malloc
(
sizeof
(
uint8_t
)
*
polarParams
->
N
);
nr_polar_bit_insertion
(
nr_polar_cPrime
,
nr_polar_u
,
polarParams
->
N
,
polarParams
->
K
,
polarParams
->
Q_I_N
,
polarParams
->
Q_PC_N
,
polarParams
->
n_pc
);
//Encoding (u to d)
uint8_t
*
pbch_polar_encoder_output
=
malloc
(
sizeof
(
uint8_t
)
*
polarParams
->
N
);
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D
(
nr_polar_u
,
polarParams
->
G_N
,
pbch_polar_encoder_output
,
polarParams
->
N
,
polarParams
->
N
);
for
(
uint16_t
i
=
0
;
i
<
polarParams
->
N
;
i
++
)
pbch_polar_encoder_output
[
i
]
=
(
pbch_polar_encoder_output
[
i
]
%
2
);
//Rate matching
//Sub-block interleaving (d to y) and Bit selection (y to e)
nr_polar_rate_matcher
(
pbch_polar_encoder_output
,
channel_input
,
polarParams
->
rate_matching_pattern
,
polarParams
->
encoderLength
);
//free(pbchTransportBlock);
free
(
nr_polar_crc
);
free
(
nr_polar_b
);
free
(
nr_polar_cPrime
);
free
(
nr_polar_u
);
free
(
pbch_polar_encoder_output
);
}
openair1/PHY/CODING/nrPolar_tools/nr_polar_info_bit_pattern.c
0 → 100644
View file @
5cf8d93a
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void
nr_polar_info_bit_pattern
(
uint8_t
*
ibp
,
uint16_t
*
Q_I_N
,
int16_t
*
Q_F_N
,
uint16_t
*
J
,
uint16_t
*
Q_0_Nminus1
,
uint16_t
K
,
uint16_t
N
,
uint16_t
E
,
uint8_t
n_PC
)
{
int16_t
*
Q_Ftmp_N
=
malloc
(
sizeof
(
int16_t
)
*
(
N
+
1
));
// Last element shows the final
int16_t
*
Q_Itmp_N
=
malloc
(
sizeof
(
int16_t
)
*
(
N
+
1
));
// array index assigned a value.
for
(
int
i
=
0
;
i
<=
N
;
i
++
)
{
Q_Ftmp_N
[
i
]
=
-
1
;
// Empty array.
Q_Itmp_N
[
i
]
=
-
1
;
}
uint8_t
flag
;
uint16_t
limit
,
ind
;
if
(
E
<
N
)
{
if
((
K
/
(
double
)
E
)
<=
(
7
.
0
/
16
))
{
//puncturing
for
(
int
n
=
0
;
n
<=
N
-
E
-
1
;
n
++
)
{
ind
=
Q_Ftmp_N
[
N
]
+
1
;
Q_Ftmp_N
[
ind
]
=
J
[
n
];
Q_Ftmp_N
[
N
]
=
Q_Ftmp_N
[
N
]
+
1
;
}
if
((
E
/
(
double
)
N
)
>=
(
3
.
0
/
4
))
{
limit
=
ceil
((
double
)
(
3
*
N
-
2
*
E
)
/
4
);
for
(
int
n
=
0
;
n
<=
limit
-
1
;
n
++
)
{
ind
=
Q_Ftmp_N
[
N
]
+
1
;
Q_Ftmp_N
[
ind
]
=
n
;
Q_Ftmp_N
[
N
]
=
Q_Ftmp_N
[
N
]
+
1
;
}
}
else
{
limit
=
ceil
((
double
)
(
9
*
N
-
4
*
E
)
/
16
);
for
(
int
n
=
0
;
n
<=
limit
-
1
;
n
++
)
{
ind
=
Q_Ftmp_N
[
N
]
+
1
;
Q_Ftmp_N
[
ind
]
=
n
;
Q_Ftmp_N
[
N
]
=
Q_Ftmp_N
[
N
]
+
1
;
}
}
}
else
{
//shortening
for
(
int
n
=
E
;
n
<=
N
-
1
;
n
++
)
{
ind
=
Q_Ftmp_N
[
N
]
+
1
;
Q_Ftmp_N
[
ind
]
=
J
[
n
];
Q_Ftmp_N
[
N
]
=
Q_Ftmp_N
[
N
]
+
1
;
}
}
}
//Q_I,tmp_N = Q_0_N-1 \ Q_F,tmp_N
for
(
int
n
=
0
;
n
<=
N
-
1
;
n
++
)
{
flag
=
1
;
for
(
int
m
=
0
;
m
<=
Q_Ftmp_N
[
N
];
m
++
)
{
if
(
Q_0_Nminus1
[
n
]
==
Q_Ftmp_N
[
m
])
{
flag
=
0
;
break
;
}
}
if
(
flag
)
{
Q_Itmp_N
[
Q_Itmp_N
[
N
]
+
1
]
=
Q_0_Nminus1
[
n
];
Q_Itmp_N
[
N
]
++
;
}
}
//Q_I_N comprises (K+n_PC) most reliable bit indices in Q_I,tmp_N
for
(
int
n
=
0
;
n
<=
(
K
+
n_PC
)
-
1
;
n
++
)
{
ind
=
Q_Itmp_N
[
N
]
+
n
-
((
K
+
n_PC
)
-
1
);
Q_I_N
[
n
]
=
Q_Itmp_N
[
ind
];
}
//Q_F_N = Q_0_N-1 \ Q_I_N
for
(
int
n
=
0
;
n
<=
N
-
1
;
n
++
)
{
flag
=
1
;
for
(
int
m
=
0
;
m
<=
(
K
+
n_PC
)
-
1
;
m
++
)
{
if
(
Q_0_Nminus1
[
n
]
==
Q_I_N
[
m
])
{
flag
=
0
;
break
;
}
}
if
(
flag
)
{
Q_F_N
[
Q_F_N
[
N
]
+
1
]
=
Q_0_Nminus1
[
n
];
Q_F_N
[
N
]
++
;
}
}
//Information Bit Pattern
for
(
int
n
=
0
;
n
<=
N
-
1
;
n
++
)
{
ibp
[
n
]
=
0
;
for
(
int
m
=
0
;
m
<=
(
K
+
n_PC
)
-
1
;
m
++
)
{
if
(
n
==
Q_I_N
[
m
])
{
ibp
[
n
]
=
1
;
break
;
}
}
}
free
(
Q_Ftmp_N
);
free
(
Q_Itmp_N
);
}
void
nr_polar_info_bit_extraction
(
uint8_t
*
input
,
uint8_t
*
output
,
uint8_t
*
pattern
,
uint16_t
size
)
{
uint16_t
j
=
0
;
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
if
(
pattern
[
i
]
>
0
)
{
output
[
j
]
=
input
[
i
];
j
++
;
}
}
}
openair1/PHY/CODING/nrPolar_tools/nr_polar_interleave.c
0 → 100644
View file @
5cf8d93a
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void
nr_polar_interleaving_pattern
(
uint16_t
K
,
uint8_t
I_IL
,
uint16_t
*
PI_k_
){
uint8_t
K_IL_max
=
164
,
k
=
0
;
uint8_t
interleaving_pattern_table
[
164
]
=
{
0
,
2
,
4
,
7
,
9
,
14
,
19
,
20
,
24
,
25
,
26
,
28
,
31
,
34
,
42
,
45
,
49
,
50
,
51
,
53
,
54
,
56
,
58
,
59
,
61
,
62
,
65
,
66
,
67
,
69
,
70
,
71
,
72
,
76
,
77
,
81
,
82
,
83
,
87
,
88
,
89
,
91
,
93
,
95
,
98
,
101
,
104
,
106
,
108
,
110
,
111
,
113
,
115
,
118
,
119
,
120
,
122
,
123
,
126
,
127
,
129
,
132
,
134
,
138
,
139
,
140
,
1
,
3
,
5
,
8
,
10
,
15
,
21
,
27
,
29
,
32
,
35
,
43
,
46
,
52
,
55
,
57
,
60
,
63
,
68
,
73
,
78
,
84
,
90
,
92
,
94
,
96
,
99
,
102
,
105
,
107
,
109
,
112
,
114
,
116
,
121
,
124
,
128
,
130
,
133
,
135
,
141
,
6
,
11
,
16
,
22
,
30
,
33
,
36
,
44
,
47
,
64
,
74
,
79
,
85
,
97
,
100
,
103
,
117
,
125
,
131
,
136
,
142
,
12
,
17
,
23
,
37
,
48
,
75
,
80
,
86
,
137
,
143
,
13
,
18
,
38
,
144
,
39
,
145
,
40
,
146
,
41
,
147
,
148
,
149
,
150
,
151
,
152
,
153
,
154
,
155
,
156
,
157
,
158
,
159
,
160
,
161
,
162
,
163
};
if
(
I_IL
==
0
){
for
(;
k
<=
K
-
1
;
k
++
)
PI_k_
[
k
]
=
k
;
}
else
{
for
(
int
m
=
0
;
m
<=
(
K_IL_max
-
1
);
m
++
){
if
(
interleaving_pattern_table
[
m
]
>=
(
K_IL_max
-
K
))
{
PI_k_
[
k
]
=
interleaving_pattern_table
[
m
]
-
(
K_IL_max
-
K
);
k
++
;
}
}
}
}
void
nr_polar_interleaver
(
uint8_t
*
input
,
uint8_t
*
output
,
uint16_t
*
pattern
,
uint16_t
size
)
{
for
(
int
i
=
0
;
i
<
size
;
i
++
)
output
[
i
]
=
input
[
pattern
[
i
]];
}
void
nr_polar_deinterleaver
(
uint8_t
*
input
,
uint8_t
*
output
,
uint16_t
*
pattern
,
uint16_t
size
)
{
for
(
int
i
=
0
;
i
<
size
;
i
++
)
output
[
pattern
[
i
]]
=
input
[
i
];
}
openair1/PHY/CODING/nrPolar_tools/nr_polar_kernal_operation.c
0 → 100644
View file @
5cf8d93a
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
void
nr_polar_kernel_operation
(
uint8_t
*
u
,
uint8_t
*
d
,
uint16_t
N
)
{
// Martino's algorithm to avoid multiplication for the generating matrix
int
i
,
j
;
printf
(
"
\n
d = "
);
for
(
i
=
0
;
i
<
N
;
i
++
)
{
d
[
i
]
=
0
;
for
(
j
=
0
;
j
<
N
;
j
++
)
{
d
[
i
]
=
d
[
i
]
+
((
(
j
-
i
)
&
i
)
==
0
)
*
u
[
j
];
}
d
[
i
]
=
d
[
i
]
%
2
;
printf
(
"%i"
,
d
[
i
]);
}
}
openair1/PHY/CODING/nrPolar_tools/nr_polar_kronecker_power_matrices.c
0 → 100644
View file @
5cf8d93a
This diff is collapsed.
Click to expand it.
openair1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c
0 → 100644
View file @
5cf8d93a
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D
(
uint8_t
*
matrix1
,
uint8_t
**
matrix2
,
uint8_t
*
output
,
uint16_t
row
,
uint16_t
col
)
{
for
(
uint16_t
i
=
0
;
i
<
col
;
i
++
)
{
output
[
i
]
=
0
;
for
(
uint16_t
j
=
0
;
j
<
row
;
j
++
)
{
output
[
i
]
+=
matrix1
[
j
]
*
matrix2
[
j
][
i
];
}
}
}
uint8_t
***
nr_alloc_uint8_t_3D_array
(
uint16_t
xlen
,
uint16_t
ylen
,
uint16_t
zlen
)
{
uint8_t
***
output
;
int
i
,
j
;
if
((
output
=
malloc
(
xlen
*
sizeof
(
*
output
)))
==
NULL
)
{
perror
(
"[nr_alloc_uint8_t_3D_array] Problem at 1D allocation"
);
return
NULL
;
}
for
(
i
=
0
;
i
<
xlen
;
i
++
)
output
[
i
]
=
NULL
;
for
(
i
=
0
;
i
<
xlen
;
i
++
)
if
((
output
[
i
]
=
malloc
(
ylen
*
sizeof
*
output
[
i
]))
==
NULL
)
{
perror
(
"[nr_alloc_uint8_t_3D_array] Problem at 2D allocation"
);
nr_free_uint8_t_3D_array
(
output
,
xlen
,
ylen
);
return
NULL
;
}
for
(
i
=
0
;
i
<
xlen
;
i
++
)
for
(
j
=
0
;
j
<
ylen
;
j
++
)
output
[
i
][
j
]
=
NULL
;
for
(
i
=
0
;
i
<
xlen
;
i
++
)
for
(
j
=
0
;
j
<
ylen
;
j
++
)
if
((
output
[
i
][
j
]
=
malloc
(
zlen
*
sizeof
*
output
[
i
][
j
]))
==
NULL
)
{
perror
(
"[nr_alloc_uint8_t_3D_array] Problem at 3D allocation"
);
nr_free_uint8_t_3D_array
(
output
,
xlen
,
ylen
);
return
NULL
;
}
return
output
;
}
double
***
nr_alloc_double_3D_array
(
uint16_t
xlen
,
uint16_t
ylen
,
uint16_t
zlen
)
{
double
***
output
;
int
i
,
j
;
if
((
output
=
malloc
(
xlen
*
sizeof
(
*
output
)))
==
NULL
)
{
perror
(
"[nr_alloc_double_3D_array] Problem at 1D allocation"
);
return
NULL
;
}
for
(
i
=
0
;
i
<
xlen
;
i
++
)
output
[
i
]
=
NULL
;
for
(
i
=
0
;
i
<
xlen
;
i
++
)
if
((
output
[
i
]
=
malloc
(
ylen
*
sizeof
*
output
[
i
]))
==
NULL
)
{
perror
(
"[nr_alloc_double_3D_array] Problem at 2D allocation"
);
nr_free_double_3D_array
(
output
,
xlen
,
ylen
);
return
NULL
;
}
for
(
i
=
0
;
i
<
xlen
;
i
++
)
for
(
j
=
0
;
j
<
ylen
;
j
++
)
output
[
i
][
j
]
=
NULL
;
for
(
i
=
0
;
i
<
xlen
;
i
++
)
for
(
j
=
0
;
j
<
ylen
;
j
++
)
if
((
output
[
i
][
j
]
=
malloc
(
zlen
*
sizeof
*
output
[
i
][
j
]))
==
NULL
)
{
perror
(
"[nr_alloc_double_3D_array] Problem at 3D allocation"
);
nr_free_double_3D_array
(
output
,
xlen
,
ylen
);
return
NULL
;
}
return
output
;
}
uint8_t
**
nr_alloc_uint8_t_2D_array
(
uint16_t
xlen
,
uint16_t
ylen
)
{
uint8_t
**
output
;
int
i
,
j
;
if
((
output
=
malloc
(
xlen
*
sizeof
(
*
output
)))
==
NULL
)
{
perror
(
"[nr_alloc_uint8_t_2D_array] Problem at 1D allocation"
);
return
NULL
;
}
for
(
i
=
0
;
i
<
xlen
;
i
++
)
output
[
i
]
=
NULL
;
for
(
i
=
0
;
i
<
xlen
;
i
++
)
if
((
output
[
i
]
=
malloc
(
ylen
*
sizeof
*
output
[
i
]))
==
NULL
)
{
perror
(
"[nr_alloc_uint8_t_2D_array] Problem at 2D allocation"
);
nr_free_uint8_t_2D_array
(
output
,
xlen
);
return
NULL
;
}
for
(
i
=
0
;
i
<
xlen
;
i
++
)
for
(
j
=
0
;
j
<
ylen
;
j
++
)
output
[
i
][
j
]
=
0
;
return
output
;
}
void
nr_free_uint8_t_3D_array
(
uint8_t
***
input
,
uint16_t
xlen
,
uint16_t
ylen
)
{
int
i
,
j
;
for
(
i
=
0
;
i
<
xlen
;
i
++
)
{
for
(
j
=
0
;
j
<
ylen
;
j
++
)
{
free
(
input
[
i
][
j
]);
}
free
(
input
[
i
]);
}
free
(
input
);
}
void
nr_free_uint8_t_2D_array
(
uint8_t
**
input
,
uint16_t
xlen
)
{
for
(
int
i
=
0
;
i
<
xlen
;
i
++
)
free
(
input
[
i
]);
free
(
input
);
}
void
nr_free_double_3D_array
(
double
***
input
,
uint16_t
xlen
,
uint16_t
ylen
)
{
int
i
,
j
;
for
(
i
=
0
;
i
<
xlen
;
i
++
)
{
for
(
j
=
0
;
j
<
ylen
;
j
++
)
{
free
(
input
[
i
][
j
]);
}
free
(
input
[
i
]);
}
free
(
input
);
}
// Modified Bubble Sort.
void
nr_sort_asc_double_1D_array_ind
(
double
*
matrix
,
uint8_t
*
ind
,
uint8_t
len
)
{
uint8_t
swaps
;
double
temp
;
uint8_t
tempInd
;
for
(
uint8_t
i
=
0
;
i
<
len
;
i
++
)
{
swaps
=
0
;
for
(
uint8_t
j
=
0
;
j
<
(
len
-
i
)
-
1
;
j
++
)
{
if
(
matrix
[
j
]
>
matrix
[
j
+
1
])
{
temp
=
matrix
[
j
];
matrix
[
j
]
=
matrix
[
j
+
1
];
matrix
[
j
+
1
]
=
temp
;
tempInd
=
ind
[
j
];
ind
[
j
]
=
ind
[
j
+
1
];
ind
[
j
+
1
]
=
tempInd
;
swaps
++
;
}
}
if
(
swaps
==
0
)
break
;
}
}
openair1/PHY/CODING/nrPolar_tools/nr_polar_output_length.c
0 → 100644
View file @
5cf8d93a
#include <math.h>
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
uint32_t
nr_polar_output_length
(
uint16_t
K
,
uint16_t
E
,
uint8_t
n_max
){
uint8_t
n_1
,
n_2
,
n_min
=
5
,
n
;
uint32_t
polar_code_output_length
;
double
R_min
=
1
.
0
/
8
;
if
(
(
E
<=
(
9
.
0
/
8
)
*
pow
(
2
,
ceil
(
log2
(
E
))
-
1
))
&&
(
K
/
E
<
9
.
0
/
16
)
)
{
n_1
=
ceil
(
log2
(
E
))
-
1
;
}
else
{
n_1
=
ceil
(
log2
(
E
));
}
n_2
=
ceil
(
log2
(
K
/
R_min
));
n
=
n_max
;
if
(
n
>
n_1
)
n
=
n_1
;
if
(
n
>
n_2
)
n
=
n_2
;
if
(
n
<
n_min
)
n
=
n_min
;
polar_code_output_length
=
(
uint32_t
)
pow
(
2
.
0
,
n
);
return
polar_code_output_length
;
}
openair1/PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h
0 → 100644
View file @
5cf8d93a
/*
* Defines the constant variables for polar coding of the PBCH.
*/
#ifndef __NR_POLAR_PBCH_DEFS__H__
#define __NR_POLAR_PBCH_DEFS__H__
#define NR_POLAR_PBCH_PAYLOAD_BITS 32 //uint16_t
#define NR_POLAR_PBCH_CRC_PARITY_BITS 24
#define NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS 3
//Assumed 3 by 3GPP when NR_POLAR_PBCH_L>8 to meet false alarm rate requirements.
//Ref. 38-212 v15.0.1, Section 7.1.4: Channel Coding
#define NR_POLAR_PBCH_N_MAX 9 //uint8_t
#define NR_POLAR_PBCH_I_IL 1 //uint8_t
#define NR_POLAR_PBCH_N_PC 0 //uint8_t
#define NR_POLAR_PBCH_N_PC_WM 0 //uint8_t
//#define NR_POLAR_PBCH_N 512 //uint16_t
//Ref. 38-212 v15.0.1, Section 7.1.5: Rate Matching
#define NR_POLAR_PBCH_I_BIL 0 //uint8_t
#define NR_POLAR_PBCH_E 864 //uint16_t
//#define NR_POLAR_PBCH_L 5 //uint8_t
#define NR_POLAR_PBCH_PATH_METRIC_APPROXIMATION 0 //uint8_t; 0 --> eq. (8a) and (11b), 1 --> eq. (9) and (12)
/*
* TEST CODE
*/
//#define DEBUG_POLAR
// Usage in code:
//#ifdef DEBUG_POLAR
//...
//#endif
//unsigned int testPayload0=0x00000000, testPayload1=0xffffffff; //payload1=~payload0;
//unsigned int testPayload2=0xa5a5a5a5; //testPayload3=0xb3f02c82;
//double testReceivedPayload3[NR_POLAR_PBCH_E] = {-1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1};
#endif
openair1/PHY/CODING/nrPolar_tools/nr_polar_plot.m
0 → 100644
View file @
5cf8d93a
openair1/PHY/CODING/nrPolar_tools/nr_polar_pucch_defs.h
0 → 100644
View file @
5cf8d93a
/*
* Defines the constant variables for polar coding of the PUCCH.
*/
#ifndef __NR_POLAR_PUCCH_DEFS__H__
#define __NR_POLAR_PUCCH_DEFS__H__
#define NR_POLAR_PUCCH_PAYLOAD_BITS 16
//Ref. 38-212 v15.0.1
#define NR_POLAR_PUCCH_N_MAX 10 //uint8_t <------
#define NR_POLAR_PUCCH_I_IL 1 //uint8_t <--- interleaving: if 0 no interleaving
#define NR_POLAR_PUCCH_N_PC 3 //uint8_t <-- or zero ??
#define NR_POLAR_PUCCH_N_PC_WM 0 //uint8_t
//#define NR_POLAR_PUCCH_N 512 //uint16_t
//Ref. 38-212 v15.0.1, Section 7.1.5: Rate Matching
#define NR_POLAR_PUCCH_I_BIL 0 //uint8_t
#define NR_POLAR_PUCCH_E 864 //uint16_t
/*
* TEST CODE
*/
//unsigned int testPayload0=0x00000000, testPayload1=0xffffffff; //payload1=~payload0;
//unsigned int testPayload2=0xa5a5a5a5, testPayload3=0xb3f02c82;
#endif
openair1/PHY/CODING/nrPolar_tools/nr_polar_rate_match.c
0 → 100644
View file @
5cf8d93a
#include <math.h>
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void
nr_polar_rate_matching_pattern
(
uint16_t
*
rmp
,
uint16_t
*
J
,
uint8_t
*
P_i_
,
uint16_t
K
,
uint16_t
N
,
uint16_t
E
){
uint8_t
i
;
uint16_t
*
d
,
*
y
,
ind
;
d
=
(
uint16_t
*
)
malloc
(
sizeof
(
uint16_t
)
*
N
);
y
=
(
uint16_t
*
)
malloc
(
sizeof
(
uint16_t
)
*
N
);
for
(
int
m
=
0
;
m
<=
N
-
1
;
m
++
)
d
[
m
]
=
m
;
for
(
int
m
=
0
;
m
<=
N
-
1
;
m
++
){
i
=
floor
((
32
*
m
)
/
N
);
J
[
m
]
=
(
P_i_
[
i
]
*
(
N
/
32
))
+
(
m
%
(
N
/
32
));
y
[
m
]
=
d
[
J
[
m
]];
}
if
(
E
>=
N
)
{
//repetition
for
(
int
k
=
0
;
k
<=
E
-
1
;
k
++
)
{
ind
=
(
k
%
N
);
rmp
[
k
]
=
y
[
ind
];
}
}
else
{
if
(
(
K
/
(
double
)
E
)
<=
(
7
.
0
/
16
)
)
{
//puncturing
for
(
int
k
=
0
;
k
<=
E
-
1
;
k
++
)
{
rmp
[
k
]
=
y
[
k
+
N
-
E
];
}
}
else
{
//shortening
for
(
int
k
=
0
;
k
<=
E
-
1
;
k
++
)
{
rmp
[
k
]
=
y
[
k
];
}
}
}
free
(
d
);
free
(
y
);
}
void
nr_polar_rate_matching
(
double
*
input
,
double
*
output
,
uint16_t
*
rmp
,
uint16_t
K
,
uint16_t
N
,
uint16_t
E
){
if
(
E
>=
N
)
{
//repetition
for
(
int
i
=
0
;
i
<=
N
-
1
;
i
++
)
output
[
i
]
=
0
;
for
(
int
i
=
0
;
i
<=
E
-
1
;
i
++
){
output
[
rmp
[
i
]]
+=
input
[
i
];
}
}
else
{
if
(
(
K
/
(
double
)
E
)
<=
(
7
.
0
/
16
)
)
{
//puncturing
for
(
int
i
=
0
;
i
<=
N
-
1
;
i
++
)
output
[
i
]
=
0
;
}
else
{
//shortening
for
(
int
i
=
0
;
i
<=
N
-
1
;
i
++
)
output
[
i
]
=
INFINITY
;
}
for
(
int
i
=
0
;
i
<=
E
-
1
;
i
++
){
output
[
rmp
[
i
]]
=
input
[
i
];
}
}
}
void
nr_polar_rate_matcher
(
uint8_t
*
input
,
unsigned
char
*
output
,
uint16_t
*
pattern
,
uint16_t
size
)
{
for
(
int
i
=
0
;
i
<
size
;
i
++
)
output
[
i
]
=
input
[
pattern
[
i
]];
}
openair1/PHY/CODING/nrPolar_tools/nr_polar_sequence_pattern.c
0 → 100644
View file @
5cf8d93a
This diff is collapsed.
Click to expand it.
openair1/PHY/CODING/nrPolar_tools/nr_pucch_encoder.c
0 → 100644
View file @
5cf8d93a
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment