diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index d379aaf58e..0aa0dd118f 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -10,8 +10,8 @@ #include "PHY/CODING/coding_defs.h" #include "SIMULATION/TOOLS/sim.h" -//#define DEBUG_POLAR_PARAMS //#define DEBUG_DCI_POLAR_PARAMS +//#define DEBUG_POLAR_TIMING int main(int argc, char *argv[]) { @@ -24,7 +24,6 @@ int main(int argc, char *argv[]) { randominit(0); crcTableInit(); - uint32_t crc; //Default simulation values (Aim for iterations = 1000000.) int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB @@ -34,14 +33,13 @@ int main(int argc, char *argv[]) { int8_t decoderState=0, blockErrorState=0; //0 = Success, -1 = Decoding failed, 1 = Block Error. uint16_t testLength = 0, coderLength = 0, blockErrorCumulative=0, bitErrorCumulative=0; double timeEncoderCumulative = 0, timeDecoderCumulative = 0; - uint8_t aggregation_level, decoderListSize, pathMetricAppr; + uint8_t aggregation_level = 8, decoderListSize = 8, pathMetricAppr = 0; while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:")) != -1) switch (arguments) { case 's': SNRstart = atof(optarg); - printf("SNRstart = %f\n", SNRstart); break; case 'd': @@ -93,7 +91,12 @@ int main(int argc, char *argv[]) { folderName=getenv("HOME"); strcat(folderName,"/Desktop/polartestResults"); + + #ifdef DEBUG_POLAR_TIMING + sprintf(fileName,"%s/TIMING_ListSize_%d_pmAppr_%d_Payload_%d_Itr_%d",folderName,decoderListSize,pathMetricAppr,testLength,iterations); + #else sprintf(fileName,"%s/_ListSize_%d_pmAppr_%d_Payload_%d_Itr_%d",folderName,decoderListSize,pathMetricAppr,testLength,iterations); + #endif strftime(currentTimeInfo, 25, "_%Y-%m-%d-%H-%M-%S.csv", localtime(¤tTime)); strcat(fileName,currentTimeInfo); @@ -107,65 +110,45 @@ int main(int argc, char *argv[]) { fprintf(stderr,"[polartest.c] Problem creating file %s with fopen\n",fileName); exit(-1); } + +#ifdef DEBUG_POLAR_TIMING + fprintf(logFile,",timeEncoderCRCByte[us],timeEncoderCRCBit[us],timeEncoderInterleaver[us],timeEncoderBitInsertion[us],timeEncoder1[us],timeEncoder2[us],timeEncoderRateMatching[us],timeEncoderByte2Bit[us]\n"); +#else fprintf(logFile,",SNR,nBitError,blockErrorState,t_encoder[us],t_decoder[us]\n"); +#endif - //uint8_t *testInput = malloc(sizeof(uint8_t) * testLength); //generate randomly - //uint8_t *encoderOutput = malloc(sizeof(uint8_t) * coderLength); - uint32_t testInput[4], encoderOutput[4]; - memset(testInput,0,sizeof(testInput)); - memset(encoderOutput,0,sizeof(encoderOutput)); + uint8_t testArrayLength = ceil(testLength / 32.0); + uint8_t coderArrayLength = ceil(coderLength / 32.0); + uint32_t *testInput = malloc(sizeof(uint32_t) * testArrayLength); //generate randomly + uint32_t *encoderOutput = malloc(sizeof(uint32_t) * coderArrayLength); + uint32_t *estimatedOutput = malloc(sizeof(uint32_t) * testArrayLength); //decoder output + memset(testInput,0,sizeof(uint32_t) * testArrayLength); + memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength); + memset(estimatedOutput,0,sizeof(uint32_t) * testArrayLength); + + uint8_t *encoderOutputByte = malloc(sizeof(uint8_t) * coderLength); double *modulatedInput = malloc (sizeof(double) * coderLength); //channel input - double *channelOutput = malloc (sizeof(double) * coderLength); //add noise - uint32_t *estimatedOutput = malloc(sizeof(uint8_t) * testLength); //decoder output t_nrPolar_paramsPtr nrPolar_params = NULL, currentPtr = NULL; nr_polar_init(&nrPolar_params, polarMessageType, testLength, aggregation_level); + currentPtr = nr_polar_params(nrPolar_params, polarMessageType, testLength, aggregation_level); + #ifdef DEBUG_DCI_POLAR_PARAMS + uint32_t crc; unsigned int poly24c = 0xb2b11700; + testInput[0]=0x01189400; printf("testInput: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", testInput[0], testInput[1], testInput[2], testInput[3]); - printf("encOutput: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", - encoderOutput[0], encoderOutput[1], encoderOutput[2], encoderOutput[3]); - testInput[0]=0x01189400; uint8_t testInput2[8]; nr_crc_bit2bit_uint32_8_t(testInput, 32, testInput2); - printf("testInput2: [0]->%x \t [1]->%x \t [2]->%x \t [3]->%x\n [4]->%x \t [5]->%x \t [6]->%x \t [7]->%x \t\n", + printf("testInput2: [0]->%x \t [1]->%x \t [2]->%x \t [3]->%x\n" + " [4]->%x \t [5]->%x \t [6]->%x \t [7]->%x\n", testInput2[0], testInput2[1], testInput2[2], testInput2[3], testInput2[4], testInput2[5], testInput2[6], testInput2[7]); printf("crc32: [0]->0x%08x\n",crc24c(testInput2, 32)); printf("crc56: [0]->0x%08x\n",crc24c(testInput2, 56)); - return 0; - uint8_t testInput8[4]; - /*testInput8[0]=0x00; - testInput8[1]=0x49; - testInput8[2]=0x81; - testInput8[3]=0x10; - testInput8[4]=0x00;*/ - testInput8[0]=0xff; - testInput8[1]=0xd0; - testInput8[2]=0xff; - testInput8[3]=0x82; - crc = crc24c(testInput8, 31); - for (int i=0;i<24;i++) printf("[i]=%d\n",(crc>>i)&1); - printf("crc: [0]->0x%08x\n",crc); - printf("crcbit: %x\n",crcbit(testInput8, 3, poly24c)); - return 0; - unsigned char test[] = "Thebigredfox"; - - for (int i=0;i<8;i++) printf("[i]=%d\n",(test[0]>>i)&1); - printf("test[0]=%x\n",test[0]); - printf("%s -- sizeof=%d\n",test,sizeof(test)); - printf("%x\n", crcbit(test, sizeof(test) - 1, poly24c)); - printf("%x\n", crc24c(test, (sizeof(test) - 1)*8)); - polarMessageType = 1; - testLength = 41; - aggregation_level=1; - coderLength = 108; - nr_polar_init(&nrPolar_params, polarMessageType, testLength, aggregation_level); - nr_polar_print_polarParams(nrPolar_params); - crc = crc24c(testInput, testLength)>>8; for (int i=0;i<24;i++) printf("[i]=%d\n",(crc>>i)&1); printf("crc: [0]->0x%08x\n",crc); @@ -174,18 +157,30 @@ int main(int argc, char *argv[]) { testInput[2+(testLength>>3)] = ((uint8_t*)&crc)[0]; printf("testInput: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", testInput[0], testInput[1], testInput[2], testInput[3]); - return (0); - currentPtr = nr_polar_params(nrPolar_params, polarMessageType, testLength, aggregation_level); - polar_encoder(testInput, encoderOutput, currentPtr); - printf("AFTER POLAR ENCODING\n"); - printf("testInput: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", - testInput[0], testInput[1], testInput[2], testInput[3]); - printf("encOutput: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", - encoderOutput[0], encoderOutput[1], encoderOutput[2], encoderOutput[3]); - return (0); #endif - currentPtr = nr_polar_params(nrPolar_params, polarMessageType, testLength, aggregation_level); +#ifdef DEBUG_POLAR_TIMING + for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) { + SNR_lin = pow(10, SNR / 10); + for (itr = 1; itr <= iterations; itr++) { + for (int j=0; j0x%08x \n", testInput[0]); + polar_encoder_timing(testInput, encoderOutput, currentPtr, cpu_freq_GHz, logFile); + } + } + fclose(logFile); + free(testInput); + free(encoderOutput); + free(modulatedInput); + free(channelOutput); + free(estimatedOutput); + return (0); +#endif // We assume no a priori knowledge available about the payload. double aPrioriArray[currentPtr->payloadBits]; @@ -195,68 +190,87 @@ int main(int argc, char *argv[]) { SNR_lin = pow(10, SNR/10); for (itr = 1; itr <= iterations; itr++) { - for(int i=0; i0) blockErrorState=1; - } - //Iteration times are in microseconds. - timeEncoderCumulative+=(timeEncoder.diff_now/(cpu_freq_GHz*1000.0)); - timeDecoderCumulative+=(timeDecoder.diff_now/(cpu_freq_GHz*1000.0)); - fprintf(logFile,",%f,%d,%d,%f,%f\n", SNR, nBitError, blockErrorState, - (timeEncoder.diff_now/(cpu_freq_GHz*1000.0)), (timeDecoder.diff_now/(cpu_freq_GHz*1000.0))); + /*printf("testInput: [0]->0x%08x\n", testInput[0]); + for (int i=0; i<32; i++) + printf("%d\n",(testInput[0]>>i)&1);*/ - if (nBitError<0) { - blockErrorCumulative++; - bitErrorCumulative+=testLength; - } else { - blockErrorCumulative+=blockErrorState; - bitErrorCumulative+=nBitError; - } + start_meas(&timeEncoder); + polar_encoder(testInput, encoderOutput, currentPtr); + stop_meas(&timeEncoder); - decoderState=0; - nBitError=0; - blockErrorState=0; + /*printf("encoderOutput: [0]->0x%08x\n", encoderOutput[0]); + printf("encoderOutput: [1]->0x%08x\n", encoderOutput[1]); +*/ + //Bit-to-byte: + nr_bit2byte_uint32_8_t(encoderOutput, coderLength, encoderOutputByte); + + //BPSK modulation + for(int i=0; i0x%08x\n", testInput[0]); + printf("estimatedOutput: [0]->0x%08x\n", estimatedOutput[0]); +*/ + + //calculate errors + if (decoderState==-1) { + blockErrorState=-1; + nBitError=-1; + } else { + for (int i = 0; i < testArrayLength; i++) { + for (int j = 0; j < (sizeof(testInput[0])*8); j++) { + if (((estimatedOutput[i]>>j) & 1) != ((testInput[i]>>j) & 1)) nBitError++; + } + } + + if (nBitError>0) blockErrorState=1; + } + + //Iteration times are in microseconds. + timeEncoderCumulative+=(timeEncoder.diff_now/(cpu_freq_GHz*1000.0)); + timeDecoderCumulative+=(timeDecoder.diff_now/(cpu_freq_GHz*1000.0)); + fprintf(logFile,",%f,%d,%d,%f,%f\n", SNR, nBitError, blockErrorState, + (timeEncoder.diff_now/(cpu_freq_GHz*1000.0)), (timeDecoder.diff_now/(cpu_freq_GHz*1000.0))); + + if (nBitError<0) { + blockErrorCumulative++; + bitErrorCumulative+=testLength; + } else { + blockErrorCumulative+=blockErrorState; + bitErrorCumulative+=nBitError; + } + + decoderState=0; + nBitError=0; + blockErrorState=0; } //Calculate error statistics for the SNR. @@ -273,11 +287,14 @@ int main(int argc, char *argv[]) { print_meas(&timeDecoder,"polar_decoder",NULL,NULL); fclose(logFile); - //free(testInput); - //free(encoderOutput); + //Bit + free(testInput); + free(encoderOutput); + free(estimatedOutput); + //Byte + free(encoderOutputByte); free(modulatedInput); free(channelOutput); - free(estimatedOutput); return (0); } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 51a0328d7e..1616c498e4 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -278,13 +278,268 @@ int8_t polar_decoder( return(0); } -int8_t polar_decoder_aPriori( - double *input, - uint32_t *out, - t_nrPolar_paramsPtr polarParams, - uint8_t listSize, - uint8_t pathMetricAppr, - double *aPrioriPayload) +int8_t polar_decoder_aPriori(double *input, + uint32_t *out, + t_nrPolar_paramsPtr polarParams, + uint8_t listSize, + uint8_t pathMetricAppr, + double *aPrioriPayload) +{ + + uint8_t ***bit = nr_alloc_uint8_t_3D_array(polarParams->N, (polarParams->n+1), 2*listSize); + uint8_t **bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True + uint8_t **llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True + double ***llr = nr_alloc_double_3D_array(polarParams->N, (polarParams->n+1), 2*listSize); + uint8_t **crcChecksum = nr_alloc_uint8_t_2D_array(polarParams->crcParityBits, 2*listSize); + double *pathMetric = malloc(sizeof(double)*(2*listSize)); + uint8_t *crcState = malloc(sizeof(uint8_t)*(2*listSize)); //0=False, 1=True + + for (int i=0; i<(2*listSize); i++) { + pathMetric[i] = 0; + crcState[i]=1; + } + for (int i=0; iN; i++) { + 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; + } + } + + double *d_tilde = malloc(sizeof(double) * polarParams->N); + nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); + for (int j = 0; j < polarParams->N; j++) llr[j][polarParams->n][0]=d_tilde[j]; + + + /* + * SCL polar decoder. + */ + + uint32_t nonFrozenBit=0; + uint8_t currentListSize=1; + uint8_t decoderIterationCheck=0; + int16_t checkCrcBits=-1; + uint8_t listIndex[2*listSize], copyIndex; + + for (uint16_t currentBit=0; currentBitN; currentBit++){ + updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr); + if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. + updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12 + } else { //Information or CRC bit. + if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) && + (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 0) ) { + //Information bit with known value of "0". + updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); + bitUpdated[currentBit][0]=1; //0=False, 1=True + } else if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) && + (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) { + //Information bit with known value of "1". + updatePathMetric(pathMetric, llr, currentListSize, 1, currentBit, pathMetricAppr); + for (uint8_t i=0; icrcParityBits); + } else { + updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr); + + for (int i = 0; i < currentListSize; i++) { + for (int j = 0; j < polarParams->N; j++) { + for (int k = 0; k < (polarParams->n+1); k++) { + bit[j][k][i+currentListSize]=bit[j][k][i]; + llr[j][k][i+currentListSize]=llr[j][k][i];}}} + for (int i = 0; i < currentListSize; i++) { + bit[currentBit][0][i]=0; + crcState[i+currentListSize]=crcState[i]; + } + for (int i = currentListSize; i < 2*currentListSize; i++) bit[currentBit][0][i]=1; + bitUpdated[currentBit][0]=1; + updateCrcChecksum2(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); + currentListSize*=2; + + //Keep only the best "listSize" number of entries. + if (currentListSize > listSize) { + for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i; + nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize); + + //sort listIndex[listSize, ..., 2*listSize-1] in descending order. + uint8_t swaps, tempInd; + for (uint8_t i = 0; i < listSize; i++) { + swaps = 0; + for (uint8_t j = listSize; j < (2*listSize - i) - 1; j++) { + if (listIndex[j+1] > listIndex[j]) { + tempInd = listIndex[j]; + listIndex[j] = listIndex[j + 1]; + listIndex[j + 1] = tempInd; + swaps++; + } + } + if (swaps == 0) + break; + } + + //First, backup the best "listSize" number of entries. + for (int k=(listSize-1); k>0; k--) { + for (int i=0; iN; i++) { + for (int j=0; j<(polarParams->n+1); j++) { + bit[i][j][listIndex[(2*listSize-1)-k]]=bit[i][j][listIndex[k]]; + llr[i][j][listIndex[(2*listSize-1)-k]]=llr[i][j][listIndex[k]]; + } + } + } + for (int k=(listSize-1); k>0; k--) { + for (int i = 0; i < polarParams->crcParityBits; i++) { + crcChecksum[i][listIndex[(2*listSize-1)-k]] = crcChecksum[i][listIndex[k]]; + } + } + for (int k=(listSize-1); k>0; k--) crcState[listIndex[(2*listSize-1)-k]]=crcState[listIndex[k]]; + + //Copy the best "listSize" number of entries to the first indices. + for (int k = 0; k < listSize; k++) { + if (k > listIndex[k]) { + copyIndex = listIndex[(2*listSize-1)-k]; + } else { //Use the backup. + copyIndex = listIndex[k]; + } + for (int i = 0; i < polarParams->N; i++) { + for (int j = 0; j < (polarParams->n + 1); j++) { + bit[i][j][k] = bit[i][j][copyIndex]; + llr[i][j][k] = llr[i][j][copyIndex]; + } + } + } + for (int k = 0; k < listSize; k++) { + if (k > listIndex[k]) { + copyIndex = listIndex[(2*listSize-1)-k]; + } else { //Use the backup. + copyIndex = listIndex[k]; + } + for (int i = 0; i < polarParams->crcParityBits; i++) { + crcChecksum[i][k]=crcChecksum[i][copyIndex]; + } + } + for (int k = 0; k < listSize; k++) { + if (k > listIndex[k]) { + copyIndex = listIndex[(2*listSize-1)-k]; + } else { //Use the backup. + copyIndex = listIndex[k]; + } + crcState[k]=crcState[copyIndex]; + } + currentListSize = listSize; + } + } + + for (int i=0; icrcParityBits; i++) { + if (last1ind[i]==nonFrozenBit) { + checkCrcBits=i; + break; + } + } + + if ( checkCrcBits > (-1) ) { + for (uint8_t i = 0; i < currentListSize; i++) { + if (crcChecksum[checkCrcBits][i]==1) { + crcState[i]=0; //0=False, 1=True + } + } + } + + for (uint8_t i = 0; i < currentListSize; i++) decoderIterationCheck+=crcState[i]; + if (decoderIterationCheck==0) { + //perror("[SCL polar decoder] All list entries have failed the CRC checks."); + free(d_tilde); + free(pathMetric); + free(crcState); + nr_free_uint8_t_3D_array(bit, polarParams->N, (polarParams->n+1)); + nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1)); + nr_free_uint8_t_2D_array(crcChecksum, polarParams->crcParityBits); + return(-1); + } + + nonFrozenBit++; + decoderIterationCheck=0; + checkCrcBits=-1; + } + } + + for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i; + nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize); + + for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) { + if ( crcState[listIndex[i]] == 1 ) { + for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_U[j]=bit[j][0][listIndex[i]]; + + //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]; + + break; + } + } + + free(d_tilde); + free(pathMetric); + free(crcState); + nr_free_uint8_t_3D_array(bit, polarParams->N, (polarParams->n+1)); + nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1)); + nr_free_uint8_t_2D_array(crcChecksum, polarParams->crcParityBits); + nr_free_uint8_t_2D_array(extended_crc_generator_matrix, polarParams->K); + nr_free_uint8_t_2D_array(tempECGM, polarParams->K); + + /* + * Return bits. + */ + nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out); + return(0); +} + + + +int8_t polar_decoder_aPriori_timing(double *input, + uint32_t *out, + t_nrPolar_paramsPtr polarParams, + uint8_t listSize, + uint8_t pathMetricAppr, + double *aPrioriPayload, + double cpuFreqGHz, + FILE* logFile) { uint8_t ***bit = nr_alloc_uint8_t_3D_array(polarParams->N, (polarParams->n+1), 2*listSize); diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index fdf34398fa..28e4c72864 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -42,6 +42,8 @@ #include "PHY/CODING/nrPolar_tools/nr_polar_dci_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h" +#include "PHY/CODING/coding_defs.h" +#include "SIMULATION/TOOLS/sim.h" #define NR_POLAR_DECODER_LISTSIZE 8 //uint8_t #define NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION 0 //uint8_t; 0 --> eq. (8a) and (11b), 1 --> eq. (9) and (12) @@ -111,6 +113,12 @@ void polar_encoder_dci(uint32_t *in, t_nrPolar_paramsPtr polarParams, uint16_t n_RNTI); +void polar_encoder_timing(uint32_t *in, + uint32_t *out, + t_nrPolar_paramsPtr polarParams, + double cpuFreqGHz, + FILE* logFile); + int8_t polar_decoder(double *input, uint8_t *output, t_nrPolar_paramsPtr polarParams, @@ -124,6 +132,15 @@ int8_t polar_decoder_aPriori(double *input, uint8_t pathMetricAppr, double *aPrioriPayload); +int8_t polar_decoder_aPriori_timing(double *input, + uint32_t *output, + t_nrPolar_paramsPtr polarParams, + uint8_t listSize, + uint8_t pathMetricAppr, + double *aPrioriPayload, + double cpuFreqGHz, + FILE* logFile); + void nr_polar_init(t_nrPolar_paramsPtr *polarParams, int8_t messageType, uint16_t messageLength, diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c index 2c9e3529a2..c1a0c31a42 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c @@ -30,10 +30,15 @@ * \warning */ +//#define DEBUG_POLAR_ENCODER //#define DEBUG_POLAR_ENCODER_DCI +//#define DEBUG_POLAR_ENCODER_TIMING #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" +//input [a_31 a_30 ... a_0] +//output [f_31 f_30 ... f_0] [f_63 f_62 ... f_32] ... + void polar_encoder(uint32_t *in, uint32_t *out, t_nrPolar_paramsPtr polarParams) @@ -95,6 +100,10 @@ void polar_encoder(uint32_t *in, /* * Return bits. */ +#ifdef DEBUG_POLAR_ENCODER + for (int i=0; i< polarParams->encoderLength;i++) printf("f[%d]=%d\n", i, polarParams->nr_polar_E[i]); +#endif + nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out); } @@ -187,3 +196,76 @@ void polar_encoder_dci(uint32_t *in, } #endif } + +void polar_encoder_timing(uint32_t *in, + uint32_t *out, + t_nrPolar_paramsPtr polarParams, + double cpuFreqGHz, + FILE* logFile) +{ + //Initiate timing. + time_stats_t timeEncoderCRCByte, timeEncoderCRCBit, timeEncoderInterleaver, timeEncoderBitInsertion, timeEncoder1, timeEncoder2, timeEncoderRateMatching, timeEncoderByte2Bit; + reset_meas(&timeEncoderCRCByte); reset_meas(&timeEncoderCRCBit); reset_meas(&timeEncoderInterleaver); reset_meas(&timeEncoderBitInsertion); reset_meas(&timeEncoder1); reset_meas(&timeEncoder2); reset_meas(&timeEncoderRateMatching); reset_meas(&timeEncoderByte2Bit); + uint16_t n_RNTI=0x0000; + + start_meas(&timeEncoderCRCByte); + nr_crc_bit2bit_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_aPrime); //(a to a') + polarParams->crcBit = crc24c(polarParams->nr_polar_aPrime, (polarParams->payloadBits+polarParams->crcParityBits)); //Parity bits computation (p) + uint8_t arrayInd = ceil(polarParams->payloadBits / 8.0); //(a to b) + for (int i=0; inr_polar_B[j+(i*8)] = ((polarParams->nr_polar_aPrime[3+i]>>(7-j)) & 1); + for (int i=0; i<((polarParams->payloadBits)%8); i++) polarParams->nr_polar_B[i+(arrayInd-1)*8] = ((polarParams->nr_polar_aPrime[3+(arrayInd-1)]>>(7-i)) & 1); + for (int i=0; i<8; i++) polarParams->nr_polar_B[polarParams->payloadBits+i] = ((polarParams->crcBit)>>(31-i))&1; + for (int i=0; i<16; i++) polarParams->nr_polar_B[polarParams->payloadBits+8+i] = ( (((polarParams->crcBit)>>(23-i))&1) + ((n_RNTI>>(15-i))&1) ) % 2; //Scrambling (b to c) + stop_meas(&timeEncoderCRCByte); + + + start_meas(&timeEncoderCRCBit); + nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_A); + nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_A, polarParams->crc_generator_matrix, polarParams->nr_polar_crc, polarParams->payloadBits, polarParams->crcParityBits); //Calculate CRC. + for (uint8_t i = 0; i < polarParams->crcParityBits; i++) polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2); + for (uint16_t i = 0; i < polarParams->payloadBits; i++) polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i]; //Attach CRC to the Transport Block. (a to b) + for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++) polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)]; + stop_meas(&timeEncoderCRCBit); + + + start_meas(&timeEncoderInterleaver); //Interleaving (c to c') + nr_polar_interleaver(polarParams->nr_polar_B, polarParams->nr_polar_CPrime, polarParams->interleaving_pattern, polarParams->K); + stop_meas(&timeEncoderInterleaver); + + + start_meas(&timeEncoderBitInsertion); //Bit insertion (c' to u) + nr_polar_bit_insertion(polarParams->nr_polar_CPrime, polarParams->nr_polar_U, polarParams->N, polarParams->K, polarParams->Q_I_N, polarParams->Q_PC_N, polarParams->n_pc); + stop_meas(&timeEncoderBitInsertion); + + + start_meas(&timeEncoder1); //Encoding (u to d) + nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_U, polarParams->G_N, polarParams->nr_polar_D, polarParams->N, polarParams->N); + stop_meas(&timeEncoder1); + + + start_meas(&timeEncoder2); + for (uint16_t i = 0; i < polarParams->N; i++) polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2); + stop_meas(&timeEncoder2); + + + start_meas(&timeEncoderRateMatching);//Rate matching //Sub-block interleaving (d to y) and Bit selection (y to e) + nr_polar_interleaver(polarParams->nr_polar_D, polarParams->nr_polar_E, polarParams->rate_matching_pattern, polarParams->encoderLength); + stop_meas(&timeEncoderRateMatching); + + + start_meas(&timeEncoderByte2Bit); //Return bits. + nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out); + stop_meas(&timeEncoderByte2Bit); + + fprintf(logFile,",%f,%f,%f,%f,%f,%f,%f,%f\n", + (timeEncoderCRCByte.diff_now/(cpuFreqGHz*1000.0)), + (timeEncoderCRCBit.diff_now/(cpuFreqGHz*1000.0)), + (timeEncoderInterleaver.diff_now/(cpuFreqGHz*1000.0)), + (timeEncoderBitInsertion.diff_now/(cpuFreqGHz*1000.0)), + (timeEncoder1.diff_now/(cpuFreqGHz*1000.0)), + (timeEncoder2.diff_now/(cpuFreqGHz*1000.0)), + (timeEncoderRateMatching.diff_now/(cpuFreqGHz*1000.0)), + (timeEncoderByte2Bit.diff_now/(cpuFreqGHz*1000.0))); +}