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
Michael Black
OpenXG-RAN
Commits
5cf8d93a
Commit
5cf8d93a
authored
6 years ago
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
);
}
This diff is collapsed.
Click to expand it.
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
);
}
This diff is collapsed.
Click to expand it.
openair1/PHY/CODING/nrPolar_tools/.gitkeep
0 → 100644
View file @
5cf8d93a
This diff is collapsed.
Click to expand it.
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
);
}
This diff is collapsed.
Click to expand it.
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
);
}
This diff is collapsed.
Click to expand it.
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
"
);
}
}
This diff is collapsed.
Click to expand it.
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
;
}
This diff is collapsed.
Click to expand it.
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
);
}
}
This diff is collapsed.
Click to expand it.
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
;
}
}
}
}
This diff is collapsed.
Click to expand it.
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
);
}
This diff is collapsed.
Click to expand it.
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
;
}
}
This diff is collapsed.
Click to expand it.
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
);
}
This diff is collapsed.
Click to expand it.
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
);
}
This diff is collapsed.
Click to expand it.
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
);
}
}
}
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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
);
}
This diff is collapsed.
Click to expand it.
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
++
;
}
}
}
This diff is collapsed.
Click to expand it.
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
];
}
This diff is collapsed.
Click to expand it.
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
]);
}
}
This diff is collapsed.
Click to expand it.
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
;
}
}
This diff is collapsed.
Click to expand it.
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
;
}
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
openair1/PHY/CODING/nrPolar_tools/nr_polar_plot.m
0 → 100644
View file @
5cf8d93a
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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
]];
}
This diff is collapsed.
Click to expand it.
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