Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG UE
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
lizhongxiao
OpenXG UE
Commits
eda57974
Commit
eda57974
authored
Oct 09, 2018
by
Raymond Knopp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added new polar decoder implementation
parent
59ec77ce
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
814 additions
and
391 deletions
+814
-391
cmake_targets/CMakeLists.txt
cmake_targets/CMakeLists.txt
+1
-0
openair1/PHY/CODING/TESTBENCH/polartest.c
openair1/PHY/CODING/TESTBENCH/polartest.c
+30
-7
openair1/PHY/CODING/nrPolar_init.c
openair1/PHY/CODING/nrPolar_init.c
+39
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
+180
-206
openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c
openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c
+308
-108
openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
+256
-70
No files found.
cmake_targets/CMakeLists.txt
View file @
eda57974
...
...
@@ -1123,6 +1123,7 @@ set(PHY_POLARSRC
${
OPENAIR1_DIR
}
/PHY/CODING/nrPolar_tools/nr_polar_bit_insertion.c
${
OPENAIR1_DIR
}
/PHY/CODING/nrPolar_tools/nr_polar_channel_interleaver_pattern.c
# ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_crc.c
# ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/decoder_K56_N512_E864.c
${
OPENAIR1_DIR
}
/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c
${
OPENAIR1_DIR
}
/PHY/CODING/nrPolar_tools/nr_polar_info_bit_pattern.c
${
OPENAIR1_DIR
}
/PHY/CODING/nrPolar_tools/nr_polar_interleaving_pattern.c
...
...
openair1/PHY/CODING/TESTBENCH/polartest.c
View file @
eda57974
...
...
@@ -43,8 +43,9 @@ int main(int argc, char *argv[]) {
double
timeEncoderCumulative
=
0
,
timeDecoderCumulative
=
0
;
uint8_t
decoderListSize
=
8
,
pathMetricAppr
=
0
;
//0 --> eq. (8a) and (11b), 1 --> eq. (9) and (12)
int
generate_optim_code
=
0
;
while
((
arguments
=
getopt
(
argc
,
argv
,
"s:d:f:m:i:l:a:h:q"
))
!=
-
1
)
while
((
arguments
=
getopt
(
argc
,
argv
,
"s:d:f:m:i:l:a:h:q
g
"
))
!=
-
1
)
switch
(
arguments
)
{
case
's'
:
...
...
@@ -80,6 +81,13 @@ int main(int argc, char *argv[]) {
decoder_int8
=
1
;
break
;
case
'g'
:
generate_optim_code
=
1
;
iterations
=
1
;
SNRstart
=-
6
.
0
;
SNRstop
=-
6
.
0
;
decoder_int8
=
1
;
break
;
case
'h'
:
printf
(
"./polartest -s SNRstart -d SNRinc -f SNRstop -m [0=DCI|1=PBCH|2=UCI] -i iterations -l decoderListSize -a pathMetricAppr
\n
"
);
exit
(
-
1
);
...
...
@@ -141,12 +149,18 @@ int main(int argc, char *argv[]) {
t_nrPolar_params
nrPolar_params
;
nr_polar_init
(
&
nrPolar_params
,
polarMessageType
);
nr_polar_llrtableinit
();
if
(
generate_optim_code
==
1
)
nrPolar_params
.
decoder_kernel
=
NULL
;
// 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
;
printf
(
"SNRstart %f, SNRstop %f,, SNRinc %f
\n
"
,
SNRstart
,
SNRstop
,
SNRinc
);
for
(
SNR
=
SNRstart
;
SNR
<=
SNRstop
;
SNR
+=
SNRinc
)
{
printf
(
"SNR %f
\n
"
,
SNR
);
SNR_lin
=
pow
(
10
,
SNR
/
10
);
for
(
itr
=
1
;
itr
<=
iterations
;
itr
++
)
{
...
...
@@ -165,20 +179,29 @@ int main(int argc, char *argv[]) {
modulatedInput
[
i
]
=
(
-
1
)
/
sqrt
(
2
);
channelOutput
[
i
]
=
modulatedInput
[
i
]
+
(
gaussdouble
(
0
.
0
,
1
.
0
)
*
(
1
/
sqrt
(
2
*
SNR_lin
)));
if
(
decoder_int8
==
1
)
{
if
(
channelOutput
[
i
]
>
1
024
)
channelOutput_int8
[
i
]
=
32768
;
else
if
(
channelOutput
[
i
]
<
-
1
023
)
channelOutput_int8
[
i
]
=
-
32767
;
else
channelOutput_int8
[
i
]
=
(
int16_t
)
(
32
*
channelOutput
[
i
]);
if
(
channelOutput
[
i
]
>
1
5
)
channelOutput_int8
[
i
]
=
127
;
else
if
(
channelOutput
[
i
]
<
-
1
6
)
channelOutput_int8
[
i
]
=
-
128
;
else
channelOutput_int8
[
i
]
=
(
int16_t
)
(
8
*
channelOutput
[
i
]);
}
}
start_meas
(
&
timeDecoder
);
if
(
decoder_int8
==
0
)
decoderState
=
polar_decoder
(
channelOutput
,
estimatedOutput
,
&
nrPolar_params
,
decoderListSize
,
aPrioriArray
,
pathMetricAppr
,
&
polar_decoder_init
,
&
polar_rate_matching
,
&
decoding
,
&
bit_extraction
,
&
deinterleaving
,
&
sorting
,
&
path_metric
,
&
update_LLR
);
if
(
decoder_int8
==
0
)
decoderState
=
polar_decoder
(
channelOutput
,
estimatedOutput
,
&
nrPolar_params
,
decoderListSize
,
aPrioriArray
,
pathMetricAppr
,
&
polar_decoder_init
,
&
polar_rate_matching
,
&
decoding
,
&
bit_extraction
,
&
deinterleaving
,
&
sorting
,
&
path_metric
,
&
update_LLR
);
else
decoderState
=
polar_decoder_int8
(
channelOutput_int8
,
estimatedOutput
,
&
nrPolar_params
,
decoderListSize
,
&
polar_decoder_init
,
&
polar_rate_matching
,
&
decoding
,
&
bit_extraction
,
&
deinterleaving
,
&
sorting
,
&
path_metric
,
&
update_LLR
);
decoderState
=
polar_decoder_int8_new
(
channelOutput_int8
,
estimatedOutput
,
&
nrPolar_params
,
decoderListSize
,
&
polar_decoder_init
,
&
polar_rate_matching
,
&
decoding
,
&
bit_extraction
,
&
deinterleaving
,
&
sorting
,
&
path_metric
,
&
update_LLR
,
generate_optim_code
);
stop_meas
(
&
timeDecoder
);
//calculate errors
if
(
decoderState
==-
1
)
{
blockErrorState
=-
1
;
...
...
openair1/PHY/CODING/nrPolar_init.c
View file @
eda57974
...
...
@@ -62,6 +62,11 @@ uint32_t poly24c = 0xB2B11700; //101100101011000100010111 -> D^24...
polarParams
->
nr_polar_u
=
malloc
(
sizeof
(
uint8_t
)
*
polarParams
->
N
);
//Decoder: nr_polar_uHat
polarParams
->
nr_polar_cPrime
=
malloc
(
sizeof
(
uint8_t
)
*
polarParams
->
K
);
//Decoder: nr_polar_cHat
polarParams
->
nr_polar_b
=
malloc
(
sizeof
(
uint8_t
)
*
polarParams
->
K
);
//Decoder: nr_polar_bHat
polarParams
->
decoder_kernel
=
NULL
;
//polar_decoder_K56_N512_E864;
}
else
if
(
messageType
==
2
)
{
//UCI
polarParams
->
payloadBits
=
NR_POLAR_PUCCH_PAYLOAD_BITS
;
//A depends on what they carry...
polarParams
->
encoderLength
=
NR_POLAR_PUCCH_E
;
//E depends on other standards 6.3.1.4
...
...
@@ -131,6 +136,7 @@ uint32_t poly24c = 0xB2B11700; //101100101011000100010111 -> D^24...
polarParams
->
nr_polar_u
=
malloc
(
sizeof
(
uint8_t
)
*
polarParams
->
N
);
//Decoder: nr_polar_uHat
polarParams
->
nr_polar_cPrime
=
malloc
(
sizeof
(
uint8_t
)
*
polarParams
->
K
);
//Decoder: nr_polar_cHat
polarParams
->
nr_polar_b
=
malloc
(
sizeof
(
uint8_t
)
*
polarParams
->
K
);
//Decoder: nr_polar_bHat
}
polarParams
->
crcCorrectionBits
=
NR_POLAR_CRC_ERROR_CORRECTION_BITS
;
...
...
@@ -161,5 +167,38 @@ uint32_t poly24c = 0xB2B11700; //101100101011000100010111 -> D^24...
nr_polar_channel_interleaver_pattern
(
polarParams
->
channel_interleaver_pattern
,
polarParams
->
i_bil
,
polarParams
->
encoderLength
);
polarParams
->
extended_crc_generator_matrix
=
malloc
(
polarParams
->
K
*
sizeof
(
uint8_t
*
));
//G_P3
uint8_t
tempECGM
[
polarParams
->
K
][
polarParams
->
crcParityBits
];
for
(
int
i
=
0
;
i
<
polarParams
->
K
;
i
++
){
polarParams
->
extended_crc_generator_matrix
[
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
]
=
polarParams
->
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
++
)
{
polarParams
->
extended_crc_generator_matrix
[
i
][
j
]
=
tempECGM
[
polarParams
->
interleaving_pattern
[
i
]][
j
];
}
}
build_decoder_tree
(
polarParams
);
printf
(
"decoder tree nodes %d
\n
"
,
polarParams
->
tree
.
num_nodes
);
free
(
J
);
}
openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
View file @
eda57974
...
...
@@ -29,7 +29,6 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "PHY/TOOLS/time_meas.h"
#define SHOWCOMP 1
int8_t
polar_decoder
(
double
*
input
,
...
...
@@ -50,31 +49,6 @@ int8_t polar_decoder(
start_meas
(
init
);
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
decoder_list_t
dlist
[
2
*
listSize
];
for
(
int
i
=
0
;
i
<
2
*
listSize
;
i
++
)
{
// dlist[i].bit = nr_alloc_uint8_t_2D_array((polarParams->n+1), polarParams->N);
// dlist[i].llr = nr_alloc_double_2D_array((polarParams->n+1), polarParams->N);
//dlist[i].crcChecksum = malloc(sizeof(uint8_t)*polarParams->crcParityBits);
for
(
int
j
=
0
;
j
<
polarParams
->
n
+
1
;
j
++
)
{
memset
((
void
*
)
&
dlist
[
i
].
bit
[
j
][
0
],
0
,
sizeof
(
uint8_t
)
*
polarParams
->
N
);
memset
((
void
*
)
&
dlist
[
i
].
llr
[
j
][
0
],
0
,
sizeof
(
double
)
*
polarParams
->
N
);
}
for
(
int
j
=
0
;
j
<
polarParams
->
crcParityBits
;
j
++
)
dlist
[
i
].
crcChecksum
[
j
]
=
0
;
dlist
[
i
].
pathMetric
=
0
;
}
for
(
int
i
=
0
;
i
<
polarParams
->
N
;
i
++
)
{
memset
((
void
*
)
&
llrUpdated
[
i
][
0
],
0
,
sizeof
(
uint8_t
)
*
polarParams
->
n
);
memset
((
void
*
)
&
bitUpdated
[
i
][
0
],
0
,
sizeof
(
uint8_t
)
*
polarParams
->
n
);
llrUpdated
[
i
][
polarParams
->
n
]
=
1
;
bitUpdated
[
i
][
0
]
=
((
polarParams
->
information_bit_pattern
[
i
]
+
1
)
%
2
);
}
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
++
){
...
...
@@ -102,6 +76,31 @@ int8_t polar_decoder(
extended_crc_generator_matrix
[
i
][
j
]
=
tempECGM
[
polarParams
->
interleaving_pattern
[
i
]][
j
];
}
}
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
decoder_list_t
dlist
[
2
*
listSize
];
for
(
int
i
=
0
;
i
<
2
*
listSize
;
i
++
)
{
// dlist[i].bit = nr_alloc_uint8_t_2D_array((polarParams->n+1), polarParams->N);
// dlist[i].llr = nr_alloc_double_2D_array((polarParams->n+1), polarParams->N);
//dlist[i].crcChecksum = malloc(sizeof(uint8_t)*polarParams->crcParityBits);
for
(
int
j
=
0
;
j
<
polarParams
->
n
+
1
;
j
++
)
{
memset
((
void
*
)
&
dlist
[
i
].
bit
[
j
][
0
],
0
,
sizeof
(
uint8_t
)
*
polarParams
->
N
);
memset
((
void
*
)
&
dlist
[
i
].
llr
[
j
][
0
],
0
,
sizeof
(
double
)
*
polarParams
->
N
);
}
for
(
int
j
=
0
;
j
<
polarParams
->
crcParityBits
;
j
++
)
dlist
[
i
].
crcChecksum
[
j
]
=
0
;
dlist
[
i
].
pathMetric
=
0
;
}
for
(
int
i
=
0
;
i
<
polarParams
->
N
;
i
++
)
{
memset
((
void
*
)
&
llrUpdated
[
i
][
0
],
0
,
sizeof
(
uint8_t
)
*
polarParams
->
n
);
memset
((
void
*
)
&
bitUpdated
[
i
][
0
],
0
,
sizeof
(
uint8_t
)
*
polarParams
->
n
);
llrUpdated
[
i
][
polarParams
->
n
]
=
1
;
bitUpdated
[
i
][
0
]
=
((
polarParams
->
information_bit_pattern
[
i
]
+
1
)
%
2
);
}
stop_meas
(
init
);
start_meas
(
polar_rate_matching
);
...
...
@@ -155,6 +154,7 @@ int8_t polar_decoder(
start_meas
(
sorting
);
if
(
currentListSize
<=
listSize
/
2
)
{
// until listsize is full we need to copy bit and LLR arrays to new entries
// below we only copy the ones we need to keep for sure
...
...
@@ -290,92 +290,8 @@ int8_t polar_decoder(
}
#define decoder_int8_A(sorted_dlist,currentListSize,polarParams) {for (int i = 0; i < currentListSize; i++) { \
for (int k = 0; k < (polarParams->n+1); k++) { \
memcpy((void*)&sorted_dlist[i+currentListSize]->bit[k][0],\
(void*)&sorted_dlist[i]->bit[k][0],\
sizeof(uint8_t)*polarParams->N);\
memcpy((void*)&sorted_dlist[i+currentListSize]->llr[k][0],\
(void*)&sorted_dlist[i]->llr[k][0],\
sizeof(int16_t)*polarParams->N);}}}
#define decoder_int8_B(sorted_dlist,currentListSize) {for (int i = 0; i < currentListSize; i++) {sorted_dlist[i]->bit[0][currentBit]=0;sorted_dlist[i+currentListSize]->bit[0][currentBit]=1;}}
void
inline
decoder_int8_C
(
decoder_list_int8_t
*
sorted_dlist
[],
t_nrPolar_params
*
polarParams
,
int
currentBit
,
int
currentListSize
,
int
listSize
)
{
int32_t
pathMetric
[
2
*
listSize
];
decoder_list_int8_t
*
temp_dlist
[
2
*
listSize
];
int
listIndex
[
2
*
listSize
];
int
listIndex2
[
2
*
listSize
];
for
(
int
i
=
0
;
i
<
currentListSize
;
i
++
)
{
listIndex
[
i
]
=
i
;
pathMetric
[
i
]
=
sorted_dlist
[
i
]
->
pathMetric
;
}
nr_sort_asc_int16_1D_array_ind
(
pathMetric
,
listIndex
,
currentListSize
);
for
(
int
i
=
0
;
i
<
currentListSize
;
i
++
)
{
listIndex2
[
listIndex
[
i
]]
=
i
;
}
// copy the llr/bit arrays that are needed
for
(
int
i
=
0
;
i
<
listSize
;
i
++
)
{
// printf("listIndex[%d] %d\n",i,listIndex[i]);
if
((
listIndex2
[
i
+
listSize
]
<
listSize
)
&&
(
listIndex2
[
i
]
<
listSize
))
{
// both '0' and '1' path metrics are to be kept
// do memcpy of LLR and Bit arrays
for
(
int
k
=
0
;
k
<
(
polarParams
->
n
+
1
);
k
++
)
{
memcpy
((
void
*
)
&
sorted_dlist
[
i
+
listSize
]
->
bit
[
k
][
0
],
(
void
*
)
&
sorted_dlist
[
i
]
->
bit
[
k
][
0
],
sizeof
(
uint8_t
)
*
polarParams
->
N
);
memcpy
((
void
*
)
&
sorted_dlist
[
i
+
listSize
]
->
llr
[
k
][
0
],
(
void
*
)
&
sorted_dlist
[
i
]
->
llr
[
k
][
0
],
sizeof
(
int16_t
)
*
polarParams
->
N
);
}
sorted_dlist
[
i
]
->
bit
[
0
][
currentBit
]
=
0
;
sorted_dlist
[
i
+
listSize
]
->
bit
[
0
][
currentBit
]
=
1
;
}
else
if
(
listIndex2
[
i
+
listSize
]
<
listSize
)
{
// only '1' path metric is to be kept
// just change the current bit from '0' to '1'
for
(
int
k
=
0
;
k
<
(
polarParams
->
n
+
1
);
k
++
)
{
memcpy
((
void
*
)
&
sorted_dlist
[
i
+
listSize
]
->
bit
[
k
][
0
],
(
void
*
)
&
sorted_dlist
[
i
]
->
bit
[
k
][
0
],
sizeof
(
uint8_t
)
*
polarParams
->
N
);
memcpy
((
void
*
)
&
sorted_dlist
[
i
+
listSize
]
->
llr
[
k
][
0
],
(
void
*
)
&
sorted_dlist
[
i
]
->
llr
[
k
][
0
],
sizeof
(
int16_t
)
*
polarParams
->
N
);
}
sorted_dlist
[
i
+
listSize
]
->
bit
[
0
][
currentBit
]
=
1
;
/*
decoder_list_t *tmp = sorted_dlist[i+listSize];
sorted_dlist[i+listSize] = sorted_dlist[i];
sorted_dlist[i+listSize]->pathMetric = tmp->pathMetric;
sorted_dlist[i+listSize]->bit[0][currentBit]=1;
memcpy((void*)&sorted_dlist[i+listSize]->crcChecksum[0],
(void*)&tmp->crcChecksum[0],
24*sizeof(uint8_t));*/
}
}
for
(
int
i
=
0
;
i
<
2
*
listSize
;
i
++
)
{
temp_dlist
[
i
]
=
sorted_dlist
[
i
];
}
for
(
int
i
=
0
;
i
<
2
*
listSize
;
i
++
)
{
// printf("i %d => %d\n",i,listIndex[i]);
sorted_dlist
[
i
]
=
temp_dlist
[
listIndex
[
i
]];
}
}
int8_t
polar_decoder_int8
(
int16_t
*
input
,
uint8_t
*
output
,
t_nrPolar_params
*
polarParams
,
...
...
@@ -387,16 +303,22 @@ int8_t polar_decoder_int8(int16_t *input,
time_stats_t
*
deinterleaving
,
time_stats_t
*
sorting
,
time_stats_t
*
path_metric
,
time_stats_t
*
update_LLR
)
time_stats_t
*
update_LLR
,
int
generate_optim_code
)
{
start_meas
(
init
);
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
uint8_t
**
bitUpdated
;
uint8_t
**
llrUpdated
;
if
(
generate_optim_code
==
1
||
polarParams
->
decoder_kernel
==
NULL
)
{
bitUpdated
=
nr_alloc_uint8_t_2D_array
(
polarParams
->
N
,
(
polarParams
->
n
+
1
));
//0=False, 1=True
llrUpdated
=
nr_alloc_uint8_t_2D_array
(
polarParams
->
N
,
(
polarParams
->
n
+
1
));
//0=False, 1=True
}
decoder_list_int8_t
dlist
[
2
*
listSize
];
start_meas
(
init
);
for
(
int
i
=
0
;
i
<
2
*
listSize
;
i
++
)
{
// dlist[i].bit = nr_alloc_uint8_t_2D_array((polarParams->n+1), polarParams->N);
...
...
@@ -409,48 +331,28 @@ int8_t polar_decoder_int8(int16_t *input,
for
(
int
j
=
0
;
j
<
polarParams
->
crcParityBits
;
j
++
)
dlist
[
i
].
crcChecksum
[
j
]
=
0
;
dlist
[
i
].
pathMetric
=
0
;
}
stop_meas
(
init
);
for
(
int
i
=
0
;
i
<
polarParams
->
N
;
i
++
)
{
memset
((
void
*
)
&
llrUpdated
[
i
][
0
],
0
,
sizeof
(
uint8_t
)
*
polarParams
->
n
);
memset
((
void
*
)
&
bitUpdated
[
i
][
0
],
0
,
sizeof
(
uint8_t
)
*
polarParams
->
n
);
llrUpdated
[
i
][
polarParams
->
n
]
=
1
;
bitUpdated
[
i
][
0
]
=
((
polarParams
->
information_bit_pattern
[
i
]
+
1
)
%
2
);
}
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
]
=
polarParams
->
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
;
}
if
(
generate_optim_code
==
1
||
polarParams
->
decoder_kernel
==
NULL
)
{
for
(
int
i
=
0
;
i
<
polarParams
->
N
;
i
++
)
{
memset
((
void
*
)
&
llrUpdated
[
i
][
0
],
0
,
sizeof
(
uint8_t
)
*
polarParams
->
n
);
memset
((
void
*
)
&
bitUpdated
[
i
][
0
],
0
,
sizeof
(
uint8_t
)
*
polarParams
->
n
);
llrUpdated
[
i
][
polarParams
->
n
]
=
1
;
bitUpdated
[
i
][
0
]
=
((
polarParams
->
information_bit_pattern
[
i
]
+
1
)
%
2
);
}
}
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
];
}
}
stop_meas
(
init
);
start_meas
(
polar_rate_matching
);
int16_t
d_tilde
[
polarParams
->
N
];
// = malloc(sizeof(double) * polarParams->N);
nr_polar_rate_matching_int8
(
input
,
d_tilde
,
polarParams
->
rate_matching_pattern
,
polarParams
->
K
,
polarParams
->
N
,
polarParams
->
encoderLength
);
for
(
int
i
=
0
;
i
<
polarParams
->
N
;
i
++
)
{
if
(
d_tilde
[
i
]
<-
128
)
d_tilde
[
i
]
=-
128
;
else
if
(
d_tilde
[
i
]
>
127
)
d_tilde
[
i
]
=
128
;
}
memcpy
((
void
*
)
&
dlist
[
0
].
llr
[
polarParams
->
n
][
0
],(
void
*
)
&
d_tilde
[
0
],
sizeof
(
int16_t
)
*
polarParams
->
N
);
stop_meas
(
polar_rate_matching
);
...
...
@@ -464,70 +366,81 @@ int8_t polar_decoder_int8(int16_t *input,
decoder_list_int8_t
*
sorted_dlist
[
2
*
listSize
];
for
(
uint8_t
i
=
0
;
i
<
2
*
listSize
;
i
++
)
sorted_dlist
[
i
]
=
&
dlist
[
i
];
char
fname
[
100
];
FILE
*
fd
;
if
(
generate_optim_code
==
1
)
{
sprintf
(
fname
,
"decoder_K%d_N%d_E%d.c"
,
polarParams
->
K
,
polarParams
->
N
,
polarParams
->
encoderLength
);
if
((
fd
=
fopen
(
fname
,
"w"
))
==
NULL
)
{
printf
(
"Cannot open %s
\n
"
,
fname
);
exit
(
-
1
);}
fprintf
(
fd
,
"#include
\"
nr_polar_defs.h
\"\n
"
);
fprintf
(
fd
,
"void polar_decoder_K%d_N%d_E%d(t_nrPolar_params *polarParams,decoder_list_int8_t **sorted_dlist) {
\n
"
,
polarParams
->
K
,
polarParams
->
N
,
polarParams
->
encoderLength
);
fprintf
(
fd
,
"int16_t mask,absllr;
\n
"
);
}
for
(
uint16_t
currentBit
=
0
;
currentBit
<
polarParams
->
N
;
currentBit
++
){
// printf("***************** BIT %d (currentListSize %d, information_bit_pattern %d)\n",
// currentBit,currentListSize,polarParams->information_bit_pattern[currentBit]);
start_meas
(
update_LLR
);
updateLLR_int8
(
sorted_dlist
,
llrUpdated
,
bitUpdated
,
currentListSize
,
currentBit
,
0
,
polarParams
->
N
,
(
polarParams
->
n
+
1
));
stop_meas
(
update_LLR
);
if
(
polarParams
->
information_bit_pattern
[
currentBit
]
==
0
)
{
//Frozen bit.
updatePathMetric0_int8
(
sorted_dlist
,
currentListSize
,
currentBit
);
//approximation=0 --> 11b, approximation=1 --> 12
}
else
{
//Information or CRC bit.
start_meas
(
path_metric
);
updatePathMetric2_int8
(
sorted_dlist
,
currentListSize
,
currentBit
);
stop_meas
(
path_metric
);
if
(
polarParams
->
decoder_kernel
)
polarParams
->
decoder_kernel
(
polarParams
,
sorted_dlist
);
else
{
for
(
uint16_t
currentBit
=
0
;
currentBit
<
polarParams
->
N
;
currentBit
++
){
printf
(
"***************** BIT %d (currentListSize %d, information_bit_pattern %d)
\n
"
,
currentBit
,
currentListSize
,
polarParams
->
information_bit_pattern
[
currentBit
]);
start_meas
(
sorting
);
start_meas
(
update_LLR
);
updateLLR_int8
(
sorted_dlist
,
llrUpdated
,
bitUpdated
,
currentListSize
,
currentBit
,
0
,
polarParams
->
N
,
(
polarParams
->
n
+
1
),
generate_optim_code
,
fd
);
stop_meas
(
update_LLR
);
if
(
currentListSize
<=
listSize
/
2
)
{
// until listsize is full we need to copy bit and LLR arrays to new entries
// below we only copy the ones we need to keep for sure
decoder_int8_A
(
sorted_dlist
,
currentListSize
,
polarParams
);
#ifdef SHOWCOMP
printf
(
"decoder_int8_A(sorted_dlist,%d,polarParams);
\n
"
,
currentListSize
);
#endif
}
decoder_int8_B
(
sorted_dlist
,
currentListSize
);
#ifdef SHOWCOMP
printf
(
"decoder_int8_B(sorted_dlist,%d);
\n
"
,
currentListSize
);
#endif
if
(
polarParams
->
information_bit_pattern
[
currentBit
]
==
0
)
{
//Frozen bit.
updatePathMetric0_int8
(
sorted_dlist
,
currentListSize
,
currentBit
,
generate_optim_code
,
fd
);
//approximation=0 --> 11b, approximation=1 --> 12
}
else
{
//Information or CRC bit.
start_meas
(
path_metric
);
updatePathMetric2_int8
(
sorted_dlist
,
currentListSize
,
currentBit
,
generate_optim_code
,
fd
);
stop_meas
(
path_metric
);
bitUpdated
[
currentBit
][
0
]
=
1
;
updateCrcChecksum2_int8
(
sorted_dlist
,
extended_crc_generator_matrix
,
currentListSize
,
nonFrozenBit
,
polarParams
->
crcParityBits
);
currentListSize
*=
2
;
//Keep only the best "listSize" number of entries.
if
(
currentListSize
>
listSize
)
{
decoder_int8_C
(
sorted_dlist
,
polarParams
,
currentBit
,
currentListSize
,
listSize
);
#ifdef SHOWCOMP
printf
(
"decoder_int8_C(sorted_dlist,polarParams,%d,%d,%d);
\n
"
,
currentBit
,
currentListSize
,
listSize
);
#endif
currentListSize
=
listSize
;
start_meas
(
sorting
);
if
(
currentListSize
<=
listSize
/
2
)
{
// until listsize is full we need to copy bit and LLR arrays to new entries
// below we only copy the ones we need to keep for sure
decoder_int8_A
(
sorted_dlist
,
currentListSize
,
polarParams
);
if
(
generate_optim_code
==
1
)
fprintf
(
fd
,
"decoder_int8_A(sorted_dlist,%d,polarParams);
\n
"
,
currentListSize
);
}
decoder_int8_B
(
sorted_dlist
,
currentBit
,
currentListSize
);
if
(
generate_optim_code
==
1
)
fprintf
(
fd
,
"decoder_int8_B(sorted_dlist,%d,%d);
\n
"
,
currentBit
,
currentListSize
);
bitUpdated
[
currentBit
][
0
]
=
1
;
updateCrcChecksum2_int8
(
sorted_dlist
,
polarParams
->
extended_crc_generator_matrix
,
currentListSize
,
nonFrozenBit
,
polarParams
->
crcParityBits
,
generate_optim_code
,
fd
);
currentListSize
*=
2
;
//Keep only the best "listSize" number of entries.
if
(
currentListSize
>
listSize
)
{
decoder_int8_C
(
sorted_dlist
,
polarParams
,
currentBit
,
currentListSize
,
listSize
);
if
(
generate_optim_code
==
1
)
fprintf
(
fd
,
"decoder_int8_C(sorted_dlist,polarParams,%d,%d,%d);
\n
"
,
currentBit
,
currentListSize
,
listSize
);
currentListSize
=
listSize
;
}
stop_meas
(
sorting
);
nonFrozenBit
++
;
}
stop_meas
(
sorting
);
nonFrozenBit
++
;
}
}
}
if
(
generate_optim_code
==
1
)
fprintf
(
fd
,
"}
\n
"
);
for
(
uint8_t
i
=
0
;
i
<
fmin
(
listSize
,
(
pow
(
2
,
polarParams
->
crcCorrectionBits
))
);
i
++
)
{
//
printf("list index %d :",i
);
//
for (int j=0;j<polarParams->crcParityBits;j++) printf("%d",sorted_dlist[i]->crcChecksum[j]);
//
printf(" => %d (%f)\n",sorted_dlist[i]->crcState
,sorted_dlist[i]->pathMetric);
//
printf("list index %d / %d :",i,listSize
);
//
for (int j=0;j<polarParams->crcParityBits;j++) printf("%d",sorted_dlist[i]->crcChecksum[j]);
//
printf(" => (%d)\n"
,sorted_dlist[i]->pathMetric);
int
crcState
=
1
;
for
(
int
j
=
0
;
j
<
polarParams
->
crcParityBits
;
j
++
)
if
(
sorted_dlist
[
i
]
->
crcChecksum
[
j
]
!=
0
)
crcState
=
0
;
if
(
crcState
==
1
)
{
...
...
@@ -556,8 +469,69 @@ int8_t polar_decoder_int8(int16_t *input,
nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1));
free(dlist[i].crcChecksum);
}*/
nr_free_uint8_t_2D_array
(
extended_crc_generator_matrix
,
polarParams
->
K
);
nr_free_uint8_t_2D_array
(
tempECGM
,
polarParams
->
K
);
stop_meas
(
decoding
);
return
(
0
);
}
int8_t
polar_decoder_int8_new
(
int16_t
*
input
,
uint8_t
*
output
,
t_nrPolar_params
*
polarParams
,
uint8_t
listSize
,
time_stats_t
*
init
,
time_stats_t
*
polar_rate_matching
,
time_stats_t
*
decoding
,
time_stats_t
*
bit_extraction
,
time_stats_t
*
deinterleaving
,
time_stats_t
*
sorting
,
time_stats_t
*
path_metric
,
time_stats_t
*
update_LLR
,
int
generate_optim_code
)
{
start_meas
(
init
);
stop_meas
(
init
);
start_meas
(
polar_rate_matching
);
int16_t
d_tilde
[
polarParams
->
N
];
// = malloc(sizeof(double) * polarParams->N);
nr_polar_rate_matching_int8
(
input
,
d_tilde
,
polarParams
->
rate_matching_pattern
,
polarParams
->
K
,
polarParams
->
N
,
polarParams
->
encoderLength
);
for
(
int
i
=
0
;
i
<
polarParams
->
N
;
i
++
)
{
if
(
d_tilde
[
i
]
<-
128
)
d_tilde
[
i
]
=-
128
;
else
if
(
d_tilde
[
i
]
>
127
)
d_tilde
[
i
]
=
128
;
}
memcpy
((
void
*
)
&
polarParams
->
tree
.
root
->
alpha
[
0
],(
void
*
)
&
d_tilde
[
0
],
sizeof
(
int16_t
)
*
polarParams
->
N
);
stop_meas
(
polar_rate_matching
);
/*
* SCL polar decoder.
*/
start_meas
(
decoding
);
generic_polar_decoder
(
polarParams
,
polarParams
->
tree
.
root
);
start_meas
(
bit_extraction
);
//Extract the information bits (û to ĉ)
nr_polar_info_bit_extraction
(
polarParams
->
nr_polar_u
,
polarParams
->
nr_polar_cPrime
,
polarParams
->
information_bit_pattern
,
polarParams
->
N
);
stop_meas
(
bit_extraction
);
//Deinterleaving (ĉ to b)
start_meas
(
deinterleaving
);
nr_polar_deinterleaver
(
polarParams
->
nr_polar_cPrime
,
polarParams
->
nr_polar_b
,
polarParams
->
interleaving_pattern
,
polarParams
->
K
);
stop_meas
(
deinterleaving
);
//Remove the CRC (â)
for
(
int
j
=
0
;
j
<
polarParams
->
payloadBits
;
j
++
)
output
[
j
]
=
polarParams
->
nr_polar_b
[
j
];
// free(d_tilde);
/*
for (int i=0;i<2*listSize;i++) {
// printf("correct: Freeing dlist[%d].bit %p\n",i,dlist[i].bit);
nr_free_uint8_t_2D_array(dlist[i].bit, (polarParams->n+1));
nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1));
free(dlist[i].crcChecksum);
}*/
stop_meas
(
decoding
);
return
(
0
);
}
openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c
View file @
eda57974
...
...
@@ -19,8 +19,9 @@
* contact@openairinterface.org
*/
#include "PHY/impl_defs_top.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#
define SHOWCOMP 1
#
include "PHY/sse_intrin.h"
inline
void
computeLLR
(
double
llr
[
1
+
nmax
][
Nmax
],
uint16_t
row
,
uint16_t
col
,
uint16_t
offset
,
uint8_t
approximation
)
__attribute__
((
always_inline
));
...
...
@@ -45,40 +46,28 @@ inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col,
// printf("LLR (a %f, b %f): llr[%d][%d] %f\n",32*a,32*b,col,row,32*llr[col][row]);
}
inline
void
computeLLR_int8
(
decoder_list_int8_t
**
dlist
,
int
i
,
uint16_t
row
,
uint16_t
col
,
uint16_t
offset
)
__attribute__
((
always_inline
));
inline
void
computeLLR_int8
(
decoder_list_int8_t
**
dlist
,
int
i
,
uint16_t
row
,
uint16_t
col
,
uint16_t
offset
)
{
int16_t
llrtab
[
256
][
256
];
int16_t
a
;
int16_t
b
;
int16_t
absA
,
absB
;
int16_t
maska
,
maskb
;
int16_t
minabs
;
// int16_t **llr=dlist[i]->llr;
void
nr_polar_llrtableinit
()
{
int16_t
absA
,
absB
;
int16_t
maska
,
maskb
;
int16_t
minabs
;
#ifdef SHOWCOMP
printf
(
"computeLLR_int8(sorted_dlist,%d,%d,%d);
\n
"
,
i
,
row
,
col
,
offset
);
#endif
a
=
dlist
[
i
]
->
llr
[
col
+
1
][
row
];
b
=
dlist
[
i
]
->
llr
[
col
+
1
][
row
+
offset
];
// printf("LLR: a %d, b %d\n",a,b);
maska
=
a
>>
15
;
maskb
=
b
>>
15
;
absA
=
(
a
+
maska
)
^
maska
;
absB
=
(
b
+
maskb
)
^
maskb
;
// printf("LLR: absA %d, absB %d\n",absA,absB);
minabs
=
absA
<
absB
?
absA
:
absB
;
if
((
maska
^
maskb
)
==
0
)
dlist
[
i
]
->
llr
[
col
][
row
]
=
minabs
;
else
dlist
[
i
]
->
llr
[
col
][
row
]
=
-
minabs
;
// printf("LLR (a %d, b %d): llr[%d][%d] %d\n",a,b,col,row,llr[col][row]);
for
(
int
a
=-
128
;
a
<
128
;
a
++
)
{
for
(
int
b
=-
128
;
b
<
128
;
b
++
)
{
absA
=
abs
(
a
);
absB
=
abs
(
b
);
minabs
=
absA
<
absB
?
absA
:
absB
;
if
((
a
<
0
&&
b
<
0
)
||
(
a
>=
0
&&
b
>=
0
))
llrtab
[
a
+
128
][
b
+
128
]
=
minabs
;
else
llrtab
[
a
+
128
][
b
+
128
]
=
-
minabs
;
}
}
}
void
updateLLR
(
decoder_list_t
**
dlist
,
uint8_t
**
llrU
,
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
/
(
1
<<
(
ylen
-
col
-
1
)));
if
((
(
row
)
%
(
2
*
offset
)
)
>=
offset
)
{
if
(
bitU
[
row
-
offset
][
col
]
==
0
)
updateBit
(
dlist
,
bitU
,
listSize
,
(
row
-
offset
),
col
,
xlen
,
ylen
);
...
...
@@ -96,33 +85,25 @@ void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU,
llrU
[
row
][
col
]
=
1
;
}
#define updateLLR_int8_A(dlist,i,col,row,offset) if (dlist[(i)]->bit[(col)][(row)-(offset)]==0) dlist[(i)]->llr[(col)][(row)] = dlist[(i)]->llr[(col)+1][(row)-(offset)] + dlist[(i)]->llr[(col)+1][(row)]; else dlist[(i)]->llr[(col)][(row)] = -dlist[(i)]->llr[(col)+1][(row)-(offset)] + dlist[(i)]->llr[(col)+1][(row)];
void
updateLLR_int8
(
decoder_list_int8_t
**
dlist
,
uint8_t
**
llrU
,
uint8_t
**
bitU
,
uint8_t
listSize
,
uint16_t
row
,
uint16_t
col
,
uint16_t
xlen
,
uint8_t
ylen
)
{
uint8_t
listSize
,
uint16_t
row
,
uint16_t
col
,
uint16_t
xlen
,
uint8_t
ylen
,
int
generate_optim_code
,
FILE
*
fd
)
{
uint16_t
offset
=
(
xlen
/
(
1
<<
(
ylen
-
col
-
1
)));
if
((
(
row
)
%
(
2
*
offset
)
)
>=
offset
)
{
if
(
bitU
[
row
-
offset
][
col
]
==
0
)
updateBit_int8
(
dlist
,
bitU
,
listSize
,
(
row
-
offset
),
col
,
xlen
,
ylen
);
if
(
llrU
[
row
-
offset
][
col
+
1
]
==
0
)
updateLLR_int8
(
dlist
,
llrU
,
bitU
,
listSize
,
(
row
-
offset
),
(
col
+
1
),
xlen
,
ylen
);
if
(
llrU
[
row
][
col
+
1
]
==
0
)
updateLLR_int8
(
dlist
,
llrU
,
bitU
,
listSize
,
row
,
(
col
+
1
),
xlen
,
ylen
);
if
(
bitU
[
row
-
offset
][
col
]
==
0
)
updateBit_int8
(
dlist
,
bitU
,
listSize
,
(
row
-
offset
),
col
,
xlen
,
ylen
,
generate_optim_code
,
fd
);
if
(
llrU
[
row
-
offset
][
col
+
1
]
==
0
)
updateLLR_int8
(
dlist
,
llrU
,
bitU
,
listSize
,
(
row
-
offset
),
(
col
+
1
),
xlen
,
ylen
,
generate_optim_code
,
fd
);
if
(
llrU
[
row
][
col
+
1
]
==
0
)
updateLLR_int8
(
dlist
,
llrU
,
bitU
,
listSize
,
row
,
(
col
+
1
),
xlen
,
ylen
,
generate_optim_code
,
fd
);
for
(
uint8_t
i
=
0
;
i
<
listSize
;
i
++
)
{
#ifdef SHOWCOMP
printf
(
"updateLLR_int8_A(sorted_dlist,%d,%d,%d,%d);
\n
"
,
i
,
row
,
col
,
offset
);
#endif
updateLLR_int8_A
(
dlist
,
i
,
col
,
row
,
offset
);
/*
if (dlist[i]->bit[col][row-offset]==0)
dlist[i]->llr[col][row] = dlist[i]->llr[col+1][row-offset] + dlist[i]->llr[col+1][row];
else
dlist[i]->llr[col][row] = -dlist[i]->llr[col+1][row-offset] + dlist[i]->llr[col+1][row];*/
}
if
(
generate_optim_code
==
1
)
fprintf
(
fd
,
"updateLLR_int8_A(sorted_dlist,%d,%d,%d,%d);
\n
"
,
listSize
,
col
,
row
,
offset
);
updateLLR_int8_A
(
dlist
,
listSize
,
col
,
row
,
offset
);
}
else
{
if
(
llrU
[
row
][
col
+
1
]
==
0
)
updateLLR_int8
(
dlist
,
llrU
,
bitU
,
listSize
,
row
,
(
col
+
1
),
xlen
,
ylen
);
if
(
llrU
[
row
+
offset
][
col
+
1
]
==
0
)
updateLLR_int8
(
dlist
,
llrU
,
bitU
,
listSize
,
(
row
+
offset
),
(
col
+
1
),
xlen
,
ylen
);
for
(
int
i
=
0
;
i
<
listSize
;
i
++
)
computeLLR_int8
(
dlist
,
i
,
row
,
col
,
offset
);
if
(
llrU
[
row
][
col
+
1
]
==
0
)
updateLLR_int8
(
dlist
,
llrU
,
bitU
,
listSize
,
row
,
(
col
+
1
),
xlen
,
ylen
,
generate_optim_code
,
fd
);
if
(
llrU
[
row
+
offset
][
col
+
1
]
==
0
)
updateLLR_int8
(
dlist
,
llrU
,
bitU
,
listSize
,
(
row
+
offset
),
(
col
+
1
),
xlen
,
ylen
,
generate_optim_code
,
fd
);
if
(
generate_optim_code
==
1
)
fprintf
(
fd
,
"computeLLR_int8(sorted_dlist,%d,%d,%d,%d);
\n
"
,
listSize
,
row
,
col
,
offset
);
computeLLR_int8
(
dlist
,
listSize
,
row
,
col
,
offset
);
}
llrU
[
row
][
col
]
=
1
;
...
...
@@ -146,33 +127,35 @@ void updateBit(decoder_list_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_
bitU
[
row
][
col
]
=
1
;
}
#define updateBit_int8_A(dlist,i,col,row) dlist[(i)]->bit[(col)][(row)] = dlist[(i)]->bit[(col)-1][(row)]
#define updateBit_int8_B(dlist,i,col,row,offset) dlist[(i)]->bit[(col)][(row)] = dlist[(i)]->bit[(col)-1][(row)]^dlist[(i)]->bit[(col)-1][(row)+(offset)]
void
updateBit_int8
(
decoder_list_int8_t
**
dlist
,
uint8_t
**
bitU
,
uint8_t
listSize
,
uint16_t
row
,
uint16_t
col
,
uint16_t
xlen
,
uint8_t
ylen
)
{
void
updateBit_int8
(
decoder_list_int8_t
**
dlist
,
uint8_t
**
bitU
,
uint8_t
listSize
,
uint16_t
row
,
uint16_t
col
,
uint16_t
xlen
,
uint8_t
ylen
,
int
generate_optim_code
,
FILE
*
fd
)
{
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_int8
(
dlist
,
bitU
,
listSize
,
row
,
(
col
-
1
),
xlen
,
ylen
);
// dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row];
#ifdef SHOWCOMP
printf
(
"updateBit_int8_A(sorted_dlist,%d,%d,%d);
\n
"
,
i
,
col
,
row
);
#endif
updateBit_int8_A
(
dlist
,
i
,
col
,
row
);
if
((
(
row
)
%
(
2
*
offset
)
)
>=
offset
)
{
}
else
{
if
(
bitU
[
row
][
col
-
1
]
==
0
)
updateBit_int8
(
dlist
,
bitU
,
listSize
,
row
,
(
col
-
1
),
xlen
,
ylen
);
if
(
bitU
[
row
+
offset
][
col
-
1
]
==
0
)
updateBit_int8
(
dlist
,
bitU
,
listSize
,
(
row
+
offset
),
(
col
-
1
),
xlen
,
ylen
);
if
(
bitU
[
row
][
col
-
1
]
==
0
)
updateBit_int8
(
dlist
,
bitU
,
listSize
,
row
,
(
col
-
1
),
xlen
,
ylen
,
generate_optim_code
,
fd
);
// dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row];
if
(
generate_optim_code
==
1
)
fprintf
(
fd
,
"updateBit_int8_A(sorted_dlist,%d,%d,%d);
\n
"
,
listSize
,
col
,
row
);
updateBit_int8_A
(
dlist
,
listSize
,
col
,
row
);
}
else
{
if
(
bitU
[
row
][
col
-
1
]
==
0
)
updateBit_int8
(
dlist
,
bitU
,
listSize
,
row
,
(
col
-
1
),
xlen
,
ylen
,
generate_optim_code
,
fd
);
if
(
bitU
[
row
+
offset
][
col
-
1
]
==
0
)
updateBit_int8
(
dlist
,
bitU
,
listSize
,
(
row
+
offset
),
(
col
-
1
),
xlen
,
ylen
,
generate_optim_code
,
fd
);
// dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]^dlist[i]->bit[col-1][row+offset];
// printf("updating dlist[%d]->bit[%d][%d] => %d\n",i,col,row,dlist[i]->bit[col][row]);
#ifdef SHOWCOMP
printf
(
"updateBit_int8_B(sorted_dlist,%d,%d,%d,%d);
\n
"
,
i
,
col
,
row
,
offset
);
#endif
updateBit_int8_B
(
dlist
,
i
,
col
,
row
,
offset
);
}
if
(
generate_optim_code
==
1
)
fprintf
(
fd
,
"updateBit_int8_B(sorted_dlist,%d,%d,%d,%d);
\n
"
,
listSize
,
col
,
row
,
offset
);
updateBit_int8_B
(
dlist
,
listSize
,
col
,
row
,
offset
);
}
bitU
[
row
][
col
]
=
1
;
}
...
...
@@ -193,17 +176,15 @@ void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue,
}
#define updatePathMetric0_int8_A(dlist,i,row,mask,absllr) { mask=dlist[i]->llr[0][row]>>15;if(mask!=0){absllr=(dlist[i]->llr[0][row]+mask)^mask;dlist[i]->pathMetric+=absllr;}}
void
updatePathMetric0_int8
(
decoder_list_int8_t
**
dlist
,
uint8_t
listSize
,
uint16_t
row
)
{
void
updatePathMetric0_int8
(
decoder_list_int8_t
**
dlist
,
uint8_t
listSize
,
uint16_t
row
,
int
generate_optim_code
,
FILE
*
fd
)
{
int16_t
mask
,
absllr
;
for
(
uint8_t
i
=
0
;
i
<
listSize
;
i
++
)
{
updatePathMetric0_int8_A
(
dlist
,
listSize
,
row
,
mask
,
absllr
);
if
(
generate_optim_code
==
1
)
fprintf
(
fd
,
"updatePathMetric0_int8_A(sorted_dlist,%d,%d,mask,absllr);
\n
"
,
listSize
,
row
);
updatePathMetric0_int8_A
(
dlist
,
i
,
row
,
mask
,
absllr
);
#ifdef SHOWCOMP
printf
(
"updatePathMetric0_int8_A(sorted_dlist,i,%d,%d);
\n
"
,
listSize
,
row
);
#endif
/*
...
...
@@ -215,7 +196,6 @@ void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16
}*/
}
}
...
...
@@ -244,24 +224,23 @@ void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, u
}
}
#define updatePathMetric2_int8_A(dlist,i,listSize,row) {dlist[i+listSize]->pathMetric = dlist[i]->pathMetric;if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric-=dlist[i]->llr[0][row];else dlist[i+listSize]->pathMetric += dlist[i]->llr[0][row];}
void
updatePathMetric2_int8
(
decoder_list_int8_t
**
dlist
,
uint8_t
listSize
,
uint16_t
row
)
{
void
updatePathMetric2_int8
(
decoder_list_int8_t
**
dlist
,
uint8_t
listSize
,
uint16_t
row
,
int
generate_optim_code
,
FILE
*
fd
)
{
int
i
;
for
(
i
=
0
;
i
<
listSize
;
i
++
)
{
#ifdef SHOWCOMP
printf
(
"updatePathMetric2_int8_A(sorted_dlist,%d,%d,%d);
\n
"
,
i
,
listSize
,
row
);
#endif
updatePathMetric2_int8_A
(
dlist
,
i
,
listSize
,
row
);
// dlist[i+listSize]->pathMetric = dlist[i]->pathMetric;
//if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric -= dlist[i]->llr[0][row];
//else dlist[i+listSize]->pathMetric += dlist[i]->llr[0][row];
}
if
(
generate_optim_code
==
1
)
fprintf
(
fd
,
"updatePathMetric2_int8_A(sorted_dlist,%d,%d);
\n
"
,
listSize
,
row
);
updatePathMetric2_int8_A
(
dlist
,
listSize
,
row
);
// dlist[i+listSize]->pathMetric = dlist[i]->pathMetric;
//if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric -= dlist[i]->llr[0][row];
//else dlist[i+listSize]->pathMetric += dlist[i]->llr[0][row];
}
...
...
@@ -283,32 +262,253 @@ void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen,
}
}
#define updateCrcChecksum_int8_A(dlist,i,crcGen,i2,len) {for (uint8_t j = 0; j < len; j++) dlist[i]->crcChecksum[j] = (dlist[i]->crcChecksum[j]^crcGen[i2][j]);}
void
updateCrcChecksum_int8
(
decoder_list_int8_t
**
dlist
,
uint8_t
**
crcGen
,
uint8_t
listSize
,
uint32_t
i2
,
uint8_t
len
)
{
for
(
uint8_t
i
=
0
;
i
<
listSize
;
i
++
)
{
#ifdef SHOWCOMP
printf
(
"updateCrcChecksum_int8_A(sorted_dlist,%d,crcGen,%d,%d);
\n
"
,
i
,
i2
,
len
);
#endif
updateCrcChecksum_int8_A
(
dlist
,
i
,
crcGen
,
i2
,
len
);
// for (uint8_t j = 0; j < len; j++) {
// dlist[i]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
// }
}
uint8_t
listSize
,
uint32_t
i2
,
uint8_t
len
,
int
generate_optim_code
,
FILE
*
fd
)
{
if
(
generate_optim_code
==
1
)
fprintf
(
fd
,
"updateCrcChecksum_int8_A(sorted_dlist,%d,crcGen,%d,%d);
\n
"
,
listSize
,
i2
,
len
);
updateCrcChecksum_int8_A
(
dlist
,
listSize
,
crcGen
,
i2
,
len
);
// for (uint8_t j = 0; j < len; j++) {
// dlist[i]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
// }
}
#define updateCrcChecksum2_int8_A(dlist,i,listSize,crcGen,i2,len) {for (uint8_t j = 0; j < len; j++) dlist[i+listSize]->crcChecksum[j]=dlist[i]->crcChecksum[j]^crcGen[i2][j];}
void
updateCrcChecksum2_int8
(
decoder_list_int8_t
**
dlist
,
uint8_t
**
crcGen
,
uint8_t
listSize
,
uint32_t
i2
,
uint8_t
len
)
{
for
(
uint8_t
i
=
0
;
i
<
listSize
;
i
++
)
{
#ifdef SHOWCOMP
printf
(
"updateCrcChecksum2_int8_A(sorted_dlist,%d,%d,crcGen,%d,%d);
\n
"
,
i
,
listSize
,
i2
,
len
);
#endif
updateCrcChecksum2_int8_A
(
dlist
,
i
,
listSize
,
crcGen
,
i2
,
len
);
// for (uint8_t j = 0; j < len; j++) {
uint8_t
listSize
,
uint32_t
i2
,
uint8_t
len
,
int
generate_optim_code
,
FILE
*
fd
)
{
if
(
generate_optim_code
==
1
)
fprintf
(
fd
,
"updateCrcChecksum2_int8_A(sorted_dlist,%d,polarParams->extended_crc_generator_matrix,%d,%d);
\n
"
,
listSize
,
i2
,
len
);
updateCrcChecksum2_int8_A
(
dlist
,
listSize
,
crcGen
,
i2
,
len
);
// for (uint8_t j = 0; j < len; j++) {
// dlist[i+listSize]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
// }
}
decoder_node_t
*
new_decoder_node
(
int
first_leaf_index
,
int
level
)
{
decoder_node_t
*
node
=
(
decoder_node_t
*
)
malloc
(
sizeof
(
decoder_node_t
));
node
->
first_leaf_index
=
first_leaf_index
;
node
->
level
=
level
;
node
->
Nv
=
1
<<
level
;
node
->
leaf
=
0
;
node
->
left
=
(
decoder_node_t
*
)
NULL
;
node
->
right
=
(
decoder_node_t
*
)
NULL
;
node
->
all_frozen
=
0
;
node
->
alpha
=
(
int16_t
*
)
malloc16
(
node
->
Nv
*
sizeof
(
int16_t
));
node
->
beta
=
(
int8_t
*
)
malloc16
(
node
->
Nv
*
sizeof
(
int16_t
));
memset
((
void
*
)
node
->
beta
,
-
1
,
node
->
Nv
*
sizeof
(
int16_t
));
return
(
node
);
}
decoder_node_t
*
add_nodes
(
int
level
,
int
first_leaf_index
,
t_nrPolar_params
*
pp
)
{
int
all_frozen_below
=
1
;
int
Nv
=
1
<<
level
;
decoder_node_t
*
new_node
=
new_decoder_node
(
first_leaf_index
,
level
);
#ifdef DEBUG_NEW_IMPL
printf
(
"New node %d order %d, level %d
\n
"
,
pp
->
tree
.
num_nodes
,
Nv
,
level
);
pp
->
tree
.
num_nodes
++
;
#endif
if
(
level
==
0
)
{
#ifdef DEBUG_NEW_IMPL
printf
(
"leaf %d (%s)
\n
"
,
first_leaf_index
,
pp
->
information_bit_pattern
[
first_leaf_index
]
==
1
?
"information or crc"
:
"frozen"
);
#endif
new_node
->
leaf
=
1
;
new_node
->
all_frozen
=
pp
->
information_bit_pattern
[
first_leaf_index
]
==
0
?
1
:
0
;
return
new_node
;
// this is a leaf node
}
for
(
int
i
=
0
;
i
<
Nv
;
i
++
)
{
if
(
pp
->
information_bit_pattern
[
i
+
first_leaf_index
]
>
0
)
all_frozen_below
=
0
;
}
if
(
all_frozen_below
==
0
)
new_node
->
left
=
add_nodes
(
level
-
1
,
first_leaf_index
,
pp
);
else
{
#ifdef DEBUG_NEW_IMPL
printf
(
"aggregating frozen bits %d ... %d at level %d (%s)
\n
"
,
first_leaf_index
,
first_leaf_index
+
Nv
-
1
,
level
,((
first_leaf_index
/
Nv
)
&
1
)
==
0
?
"left"
:
"right"
);
#endif
new_node
->
leaf
=
1
;
new_node
->
all_frozen
=
1
;
}
if
(
all_frozen_below
==
0
)
new_node
->
right
=
add_nodes
(
level
-
1
,
first_leaf_index
+
(
Nv
/
2
),
pp
);
return
(
new_node
);
}
void
build_decoder_tree
(
t_nrPolar_params
*
pp
)
{
pp
->
tree
.
num_nodes
=
0
;
pp
->
tree
.
root
=
add_nodes
(
pp
->
n
,
0
,
pp
);
}
void
applyFtoleft
(
t_nrPolar_params
*
pp
,
decoder_node_t
*
node
)
{
int16_t
*
alpha_v
=
node
->
alpha
;
int16_t
*
alpha_l
=
node
->
left
->
alpha
;
int16_t
*
betal
=
node
->
left
->
beta
;
int16_t
a
,
b
,
absa
,
absb
,
maska
,
maskb
,
minabs
;
#ifdef DEBUG_NEW_IMPL
printf
(
"applyFtoleft %d, Nv %d (level %d,node->left (leaf %d, AF %d))
\n
"
,
node
->
first_leaf_index
,
node
->
Nv
,
node
->
level
,
node
->
left
->
leaf
,
node
->
left
->
all_frozen
);
for
(
int
i
=
0
;
i
<
node
->
Nv
;
i
++
)
printf
(
"i%d (frozen %d): alpha_v[i] = %d
\n
"
,
i
,
1
-
pp
->
information_bit_pattern
[
node
->
first_leaf_index
+
i
],
alpha_v
[
i
]);
#endif
if
(
node
->
left
->
all_frozen
==
0
)
{
#if defined(__AVX2__)
int
avx2mod
=
(
node
->
Nv
/
2
)
&
15
;
if
(
avx2mod
==
0
)
{
__m256i
a256
,
b256
,
absa256
,
absb256
,
minabs256
;
int
avx2len
=
node
->
Nv
/
2
/
16
;
for
(
int
i
=
0
;
i
<
avx2len
;
i
++
)
{
a256
=
((
__m256i
*
)
alpha_v
)[
i
];
b256
=
((
__m256i
*
)
alpha_v
)[
i
+
avx2len
];
absa256
=
_mm256_abs_epi16
(
a256
);
absb256
=
_mm256_abs_epi16
(
b256
);
minabs256
=
_mm256_min_epi16
(
absa256
,
absb256
);
((
__m256i
*
)
alpha_l
)[
i
]
=
_mm256_sign_epi16
(
minabs256
,
_mm256_xor_si256
(
a256
,
b256
));
}
}
else
if
(
avx2mod
==
8
)
{
__m128i
a128
,
b128
,
absa128
,
absb128
,
minabs128
;
a128
=*
((
__m128i
*
)
alpha_v
);
b128
=
((
__m128i
*
)
alpha_v
)[
1
];
absa128
=
_mm_abs_epi16
(
a128
);
absb128
=
_mm_abs_epi16
(
b128
);
minabs128
=
_mm_min_epi16
(
absa128
,
absb128
);
*
((
__m128i
*
)
alpha_l
)
=
_mm_sign_epi16
(
minabs128
,
_mm_xor_si128
(
a128
,
b128
));
}
else
if
(
avx2mod
==
4
)
{
__m64
a64
,
b64
,
absa64
,
absb64
,
minabs64
;
a64
=*
((
__m64
*
)
alpha_v
);
b64
=
((
__m64
*
)
alpha_v
)[
1
];
absa64
=
_mm_abs_pi16
(
a64
);
absb64
=
_mm_abs_pi16
(
b64
);
minabs64
=
_mm_min_pi16
(
absa64
,
absb64
);
*
((
__m64
*
)
alpha_l
)
=
_mm_sign_pi16
(
minabs64
,
_mm_xor_si64
(
a64
,
b64
));
}
else
#endif
{
for
(
int
i
=
0
;
i
<
node
->
Nv
/
2
;
i
++
)
{
a
=
alpha_v
[
i
];
b
=
alpha_v
[
i
+
(
node
->
Nv
/
2
)];
maska
=
a
>>
15
;
maskb
=
b
>>
15
;
absa
=
(
a
+
maska
)
^
maska
;
absb
=
(
b
+
maskb
)
^
maskb
;
minabs
=
absa
<
absb
?
absa
:
absb
;
alpha_l
[
i
]
=
(
maska
^
maskb
)
==
0
?
minabs
:
-
minabs
;
}
}
if
(
node
->
Nv
==
2
)
{
// apply hard decision on left node
betal
[
0
]
=
(
alpha_l
[
0
]
>
0
)
?
-
1
:
1
;
#ifdef DEBUG_NEW_IMPL
printf
(
"betal[0] %d (%p)
\n
"
,
betal
[
0
],
&
betal
[
0
]);
#endif
pp
->
nr_polar_u
[
node
->
first_leaf_index
]
=
(
betal
[
0
]
+
1
)
>>
1
;
#ifdef DEBUG_NEW_IMPL
printf
(
"Setting bit %d to %d (LLR %d)
\n
"
,
node
->
first_leaf_index
,(
betal
[
0
]
+
1
)
>>
1
,
alpha_l
[
0
]);
#endif
}
}
}
void
applyGtoright
(
t_nrPolar_params
*
pp
,
decoder_node_t
*
node
)
{
int16_t
*
alpha_v
=
node
->
alpha
;
int16_t
*
alpha_r
=
node
->
right
->
alpha
;
int16_t
*
betal
=
node
->
left
->
beta
;
int16_t
*
betar
=
node
->
right
->
beta
;
int8_t
frozen_mask
=-
1
;
if
(
node
->
Nv
==
2
)
frozen_mask
=-
pp
->
information_bit_pattern
[
node
->
first_leaf_index
+
1
];
#ifdef DEBUG_NEW_IMPL
printf
(
"applyGtoright %d, Nv %d (level %d), (leaf %d, AF %d)
\n
"
,
node
->
first_leaf_index
,
node
->
Nv
,
node
->
level
,
node
->
right
->
leaf
,
node
->
right
->
all_frozen
);
#endif
if
(
node
->
right
->
all_frozen
==
0
)
{
#if defined(__AVX2__)
int
avx2mod
=
(
node
->
Nv
/
2
)
&
15
;
if
(
avx2mod
==
0
)
{
int
avx2len
=
node
->
Nv
/
2
/
16
;
for
(
int
i
=
0
;
i
<
avx2len
;
i
++
)
{
((
__m256i
*
)
alpha_r
)[
i
]
=
_mm256_subs_epi16
(((
__m256i
*
)
alpha_v
)[
i
+
avx2len
],
_mm256_sign_epi16
(((
__m256i
*
)
alpha_v
)[
i
],
((
__m256i
*
)
betal
)[
i
]));
}
}
else
if
(
avx2mod
==
8
)
{
((
__m128i
*
)
alpha_r
)[
0
]
=
_mm_subs_epi16
(((
__m128i
*
)
alpha_v
)[
1
],
_mm_sign_epi16
(((
__m128i
*
)
alpha_v
)[
0
],((
__m128i
*
)
betal
)[
0
]));
}
else
#endif
{
for
(
int
i
=
0
;
i
<
node
->
Nv
/
2
;
i
++
)
{
alpha_r
[
i
]
=
alpha_v
[
i
+
(
node
->
Nv
/
2
)]
-
(
betal
[
i
]
*
alpha_v
[
i
]);
}
}
if
(
node
->
Nv
==
2
)
{
// apply hard decision on right node
betar
[
0
]
=
(
alpha_r
[
0
]
>
0
)
?
-
1
:
1
;
pp
->
nr_polar_u
[
node
->
first_leaf_index
+
1
]
=
(
betar
[
0
]
+
1
)
>>
1
;
#ifdef DEBUG_NEW_IMPL
printf
(
"Setting bit %d to %d (LLR %d frozen_mask %d)
\n
"
,
node
->
first_leaf_index
+
1
,(
betar
[
0
]
+
1
)
>>
1
,
alpha_r
[
0
],
frozen_mask
);
#endif
}
}
}
void
computeBeta
(
t_nrPolar_params
*
pp
,
decoder_node_t
*
node
)
{
int16_t
*
betav
=
node
->
beta
;
int16_t
*
betal
=
node
->
left
->
beta
;
int16_t
*
betar
=
node
->
right
->
beta
;
#ifdef DEBUG_NEW_IMPL
printf
(
"Computing beta @ level %d first_leaf_index %d (all_frozen %d)
\n
"
,
node
->
level
,
node
->
first_leaf_index
,
node
->
left
->
all_frozen
);
#endif
if
(
node
->
left
->
all_frozen
==
0
)
{
// if left node is not aggregation of frozen bits
for
(
int
i
=
0
;
i
<
node
->
Nv
/
2
;
i
++
)
{
betav
[
i
]
=
(
betal
[
i
]
!=
betar
[
i
])
?
1
:
-
1
;
#ifdef DEBUG_NEW_IMPL
printf
(
"COMPUTE betav[%d] %d (%p)
\n
"
,
i
,
betav
[
i
],
&
betav
[
i
]);
#endif
}
}
else
memcpy
((
void
*
)
&
betav
[
0
],
betar
,(
node
->
Nv
/
2
)
*
sizeof
(
int16_t
));
memcpy
((
void
*
)
&
betav
[
node
->
Nv
/
2
],
betar
,(
node
->
Nv
/
2
)
*
sizeof
(
int16_t
));
}
void
generic_polar_decoder
(
t_nrPolar_params
*
pp
,
decoder_node_t
*
node
)
{
// Apply F to left
applyFtoleft
(
pp
,
node
);
// if left is not a leaf recurse down to the left
if
(
node
->
left
->
leaf
==
0
)
generic_polar_decoder
(
pp
,
node
->
left
);
applyGtoright
(
pp
,
node
);
if
(
node
->
right
->
leaf
==
0
)
generic_polar_decoder
(
pp
,
node
->
right
);
computeBeta
(
pp
,
node
);
}
openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
View file @
eda57974
...
...
@@ -34,58 +34,125 @@
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
};
#define Nmax 1024
#define nmax 10
typedef
struct
decoder_list_s
{
uint8_t
bit
[
1
+
nmax
][
Nmax
];
double
llr
[
1
+
nmax
][
Nmax
];
uint8_t
crcChecksum
[
24
];
double
pathMetric
;
}
decoder_list_t
;
typedef
struct
decoder_list_int8_s
{
uint8_t
bit
[
1
+
nmax
][
Nmax
]
__attribute__
((
aligned
(
32
)));
int16_t
llr
[
1
+
nmax
][
Nmax
]
__attribute__
((
aligned
(
32
)));
uint8_t
crcChecksum
[
24
];
int32_t
pathMetric
;
}
decoder_list_int8_t
;
typedef
struct
decoder_node_t_s
{
struct
decoder_node_t_s
*
left
;
struct
decoder_node_t_s
*
right
;
int
level
;
int
leaf
;
int
Nv
;
int
first_leaf_index
;
int
all_frozen
;
int16_t
*
alpha
;
int8_t
*
beta
;
}
decoder_node_t
;
typedef
struct
decoder_tree_t_s
{
decoder_node_t
*
root
;
int
num_nodes
;
}
decoder_tree_t
;
struct
nrPolar_params
{
uint8_t
n_max
;
uint8_t
i_il
;
uint8_t
i_seg
;
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
;
const
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
;
uint32_t
crc_polynomial
;
uint8_t
**
crc_generator_matrix
;
//G_P
uint8_t
**
G_N
;
uint32_t
*
crc256Table
;
//polar_encoder vectors:
uint8_t
*
nr_polar_crc
;
uint8_t
*
nr_polar_b
;
uint8_t
*
nr_polar_cPrime
;
uint8_t
*
nr_polar_u
;
uint8_t
*
nr_polar_d
;
uint8_t
n_max
;
uint8_t
i_il
;
uint8_t
i_seg
;
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
;
const
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
;
uint32_t
crc_polynomial
;
uint8_t
**
crc_generator_matrix
;
//G_P
uint8_t
**
G_N
;
uint32_t
*
crc256Table
;
uint8_t
**
extended_crc_generator_matrix
;
//polar_encoder vectors:
uint8_t
*
nr_polar_crc
;
uint8_t
*
nr_polar_b
;
uint8_t
*
nr_polar_cPrime
;
uint8_t
*
nr_polar_u
;
uint8_t
*
nr_polar_d
;
void
(
*
decoder_kernel
)(
struct
nrPolar_params
*
,
decoder_list_int8_t
**
);
decoder_tree_t
tree
;
}
__attribute__
((
__packed__
));
typedef
struct
nrPolar_params
t_nrPolar_params
;
void
polar_encoder
(
uint8_t
*
input
,
uint8_t
*
output
,
t_nrPolar_params
*
polarParams
);
void
nr_polar_kernal_operation
(
uint8_t
*
u
,
uint8_t
*
d
,
uint16_t
N
);
int8_t
polar_decoder
(
double
*
input
,
uint8_t
*
output
,
t_nrPolar_params
*
polarParams
,
uint8_t
listSize
,
double
*
aPrioriPayload
,
uint8_t
pathMetricAppr
,
time_stats_t
*
init
,
time_stats_t
*
polar_rate_matching
,
time_stats_t
*
decoding
,
time_stats_t
*
bit_extraction
,
time_stats_t
*
deinterleaving
,
time_stats_t
*
sorting
,
time_stats_t
*
path_metric
,
time_stats_t
*
update_LLR
);
uint8_t
listSize
,
double
*
aPrioriPayload
,
uint8_t
pathMetricAppr
,
time_stats_t
*
init
,
time_stats_t
*
polar_rate_matching
,
time_stats_t
*
decoding
,
time_stats_t
*
bit_extraction
,
time_stats_t
*
deinterleaving
,
time_stats_t
*
sorting
,
time_stats_t
*
path_metric
,
time_stats_t
*
update_LLR
);
int8_t
polar_decoder_int8
(
int16_t
*
input
,
uint8_t
*
output
,
t_nrPolar_params
*
polarParams
,
uint8_t
listSize
,
time_stats_t
*
init
,
time_stats_t
*
polar_rate_matching
,
time_stats_t
*
decoding
,
time_stats_t
*
bit_extraction
,
time_stats_t
*
deinterleaving
,
time_stats_t
*
sorting
,
time_stats_t
*
path_metric
,
time_stats_t
*
update_LLR
,
int
generate_optim_code
);
void
nr_polar_llrtableinit
(
void
);
void
nr_polar_init
(
t_nrPolar_params
*
polarParams
,
int
messageType
);
...
...
@@ -133,59 +200,38 @@ 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_2D_array
(
double
**
input
,
uint16_t
xlen
);
#define Nmax 1024
#define nmax 10
typedef
struct
decoder_list_s
{
uint8_t
bit
[
1
+
nmax
][
Nmax
];
double
llr
[
1
+
nmax
][
Nmax
];
uint8_t
crcChecksum
[
24
];
double
pathMetric
;
}
decoder_list_t
;
typedef
struct
decoder_list_int8_s
{
uint8_t
bit
[
1
+
nmax
][
Nmax
]
__attribute__
((
aligned
(
32
)));
int16_t
llr
[
1
+
nmax
][
Nmax
]
__attribute__
((
aligned
(
32
)));
uint8_t
crcChecksum
[
24
];
int32_t
pathMetric
;
}
decoder_list_int8_t
;
void
updateLLR
(
decoder_list_t
**
dlist
,
uint8_t
**
llrU
,
uint8_t
**
bitU
,
uint8_t
listSize
,
uint16_t
row
,
uint16_t
col
,
uint16_t
xlen
,
uint8_t
ylen
,
uint8_t
approximation
);
void
updateLLR_int8
(
decoder_list_int8_t
**
dlist
,
uint8_t
**
llrU
,
uint8_t
**
bitU
,
uint8_t
listSize
,
uint16_t
row
,
uint16_t
col
,
uint16_t
xlen
,
uint8_t
ylen
);
uint8_t
listSize
,
uint16_t
row
,
uint16_t
col
,
uint16_t
xlen
,
uint8_t
ylen
,
int
generate_optim_code
,
FILE
*
fd
);
void
updateBit
(
decoder_list_t
**
dlist
,
uint8_t
**
bitU
,
uint8_t
listSize
,
uint16_t
row
,
uint16_t
col
,
uint16_t
xlen
,
uint8_t
ylen
);
void
updateBit_int8
(
decoder_list_int8_t
**
dlist
,
uint8_t
**
bitU
,
uint8_t
listSize
,
uint16_t
row
,
uint16_t
col
,
uint16_t
xlen
,
uint8_t
ylen
);
uint16_t
col
,
uint16_t
xlen
,
uint8_t
ylen
,
int
generate_optim_code
,
FILE
*
fd
);
void
updatePathMetric
(
decoder_list_t
**
dlist
,
uint8_t
listSize
,
uint8_t
bitValue
,
uint16_t
row
,
uint8_t
approximation
);
void
updatePathMetric0_int8
(
decoder_list_int8_t
**
dlist
,
uint8_t
listSize
,
uint16_t
row
);
void
updatePathMetric0_int8
(
decoder_list_int8_t
**
dlist
,
uint8_t
listSize
,
uint16_t
row
,
int
generate_optim_code
,
FILE
*
fd
);
void
updatePathMetric2
(
decoder_list_t
**
dlist
,
uint8_t
listSize
,
uint16_t
row
,
uint8_t
appr
);
void
updatePathMetric2_int8
(
decoder_list_int8_t
**
dlist
,
uint8_t
listSize
,
uint16_t
row
);
void
updatePathMetric2_int8
(
decoder_list_int8_t
**
dlist
,
uint8_t
listSize
,
uint16_t
row
,
int
generate_optim_code
,
FILE
*
fd
);
void
updateCrcChecksum
(
decoder_list_t
**
dlist
,
uint8_t
**
crcGen
,
uint8_t
listSize
,
uint32_t
i2
,
uint8_t
len
);
void
updateCrcChecksum_int8
(
decoder_list_int8_t
**
dlist
,
uint8_t
**
crcGen
,
uint8_t
listSize
,
uint32_t
i2
,
uint8_t
len
);
uint8_t
listSize
,
uint32_t
i2
,
uint8_t
len
,
int
generate_optim_code
,
FILE
*
fd
);
void
updateCrcChecksum2
(
decoder_list_t
**
dlist
,
uint8_t
**
crcGen
,
uint8_t
listSize
,
uint32_t
i2
,
uint8_t
len
);
void
updateCrcChecksum2_int8
(
decoder_list_int8_t
**
dlist
,
uint8_t
**
crcGen
,
uint8_t
listSize
,
uint32_t
i2
,
uint8_t
len
);
uint8_t
listSize
,
uint32_t
i2
,
uint8_t
len
,
int
generate_optim_code
,
FILE
*
fd
);
void
nr_sort_asc_double_1D_array_ind
(
double
*
matrix
,
int
*
ind
,
int
len
);
...
...
@@ -213,4 +259,144 @@ static inline void nr_polar_deinterleaver(uint8_t *input, uint8_t *output, uint1
for
(
int
i
=
0
;
i
<
size
;
i
++
)
output
[
pattern
[
i
]]
=
input
[
i
];
}
void
polar_decoder_K56_N512_E864
(
t_nrPolar_params
*
polarParams
,
decoder_list_int8_t
**
sorted_list
);
void
build_decoder_tree
(
t_nrPolar_params
*
pp
);
#define updateLLR_int8_A(dlist,listSize,col,row,offset) {for (int i=0;i<listSize;i++) {if (dlist[(i)]->bit[(col)][(row)-(offset)]==0) dlist[(i)]->llr[(col)][(row)] = dlist[(i)]->llr[(col)+1][(row)-(offset)] + dlist[(i)]->llr[(col)+1][(row)]; else dlist[(i)]->llr[(col)][(row)] = -dlist[(i)]->llr[(col)+1][(row)-(offset)] + dlist[(i)]->llr[(col)+1][(row)];if(dlist[(i)]->llr[col][row]>127 || dlist[i]->llr[col][row]<-128) printf("dlist[%d]->llr[%d][%d] = %d> 8bit\n",i,col,row,dlist[i]->llr[col][row]);}}
#define updateBit_int8_A(dlist,listSize,col,row) {for (int i=0;i<listSize;i++) {dlist[(i)]->bit[(col)][(row)] = dlist[(i)]->bit[(col)-1][(row)];}}
#define updateBit_int8_B(dlist,listSize,col,row,offset) {for (int i=0;i<listSize;i++) {dlist[(i)]->bit[(col)][(row)] = dlist[(i)]->bit[(col)-1][(row)]^dlist[(i)]->bit[(col)-1][(row)+(offset)];}}
#define updatePathMetric0_int8_A(dlist,listSize,row,mask,absllr) {for (int i=0;i<listSize;i++) { mask=dlist[i]->llr[0][row]>>15;if(mask!=0){absllr=(dlist[i]->llr[0][row]+mask)^mask;dlist[i]->pathMetric+=absllr;}}}
#define updatePathMetric2_int8_A(dlist,listSize,row) {for (int i=0;i<listSize;i++) {{dlist[i+listSize]->pathMetric = dlist[i]->pathMetric;if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric-=dlist[i]->llr[0][row];else dlist[i+listSize]->pathMetric += dlist[i]->llr[0][row];}}}
#define updateCrcChecksum_int8_A(dlist,listSize,crcGen,i2,len) {for (int i=0;i<listSize;i++){for (uint8_t j = 0; j < len; j++) dlist[i]->crcChecksum[j] = (dlist[i]->crcChecksum[j]^crcGen[i2][j]);}}
#define updateCrcChecksum2_int8_A(dlist,listSize,crcGen,i2,len) {for (int i=0;i<listSize;i++){for (uint8_t j = 0; j < len; j++) dlist[i+listSize]->crcChecksum[j]=dlist[i]->crcChecksum[j]^crcGen[i2][j];}}
extern
int16_t
llrtab
[
256
][
256
];
inline
void
computeLLR_int8
(
decoder_list_int8_t
**
dlist
,
int
listSize
,
uint16_t
row
,
uint16_t
col
,
uint16_t
offset
)
__attribute__
((
always_inline
));
inline
void
computeLLR_int8
(
decoder_list_int8_t
**
dlist
,
int
listSize
,
uint16_t
row
,
uint16_t
col
,
uint16_t
offset
)
{
int16_t
a
;
int16_t
b
;
int16_t
absA
,
absB
;
int16_t
maska
,
maskb
;
int16_t
minabs
;
// int16_t **llr=dlist[i]->llr;
for
(
int
i
=
0
;
i
<
listSize
;
i
++
)
{
a
=
dlist
[
i
]
->
llr
[
col
+
1
][
row
];
b
=
dlist
[
i
]
->
llr
[
col
+
1
][
row
+
offset
];
// printf("LLR: a %d, b %d\n",a,b);
maska
=
a
>>
15
;
maskb
=
b
>>
15
;
absA
=
(
a
+
maska
)
^
maska
;
absB
=
(
b
+
maskb
)
^
maskb
;
// printf("LLR: absA %d, absB %d\n",absA,absB);
minabs
=
absA
<
absB
?
absA
:
absB
;
if
((
maska
^
maskb
)
==
0
)
dlist
[
i
]
->
llr
[
col
][
row
]
=
minabs
;
else
dlist
[
i
]
->
llr
[
col
][
row
]
=
-
minabs
;
// printf("LLR (a %d, b %d): llr[%d][%d] %d\n",a,b,col,row,llr[col][row]);
//dlist[i]->llr[col][row] = llrtab[a+128][b+128];
// printf("newLLR [%d,%d]: %d\n",col,row,dlist[i]->llr[col][row]);
}
}
#define decoder_int8_A(sorted_dlist,currentListSize,polarParams) {for (int i = 0; i < currentListSize; i++) { \
for (int k = 0; k < (polarParams->n+1); k++) { \
memcpy((void*)&sorted_dlist[i+currentListSize]->bit[k][0],\
(void*)&sorted_dlist[i]->bit[k][0],\
sizeof(uint8_t)*polarParams->N);\
memcpy((void*)&sorted_dlist[i+currentListSize]->llr[k][0],\
(void*)&sorted_dlist[i]->llr[k][0],\
sizeof(int16_t)*polarParams->N);}}}
#define decoder_int8_B(sorted_dlist,currentBit,currentListSize) {for (int i = 0; i < currentListSize; i++) {sorted_dlist[i]->bit[0][currentBit]=0;sorted_dlist[i+currentListSize]->bit[0][currentBit]=1;}}
void
inline
decoder_int8_C
(
decoder_list_int8_t
*
sorted_dlist
[],
t_nrPolar_params
*
polarParams
,
int
currentBit
,
int
currentListSize
,
int
listSize
)
{
int32_t
pathMetric
[
2
*
listSize
];
decoder_list_int8_t
*
temp_dlist
[
2
*
listSize
];
int
listIndex
[
2
*
listSize
];
int
listIndex2
[
2
*
listSize
];
for
(
int
i
=
0
;
i
<
currentListSize
;
i
++
)
{
listIndex
[
i
]
=
i
;
pathMetric
[
i
]
=
sorted_dlist
[
i
]
->
pathMetric
;
}
nr_sort_asc_int16_1D_array_ind
(
pathMetric
,
listIndex
,
currentListSize
);
for
(
int
i
=
0
;
i
<
currentListSize
;
i
++
)
{
listIndex2
[
listIndex
[
i
]]
=
i
;
}
// copy the llr/bit arrays that are needed
for
(
int
i
=
0
;
i
<
listSize
;
i
++
)
{
// printf("listIndex[%d] %d\n",i,listIndex[i]);
if
((
listIndex2
[
i
+
listSize
]
<
listSize
)
&&
(
listIndex2
[
i
]
<
listSize
))
{
// both '0' and '1' path metrics are to be kept
// do memcpy of LLR and Bit arrays
for
(
int
k
=
0
;
k
<
(
polarParams
->
n
+
1
);
k
++
)
{
memcpy
((
void
*
)
&
sorted_dlist
[
i
+
listSize
]
->
bit
[
k
][
0
],
(
void
*
)
&
sorted_dlist
[
i
]
->
bit
[
k
][
0
],
sizeof
(
uint8_t
)
*
polarParams
->
N
);
memcpy
((
void
*
)
&
sorted_dlist
[
i
+
listSize
]
->
llr
[
k
][
0
],
(
void
*
)
&
sorted_dlist
[
i
]
->
llr
[
k
][
0
],
sizeof
(
int16_t
)
*
polarParams
->
N
);
}
sorted_dlist
[
i
]
->
bit
[
0
][
currentBit
]
=
0
;
sorted_dlist
[
i
+
listSize
]
->
bit
[
0
][
currentBit
]
=
1
;
}
else
if
(
listIndex2
[
i
+
listSize
]
<
listSize
)
{
// only '1' path metric is to be kept
// just change the current bit from '0' to '1'
for
(
int
k
=
0
;
k
<
(
polarParams
->
n
+
1
);
k
++
)
{
memcpy
((
void
*
)
&
sorted_dlist
[
i
+
listSize
]
->
bit
[
k
][
0
],
(
void
*
)
&
sorted_dlist
[
i
]
->
bit
[
k
][
0
],
sizeof
(
uint8_t
)
*
polarParams
->
N
);
memcpy
((
void
*
)
&
sorted_dlist
[
i
+
listSize
]
->
llr
[
k
][
0
],
(
void
*
)
&
sorted_dlist
[
i
]
->
llr
[
k
][
0
],
sizeof
(
int16_t
)
*
polarParams
->
N
);
}
sorted_dlist
[
i
+
listSize
]
->
bit
[
0
][
currentBit
]
=
1
;
/*
decoder_list_t *tmp = sorted_dlist[i+listSize];
sorted_dlist[i+listSize] = sorted_dlist[i];
sorted_dlist[i+listSize]->pathMetric = tmp->pathMetric;
sorted_dlist[i+listSize]->bit[0][currentBit]=1;
memcpy((void*)&sorted_dlist[i+listSize]->crcChecksum[0],
(void*)&tmp->crcChecksum[0],
24*sizeof(uint8_t));*/
}
}
for
(
int
i
=
0
;
i
<
2
*
listSize
;
i
++
)
{
temp_dlist
[
i
]
=
sorted_dlist
[
i
];
}
for
(
int
i
=
0
;
i
<
2
*
listSize
;
i
++
)
{
// printf("i %d => %d\n",i,listIndex[i]);
sorted_dlist
[
i
]
=
temp_dlist
[
listIndex
[
i
]];
}
}
#endif
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