Commit 918d1fd1 authored by Florian Kaltenberger's avatar Florian Kaltenberger

Merge branch 'polar-decoder-optimizations' into 'develop-nr'

Polar decoder optimizations

See merge request oai/openairinterface5g!413
parents 9b3fc8b3 76ebc5ad
...@@ -18,13 +18,17 @@ int main(int argc, char *argv[]) { ...@@ -18,13 +18,17 @@ int main(int argc, char *argv[]) {
//Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.) //Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.)
time_stats_t timeEncoder,timeDecoder; time_stats_t timeEncoder,timeDecoder;
time_stats_t polar_decoder_init,polar_rate_matching,decoding,bit_extraction,deinterleaving;
time_stats_t path_metric,sorting,update_LLR;
opp_enabled=1; opp_enabled=1;
int decoder_int16=0;
int generate_optim_code=0;
cpu_freq_GHz = get_cpu_freq_GHz(); cpu_freq_GHz = get_cpu_freq_GHz();
reset_meas(&timeEncoder); reset_meas(&timeEncoder);
reset_meas(&timeDecoder); reset_meas(&timeDecoder);
randominit(0); randominit(0);
crcTableInit(); crcTableInit();
//Default simulation values (Aim for iterations = 1000000.) //Default simulation values (Aim for iterations = 1000000.)
int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI
double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB
...@@ -36,7 +40,7 @@ int main(int argc, char *argv[]) { ...@@ -36,7 +40,7 @@ int main(int argc, char *argv[]) {
double timeEncoderCumulative = 0, timeDecoderCumulative = 0; double timeEncoderCumulative = 0, timeDecoderCumulative = 0;
uint8_t aggregation_level = 8, decoderListSize = 8, pathMetricAppr = 0; uint8_t aggregation_level = 8, decoderListSize = 8, pathMetricAppr = 0;
while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:h")) != -1) while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:h:qg")) != -1)
switch (arguments) switch (arguments)
{ {
case 's': case 's':
...@@ -67,6 +71,17 @@ int main(int argc, char *argv[]) { ...@@ -67,6 +71,17 @@ int main(int argc, char *argv[]) {
pathMetricAppr = (uint8_t) atoi(optarg); pathMetricAppr = (uint8_t) atoi(optarg);
break; break;
case 'q':
decoder_int16=1;
break;
case 'g':
generate_optim_code=1;
iterations=1;
SNRstart=-6.0;
SNRstop =-6.0;
decoder_int16=1;
break;
case 'h': case 'h':
printf("./polartest -s SNRstart -d SNRinc -f SNRstop -m [0=PBCH|1=DCI|2=UCI] -i iterations -l decoderListSize -a pathMetricAppr\n"); printf("./polartest -s SNRstart -d SNRinc -f SNRstop -m [0=PBCH|1=DCI|2=UCI] -i iterations -l decoderListSize -a pathMetricAppr\n");
exit(-1); exit(-1);
...@@ -136,6 +151,8 @@ int main(int argc, char *argv[]) { ...@@ -136,6 +151,8 @@ int main(int argc, char *argv[]) {
uint8_t *encoderOutputByte = malloc(sizeof(uint8_t) * coderLength); uint8_t *encoderOutputByte = malloc(sizeof(uint8_t) * coderLength);
double *modulatedInput = malloc (sizeof(double) * coderLength); //channel input double *modulatedInput = malloc (sizeof(double) * coderLength); //channel input
double *channelOutput = malloc (sizeof(double) * coderLength); //add noise double *channelOutput = malloc (sizeof(double) * coderLength); //add noise
int16_t *channelOutput_int16;
if (decoder_int16 == 1) channelOutput_int16 = (int16_t*)malloc (sizeof(int16_t) * coderLength);
t_nrPolar_paramsPtr nrPolar_params = NULL, currentPtr = NULL; t_nrPolar_paramsPtr nrPolar_params = NULL, currentPtr = NULL;
nr_polar_init(&nrPolar_params, polarMessageType, testLength, aggregation_level); nr_polar_init(&nrPolar_params, polarMessageType, testLength, aggregation_level);
...@@ -285,6 +302,7 @@ int main(int argc, char *argv[]) { ...@@ -285,6 +302,7 @@ int main(int argc, char *argv[]) {
for (int i=0; i<currentPtr->payloadBits; i++) aPrioriArray[i] = NAN; for (int i=0; i<currentPtr->payloadBits; i++) aPrioriArray[i] = NAN;
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) { for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
printf("SNR %f\n",SNR);
SNR_lin = pow(10, SNR/10); SNR_lin = pow(10, SNR/10);
for (itr = 1; itr <= iterations; itr++) { for (itr = 1; itr <= iterations; itr++) {
...@@ -318,6 +336,15 @@ int main(int argc, char *argv[]) { ...@@ -318,6 +336,15 @@ int main(int argc, char *argv[]) {
modulatedInput[i]=(-1)/sqrt(2); modulatedInput[i]=(-1)/sqrt(2);
channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin))); channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin)));
if (decoder_int16==1) {
if (channelOutput[i] > 15) channelOutput_int16[i] = 127;
else if (channelOutput[i] < -16) channelOutput_int16[i] = -128;
else channelOutput_int16[i] = (int16_t) (8*channelOutput[i]);
}
} }
start_meas(&timeDecoder); start_meas(&timeDecoder);
...@@ -327,12 +354,19 @@ int main(int argc, char *argv[]) { ...@@ -327,12 +354,19 @@ int main(int argc, char *argv[]) {
NR_POLAR_DECODER_LISTSIZE, NR_POLAR_DECODER_LISTSIZE,
aPrioriArray, aPrioriArray,
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION);*/ NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION);*/
if (decoder_int16==0)
decoderState = polar_decoder_aPriori(channelOutput, decoderState = polar_decoder_aPriori(channelOutput,
estimatedOutput, estimatedOutput,
currentPtr, currentPtr,
NR_POLAR_DECODER_LISTSIZE, NR_POLAR_DECODER_LISTSIZE,
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION, NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION,
aPrioriArray); aPrioriArray);
else
decoderState = polar_decoder_int16(channelOutput_int16,
estimatedOutput,
currentPtr);
stop_meas(&timeDecoder); stop_meas(&timeDecoder);
/*printf("testInput: [0]->0x%08x\n", testInput[0]); /*printf("testInput: [0]->0x%08x\n", testInput[0]);
printf("estimatedOutput: [0]->0x%08x\n", estimatedOutput[0]);*/ printf("estimatedOutput: [0]->0x%08x\n", estimatedOutput[0]);*/
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "nrPolar_tools/nr_polar_defs.h"
#include "nrPolar_tools/nr_polar_pbch_defs.h"
#include "nrPolar_tools/nr_polar_uci_defs.h"
void nr_polar_init(t_nrPolar_params* polarParams, int messageType) {
uint32_t poly6 = 0x84000000; // 1000100000... -> D^6+D^5+1
uint32_t poly11 = 0x63200000; //11000100001000... -> D^11+D^10+D^9+D^5+1
//uint32_t poly16 = 0x81080000; //100000010000100... - > D^16+D^12+D^5+1
//uint32_t poly24a = 0x864cfb00; //100001100100110011111011 -> D^24+D^23+D^18+D^17+D^14+D^11+D^10+D^7+D^6+D^5+D^4+D^3+D+1
//uint32_t poly24b = 0x80006300; //100000000000000001100011 -> D^24+D^23+D^6+D^5+D+1
uint32_t poly24c = 0xB2B11700; //101100101011000100010111 -> D^24...
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->i_seg = NR_POLAR_PBCH_I_SEG;
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->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->crc_polynomial = poly24c;
polarParams->G_N = nr_polar_kronecker_power_matrices(polarParams->n);
//polar_encoder vectors:
polarParams->nr_polar_crc = malloc(sizeof(uint8_t) * polarParams->crcParityBits);
polarParams->nr_polar_cPrime = malloc(sizeof(uint8_t) * polarParams->K);
polarParams->nr_polar_d = malloc(sizeof(uint8_t) * polarParams->N);
//Polar Coding vectors
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
if (polarParams->payloadBits <= 11) //Ref. 38-212, Section 6.3.1.2.2
polarParams->crcParityBits = 0; //K=A
else //Ref. 38-212, Section 6.3.1.2.1
{
if (polarParams->payloadBits < 20)
polarParams->crcParityBits = NR_POLAR_PUCCH_CRC_PARITY_BITS_SHORT;
else
polarParams->crcParityBits = NR_POLAR_PUCCH_CRC_PARITY_BITS_LONG;
if (polarParams->payloadBits >= 360 && polarParams->encoderLength >= 1088)
polarParams->i_seg = NR_POLAR_PUCCH_I_SEG_LONG; // -> C=2
else
polarParams->i_seg = NR_POLAR_PUCCH_I_SEG_SHORT; // -> C=1
}
polarParams->K = polarParams->payloadBits + polarParams->crcParityBits; // Number of bits to encode.
//K_r = K/C ; C = I_seg+1
if((polarParams->K)/(polarParams->i_seg+1)>=18 && (polarParams->K)/(polarParams->i_seg+1)<=25) //Ref. 38-212, Section 6.3.1.3.1
{
polarParams->n_max = NR_POLAR_PUCCH_N_MAX;
polarParams->i_il =NR_POLAR_PUCCH_I_IL;
polarParams->n_pc = NR_POLAR_PUCCH_N_PC_SHORT;
if( (polarParams->encoderLength - polarParams->K)/(polarParams->i_seg + 1) + 3 > 192 )
polarParams->n_pc_wm = NR_POLAR_PUCCH_N_PC_WM_LONG;
else
polarParams->n_pc_wm = NR_POLAR_PUCCH_N_PC_WM_SHORT;
}
if( (polarParams->K)/(polarParams->i_seg + 1) > 30 ) //Ref. 38-212, Section 6.3.1.3.1
{
polarParams->n_max = NR_POLAR_PUCCH_N_MAX;
polarParams->i_il =NR_POLAR_PUCCH_I_IL;
polarParams->n_pc = NR_POLAR_PUCCH_N_PC_LONG;
polarParams->n_pc_wm = NR_POLAR_PUCCH_N_PC_WM_LONG;
}
polarParams->i_bil = NR_POLAR_PUCCH_I_BIL; //Ref. 38-212, Section 6.3.1.4.1
polarParams->N = nr_polar_output_length(polarParams->K, polarParams->encoderLength, polarParams->n_max);
polarParams->n = log2(polarParams->N);
if((polarParams->payloadBits) <= 19)
{
polarParams->crc_generator_matrix=crc6_generator_matrix(polarParams->payloadBits);
polarParams->crc_polynomial = poly6;
}
else
{
polarParams->crc_generator_matrix=crc11_generator_matrix(polarParams->payloadBits);
polarParams->crc_polynomial = poly11;
}
polarParams->G_N = nr_polar_kronecker_power_matrices(polarParams->n);
//polar_encoder vectors:
polarParams->nr_polar_crc = malloc(sizeof(uint8_t) * polarParams->crcParityBits);
polarParams->nr_polar_cPrime = malloc(sizeof(uint8_t) * polarParams->K);
polarParams->nr_polar_d = malloc(sizeof(uint8_t) * polarParams->N);
//Polar Coding vectors
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;
polarParams->crc256Table = malloc(sizeof(uint32_t)*256);
crcTable256Init(polarParams->crc_polynomial, polarParams->crc256Table);
polarParams->Q_0_Nminus1 = nr_polar_sequence_pattern(polarParams->n);
polarParams->interleaving_pattern = malloc(sizeof(uint16_t) * polarParams->K);
nr_polar_interleaving_pattern(polarParams->K, polarParams->i_il, polarParams->interleaving_pattern);
polarParams->rate_matching_pattern = 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);
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);
}
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*------------------------------------------------------------------------------- *-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance: * For more information about the OpenAirInterface (OAI) Software Alliance
* contact@openairinterface.org * contact@openairinterface.org
*/ */
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
int8_t polar_decoder( int8_t polar_decoder(
double *input, double *input,
uint8_t *out, uint8_t *out,
...@@ -285,7 +286,6 @@ int8_t polar_decoder_aPriori(double *input, ...@@ -285,7 +286,6 @@ int8_t polar_decoder_aPriori(double *input,
uint8_t pathMetricAppr, uint8_t pathMetricAppr,
double *aPrioriPayload) double *aPrioriPayload)
{ {
uint8_t ***bit = nr_alloc_uint8_t_3D_array(polarParams->N, (polarParams->n+1), 2*listSize); 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 **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 **llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
...@@ -355,6 +355,7 @@ int8_t polar_decoder_aPriori(double *input, ...@@ -355,6 +355,7 @@ int8_t polar_decoder_aPriori(double *input,
uint8_t listIndex[2*listSize], copyIndex; uint8_t listIndex[2*listSize], copyIndex;
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++){ for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++){
updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr); updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr);
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12 updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12
...@@ -528,6 +529,7 @@ int8_t polar_decoder_aPriori(double *input, ...@@ -528,6 +529,7 @@ int8_t polar_decoder_aPriori(double *input,
*/ */
nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out); nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out);
return(0); return(0);
} }
...@@ -1034,3 +1036,42 @@ int8_t polar_decoder_dci(double *input, ...@@ -1034,3 +1036,42 @@ int8_t polar_decoder_dci(double *input,
nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out); nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out);
return(0); return(0);
} }
int8_t polar_decoder_int16(int16_t *input,
uint8_t *out,
t_nrPolar_params *polarParams)
{
int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N);
nr_polar_rate_matching_int16(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);
/*
* SCL polar decoder.
*/
generic_polar_decoder(polarParams,polarParams->tree.root);
//Extract the information bits (û to ĉ)
nr_polar_info_bit_extraction(polarParams->nr_polar_U, polarParams->nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N);
//Deinterleaving (ĉ to b)
nr_polar_deinterleaver(polarParams->nr_polar_CPrime, polarParams->nr_polar_B, polarParams->interleaving_pattern, polarParams->K);
//Remove the CRC (â)
for (int j = 0; j < polarParams->payloadBits; j++) polarParams->nr_polar_A[j]=polarParams->nr_polar_B[j];
nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out);
return(0);
}
...@@ -56,6 +56,27 @@ ...@@ -56,6 +56,27 @@
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 }; 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_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;
int16_t *beta;
} decoder_node_t;
typedef struct decoder_tree_t_s {
decoder_node_t *root;
int num_nodes;
} decoder_tree_t;
struct nrPolar_params { struct nrPolar_params {
//messageType: 0=PBCH, 1=DCI, -1=UCI //messageType: 0=PBCH, 1=DCI, -1=UCI
int idx; //idx = (messageType * messageLength * aggregation_prime); int idx; //idx = (messageType * messageLength * aggregation_prime);
...@@ -89,7 +110,7 @@ struct nrPolar_params { ...@@ -89,7 +110,7 @@ struct nrPolar_params {
uint8_t **crc_generator_matrix; //G_P uint8_t **crc_generator_matrix; //G_P
uint8_t **G_N; uint8_t **G_N;
uint32_t* crc256Table; uint32_t* crc256Table;
uint8_t **extended_crc_generator_matrix;
//lowercase: bits, Uppercase: Bits stored in bytes //lowercase: bits, Uppercase: Bits stored in bytes
//polar_encoder vectors //polar_encoder vectors
uint8_t *nr_polar_crc; uint8_t *nr_polar_crc;
...@@ -103,6 +124,8 @@ struct nrPolar_params { ...@@ -103,6 +124,8 @@ struct nrPolar_params {
uint8_t *nr_polar_CPrime; uint8_t *nr_polar_CPrime;
uint8_t *nr_polar_B; uint8_t *nr_polar_B;
uint8_t *nr_polar_U; uint8_t *nr_polar_U;
decoder_tree_t tree;
} __attribute__ ((__packed__)); } __attribute__ ((__packed__));
typedef struct nrPolar_params t_nrPolar_params; typedef struct nrPolar_params t_nrPolar_params;
typedef t_nrPolar_params *t_nrPolar_paramsPtr; typedef t_nrPolar_params *t_nrPolar_paramsPtr;
...@@ -151,6 +174,8 @@ int8_t polar_decoder_dci(double *input, ...@@ -151,6 +174,8 @@ int8_t polar_decoder_dci(double *input,
uint8_t pathMetricAppr, uint8_t pathMetricAppr,
uint16_t n_RNTI); uint16_t n_RNTI);
void generic_polar_decoder(t_nrPolar_params *,decoder_node_t *);
void nr_polar_init(t_nrPolar_paramsPtr *polarParams, void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
int8_t messageType, int8_t messageType,
uint16_t messageLength, uint16_t messageLength,
...@@ -196,6 +221,8 @@ void nr_polar_rate_matching(double *input, ...@@ -196,6 +221,8 @@ void nr_polar_rate_matching(double *input,
uint16_t N, uint16_t N,
uint16_t E); uint16_t E);
void nr_polar_rate_matching_int16(int16_t *input, int16_t *output, uint16_t *rmp, uint16_t K, uint16_t N, uint16_t E);
void nr_polar_interleaving_pattern(uint16_t K, void nr_polar_interleaving_pattern(uint16_t K,
uint8_t I_IL, uint8_t I_IL,
uint16_t *PI_k_); uint16_t *PI_k_);
......
...@@ -111,6 +111,32 @@ double ***nr_alloc_double_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen) ...@@ -111,6 +111,32 @@ double ***nr_alloc_double_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen)
return output; return output;
} }
double **nr_alloc_double_2D_array(uint16_t xlen, uint16_t ylen) {
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_2D_array] Problem at 2D allocation");
nr_free_double_2D_array(output, xlen);
return NULL;
}
for (i = 0; i < xlen; i++)
for (j = 0; j < ylen; j++)
output[i][j] = 0;
return output;
}
uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen, uint16_t ylen) { uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen, uint16_t ylen) {
uint8_t **output; uint8_t **output;
int i, j; int i, j;
...@@ -136,6 +162,18 @@ uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen, uint16_t ylen) { ...@@ -136,6 +162,18 @@ uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen, uint16_t ylen) {
return output; return output;
} }
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);
}
void nr_free_uint8_t_3D_array(uint8_t ***input, uint16_t xlen, uint16_t ylen) { void nr_free_uint8_t_3D_array(uint8_t ***input, uint16_t xlen, uint16_t ylen) {
int i, j; int i, j;
...@@ -153,13 +191,10 @@ void nr_free_uint8_t_2D_array(uint8_t **input, uint16_t xlen) { ...@@ -153,13 +191,10 @@ void nr_free_uint8_t_2D_array(uint8_t **input, uint16_t xlen) {
free(input); free(input);
} }
void nr_free_double_3D_array(double ***input, uint16_t xlen, uint16_t ylen) { void nr_free_double_2D_array(double **input, uint16_t xlen) {
int i, j; int i;
for (i = 0; i < xlen; i++) { for (i = 0; i < xlen; i++) {
for (j = 0; j < ylen; j++) {
free(input[i][j]);
}
free(input[i]); free(input[i]);
} }
free(input); free(input);
...@@ -167,13 +202,38 @@ void nr_free_double_3D_array(double ***input, uint16_t xlen, uint16_t ylen) { ...@@ -167,13 +202,38 @@ void nr_free_double_3D_array(double ***input, uint16_t xlen, uint16_t ylen) {
// Modified Bubble Sort. // Modified Bubble Sort.
void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len) { void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len) {
uint8_t swaps; int swaps;
double temp; double temp;
uint8_t tempInd; int tempInd;
for (int i = 0; i < len; i++) {
swaps = 0;
for (int 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;
}
}
void nr_sort_asc_int16_1D_array_ind(int32_t *matrix, int *ind, int len) {
int swaps;
int16_t temp;
int tempInd;
for (uint8_t i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
swaps = 0; swaps = 0;
for (uint8_t j = 0; j < (len - i) - 1; j++) { for (int j = 0; j < (len - i) - 1; j++) {
if (matrix[j] > matrix[j + 1]) { if (matrix[j] > matrix[j + 1]) {
temp = matrix[j]; temp = matrix[j];
matrix[j] = matrix[j + 1]; matrix[j] = matrix[j + 1];
......
...@@ -313,3 +313,25 @@ void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp, uint16 ...@@ -313,3 +313,25 @@ void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp, uint16
} }
} }
void nr_polar_rate_matching_int16(int16_t *input, int16_t *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];
}
}
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <math.h>
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const 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_matching_int8(int16_t *input, int16_t *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];
}
}
}
...@@ -147,6 +147,9 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams, ...@@ -147,6 +147,9 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
free(J); free(J);
build_decoder_tree(newPolarInitNode);
printf("decoder tree nodes %d\n",newPolarInitNode->tree.num_nodes);
} else { } else {
AssertFatal(1 == 0, "[nr_polar_init] New t_nrPolar_paramsPtr could not be created"); AssertFatal(1 == 0, "[nr_polar_init] New t_nrPolar_paramsPtr could not be created");
} }
......
...@@ -215,7 +215,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, ...@@ -215,7 +215,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
uint8_t nushift; uint8_t nushift;
uint8_t *xbyte = pbch->pbch_a; uint8_t *xbyte = pbch->pbch_a;
memset((void*) xbyte, 0, 1); memset((void*) xbyte, 0, 1);
uint8_t pbch_a_b[32]; //uint8_t pbch_a_b[32];
LOG_I(PHY, "PBCH generation started\n"); LOG_I(PHY, "PBCH generation started\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment