diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index e844ed74dbdbf137516b751a76a6ca34f6fd18ac..9a10b42edb068c67efeaec92f9047dcb5f754e1d 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -18,6 +18,7 @@ int main(int argc, char *argv[]) { time_stats_t polar_decoder_init,polar_rate_matching,decoding,bit_extraction,deinterleaving; time_stats_t path_metric,sorting,update_LLR; opp_enabled=1; + int decoder_int8=0; cpu_freq_GHz = get_cpu_freq_GHz(); reset_meas(&timeEncoder); reset_meas(&timeDecoder); @@ -30,7 +31,7 @@ int main(int argc, char *argv[]) { reset_meas(&path_metric); reset_meas(&update_LLR); - randominit(0); + randominit(1234); //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 = 0.0, SNRinc= 0.5; //dB @@ -43,7 +44,7 @@ int main(int argc, char *argv[]) { 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:h")) != -1) + while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:h:q")) != -1) switch (arguments) { case 's': @@ -75,6 +76,10 @@ int main(int argc, char *argv[]) { pathMetricAppr = (uint8_t) atoi(optarg); break; + case 'q': + 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); @@ -131,6 +136,7 @@ int main(int argc, char *argv[]) { double *modulatedInput = malloc (sizeof(double) * coderLength); //channel input double *channelOutput = malloc (sizeof(double) * coderLength); //add noise + int16_t *channelOutput_int8 = malloc (sizeof(int16_t) * coderLength); //add noise uint8_t *estimatedOutput = malloc(sizeof(uint8_t) * testLength); //decoder output t_nrPolar_params nrPolar_params; @@ -159,12 +165,19 @@ 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] > 1024) channelOutput_int8[i] = 32768; + else if (channelOutput[i] < -1023) channelOutput_int8[i] = -32767; + else channelOutput_int8[i] = (int16_t) (32*channelOutput[i]); + } } start_meas(&timeDecoder); - 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); - stop_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); + 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); + stop_meas(&timeDecoder); //calculate errors if (decoderState==-1) { @@ -207,9 +220,9 @@ int main(int argc, char *argv[]) { printf("decoding decoding %9.3fus\n",decoding.diff/(cpu_freq_GHz*1000.0*decoding.trials)); printf("decoding bit_extraction %9.3fus\n",bit_extraction.diff/(cpu_freq_GHz*1000.0*bit_extraction.trials)); printf("decoding deinterleaving %9.3fus\n",deinterleaving.diff/(cpu_freq_GHz*1000.0*deinterleaving.trials)); - printf("decoding path_metric %9.3fus\n",path_metric.diff/(cpu_freq_GHz*1000.0*deinterleaving.trials)); - printf("decoding sorting %9.3fus\n",sorting.diff/(cpu_freq_GHz*1000.0*deinterleaving.trials)); - printf("decoding updateLLR %9.3fus\n",update_LLR.diff/(cpu_freq_GHz*1000.0*deinterleaving.trials)); + printf("decoding path_metric %9.3fus\n",path_metric.diff/(cpu_freq_GHz*1000.0*decoding.trials)); + printf("decoding sorting %9.3fus\n",sorting.diff/(cpu_freq_GHz*1000.0*decoding.trials)); + printf("decoding updateLLR %9.3fus\n",update_LLR.diff/(cpu_freq_GHz*1000.0*decoding.trials)); blockErrorCumulative = 0; bitErrorCumulative = 0; timeEncoderCumulative = 0; timeDecoderCumulative = 0; } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 9e9029800e1c7a52f6b90948aaaa1308ce2e360c..e1b248b27e33d9d1c4b8b939374c5e953a5b7b76 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -48,193 +48,499 @@ int8_t polar_decoder( time_stats_t *update_LLR) { - 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]; + 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;jcrcParityBits;j++) dlist[i].crcChecksum[j] = 0; + dlist[i].pathMetric = 0; + } + + for (int i=0; iN; 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; ipayloadBits; i++) { + for (int j=0; jcrcParityBits; j++) { + tempECGM[i][j]=polarParams->crc_generator_matrix[i][j]; + } + } + for (int i=polarParams->payloadBits; iK; i++) { + for (int j=0; jcrcParityBits; j++) { + if( (i-polarParams->payloadBits) == j ){ + tempECGM[i][j]=1; + } else { + tempECGM[i][j]=0; + } + } + } + + for (int i=0; iK; i++) { + for (int j=0; jcrcParityBits; j++) { + extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j]; + } + } + + stop_meas(init); + start_meas(polar_rate_matching); + + double d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); + nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); + memcpy((void*)&dlist[0].llr[polarParams->n][0],(void*)&d_tilde[0],sizeof(double)*polarParams->N); + stop_meas(polar_rate_matching); + + /* + * SCL polar decoder. + */ + start_meas(decoding); + uint32_t nonFrozenBit=0; + uint8_t currentListSize=1; + + decoder_list_t *sorted_dlist[2*listSize]; + decoder_list_t *temp_dlist[2*listSize]; + int listIndex[2*listSize]; + double pathMetric[2*listSize]; + + for (uint8_t i = 0; i < 2*listSize; i++) sorted_dlist[i] = &dlist[i]; + + for (uint16_t currentBit=0; currentBitN; currentBit++){ + printf("***************** BIT %d (currentListSize %d, information_bit_pattern %d)\n", + currentBit,currentListSize,polarParams->information_bit_pattern[currentBit]); + + start_meas(update_LLR); + updateLLR(sorted_dlist, llrUpdated, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr); + stop_meas(update_LLR); + + if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. + updatePathMetric(sorted_dlist,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(sorted_dlist, 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". + printf("Information bit with known value of 1\n"); + updatePathMetric(sorted_dlist, currentListSize, 1, currentBit, pathMetricAppr); + for (uint8_t i=0; ibit[0][currentBit]=1; + bitUpdated[currentBit][0]=1; + updateCrcChecksum(sorted_dlist, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); + } else { + + start_meas(path_metric); + updatePathMetric2(sorted_dlist, currentListSize, currentBit, pathMetricAppr); + stop_meas(path_metric); + + start_meas(sorting); - 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 i=0;ipathMetric); + } + 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 + + 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(double)*polarParams->N); + } } - for (int j=0;jcrcParityBits;j++) dlist[i].crcChecksum[j] = 0; - dlist[i].crcState = 1; - dlist[i].pathMetric = 0; - } - - for (int i=0; iN; 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; ipayloadBits; i++) { - for (int j=0; jcrcParityBits; j++) { - tempECGM[i][j]=polarParams->crc_generator_matrix[i][j]; - } - } - for (int i=polarParams->payloadBits; iK; i++) { - for (int j=0; jcrcParityBits; j++) { - if( (i-polarParams->payloadBits) == j ){ - tempECGM[i][j]=1; - } else { - tempECGM[i][j]=0; - } - } - } - - for (int i=0; iK; i++) { - for (int j=0; jcrcParityBits; 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; jcrcParityBits; j++) { - for (int i=0; iK; i++) { - if (extended_crc_generator_matrix[i][j]==1) last1ind[j]=i; - } + for (int i = 0; i < currentListSize; i++) { + sorted_dlist[i]->bit[0][currentBit]=0; + sorted_dlist[i+currentListSize]->bit[0][currentBit]=1; } + bitUpdated[currentBit][0]=1; + updateCrcChecksum2(sorted_dlist,extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); + + currentListSize*=2; + + //Keep only the best "listSize" number of entries. + if (currentListSize > listSize) { + int listIndex2[listSize]; + + for (int i = 0; i < currentListSize; i++) { + listIndex[i]=i; + pathMetric[i] = sorted_dlist[i]->pathMetric; + } + nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize); + for (int i=0;iN];// = malloc(sizeof(double) * polarParams->N); - nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); - memcpy((void*)&dlist[0].llr[polarParams->n][0],(void*)&d_tilde[0],sizeof(double)*polarParams->N); - stop_meas(polar_rate_matching); - - /* - * SCL polar decoder. - */ - start_meas(decoding); - uint32_t nonFrozenBit=0; - uint8_t currentListSize=1; - uint8_t copyIndex=0; - - decoder_list_t *sorted_dlist[2*listSize]; - int listIndex[2*listSize]; - double pathMetric[2*listSize]; - - for (uint8_t i = 0; i < 2*listSize; i++) sorted_dlist[i] = &dlist[i]; - - for (uint16_t currentBit=0; currentBitN; currentBit++){ - // printf("***************** BIT %d\n",currentBit); - - start_meas(update_LLR); - updateLLR(sorted_dlist, llrUpdated, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr); - stop_meas(update_LLR); - - if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. - updatePathMetric(sorted_dlist,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) ) { - printf("app[%d] %f, payloadBits %d\n",polarParams->interleaving_pattern[nonFrozenBit], - polarParams->payloadBits, - aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]]); + + // 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]interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) { - //Information bit with known value of "1". - updatePathMetric(sorted_dlist, currentListSize, 1, currentBit, pathMetricAppr); - for (uint8_t i=0; ibit[0][currentBit]=1; - bitUpdated[currentBit][0]=1; - updateCrcChecksum(sorted_dlist, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); - } else { - - start_meas(path_metric); - updatePathMetric2(sorted_dlist, currentListSize, currentBit, pathMetricAppr); - stop_meas(path_metric); - - start_meas(sorting); - 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(double)*polarParams->N); - } + 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(double)*polarParams->N); } + sorted_dlist[i]->bit[0][currentBit]=0; + sorted_dlist[i+listSize]->bit[0][currentBit]=1; + } + else if (listIndex2[i+listSize]bit[0][currentBit]=0; - sorted_dlist[i+currentListSize]->crcState=sorted_dlist[i]->crcState; + 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(double)*polarParams->N); } - for (int i = currentListSize; i < 2*currentListSize; i++) sorted_dlist[i]->bit[0][currentBit]=1; - bitUpdated[currentBit][0]=1; - updateCrcChecksum2(sorted_dlist,extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); - currentListSize*=2; + sorted_dlist[i+listSize]->bit[0][currentBit]=1; - //Keep only the best "listSize" number of entries. - if (currentListSize > listSize) { - for (int i = 0; i < currentListSize; i++) { - listIndex[i]=i; - pathMetric[i] = dlist[i].pathMetric; - } - nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize); - currentListSize = listSize; - for (uint8_t i = 0; i < 2*listSize; i++) { - sorted_dlist[i] = &dlist[listIndex[i]]; - } - } - stop_meas(sorting); + /* + 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));*/ } - nonFrozenBit++; } - + + currentListSize = listSize; + + 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]]; + } } + stop_meas(sorting); - for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) { - // printf("list index %d :",i); - // for (int j=0;jcrcParityBits;j++) printf("%d",sorted_dlist[i]->crcChecksum[j]); - // printf(" => %d (%f)\n",sorted_dlist[i]->crcState,sorted_dlist[i]->pathMetric); - int crcState = 1; - for (int j=0;jcrcParityBits;j++) if (sorted_dlist[i]->crcChecksum[j]!=0) crcState=0; - if (crcState == 1) { - for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=sorted_dlist[i]->bit[0][j]; + } + nonFrozenBit++; + } + + } + + for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) { + // printf("list index %d :",i); + // for (int j=0;jcrcParityBits;j++) printf("%d",sorted_dlist[i]->crcChecksum[j]); + // printf(" => %d (%f)\n",sorted_dlist[i]->crcState,sorted_dlist[i]->pathMetric); + int crcState = 1; + for (int j=0;jcrcParityBits;j++) if (sorted_dlist[i]->crcChecksum[j]!=0) crcState=0; + if (crcState == 1) { + for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=sorted_dlist[i]->bit[0][j]; + + 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]; + + break; + } + } + + // 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); + }*/ + 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(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) +{ + + 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_int8_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(int16_t)*polarParams->N); + } + for (int j=0;jcrcParityBits;j++) dlist[i].crcChecksum[j] = 0; + dlist[i].pathMetric = 0; + } + + for (int i=0; iN; 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; ipayloadBits; i++) { + for (int j=0; jcrcParityBits; j++) { + tempECGM[i][j]=polarParams->crc_generator_matrix[i][j]; + } + } + for (int i=polarParams->payloadBits; iK; i++) { + for (int j=0; jcrcParityBits; j++) { + if( (i-polarParams->payloadBits) == j ){ + tempECGM[i][j]=1; + } else { + tempECGM[i][j]=0; + } + } + } + + for (int i=0; iK; i++) { + for (int j=0; jcrcParityBits; 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); + memcpy((void*)&dlist[0].llr[polarParams->n][0],(void*)&d_tilde[0],sizeof(int16_t)*polarParams->N); + stop_meas(polar_rate_matching); + + /* + * SCL polar decoder. + */ + start_meas(decoding); + uint32_t nonFrozenBit=0; + uint8_t currentListSize=1; + + decoder_list_int8_t *sorted_dlist[2*listSize]; + decoder_list_int8_t *temp_dlist[2*listSize]; + int listIndex[2*listSize]; + int32_t pathMetric[2*listSize]; + + for (uint8_t i = 0; i < 2*listSize; i++) sorted_dlist[i] = &dlist[i]; + + for (uint16_t currentBit=0; currentBitN; 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); + + start_meas(sorting); + + // for (int i=0;ipathMetric); + // } + 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 + + 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); + } + } + } + + for (int i = 0; i < currentListSize; i++) { + sorted_dlist[i]->bit[0][currentBit]=0; + sorted_dlist[i+currentListSize]->bit[0][currentBit]=1; + } + 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) { + int listIndex2[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;inr_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]; + 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]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));*/ - break; } } - // 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); - }*/ - 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); + currentListSize = listSize; + + 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]]; + } + } + stop_meas(sorting); + + nonFrozenBit++; + } + + } + + + + for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) { + // printf("list index %d :",i); + // for (int j=0;jcrcParityBits;j++) printf("%d",sorted_dlist[i]->crcChecksum[j]); + // printf(" => %d (%f)\n",sorted_dlist[i]->crcState,sorted_dlist[i]->pathMetric); + int crcState = 1; + for (int j=0;jcrcParityBits;j++) if (sorted_dlist[i]->crcChecksum[j]!=0) crcState=0; + if (crcState == 1) { + for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=sorted_dlist[i]->bit[0][j]; + + 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]; + + break; + } + } + + // 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); + }*/ + 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); } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c index 2596962d9792137e120870f9123343bfefaefe06..6cc67965fb45ce70d9d72003e3ee7ee14574af72 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -33,7 +33,7 @@ inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col, #ifdef SHOWCOMP - printf("computeLLR (%d,%d,%d,%d)\n",row,col,offset,i); + printf("computeLLR (%d,%d,%d)\n",row,col,offset); #endif a = llr[col + 1][row]; b = llr[col+1][row + offset]; @@ -45,6 +45,37 @@ inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col, } else { //eq. (8a) llr[col][row] = log((exp(a + b) + 1) / (exp(a) + exp(b))); } + // 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(int16_t llr[1+nmax][Nmax], uint16_t row, uint16_t col, + uint16_t offset) __attribute__((always_inline)); +inline void computeLLR_int8(int16_t llr[1+nmax][Nmax], 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; + +#ifdef SHOWCOMP + printf("computeLLR_int8 (%d,%d,%d)\n",row,col,offset); +#endif + a = llr[col + 1][row]; + b = 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 = absAllr[col][row] = (pow((-1),dlist[i]->bit[col][row-offset])*dlist[i]->llr[col+1][row-offset]) + dlist[i]->llr[col+1][row]; + // printf("updating dlist[%d]->llr[%d][%d] => %f (%f,%f) offset %d\n",i,col,row,32*dlist[i]->llr[col][row], + // (pow((-1),dlist[i]->bit[col][row-offset])*32*dlist[i]->llr[col+1][row-offset]),32*dlist[i]->llr[col+1][row],offset); } } else { if (llrU[row][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen, approximation); if (llrU[row+offset][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, (row+offset), (col+1), xlen, ylen, approximation); for (int i=0;illr, row, col, offset, approximation); - + } + + llrU[row][col]=1; +} + +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) { + 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); + for (uint8_t i=0; ibit[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]; + // printf("updating dlist[%d]->llr[%d][%d] => %d (%d,%d) offset %d\n",i,col,row,dlist[i]->llr[col][row], + // (dlist[i]->bit[col][row-offset]==0 ? 1 : -1)*dlist[i]->llr[col+1][row-offset],dlist[i]->llr[col+1][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;illr, row, col, offset); } llrU[row][col]=1; @@ -90,6 +148,34 @@ void updateBit(decoder_list_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_ if (bitU[row][col-1]==0) updateBit(dlist, bitU, listSize, row, (col-1), xlen, ylen); if (bitU[row+offset][col-1]==0) updateBit(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen); dlist[i]->bit[col][row] = ( (dlist[i]->bit[col-1][row]+dlist[i]->bit[col-1][row+offset]) % 2); + // printf("updating dlist[%d]->bit[%d][%d] => %d\n",i,col,row,dlist[i]->bit[col][row]); +#ifdef SHOWCOMP + printf("updating bit (%d,%d,%d) from (%d,%d,%d)+(%d,%d,%d)\n", + row,col,i,row,col-1,i,row+offset,col-1,i); +#endif + } + } + + bitU[row][col]=1; +} + +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 offset = ( xlen/(pow(2,(ylen-col))) ); + + for (uint8_t i=0; i= 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("updating bit (%d,%d,%d) from (%d,%d,%d)\n", + row,col,i,row,col-1,i); +#endif + } 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); + 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("updating bit (%d,%d,%d) from (%d,%d,%d)+(%d,%d,%d)\n", row,col,i,row,col-1,i,row+offset,col-1,i); @@ -111,44 +197,42 @@ void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue, if (approximation) { //eq. (12) for (uint8_t i=0; illr[0][row]) )) dlist[i]->pathMetric += fabs(dlist[i]->llr[0][row]); + // printf("updatepathmetric : llr %f pathMetric %f (bitValue %d)\n",32*dlist[i]->llr[0][row],32*dlist[i]->pathMetric,bitValue); } } else { //eq. (11b) - int8_t multiplier = (2*bitValue) - 1; - for (uint8_t i=0; ipathMetric += log ( 1 + exp(multiplier*dlist[i]->llr[0][row]) ) ; + int8_t multiplier = (2*bitValue) - 1; + for (uint8_t i=0; ipathMetric += log ( 1 + exp(multiplier*dlist[i]->llr[0][row]) ) ; + // printf("updatepathmetric : llr %f pathMetric %f\n",32*dlist[i]->llr[0][row],32*dlist[i]->pathMetric); + } } } -/* -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])); - } +void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16_t row) { - 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)])); - } +#ifdef SHOWCOMP + printf("updating path_metric from Frozen bit (%d,%d) \n", + row,0); +#endif + int16_t mask; + for (uint8_t i=0; illr[0][row]) )) dlist[i]->pathMetric += fabs(dlist[i]->llr[0][row]); + // equiv: if ((llr>0 && bitValue==1) || (llr<0 && bitValue==0) ... + // equiv: (llr>>7 + bitValue) != 0, in opposite case (llr>8 + bitValue) = -1 or 1 + - free(tempPM); + mask = dlist[i]->llr[0][row]>>15; + + if (mask != 0) { + int16_t absllr = (dlist[i]->llr[0][row]+mask)^mask; + dlist[i]->pathMetric += absllr; + } + // printf("updatepathmetric : llr %d, pathMetric %d (bitValue %d)\n",dlist[i]->llr[0][row],dlist[i]->pathMetric); + } } -*/ void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, uint8_t appr) { @@ -174,10 +258,29 @@ void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, u dlist[i]->pathMetric += log(1 + exp(-dlist[i]->llr[0][row])); // bitValue=1 dlist2[i]->pathMetric += log(1 + exp(dlist[i]->llr[0][row])); + } } } +void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint16_t row) { + + int i; + + for (i=0;ipathMetric = dlist[i]->pathMetric; + decoder_list_int8_t **dlist2 = &dlist[listSize]; + +#ifdef SHOWCOMP + printf("updating path_metric from information bit (%d,%d) \n", + row,0); +#endif + for (i = 0; i < listSize; i++) { + // bitValue=0 + if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric -= dlist[i]->llr[0][row]; + // bitValue=1 + else dlist2[i]->pathMetric += dlist[i]->llr[0][row]; + } +} void updateCrcChecksum(decoder_list_t **dlist, uint8_t **crcGen, @@ -197,3 +300,21 @@ void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen, } } } + +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++) { + for (uint8_t j = 0; j < len; j++) { + dlist[i]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 ); + } + } +} + +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++) { + for (uint8_t j = 0; j < len; j++) { + dlist[i+listSize]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 ); + } + } +} diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index c35856a0ced784f9338373dfeb82e3895ab71cc5..43142864cbf6ccdc72579aebc1ae75827fae1617 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -104,6 +104,9 @@ void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P 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_matching_int8(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, uint8_t I_IL, uint16_t *PI_k_); void nr_polar_info_bit_pattern(uint8_t *ibp, int16_t *Q_I_N, int16_t *Q_F_N, @@ -138,31 +141,57 @@ typedef struct decoder_list_s { uint8_t bit[1+nmax][Nmax]; double llr[1+nmax][Nmax]; uint8_t crcChecksum[24]; - uint8_t crcState; double pathMetric; } decoder_list_t; +typedef struct decoder_list_int8_s { + + uint8_t bit[1+nmax][Nmax]; + int16_t llr[1+nmax][Nmax]; + 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); + 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); + void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue, - uint16_t row, uint8_t approximation); + uint16_t row, uint8_t approximation); + +void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16_t row); 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 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); + 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); + void nr_sort_asc_double_1D_array_ind(double *matrix, int *ind, int len); +void nr_sort_asc_int16_1D_array_ind(int32_t *matrix, int *ind, int len); + uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits); uint8_t **crc11_generator_matrix(uint16_t payloadSizeBits); uint8_t **crc6_generator_matrix(uint16_t payloadSizeBits); diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c index 87da27a59fea0f15fbcf02721e4452bca9db609a..23ec51a400f7e995d940ae05d559f2b38a8068e1 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c @@ -168,3 +168,28 @@ void nr_sort_asc_double_1D_array_ind(double *matrix, int *ind, int len) { break; } } + +void nr_sort_asc_int16_1D_array_ind(int32_t *matrix, int *ind, int len) { + int swaps; + int16_t temp; + 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; + } +} diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_rate_match.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_rate_match.c index 90f16183c8e51f1fc28d4f1b6f27a5cb790a2867..d23760305936857190d03885ca9efe93b5796aec 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_rate_match.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_rate_match.c @@ -79,3 +79,24 @@ void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp, uint16 } } + +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]; + } + } + +}