diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 4af5bf82f4..eb06b151cb 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1125,6 +1125,7 @@ set(PHY_POLARSRC ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_bit_insertion.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_channel_interleaver_pattern.c # ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_crc.c +# ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/decoder_K56_N512_E864.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_info_bit_pattern.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_interleaving_pattern.c diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index 144b63b353..e23c69215a 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -15,12 +15,23 @@ int main(int argc, char *argv[]) { //Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.) time_stats_t timeEncoder,timeDecoder; + 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); + reset_meas(&polar_decoder_init); + reset_meas(&polar_rate_matching); + reset_meas(&decoding); + reset_meas(&bit_extraction); + reset_meas(&deinterleaving); + reset_meas(&sorting); + 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 @@ -32,8 +43,9 @@ int main(int argc, char *argv[]) { double timeEncoderCumulative = 0, timeDecoderCumulative = 0; uint8_t decoderListSize = 8, pathMetricAppr = 0; //0 --> eq. (8a) and (11b), 1 --> eq. (9) and (12) + int generate_optim_code=0; - while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:h")) != -1) + while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:h:qg")) != -1) switch (arguments) { case 's': @@ -65,6 +77,17 @@ int main(int argc, char *argv[]) { pathMetricAppr = (uint8_t) atoi(optarg); break; + case 'q': + decoder_int8=1; + break; + + case 'g': + generate_optim_code=1; + iterations=1; + SNRstart=-6.0; + SNRstop =-6.0; + decoder_int8=1; + break; case 'h': printf("./polartest -s SNRstart -d SNRinc -f SNRstop -m [0=DCI|1=PBCH|2=UCI] -i iterations -l decoderListSize -a pathMetricAppr\n"); exit(-1); @@ -121,16 +144,23 @@ 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; nr_polar_init(&nrPolar_params, polarMessageType); + nr_polar_llrtableinit(); + + if (generate_optim_code==1) nrPolar_params.decoder_kernel = NULL; // We assume no a priori knowledge available about the payload. double aPrioriArray[nrPolar_params.payloadBits]; - for (int i=0; i 15) channelOutput_int8[i] = 127; + else if (channelOutput[i] < -16) channelOutput_int8[i] = -128; + else channelOutput_int8[i] = (int16_t) (8*channelOutput[i]); + } } start_meas(&timeDecoder); - decoderState = polar_decoder(channelOutput, estimatedOutput, &nrPolar_params, decoderListSize, aPrioriArray, pathMetricAppr); - 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_new(channelOutput_int8, estimatedOutput, &nrPolar_params, + decoderListSize, &polar_decoder_init,&polar_rate_matching, + &decoding,&bit_extraction,&deinterleaving, + &sorting,&path_metric,&update_LLR, + generate_optim_code); + stop_meas(&timeDecoder); + //calculate errors if (decoderState==-1) { blockErrorState=-1; @@ -191,7 +237,15 @@ int main(int argc, char *argv[]) { decoderListSize, pathMetricAppr, SNR, ((double)blockErrorCumulative/iterations), ((double)bitErrorCumulative / (iterations*testLength)), (timeEncoderCumulative/iterations),timeDecoderCumulative/iterations); + printf("decoding init %9.3fus\n",polar_decoder_init.diff/(cpu_freq_GHz*1000.0*polar_decoder_init.trials)); + printf("decoding polar_rate_matching %9.3fus\n",polar_rate_matching.diff/(cpu_freq_GHz*1000.0*polar_rate_matching.trials)); + 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*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_init.c b/openair1/PHY/CODING/nrPolar_init.c index 65422ee073..f606acbe95 100644 --- a/openair1/PHY/CODING/nrPolar_init.c +++ b/openair1/PHY/CODING/nrPolar_init.c @@ -27,9 +27,9 @@ 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 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 @@ -62,6 +62,11 @@ uint32_t poly24c = 0xB2B11700; //101100101011000100010111 -> D^24... polarParams->nr_polar_u = malloc(sizeof(uint8_t) * polarParams->N); //Decoder: nr_polar_uHat polarParams->nr_polar_cPrime = malloc(sizeof(uint8_t) * polarParams->K); //Decoder: nr_polar_cHat polarParams->nr_polar_b = malloc(sizeof(uint8_t) * polarParams->K); //Decoder: nr_polar_bHat + + polarParams->decoder_kernel = NULL;//polar_decoder_K56_N512_E864; + + + } else if (messageType == 2) { //UCI polarParams->payloadBits = NR_POLAR_PUCCH_PAYLOAD_BITS; //A depends on what they carry... polarParams->encoderLength = NR_POLAR_PUCCH_E ; //E depends on other standards 6.3.1.4 @@ -131,6 +136,7 @@ uint32_t poly24c = 0xB2B11700; //101100101011000100010111 -> D^24... polarParams->nr_polar_u = malloc(sizeof(uint8_t) * polarParams->N); //Decoder: nr_polar_uHat polarParams->nr_polar_cPrime = malloc(sizeof(uint8_t) * polarParams->K); //Decoder: nr_polar_cHat polarParams->nr_polar_b = malloc(sizeof(uint8_t) * polarParams->K); //Decoder: nr_polar_bHat + } polarParams->crcCorrectionBits = NR_POLAR_CRC_ERROR_CORRECTION_BITS; @@ -161,5 +167,38 @@ uint32_t poly24c = 0xB2B11700; //101100101011000100010111 -> D^24... nr_polar_channel_interleaver_pattern(polarParams->channel_interleaver_pattern, polarParams->i_bil, polarParams->encoderLength); + polarParams->extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3 + uint8_t tempECGM[polarParams->K][polarParams->crcParityBits]; + for (int i = 0; i < polarParams->K; i++){ + polarParams->extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t)); + } + + for (int i=0; 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++) { + 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); } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 3d076296d0..67fe489424 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * 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 */ @@ -27,6 +27,8 @@ #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h" +#include "PHY/TOOLS/time_meas.h" + int8_t polar_decoder( double *input, @@ -34,242 +36,502 @@ int8_t polar_decoder( t_nrPolar_params *polarParams, uint8_t listSize, double *aPrioriPayload, - uint8_t pathMetricAppr) + uint8_t pathMetricAppr, + time_stats_t *init, + time_stats_t *polar_rate_matching, + time_stats_t *decoding, + time_stats_t *bit_extraction, + time_stats_t *deinterleaving, + time_stats_t *sorting, + time_stats_t *path_metric, + time_stats_t *update_LLR) { - uint8_t ***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 + start_meas(init); + + 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]; + } + } + 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); + } + + + 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++) { - pathMetric[i] = 0; - crcState[i]=1; + + 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 i=0; iN; i++) { - llrUpdated[i][polarParams->n]=1; - bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2); + + 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;iK * 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)); + + // copy the llr/bit arrays that are needed + for (int i = 0; i < listSize; i++) { + 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(double)*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(double)*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));*/ + + } + } + + 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); +} - 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; - } - } - } + + + +int8_t polar_decoder_int8(int16_t *input, + uint8_t *output, + t_nrPolar_params *polarParams, + uint8_t listSize, + time_stats_t *init, + time_stats_t *polar_rate_matching, + time_stats_t *decoding, + time_stats_t *bit_extraction, + time_stats_t *deinterleaving, + time_stats_t *sorting, + time_stats_t *path_metric, + time_stats_t *update_LLR, + int generate_optim_code) +{ + + + uint8_t **bitUpdated; + uint8_t **llrUpdated; + + if (generate_optim_code == 1 || polarParams->decoder_kernel==NULL) { + bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True + llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True + } + decoder_list_int8_t dlist[2*listSize]; + + + start_meas(init); + + for ( int i=0;i<2*listSize;i++) { + // dlist[i].bit = nr_alloc_uint8_t_2D_array((polarParams->n+1), polarParams->N); + // 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; + } + + stop_meas(init); + + if (generate_optim_code == 1 || polarParams->decoder_kernel==NULL) { + 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); + } + } + + + + start_meas(polar_rate_matching); + + int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); + nr_polar_rate_matching_int8(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); + for (int i=0;iN;i++) { + if (d_tilde[i]<-128) d_tilde[i]=-128; + else if (d_tilde[i]>127) d_tilde[i]=128; + } + memcpy((void*)&dlist[0].llr[polarParams->n][0],(void*)&d_tilde[0],sizeof(int16_t)*polarParams->N); + stop_meas(polar_rate_matching); + + /* + * SCL polar decoder. + */ + start_meas(decoding); + uint32_t nonFrozenBit=0; + uint8_t currentListSize=1; + + decoder_list_int8_t *sorted_dlist[2*listSize]; + + for (uint8_t i = 0; i < 2*listSize; i++) sorted_dlist[i] = &dlist[i]; + char fname[100]; + FILE *fd; + if (generate_optim_code==1) { + sprintf(fname,"decoder_K%d_N%d_E%d.c",polarParams->K,polarParams->N,polarParams->encoderLength); + if ((fd=fopen(fname,"w"))==NULL) {printf("Cannot open %s\n",fname); exit(-1);} + fprintf(fd,"#include \"nr_polar_defs.h\"\n"); + fprintf(fd,"void polar_decoder_K%d_N%d_E%d(t_nrPolar_params *polarParams,decoder_list_int8_t **sorted_dlist) {\n", + polarParams->K,polarParams->N,polarParams->encoderLength); + fprintf(fd,"int16_t mask,absllr;\n"); + } - for (int i=0; iK; i++) { - for (int j=0; jcrcParityBits; j++) { - extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j]; - } + if (polarParams->decoder_kernel) polarParams->decoder_kernel(polarParams,sorted_dlist); + else { + 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),generate_optim_code,fd); + stop_meas(update_LLR); + + if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. + updatePathMetric0_int8(sorted_dlist,currentListSize, currentBit,generate_optim_code,fd); //approximation=0 --> 11b, approximation=1 --> 12 + } else { //Information or CRC bit. + start_meas(path_metric); + updatePathMetric2_int8(sorted_dlist, currentListSize, currentBit,generate_optim_code,fd); + stop_meas(path_metric); + + start_meas(sorting); + + if (currentListSize <= listSize/2) { + // until listsize is full we need to copy bit and LLR arrays to new entries + // below we only copy the ones we need to keep for sure + decoder_int8_A(sorted_dlist,currentListSize,polarParams); + if (generate_optim_code == 1) fprintf(fd,"decoder_int8_A(sorted_dlist,%d,polarParams);\n",currentListSize); + } + decoder_int8_B(sorted_dlist,currentBit,currentListSize); + if (generate_optim_code == 1) fprintf(fd,"decoder_int8_B(sorted_dlist,%d,%d);\n",currentBit,currentListSize); + + + bitUpdated[currentBit][0]=1; + + updateCrcChecksum2_int8(sorted_dlist,polarParams->extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits,generate_optim_code,fd); + + currentListSize*=2; + + //Keep only the best "listSize" number of entries. + if (currentListSize > listSize) { + + decoder_int8_C(sorted_dlist, + polarParams, + currentBit, + currentListSize, + listSize); + + if (generate_optim_code == 1) fprintf(fd,"decoder_int8_C(sorted_dlist,polarParams,%d,%d,%d);\n",currentBit,currentListSize,listSize); + + currentListSize = listSize; } + + stop_meas(sorting); + + nonFrozenBit++; + } + + } + + } - //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; - } - } + if (generate_optim_code==1) fprintf(fd,"}\n"); - 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 < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) { + // printf("list index %d / %d :",i,listSize); + // for (int j=0;jcrcParityBits;j++) printf("%d",sorted_dlist[i]->crcChecksum[j]); + // printf(" => (%d)\n",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); + }*/ + stop_meas(decoding); + return(0); +} - 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]]; +int8_t polar_decoder_int8_new(int16_t *input, + uint8_t *output, + t_nrPolar_params *polarParams, + uint8_t listSize, + time_stats_t *init, + time_stats_t *polar_rate_matching, + time_stats_t *decoding, + time_stats_t *bit_extraction, + time_stats_t *deinterleaving, + time_stats_t *sorting, + time_stats_t *path_metric, + time_stats_t *update_LLR, + int generate_optim_code) +{ + - //Extract the information bits (û to ĉ) - nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N); + start_meas(init); + stop_meas(init); - //Deinterleaving (ĉ to b) - nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K); + start_meas(polar_rate_matching); + + int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); + nr_polar_rate_matching_int8(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); + for (int i=0;iN;i++) { + if (d_tilde[i]<-128) d_tilde[i]=-128; + else if (d_tilde[i]>127) d_tilde[i]=128; + } + memcpy((void*)&polarParams->tree.root->alpha[0],(void*)&d_tilde[0],sizeof(int16_t)*polarParams->N); + stop_meas(polar_rate_matching); + + /* + * SCL polar decoder. + */ + start_meas(decoding); - //Remove the CRC (â) - for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j]; + generic_polar_decoder(polarParams,polarParams->tree.root); - break; - } - } + start_meas(bit_extraction); + //Extract the information bits (û to ĉ) + nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N); + stop_meas(bit_extraction); + //Deinterleaving (ĉ to b) + start_meas(deinterleaving); + nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K); + stop_meas(deinterleaving); + //Remove the CRC (â) + for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j]; + - free(d_tilde); - 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(0); + + // free(d_tilde); + /* + for (int i=0;i<2*listSize;i++) { + // printf("correct: Freeing dlist[%d].bit %p\n",i,dlist[i].bit); + nr_free_uint8_t_2D_array(dlist[i].bit, (polarParams->n+1)); + nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1)); + free(dlist[i].crcChecksum); + }*/ + stop_meas(decoding); + return(0); } 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 0b010131cd..d2a3903dd9 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -19,118 +19,519 @@ * contact@openairinterface.org */ +#include "PHY/impl_defs_top.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" +#include "PHY/sse_intrin.h" -void updateLLR(double ***llr, uint8_t **llrU, uint8_t ***bit, uint8_t **bitU, - uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation) { - uint16_t offset = (xlen/(pow(2,(ylen-col-1)))); - for (uint8_t i=0; i= offset ) { - if(bitU[row-offset][col]==0) updateBit(bit, bitU, listSize, (row-offset), col, xlen, ylen); - if(llrU[row-offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row-offset), (col+1), xlen, ylen, approximation); - if(llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation); - llr[row][col][i] = (pow((-1),bit[row-offset][col][i])*llr[row-offset][col+1][i]) + llr[row][col+1][i]; - } else { - if(llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation); - if(llrU[row+offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row+offset), (col+1), xlen, ylen, approximation); - computeLLR(llr, row, col, i, offset, approximation); - } - } +inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col, + uint16_t offset, uint8_t approximation) __attribute__((always_inline)); +inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col, + uint16_t offset, uint8_t approximation) { - llrU[row][col]=1; -} + double a; + double b; + double absA,absB; -void updateBit(uint8_t ***bit, uint8_t **bitU, uint8_t listSize, uint16_t row, - uint16_t col, uint16_t xlen, uint8_t ylen) { - uint16_t offset = ( xlen/(pow(2,(ylen-col))) ); - for (uint8_t i=0; i= offset ) { - if (bitU[row][col-1]==0) updateBit(bit, bitU, listSize, row, (col-1), xlen, ylen); - bit[row][col][i] = bit[row][col-1][i]; - } else { - if (bitU[row][col-1]==0) updateBit(bit, bitU, listSize, row, (col-1), xlen, ylen); - if (bitU[row+offset][col-1]==0) updateBit(bit, bitU, listSize, (row+offset), (col-1), xlen, ylen); - bit[row][col][i] = ( (bit[row][col-1][i]+bit[row+offset][col-1][i]) % 2); - } - } - - bitU[row][col]=1; -} - -void updatePathMetric(double *pathMetric, double ***llr, uint8_t listSize, uint8_t bitValue, - uint16_t row, uint8_t approximation) { - - if (approximation) { //eq. (12) - for (uint8_t i=0; i=0 && b>=0)) llrtab[a+128][b+128] = minabs; + else llrtab[a+128][b+128] = -minabs; + } + } +} + + +void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU, + uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation) { + + uint16_t offset = (xlen/(1<<(ylen-col-1))); + if (( (row) % (2*offset) ) >= offset ) { + if (bitU[row-offset][col]==0) updateBit(dlist, bitU, listSize, (row-offset), col, xlen, ylen); + if (llrU[row-offset][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, (row-offset), (col+1), xlen, ylen, approximation); + if (llrU[row][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen, approximation); + for (uint8_t i=0; illr[col][row] = (pow((-1),dlist[i]->bit[col][row-offset])*dlist[i]->llr[col+1][row-offset]) + dlist[i]->llr[col+1][row]; + } + } 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, + int generate_optim_code,FILE *fd) { + uint16_t offset = (xlen/(1<<(ylen-col-1))); + if (( (row) % (2*offset) ) >= offset ) { + if (bitU[row-offset][col]==0) updateBit_int8(dlist, bitU, listSize, (row-offset), col, xlen, ylen,generate_optim_code,fd); + if (llrU[row-offset][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, (row-offset), (col+1), xlen, ylen,generate_optim_code,fd); + if (llrU[row][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen,generate_optim_code,fd); + + + if (generate_optim_code==1) fprintf(fd,"updateLLR_int8_A(sorted_dlist,%d,%d,%d,%d);\n",listSize,col,row,offset); + + updateLLR_int8_A(dlist,listSize,col,row,offset); + + } else { + if (llrU[row][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen,generate_optim_code,fd); + if (llrU[row+offset][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, (row+offset), (col+1), xlen, ylen,generate_optim_code,fd); + if (generate_optim_code==1) fprintf(fd,"computeLLR_int8(sorted_dlist,%d,%d,%d,%d);\n",listSize,row,col,offset); + computeLLR_int8(dlist,listSize, row, col, offset); + } + + llrU[row][col]=1; +} + +void updateBit(decoder_list_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(dlist, bitU, listSize, row, (col-1), xlen, ylen); + dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]; + } else { + 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); + } + } + + 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, + int generate_optim_code,FILE *fd) { + + uint16_t offset = ( xlen/(pow(2,(ylen-col))) ); + + if (( (row) % (2*offset) ) >= offset ) { + + if (bitU[row][col-1]==0) updateBit_int8(dlist, bitU, listSize, row, (col-1), xlen, ylen,generate_optim_code,fd); + // dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]; + + if (generate_optim_code==1) fprintf(fd,"updateBit_int8_A(sorted_dlist,%d,%d,%d);\n",listSize,col,row); + + updateBit_int8_A(dlist,listSize,col,row); + + } else { + if (bitU[row][col-1]==0) updateBit_int8(dlist, bitU, listSize, row, (col-1), xlen, ylen,generate_optim_code,fd); + if (bitU[row+offset][col-1]==0) updateBit_int8(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen,generate_optim_code,fd); + // dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]^dlist[i]->bit[col-1][row+offset]; + // printf("updating dlist[%d]->bit[%d][%d] => %d\n",i,col,row,dlist[i]->bit[col][row]); + + if (generate_optim_code==1) fprintf(fd,"updateBit_int8_B(sorted_dlist,%d,%d,%d,%d);\n",listSize,col,row,offset); + + updateBit_int8_B(dlist,listSize,col,row,offset); + } + + + bitU[row][col]=1; +} + +void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue, + uint16_t row, uint8_t approximation) { + + if (approximation) { //eq. (12) + for (uint8_t i=0; illr[0][row]) )) dlist[i]->pathMetric += fabs(dlist[i]->llr[0][row]); + } + } else { //eq. (11b) + int8_t multiplier = (2*bitValue) - 1; + for (uint8_t i=0; ipathMetric += log ( 1 + exp(multiplier*dlist[i]->llr[0][row]) ) ; + } + } + +} + + + +void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16_t row,int generate_optim_code,FILE *fd) { + + int16_t mask,absllr; + updatePathMetric0_int8_A(dlist,listSize,row,mask,absllr); + + if (generate_optim_code == 1) fprintf(fd,"updatePathMetric0_int8_A(sorted_dlist,%d,%d,mask,absllr);\n",listSize,row); + + + + /* + mask = dlist[i]->llr[0][row]>>15; + + if (mask != 0) { + int16_t absllr = (dlist[i]->llr[0][row]+mask)^mask; + dlist[i]->pathMetric += absllr; + }*/ + + } -void updateCrcChecksum(uint8_t **crcChecksum, uint8_t **crcGen, - uint8_t listSize, uint32_t i2, uint8_t len) { - for (uint8_t i = 0; i < listSize; i++) { - for (uint8_t j = 0; j < len; j++) { - crcChecksum[j][i] = ( (crcChecksum[j][i] + crcGen[i2][j]) % 2 ); - } - } +void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, uint8_t appr) { + + int i; + + for (i=0;ipathMetric = dlist[i]->pathMetric; + decoder_list_t **dlist2 = &dlist[listSize]; + + if (appr) { //eq. (12) + 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]; + } + } else { //eq. (11b) + for (i = 0; i < listSize; i++) { + // bitValue=0 + 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 updateCrcChecksum2(uint8_t **crcChecksum, uint8_t **crcGen, - uint8_t listSize, uint32_t i2, uint8_t len) { - for (uint8_t i = 0; i < listSize; i++) { - for (uint8_t j = 0; j < len; j++) { - crcChecksum[j][i+listSize] = ( (crcChecksum[j][i] + crcGen[i2][j]) % 2 ); - } - } + + + +void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint16_t row,int generate_optim_code,FILE *fd) { + + + + + if (generate_optim_code == 1) fprintf(fd,"updatePathMetric2_int8_A(sorted_dlist,%d,%d);\n", + listSize,row); + + updatePathMetric2_int8_A(dlist,listSize,row); + // dlist[i+listSize]->pathMetric = dlist[i]->pathMetric; + //if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric -= dlist[i]->llr[0][row]; + //else dlist[i+listSize]->pathMetric += dlist[i]->llr[0][row]; + } + + +void updateCrcChecksum(decoder_list_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(decoder_list_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 ); + } + } +} + + + +void updateCrcChecksum_int8(decoder_list_int8_t **dlist, uint8_t **crcGen, + uint8_t listSize, uint32_t i2, uint8_t len,int generate_optim_code,FILE *fd) { + + if (generate_optim_code == 1) fprintf(fd,"updateCrcChecksum_int8_A(sorted_dlist,%d,crcGen,%d,%d);\n",listSize,i2,len); + + updateCrcChecksum_int8_A(dlist,listSize,crcGen,i2,len); + // for (uint8_t j = 0; j < len; j++) { + // dlist[i]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 ); + // } + +} + + + +void updateCrcChecksum2_int8(decoder_list_int8_t **dlist, uint8_t **crcGen, + uint8_t listSize, uint32_t i2, uint8_t len,int generate_optim_code,FILE *fd) { + + if (generate_optim_code == 1) fprintf(fd,"updateCrcChecksum2_int8_A(sorted_dlist,%d,polarParams->extended_crc_generator_matrix,%d,%d);\n",listSize,i2,len); + + updateCrcChecksum2_int8_A(dlist,listSize,crcGen,i2,len); + // for (uint8_t j = 0; j < len; j++) { + // dlist[i+listSize]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 ); + // } + +} + + +decoder_node_t *new_decoder_node(int first_leaf_index,int level) { + + decoder_node_t *node=(decoder_node_t *)malloc(sizeof(decoder_node_t)); + + node->first_leaf_index=first_leaf_index; + node->level=level; + node->Nv = 1<leaf = 0; + node->left=(decoder_node_t *)NULL; + node->right=(decoder_node_t *)NULL; + node->all_frozen=0; + node->alpha = (int16_t*)malloc16(node->Nv*sizeof(int16_t)); + node->beta = (int16_t*)malloc16(node->Nv*sizeof(int16_t)); + memset((void*)node->beta,-1,node->Nv*sizeof(int16_t)); + + + return(node); +} + +decoder_node_t *add_nodes(int level,int first_leaf_index,t_nrPolar_params *pp) { + + int all_frozen_below=1; + int Nv = 1<tree.num_nodes,Nv,level); + pp->tree.num_nodes++; +#endif + if (level==0) { +#ifdef DEBUG_NEW_IMPL + printf("leaf %d (%s)\n",first_leaf_index,pp->information_bit_pattern[first_leaf_index]==1 ? "information or crc" : "frozen"); +#endif + new_node->leaf=1; + new_node->all_frozen = pp->information_bit_pattern[first_leaf_index]==0 ? 1 : 0; + return new_node; // this is a leaf node + } + + for (int i=0;iinformation_bit_pattern[i+first_leaf_index]>0) all_frozen_below=0; + } +if (all_frozen_below==0) new_node->left=add_nodes(level-1,first_leaf_index,pp); + else { +#ifdef DEBUG_NEW_IMPL + printf("aggregating frozen bits %d ... %d at level %d (%s)\n",first_leaf_index,first_leaf_index+Nv-1,level,((first_leaf_index/Nv)&1)==0?"left":"right"); +#endif + new_node->leaf=1; + new_node->all_frozen=1; + } + if (all_frozen_below==0) new_node->right=add_nodes(level-1,first_leaf_index+(Nv/2),pp); + + return(new_node); +} + +void build_decoder_tree(t_nrPolar_params *pp) { + + pp->tree.num_nodes=0; + pp->tree.root = add_nodes(pp->n,0,pp); + +} + +void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) { + int16_t *alpha_v=node->alpha; + int16_t *alpha_l=node->left->alpha; + int16_t *betal = node->left->beta; + int16_t a,b,absa,absb,maska,maskb,minabs; + +#ifdef DEBUG_NEW_IMPL + printf("applyFtoleft %d, Nv %d (level %d,node->left (leaf %d, AF %d))\n",node->first_leaf_index,node->Nv,node->level,node->left->leaf,node->left->all_frozen); + + + for (int i=0;iNv;i++) printf("i%d (frozen %d): alpha_v[i] = %d\n",i,1-pp->information_bit_pattern[node->first_leaf_index+i],alpha_v[i]); +#endif + + + + if (node->left->all_frozen == 0) { + +#if defined(__AVX2__) + int avx2mod = (node->Nv/2)&15; + if (avx2mod == 0) { + __m256i a256,b256,absa256,absb256,minabs256; + int avx2len = node->Nv/2/16; + + for (int i=0;iNv/2;i++) { + a=alpha_v[i]; + b=alpha_v[i+(node->Nv/2)]; + maska=a>>15; + maskb=b>>15; + absa=(a+maska)^maska; + absb=(b+maskb)^maskb; + minabs = absaNv == 2) { // apply hard decision on left node + betal[0] = (alpha_l[0]>0) ? -1 : 1; +#ifdef DEBUG_NEW_IMPL + printf("betal[0] %d (%p)\n",betal[0],&betal[0]); +#endif + pp->nr_polar_u[node->first_leaf_index] = (1+betal[0])>>1; +#ifdef DEBUG_NEW_IMPL + printf("Setting bit %d to %d (LLR %d)\n",node->first_leaf_index,(betal[0]+1)>>1,alpha_l[0]); +#endif + } + } +} + +void applyGtoright(t_nrPolar_params *pp,decoder_node_t *node) { + + int16_t *alpha_v=node->alpha; + int16_t *alpha_r=node->right->alpha; + int16_t *betal = node->left->beta; + int16_t *betar = node->right->beta; + +#ifdef DEBUG_NEW_IMPL + printf("applyGtoright %d, Nv %d (level %d), (leaf %d, AF %d)\n",node->first_leaf_index,node->Nv,node->level,node->right->leaf,node->right->all_frozen); +#endif + + if (node->right->all_frozen == 0) { +#if defined(__AVX2__) + int avx2mod = (node->Nv/2)&15; + if (avx2mod == 0) { + int avx2len = node->Nv/2/16; + + for (int i=0;iNv/2;i++) { + alpha_r[i] = alpha_v[i+(node->Nv/2)] - (betal[i]*alpha_v[i]); + } + } + if (node->Nv == 2) { // apply hard decision on right node + betar[0] = (alpha_r[0]>0) ? -1 : 1; + pp->nr_polar_u[node->first_leaf_index+1] = (1+betar[0])>>1; +#ifdef DEBUG_NEW_IMPL + printf("Setting bit %d to %d (LLR %d frozen_mask %d)\n",node->first_leaf_index+1,(betar[0]+1)>>1,alpha_r[0],frozen_mask); +#endif + } + } +} + +int16_t minus1[16] = {-1,-1,-1,-1, + -1,-1,-1,-1, + -1,-1,-1,-1, + -1,-1,-1,-1}; + +void computeBeta(t_nrPolar_params *pp,decoder_node_t *node) { + + int16_t *betav = node->beta; + int16_t *betal = node->left->beta; + int16_t *betar = node->right->beta; +#ifdef DEBUG_NEW_IMPL + printf("Computing beta @ level %d first_leaf_index %d (all_frozen %d)\n",node->level,node->first_leaf_index,node->left->all_frozen); +#endif + if (node->left->all_frozen==0) { // if left node is not aggregation of frozen bits +#if defined(__AVX2__) + int avx2mod = (node->Nv/2)&15; + if (avx2mod == 0) { + int avx2len = node->Nv/2/16; + + for (int i=0;iNv/2;i++) { + betav[i] = (betal[i] != betar[i]) ? 1 : -1; + } + } + } + else memcpy((void*)&betav[0],betar,(node->Nv/2)*sizeof(int16_t)); + memcpy((void*)&betav[node->Nv/2],betar,(node->Nv/2)*sizeof(int16_t)); + +} + +void generic_polar_decoder(t_nrPolar_params *pp,decoder_node_t *node) { + + + // Apply F to left + applyFtoleft(pp,node); + // if left is not a leaf recurse down to the left + if (node->left->leaf==0) generic_polar_decoder(pp,node->left); + + applyGtoright(pp,node); + if (node->right->leaf==0) generic_polar_decoder(pp,node->right); + + computeBeta(pp,node); + +} diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index 7caf547395..4a4055d404 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -30,52 +30,144 @@ #include #include +#include "PHY/TOOLS/time_meas.h" + static const uint8_t nr_polar_subblock_interleaver_pattern[32] = { 0, 1, 2, 4, 3, 5, 6, 7, 8, 16, 9, 17, 10, 18, 11, 19, 12, 20, 13, 21, 14, 22, 15, 23, 24, 25, 26, 28, 27, 29, 30, 31 }; + +#define Nmax 1024 +#define nmax 10 + +typedef struct decoder_list_s { + + uint8_t bit[1+nmax][Nmax]; + double llr[1+nmax][Nmax]; + uint8_t crcChecksum[24]; + double pathMetric; + +} decoder_list_t; + +typedef struct decoder_list_int8_s { + + uint8_t bit[1+nmax][Nmax] __attribute__((aligned(32))); + int16_t llr[1+nmax][Nmax]__attribute__((aligned(32))); + uint8_t crcChecksum[24]; + int32_t pathMetric; + +} decoder_list_int8_t; + + + +typedef struct decoder_node_t_s { + struct decoder_node_t_s *left; + struct decoder_node_t_s *right; + int level; + int leaf; + int Nv; + int first_leaf_index; + int all_frozen; + int16_t *alpha; + 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 { - uint8_t n_max; - uint8_t i_il; - uint8_t i_seg; - uint8_t n_pc; - uint8_t n_pc_wm; - uint8_t i_bil; - uint16_t payloadBits; - uint16_t encoderLength; - uint8_t crcParityBits; - uint8_t crcCorrectionBits; - uint16_t K; - uint16_t N; - uint8_t n; + uint8_t n_max; + uint8_t i_il; + uint8_t i_seg; + uint8_t n_pc; + uint8_t n_pc_wm; + uint8_t i_bil; + uint16_t payloadBits; + uint16_t encoderLength; + uint8_t crcParityBits; + uint8_t crcCorrectionBits; + uint16_t K; + uint16_t N; + uint8_t n; + + uint16_t *interleaving_pattern; + uint16_t *rate_matching_pattern; + const uint16_t *Q_0_Nminus1; + int16_t *Q_I_N; + int16_t *Q_F_N; + int16_t *Q_PC_N; + uint8_t *information_bit_pattern; + uint16_t *channel_interleaver_pattern; + uint32_t crc_polynomial; + + uint8_t **crc_generator_matrix; //G_P + uint8_t **G_N; + uint32_t* crc256Table; + uint8_t **extended_crc_generator_matrix; - uint16_t *interleaving_pattern; - uint16_t *rate_matching_pattern; - const uint16_t *Q_0_Nminus1; - int16_t *Q_I_N; - int16_t *Q_F_N; - int16_t *Q_PC_N; - uint8_t *information_bit_pattern; - uint16_t *channel_interleaver_pattern; - uint32_t crc_polynomial; - - uint8_t **crc_generator_matrix; //G_P - uint8_t **G_N; - uint32_t* crc256Table; - - //polar_encoder vectors: - uint8_t *nr_polar_crc; - uint8_t *nr_polar_b; - uint8_t *nr_polar_cPrime; - uint8_t *nr_polar_u; - uint8_t *nr_polar_d; + //polar_encoder vectors: + uint8_t *nr_polar_crc; + uint8_t *nr_polar_b; + uint8_t *nr_polar_cPrime; + uint8_t *nr_polar_u; + uint8_t *nr_polar_d; + + void (*decoder_kernel)(struct nrPolar_params *,decoder_list_int8_t **); + decoder_tree_t tree; } __attribute__ ((__packed__)); typedef struct nrPolar_params t_nrPolar_params; + + + + void polar_encoder(uint8_t *input, uint8_t *output, t_nrPolar_params* polarParams); void nr_polar_kernal_operation(uint8_t *u, uint8_t *d, uint16_t N); +void generic_polar_decoder(t_nrPolar_params *,decoder_node_t *); + int8_t polar_decoder(double *input, uint8_t *output, t_nrPolar_params *polarParams, - uint8_t listSize, double *aPrioriPayload, uint8_t pathMetricAppr); + uint8_t listSize, double *aPrioriPayload, uint8_t pathMetricAppr, + time_stats_t *init, + time_stats_t *polar_rate_matching, + time_stats_t *decoding, + time_stats_t *bit_extraction, + time_stats_t *deinterleaving, + time_stats_t *sorting, + time_stats_t *path_metric, + time_stats_t *update_LLR); + +int8_t polar_decoder_int8(int16_t *input, + uint8_t *output, + t_nrPolar_params *polarParams, + uint8_t listSize, + time_stats_t *init, + time_stats_t *polar_rate_matching, + time_stats_t *decoding, + time_stats_t *bit_extraction, + time_stats_t *deinterleaving, + time_stats_t *sorting, + time_stats_t *path_metric, + time_stats_t *update_LLR, + int generate_optim_code); + +int8_t polar_decoder_int8_new(int16_t *input, + uint8_t *output, + t_nrPolar_params *polarParams, + uint8_t listSize, + time_stats_t *init, + time_stats_t *polar_rate_matching, + time_stats_t *decoding, + time_stats_t *bit_extraction, + time_stats_t *deinterleaving, + time_stats_t *sorting, + time_stats_t *path_metric, + time_stats_t *update_LLR, + int generate_optim_code); + + +void nr_polar_llrtableinit(void); void nr_polar_init(t_nrPolar_params* polarParams, int messageType); @@ -94,6 +186,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, @@ -114,28 +209,49 @@ void nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(uint8_t *matrix1, uint8_t ** uint8_t ***nr_alloc_uint8_t_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen); uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen, uint16_t ylen); -double ***nr_alloc_double_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen); +double **nr_alloc_double_2D_array(uint16_t xlen, uint16_t ylen); void nr_free_uint8_t_3D_array(uint8_t ***input, uint16_t xlen, uint16_t ylen); void nr_free_uint8_t_2D_array(uint8_t **input, uint16_t xlen); -void nr_free_double_3D_array(double ***input, uint16_t xlen, uint16_t ylen); +void nr_free_double_2D_array(double **input, uint16_t xlen); -void updateLLR(double ***llr, uint8_t **llrU, uint8_t ***bit, uint8_t **bitU, - uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, - uint8_t ylen, uint8_t approximation); -void updateBit(uint8_t ***bit, uint8_t **bitU, uint8_t listSize, uint16_t row, - uint16_t col, uint16_t xlen, uint8_t ylen); -void updatePathMetric(double *pathMetric, double ***llr, uint8_t listSize, - uint8_t bitValue, uint16_t row, uint8_t approximation); -void updatePathMetric2(double *pathMetric, double ***llr, uint8_t listSize, - uint16_t row, uint8_t approximation); -void computeLLR(double ***llr, uint16_t row, uint16_t col, uint8_t i, - uint16_t offset, uint8_t approximation); -void updateCrcChecksum(uint8_t **crcChecksum, uint8_t **crcGen, - uint8_t listSize, uint32_t i2, uint8_t len); -void updateCrcChecksum2(uint8_t **crcChecksum, uint8_t **crcGen, - uint8_t listSize, uint32_t i2, uint8_t len); -void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len); +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,int generate_optim_code,FILE *fd); + +void updateBit(decoder_list_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row, + uint16_t col, uint16_t xlen, uint8_t ylen); + +void updateBit_int8(decoder_list_int8_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row, + uint16_t col, uint16_t xlen, uint8_t ylen,int generate_optim_code,FILE *fd); + +void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue, + uint16_t row, uint8_t approximation); + +void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16_t row,int generate_optim_code,FILE *fd); + +void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, uint8_t appr); + +void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint16_t row,int generate_optim_code,FILE *fd); + +void updateCrcChecksum(decoder_list_t **dlist, uint8_t **crcGen, + uint8_t listSize, uint32_t i2, uint8_t len); + +void updateCrcChecksum_int8(decoder_list_int8_t **dlist, uint8_t **crcGen, + uint8_t listSize, uint32_t i2, uint8_t len,int generate_optim_code,FILE *fd); + +void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen, + uint8_t listSize, uint32_t i2, uint8_t len); + +void updateCrcChecksum2_int8(decoder_list_int8_t **dlist, uint8_t **crcGen, + uint8_t listSize, uint32_t i2, uint8_t len,int generate_optim_code,FILE *fd); + + +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); @@ -158,4 +274,144 @@ static inline void nr_polar_deinterleaver(uint8_t *input, uint8_t *output, uint1 for (int 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)];if(dlist[(i)]->llr[col][row]>127 || dlist[i]->llr[col][row]<-128) printf("dlist[%d]->llr[%d][%d] = %d> 8bit\n",i,col,row,dlist[i]->llr[col][row]);}} + +#define updateBit_int8_A(dlist,listSize,col,row) {for (int i=0;ibit[(col)][(row)] = dlist[(i)]->bit[(col)-1][(row)];}} +#define updateBit_int8_B(dlist,listSize,col,row,offset) {for (int i=0;ibit[(col)][(row)] = dlist[(i)]->bit[(col)-1][(row)]^dlist[(i)]->bit[(col)-1][(row)+(offset)];}} + +#define updatePathMetric0_int8_A(dlist,listSize,row,mask,absllr) {for (int i=0;illr[0][row]>>15;if(mask!=0){absllr=(dlist[i]->llr[0][row]+mask)^mask;dlist[i]->pathMetric+=absllr;}}} + +#define updatePathMetric2_int8_A(dlist,listSize,row) {for (int i=0;ipathMetric = dlist[i]->pathMetric;if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric-=dlist[i]->llr[0][row];else dlist[i+listSize]->pathMetric += dlist[i]->llr[0][row];}}} + +#define updateCrcChecksum_int8_A(dlist,listSize,crcGen,i2,len) {for (int i=0;icrcChecksum[j] = (dlist[i]->crcChecksum[j]^crcGen[i2][j]);}} + +#define updateCrcChecksum2_int8_A(dlist,listSize,crcGen,i2,len) {for (int i=0;icrcChecksum[j]=dlist[i]->crcChecksum[j]^crcGen[i2][j];}} + +extern int16_t llrtab[256][256]; + +inline void computeLLR_int8(decoder_list_int8_t **dlist,int listSize, uint16_t row, uint16_t col, + uint16_t offset) __attribute__((always_inline)); +inline void computeLLR_int8(decoder_list_int8_t **dlist,int listSize, uint16_t row, uint16_t col, + uint16_t offset) { + + int16_t a; + int16_t b; + + int16_t absA,absB; + int16_t maska,maskb; + int16_t minabs; + // int16_t **llr=dlist[i]->llr; + + + for (int i=0;illr[col + 1][row]; + b = dlist[i]->llr[col+1][row + offset]; + + // printf("LLR: a %d, b %d\n",a,b); + maska = a>>15; + maskb = b>>15; + absA = (a+maska)^maska; + absB = (b+maskb)^maskb; + // printf("LLR: absA %d, absB %d\n",absA,absB); + minabs = absAllr[col][row] = minabs; + else + dlist[i]->llr[col][row] = -minabs; + // printf("LLR (a %d, b %d): llr[%d][%d] %d\n",a,b,col,row,llr[col][row]); + + //dlist[i]->llr[col][row] = llrtab[a+128][b+128]; + // printf("newLLR [%d,%d]: %d\n",col,row,dlist[i]->llr[col][row]); + } +} + +#define decoder_int8_A(sorted_dlist,currentListSize,polarParams) {for (int i = 0; i < currentListSize; i++) { \ + for (int k = 0; k < (polarParams->n+1); k++) { \ + memcpy((void*)&sorted_dlist[i+currentListSize]->bit[k][0],\ + (void*)&sorted_dlist[i]->bit[k][0],\ + sizeof(uint8_t)*polarParams->N);\ + memcpy((void*)&sorted_dlist[i+currentListSize]->llr[k][0],\ + (void*)&sorted_dlist[i]->llr[k][0],\ + sizeof(int16_t)*polarParams->N);}}} + +#define decoder_int8_B(sorted_dlist,currentBit,currentListSize) {for (int i = 0; i < currentListSize; i++) {sorted_dlist[i]->bit[0][currentBit]=0;sorted_dlist[i+currentListSize]->bit[0][currentBit]=1;}} + +void inline decoder_int8_C(decoder_list_int8_t *sorted_dlist[], + t_nrPolar_params *polarParams, + int currentBit, + int currentListSize, + int listSize) { + + int32_t pathMetric[2*listSize]; + decoder_list_int8_t *temp_dlist[2*listSize]; + + int listIndex[2*listSize]; + int listIndex2[2*listSize]; + + for (int i = 0; i < currentListSize; i++) { + listIndex[i]=i; + pathMetric[i] = sorted_dlist[i]->pathMetric; + } + nr_sort_asc_int16_1D_array_ind(pathMetric, listIndex, currentListSize); + for (int i=0;in+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));*/ + + } + } + + + + for (int i = 0; i < 2*listSize; i++) { + temp_dlist[i] = sorted_dlist[i]; + } + for (int i = 0; i < 2*listSize; i++) { + // printf("i %d => %d\n",i,listIndex[i]); + sorted_dlist[i] = temp_dlist[listIndex[i]]; + } +} #endif 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 572b016cfa..23ec51a400 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 @@ -66,38 +66,30 @@ uint8_t ***nr_alloc_uint8_t_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen return output; } -double ***nr_alloc_double_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen) { - double ***output; - int i, j; +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; + - if ((output = malloc(xlen * sizeof(*output))) == NULL) { - perror("[nr_alloc_double_3D_array] Problem at 1D allocation"); - return NULL; - } - for (i = 0; i < xlen; i++) - output[i] = NULL; - - - for (i = 0; i < xlen; i++) - if ((output[i] = malloc(ylen * sizeof *output[i])) == NULL) { - perror("[nr_alloc_double_3D_array] Problem at 2D allocation"); - nr_free_double_3D_array(output, xlen, ylen); - return NULL; - } - for (i = 0; i < xlen; i++) - for (j = 0; j < ylen; j++) - output[i][j] = NULL; - - - for (i = 0; i < xlen; i++) - for (j = 0; j < ylen; j++) - if ((output[i][j] = malloc(zlen * sizeof *output[i][j])) == NULL) { - perror("[nr_alloc_double_3D_array] Problem at 3D allocation"); - nr_free_double_3D_array(output, xlen, ylen); - return NULL; - } - - return output; + return output; } uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen, uint16_t ylen) { @@ -138,31 +130,28 @@ void nr_free_uint8_t_3D_array(uint8_t ***input, uint16_t xlen, uint16_t ylen) { } void nr_free_uint8_t_2D_array(uint8_t **input, uint16_t xlen) { - for (int i = 0; i < xlen; i++) free(input[i]); - free(input); + for (int i = 0; i < xlen; i++) free(input[i]); + free(input); } -void nr_free_double_3D_array(double ***input, uint16_t xlen, uint16_t ylen) { - int i, j; - - for (i = 0; i < xlen; i++) { - for (j = 0; j < ylen; j++) { - free(input[i][j]); - } - free(input[i]); - } - free(input); +void nr_free_double_2D_array(double **input, uint16_t xlen) { + int i; + + for (i = 0; i < xlen; i++) { + free(input[i]); + } + free(input); } // Modified Bubble Sort. -void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len) { - uint8_t swaps; +void nr_sort_asc_double_1D_array_ind(double *matrix, int *ind, int len) { + int swaps; double temp; - uint8_t tempInd; + int tempInd; - for (uint8_t i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { 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]) { temp = matrix[j]; matrix[j] = matrix[j + 1]; @@ -179,3 +168,28 @@ void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t 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 90f16183c8..d237603059 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]; + } + } + +} diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c index 70cd80c47e..f805689b9c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c @@ -220,7 +220,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, uint8_t nushift; uint8_t *xbyte = pbch->pbch_a; memset((void*) xbyte, 0, 1); - uint8_t pbch_a_b[32]; + //uint8_t pbch_a_b[32]; LOG_I(PHY, "PBCH generation started\n"); @@ -283,10 +283,10 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, printf("pbch_a_prime[%d]: 0x%02x\n", i, pbch->pbch_a_prime[i]); #endif -for (int m=0;m<32;m++){ -pbch_a_b[m] = ((pbch->pbch_a_prime[m/8]>>(m&7))&01); +//for (int m=0;m<32;m++){ +//pbch_a_b[m] = ((pbch->pbch_a_prime[m/8]>>(m&7))&01); //printf("pbch_a_b[%d] %d\n", m, pbch_a_b[m] ); -} +//} /// CRC, coding and rate matching polar_encoder (pbch->pbch_a_prime, pbch->pbch_e, &frame_parms->pbch_polar_params); diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c index 3299d556b2..fc053aaef0 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c @@ -35,6 +35,7 @@ #include "PHY/defs_nr_UE.h" //#include "PHY/extern.h" //#include "LAYER2/MAC/extern.h" +#include "PHY/NR_UE_TRANSPORT/pucch_nr.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" @@ -44,269 +45,8 @@ #define DEBUG_PUCCH_TX #define DEBUG_NR_PUCCH_TX #endif -#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) +//#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) - /* - * The following tables implement TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (rows->u {0,1,..,29} / columns->n {0,1,...,M_ZC-1) - * Where base sequence r_u_v(n)=exp[j*phi(n)*pi/4] 0<=n<=M_ZC-1 and M_ZC={6,12,18,24} - * For M_ZC=30, base sequence r_u_v(n)=exp[-j((pi*[u+1]*[n+1]*[n+2])/31)] - */ - int16_t table_5_2_2_2_1_Re[30][6]={ // Table 5.2.2.2-1 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=6) - {-23170, 23170,-23170,-23170, 23170,-23170}, - {-23170,-23170, 23170, 23170,-23170,-23170}, - {-23170,-23170,-23170,-23170, 23170,-23170}, - { 23170, 23170, 23170,-23170, 23170,-23170}, - { 23170, 23170, 23170,-23170, 23170,-23170}, - {-23170, 23170, 23170,-23170,-23170,-23170}, - {-23170, 23170,-23170,-23170,-23170,-23170}, - {-23170, 23170, 23170,-23170, 23170, 23170}, - {-23170, 23170,-23170, 23170,-23170,-23170}, - {-23170,-23170, 23170,-23170,-23170,-23170}, - {-23170, 23170,-23170, 23170,-23170,-23170}, - {-23170, 23170,-23170, 23170, 23170,-23170}, - { 23170, 23170,-23170, 23170,-23170,-23170}, - { 23170, 23170,-23170,-23170, 23170,-23170}, - { 23170, 23170, 23170,-23170,-23170, 23170}, - { 23170, 23170, 23170, 23170,-23170,-23170}, - {-23170, 23170, 23170, 23170,-23170, 23170}, - {-23170,-23170, 23170, 23170, 23170,-23170}, - {-23170,-23170,-23170, 23170,-23170, 23170}, - {-23170, 23170, 23170,-23170, 23170,-23170}, - {-23170,-23170,-23170, 23170, 23170,-23170}, - {-23170, 23170,-23170,-23170,-23170, 23170}, - { 23170, 23170,-23170,-23170, 23170,-23170}, - { 23170, 23170,-23170,-23170, 23170,-23170}, - { 23170, 23170,-23170, 23170,-23170,-23170}, - { 23170, 23170,-23170, 23170,-23170,-23170}, - { 23170, 23170, 23170, 23170,-23170, 23170}, - { 23170, 23170, 23170,-23170, 23170, 23170}, - { 23170, 23170, 23170,-23170,-23170, 23170}, - { 23170, 23170,-23170, 23170, 23170, 23170} - }; - int16_t table_5_2_2_2_1_Im[30][6]={ // Table 5.2.2.2-1 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=6) - {-23170,-23170, 23170, 23170,-23170,-23170}, - {-23170, 23170,-23170,-23170, 23170,-23170}, - {-23170,-23170,-23170, 23170, 23170,-23170}, - { 23170, 23170, 23170, 23170,-23170,-23170}, - { 23170, 23170, 23170,-23170,-23170, 23170}, - {-23170, 23170,-23170,-23170,-23170,-23170}, - {-23170, 23170, 23170,-23170,-23170,-23170}, - {-23170,-23170, 23170,-23170, 23170,-23170}, - {-23170,-23170,-23170, 23170,-23170,-23170}, - {-23170,-23170, 23170,-23170, 23170,-23170}, - {-23170, 23170, 23170, 23170,-23170,-23170}, - {-23170,-23170,-23170, 23170, 23170,-23170}, - { 23170, 23170, 23170,-23170,-23170, 23170}, - { 23170, 23170, 23170, 23170,-23170, 23170}, - { 23170, 23170, 23170,-23170, 23170,-23170}, - { 23170, 23170, 23170,-23170, 23170,-23170}, - {-23170,-23170,-23170,-23170, 23170,-23170}, - {-23170,-23170,-23170, 23170,-23170,-23170}, - {-23170,-23170,-23170, 23170,-23170,-23170}, - {-23170, 23170, 23170,-23170,-23170,-23170}, - {-23170, 23170,-23170, 23170, 23170,-23170}, - {-23170, 23170,-23170,-23170,-23170,-23170}, - { 23170, 23170,-23170, 23170, 23170, 23170}, - { 23170, 23170,-23170,-23170, 23170,-23170}, - { 23170, 23170, 23170,-23170, 23170, 23170}, - { 23170, 23170,-23170, 23170, 23170, 23170}, - { 23170, 23170,-23170,-23170, 23170,-23170}, - { 23170, 23170,-23170, 23170,-23170,-23170}, - { 23170, 23170,-23170, 23170,-23170,-23170}, - { 23170, 23170,-23170, 23170,-23170,-23170} - }; - int16_t table_5_2_2_2_2_Re[30][12]={ // Table 5.2.2.2-2 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=12) - {-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170}, - {-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170}, - {-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170}, - {-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170}, - {-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170}, - {-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170}, - { 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170}, - { 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170}, - {-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170}, - {-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170}, - {-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170}, - {-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170}, - {-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170}, - {-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170}, - { 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170}, - {-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170}, - { 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170}, - { 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170}, - {-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170}, - {-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170}, - {-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170}, - {-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170}, - {-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170}, - {-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170}, - {-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170}, - {-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170}, - { 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170}, - {-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170}, - { 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170}, - {-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170} - }; - int16_t table_5_2_2_2_2_Im[30][12]={ // Table 5.2.2.2-2 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=12) - {-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170}, - {-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170}, - {-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170}, - {-23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170}, - {-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170}, - {-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170}, - { 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170}, - {-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170}, - {-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170}, - {-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170}, - {-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170}, - {-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170}, - {-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170}, - {-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170}, - { 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170}, - {-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170}, - {-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170}, - {-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170}, - {-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170}, - {-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170}, - { 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170}, - {-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170}, - {-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170}, - { 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170}, - {-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170}, - {-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170}, - {-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170}, - {-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170}, - { 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170}, - {-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170} - }; - int16_t table_5_2_2_2_3_Re[30][18]={ // Table 5.2.2.2-3 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=18) - { 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170}, - {-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170}, - {-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170}, - {-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170}, - { 23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170}, - {-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170}, - {-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170}, - { 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170}, - {-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170}, - {-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170}, - {-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170}, - {-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170}, - {-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170}, - { 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170}, - {-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170}, - {-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170}, - {-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170}, - {-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170}, - {-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170}, - {-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170}, - {-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170}, - { 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170}, - {-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170}, - {-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170}, - {-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170}, - {-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170}, - {-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170}, - {-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170}, - { 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170}, - {-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170} - }; - int16_t table_5_2_2_2_3_Im[30][18]={ // Table 5.2.2.2-3 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=18) - {-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170}, - { 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170}, - {-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170}, - {-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170}, - { 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170}, - { 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170}, - {-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170}, - { 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170}, - {-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170}, - { 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170}, - {-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170}, - {-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170}, - {-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170}, - { 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170}, - {-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170}, - { 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170}, - {-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170}, - {-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170}, - {-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170}, - { 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170}, - {-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170}, - { 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170}, - {-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170}, - { 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170}, - { 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170}, - {-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170}, - {-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170}, - {-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170}, - {-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170}, - {-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170} - }; - int16_t table_5_2_2_2_4_Re[30][24]={ // Table 5.2.2.2-4 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=24) - { 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170}, - { 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170}, - { 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170}, - { 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170}, - { 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170}, - {-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170}, - {-23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170}, - {-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170}, - {-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170}, - { 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170}, - {-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170}, - {-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170}, - {-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170}, - {-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170}, - {-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170}, - {-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170}, - {-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170}, - {-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170}, - {-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170}, - {-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170}, - {-23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170}, - {-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170}, - {-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170}, - {-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170}, - {-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170}, - {-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170}, - { 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170}, - {-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170}, - {-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170}, - {-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170} - }; - int16_t table_5_2_2_2_4_Im[30][24]={ // Table 5.2.2.2-4 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=24) - {-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170}, - {-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170}, - {-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170}, - { 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170}, - {-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170}, - {-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170}, - {-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170}, - {-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170}, - {-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170}, - { 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170}, - {-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170}, - {-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170}, - { 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170}, - {-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170}, - {-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170}, - {-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170}, - {-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170}, - { 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170}, - {-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170}, - {-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170}, - {-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170}, - { 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170}, - {-23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170}, - {-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170}, - {-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170}, - {-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170}, - {-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170}, - { 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170}, - {-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170}, - { 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170} - }; void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_nr.puch_GroupHopping, //uint8_t PUCCH_GroupHopping, PHY_VARS_NR_UE *ue, @@ -336,13 +76,12 @@ void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_n uint16_t n_id = ue->pucch_config_common_nr->hoppingId; // from higher layers FIXME!!! -//////////////////////////////////////initialization to be removed/////////////////////////////////////////////////////////// - PUCCH_GroupHopping=neither; - n_id=10; #ifdef DEBUG_NR_PUCCH_TX + // initialization to be removed + PUCCH_GroupHopping=neither; + n_id=10; printf("\t\t [nr_group_sequence_hopping] initialization PUCCH_GroupHopping=%d, n_id=%d -> variable initializations TO BE REMOVED\n",PUCCH_GroupHopping,n_id); #endif -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// uint8_t f_ss=0,f_gh=0; @@ -373,6 +112,7 @@ void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_n printf("%d,%d\n",*u,*v); #endif } + double nr_cyclic_shift_hopping(PHY_VARS_NR_UE *ue, uint8_t m0, uint8_t mcs, @@ -391,14 +131,11 @@ double nr_cyclic_shift_hopping(PHY_VARS_NR_UE *ue, double alpha = 0.5235987756; uint16_t c_init = ue->pucch_config_common_nr->hoppingId; // we initialize c_init again to calculate n_cs - - //////////////////////////////////////initialization to be removed/////////////////////////////////////////////////////////// + #ifdef DEBUG_NR_PUCCH_TX + // initialization to be removed c_init=10; - #ifdef DEBUG_NR_PUCCH_TX - printf("\t\t [nr_cyclic_shift_hopping] initialization c_init=%d -> variable initialization TO BE REMOVED\n",c_init); - #endif - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - + printf("\t\t [nr_cyclic_shift_hopping] initialization c_init=%d -> variable initialization TO BE REMOVED\n",c_init); + #endif uint32_t x1,s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 uint8_t n_cs=0; @@ -438,11 +175,6 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue, printf("\t [nr_generate_pucch0] sequence generation\n"); #endif - // number of symbols defined in the PUCCH-Config from higher layers: format 0 {1-2} FIXME! - //uint8_t nrofSymbols; - //uint8_t startingSymbolIndex; - //uint8_t startingPRB; - /* * Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2 */ @@ -542,6 +274,7 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue, } } } + void nr_generate_pucch1(PHY_VARS_NR_UE *ue, int32_t **txdataF, NR_DL_FRAME_PARMS *frame_parms, @@ -557,69 +290,300 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, uint8_t timeDomainOCC, uint8_t nr_bit) { #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d\n",nr_tti_tx); - printf("\t [nr_generate_pucch1] startingPRB=%d startingPRB_intraSlotHopping=%d\n",startingPRB,startingPRB_intraSlotHopping); + printf("\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d payload=%d m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n", + nr_tti_tx,payload,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit); #endif - /* - * The following tables implement TS 38.211 table 6.3.2.4.1-1: Number of PUCCH symbols and the corresponding N_SF_mprime_PUCCH_1 - * One table for no intra-slot hopping - * Two tables for intra-slot hopping (mprime=0 and mprime=1) - */ - uint8_t table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[14] = {0,0,0,2,2,3,3,4,4,5,5,6,6,7}; // for index PUCCH-length, we obtain N_SF_mprime_PUCCH_1 when no intra-slot hopping - uint8_t table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[14] = {0,0,0,1,1,1,1,2,2,2,2,3,3,3}; // for index PUCCH-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=0 - uint8_t table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[14] = {0,0,0,1,1,2,2,2,2,3,3,3,3,4}; // for index PUCCH-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=1 - /* - * The following tables implement TS 38.211 table 6.4.1.3.1.1-1: Number of DM-RS symbols and the corresponding N_SF_mprime_PUCCH_1 - * One table for no intra-slot hopping - * Two tables for intra-slot hopping (mprime=0 and mprime=1) - */ - uint8_t table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[14] = {0,0,0,2,3,3,4,4,5,5,6,6,7,7}; // for index PUCCH-DM-RS-length, we obtain N_SF_mprime_PUCCH_1 when no intra-slot hopping - uint8_t table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[14] = {0,0,0,1,1,2,2,2,2,3,3,3,3,4}; // for index PUCCH-DM-RS-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=0 - uint8_t table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m1Hop[14] = {0,0,0,1,2,1,2,2,3,2,3,3,4,3}; // for index PUCCH-DM-RS-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=1 -/* The following tables implement TS 38.211 table 6.3.2.4.1-2: Orthogonal sequences wi(m)=exp(j*2*pi*phi(m)/N_SF) for PUCCH format 1 - uint16_t table_6_3_2_4_1_2_W2[2][2] = {{0,0}, {0,1}}; - uint16_t table_6_3_2_4_1_2_W3[3][3] = {{0,0,0}, {0,1,2}, {0,2,1}}; - uint16_t table_6_3_2_4_1_2_W4[4][4] = {{0,0,0,0}, {0,2,0,2}, {0,0,2,2} , {0,2,2,0}}; - uint16_t table_6_3_2_4_1_2_W5[2][2] = {{0,0,0,0,0}, {0,1,2,3,4}, {0,2,4,1,3}, {0,3,1,4,2}, {0,4,3,2,1}}; - uint16_t table_6_3_2_4_1_2_W6[2][2] = {{0,0,0,0,0,0}, {0,1,2,3,4,5}, {0,2,4,0,2,4}, {0,3,0,3,0,3}, {0,4,2,0,4,2}, {0,5,4,3,2,1}}; - uint16_t table_6_3_2_4_1_2_W7[2][2] = {{0,0,0,0,0,0,0},{0,1,2,3,4,5,6},{0,2,4,6,1,3,5},{0,3,6,2,5,1,4},{0,4,1,5,2,6,3},{0,5,3,1,6,4,2},{0,6,5,4,3,2,1}}; -*/ - int16_t table_6_3_2_4_1_2_Wi_Re[8][7][7] = { - {{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, - {{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, - {{32767,32767,0,0,0,0,0}, {32767,-32767,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, - {{32767,32767,32767,0,0,0,0}, {32767,-16384,-16384,0,0,0,0}, {32767,-16384,-16384,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, - {{32767,32767,32767,32767,0,0,0}, {32767,-32767,32767,-32767,0,0,0}, {32767,32767,-32767,-32767,0,0,0}, {32767,-32767,-32767,32767,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, - {{32767,32767,32767,32767,32767,0,0}, {32767,10126,-26509,-26509,10126,0,0}, {32767,-26509,10126,10126,-26509,0,0}, {32767,-26509,10126,10126,-26509,0,0}, {32767,10126,-26509,-26509,10126,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, - {{32767,32767,32767,32767,32767,32767,0}, {32767,16384,-16384,-32767,-16384,16384,0}, {32767,-16384,-16384,32767,-16384,-16384,0}, {32767,-32767,32767,-32767,32767,-32767,0}, {32767,-16384,-16384,32767,-16384,-16384,0}, {32767,16384,-16384,-32767,-16384,16384,0}, {0,0,0,0,0,0,0}}, - {{32767,32767,32767,32767,32767,32767,32767},{32767,20430,-7291,-29522,-29522,-7291,20430},{32767,-7291,-29522,20430,20430,-29522,-7291},{32767,-29522,20430,-7291,-7291,20430,-29522},{32767,-29522,20430,-7291,-7291,20430,-29522},{32767,-7291,-29522,20430,20430,-29522,-7291},{32767,20430,-7291,-29522,-29522,-7291,20430}} - }; - int16_t table_6_3_2_4_1_2_Wi_Im[8][7][7] = { - {{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, - {{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, - {{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, - {{0,0,0,0,0,0,0},{0,28377,-28377,0,0,0,0}, {0,-28377,28377,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, - {{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, - {{0,0,0,0,0,0,0},{0,31163,19260,-19260,-31163,0,0}, {0,19260,-31163,31163,-19260,0,0}, {0,-19260,31163,-31163,19260,0,0}, {0,-31163,-19260,19260,31163,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, - {{0,0,0,0,0,0,0},{0,28377,28377,0,-28377,-28377,0}, {0,28377,-28377,0,28377,-28377,0}, {0,0,0,0,0,0,0}, {0,-28377,28377,0,-28377,28377,0}, {0,-28377,-28377,0,28377,28377,0}, {0,0,0,0,0,0,0}}, - {{0,0,0,0,0,0,0},{0,25618,31945,14217,-14217,-31945,-25618},{0,31945,-14217,-25618,25618,14217,-31945},{0,14217,-25618,31945,-31945,25618,-14217},{0,-14217,25618,-31945,31945,-25618,14217},{0,-31945,14217,25618,-25618,-14217,31945},{0,-25618,-31945,-14217,14217,31945,25618}} - }; - /* * Implement TS 38.211 Subclause 6.3.2.4.1 Sequence modulation * */ - // nr_bit = {1,2}, to be provided in function call. FIXME! - //uint8_t M_bit=1; -//#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) // complex-valued symbol d_re, d_im containing complex-valued symbol d(0): int16_t d_re, d_im; - if (nr_bit == 1){ // using BPSK if M_bit=1 according to TC 38.211 Subclause 5.1.2 + if (nr_bit == 1) { // using BPSK if M_bit=1 according to TC 38.211 Subclause 5.1.2 d_re = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); } - else { // using QPSK if M_bit=2 according to TC 38.211 Subclause 5.1.2 + if (nr_bit == 2) { // using QPSK if M_bit=2 according to TC 38.211 Subclause 5.1.2 + if (((payload&1)==0) && (((payload>>1)&1)==0)) { + d_re = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) + d_im = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + if (((payload&1)==0) && (((payload>>1)&1)==1)) { + d_re = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + if (((payload&1)==1) && (((payload>>1)&1)==0)) { + d_re = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + if (((payload&1)==1) && (((payload>>1)&1)==1)) { + d_re = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + } + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] sequence modulation: payload=%x \tde_re=%d \tde_im=%d\n",payload,d_re,d_im); + #endif + + /* + * Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2 + */ + // alpha is cyclic shift + double alpha; + // lnormal is the OFDM symbol number in the PUCCH transmission where l=0 corresponds to the first OFDM symbol of the PUCCH transmission + uint8_t lnormal = 0 ; + // lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213] + uint8_t lprime = startingSymbolIndex; + // mcs = 0 except for PUCCH format 0 + uint8_t mcs=0; + // r_u_v_alpha_delta_re and r_u_v_alpha_delta_im tables containing the sequence y(n) for the PUCCH, when they are multiplied by d(0) + // r_u_v_alpha_delta_dmrs_re and r_u_v_alpha_delta_dmrs_im tables containing the sequence for the DM-RS. + int16_t r_u_v_alpha_delta_re[12],r_u_v_alpha_delta_im[12],r_u_v_alpha_delta_dmrs_re[12],r_u_v_alpha_delta_dmrs_im[12]; + /* + * in TS 38.213 Subclause 9.2.1 it is said that: + * for PUCCH format 0 or PUCCH format 1, the index of the cyclic shift + * is indicated by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift + */ + + /* + * the complex-valued symbol d_0 shall be multiplied with a sequence r_u_v_alpha_delta(n): y(n) = d_0 * r_u_v_alpha_delta(n) + */ + // the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1 + uint8_t u=0,v=0,delta=0; + // if frequency hopping is disabled, intraSlotFrequencyHopping is not provided + // n_hop = 0 + // if frequency hopping is enabled, intraSlotFrequencyHopping is provided + // n_hop = 0 for first hop + // n_hop = 1 for second hop + uint8_t n_hop = 0; + // Intra-slot frequency hopping shall be assumed when the higher-layer parameter intraSlotFrequencyHopping is provided, + // regardless of whether the frequency-hop distance is zero or not, + // otherwise no intra-slot frequency hopping shall be assumed + //uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers + uint8_t intraSlotFrequencyHopping = 0; + if (startingPRB != startingPRB_intraSlotHopping){ + intraSlotFrequencyHopping=1; + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] intraSlotFrequencyHopping=%d \n",intraSlotFrequencyHopping); + #endif + } +/* + * Implementing TS 38.211 Subclause 6.3.2.4.2 Mapping to physical resources + */ + int32_t *txptr; + uint32_t re_offset; + int i=0; + #define MAX_SIZE_Z 168 // this value has to be calculated from mprime*12*table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n + int16_t z_re[MAX_SIZE_Z],z_im[MAX_SIZE_Z]; + int16_t z_dmrs_re[MAX_SIZE_Z],z_dmrs_im[MAX_SIZE_Z]; + + for (int l=0; l= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_tti_tx=%d\n", + n_hop,nr_tti_tx); + #endif + nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value + alpha = nr_cyclic_shift_hopping(ue,m0,mcs,l,lprime,nr_tti_tx); + for (int n=0; n<12; n++){ + r_u_v_alpha_delta_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) + - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of base sequence shifted by alpha + r_u_v_alpha_delta_im[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15) + + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of base sequence shifted by alpha + r_u_v_alpha_delta_dmrs_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) + - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of DMRS base sequence shifted by alpha + r_u_v_alpha_delta_dmrs_im[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15) + + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of DMRS base sequence shifted by alpha + // PUCCH sequence = DM-RS sequence multiplied by d(0) + y_n_re[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_re)>>15) + - (((int32_t)(r_u_v_alpha_delta_im[n])*d_im)>>15))); // Re part of y(n) + y_n_im[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_im)>>15) + + (((int32_t)(r_u_v_alpha_delta_im[n])*d_re)>>15))); // Im part of y(n) + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] sequence generation \tu=%d \tv=%d \talpha=%lf \tr_u_v_alpha_delta[n=%d]=(%d,%d) \ty_n[n=%d]=(%d,%d)\n", + u,v,alpha,n,r_u_v_alpha_delta_re[n],r_u_v_alpha_delta_im[n],n,y_n_re[n],y_n_im[n]); + #endif + } + /* + * The block of complex-valued symbols y(n) shall be block-wise spread with the orthogonal sequence wi(m) + * (defined in table_6_3_2_4_1_2_Wi_Re and table_6_3_2_4_1_2_Wi_Im) + * z(mprime*12*table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n)=wi(m)*y(n) + * + * The block of complex-valued symbols r_u_v_alpha_dmrs_delta(n) for DM-RS shall be block-wise spread with the orthogonal sequence wi(m) + * (defined in table_6_3_2_4_1_2_Wi_Re and table_6_3_2_4_1_2_Wi_Im) + * z(mprime*12*table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n)=wi(m)*y(n) + * + */ + // the orthogonal sequence index for wi(m) defined in TS 38.213 Subclause 9.2.1 + // the index of the orthogonal cover code is from a set determined as described in [4, TS 38.211] + // and is indicated by higher layer parameter PUCCH-F1-time-domain-OCC + // In the PUCCH_Config IE, the PUCCH-format1, timeDomainOCC field + uint8_t w_index = timeDomainOCC; + // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime and intra-slot hopping enabled/disabled) + uint8_t N_SF_mprime_PUCCH_1; + // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.4.1.3.1.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime and intra-slot hopping enabled/disabled) + uint8_t N_SF_mprime_PUCCH_DMRS_1; + // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime=0 and intra-slot hopping enabled/disabled) + uint8_t N_SF_mprime0_PUCCH_1; + // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.4.1.3.1.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime=0 and intra-slot hopping enabled/disabled) + uint8_t N_SF_mprime0_PUCCH_DMRS_1; + // mprime is 0 if no intra-slot hopping / mprime is {0,1} if intra-slot hopping + uint8_t mprime = 0; + if (intraSlotFrequencyHopping == 0) { // intra-slot hopping disabled + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d\n", + intraSlotFrequencyHopping); + #endif + N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (PUCCH) + N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (DM-RS) + N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (PUCCH) + N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (DM-RS) + for (int m=0; m < N_SF_mprime_PUCCH_1; m++){ + for (int n=0; n<12 ; n++){ + z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15) + - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15)); + z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15) + + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15)); + #ifdef DEBUG_NR_PUCCH_TX + printf("\t\t z_pucch[%d] \t= ((%d \t* %d \t-%d \t* %d), (%d \t* %d \t+%d \t*%d)) = (%d,%d)\n", + (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, + table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n], + table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n], + z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); + #endif + } + } + for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++){ + for (int n=0; n<12 ; n++){ + z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15) + - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15)); + z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15) + + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15)); + #ifdef DEBUG_NR_PUCCH_TX + printf("\t\t z_dm-rs[%d] = ((),()) =(%d,%d)\n", + (mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n,z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); + #endif + } + } + } + if (intraSlotFrequencyHopping == 1) { // intra-slot hopping enabled + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d\n", + intraSlotFrequencyHopping); + #endif + N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH) + N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS) + N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH) + N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS) + for (mprime = 0; mprime<2; mprime++){ // mprime can get values {0,1} + for (int m=0; m < N_SF_mprime_PUCCH_1; m++){ + for (int n=0; n<12 ; n++){ + z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15) + - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15)); + z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15) + + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15)); + } + } + for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++){ + for (int n=0; n<12 ; n++){ + z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15) + - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15)); + z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15) + + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15)); + } + } + N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (PUCCH) + N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (DM-RS) + } + } + if ((intraSlotFrequencyHopping == 1) && (lN_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + } + if ((startingPRB >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))); + } + if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + } + if ((startingPRB > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6; + } + if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + } + + + txptr = &txdataF[0][re_offset]; + for (int n=0; n<12; n++){ + if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { + // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); + } + if (l%2 == 1) { // mapping PUCCH according to TS38.211 subclause 6.4.1.3.1 + ((int16_t *)&txdataF[0][re_offset])[0] = z_re[i+n]; + ((int16_t *)&txdataF[0][re_offset])[1] = z_im[i+n]; + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", + amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset, + l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); + #endif + } + if (l%2 == 0) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.1 + ((int16_t *)&txdataF[0][re_offset])[0] = z_dmrs_re[i+n]; + ((int16_t *)&txdataF[0][re_offset])[1] = z_dmrs_im[i+n]; + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", + amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset, + l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); + #endif + } + re_offset++; + } + if (l%2 == 1) i+=12; + } +} + +#if 0 +void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue, + int32_t **txdataF, + NR_DL_FRAME_PARMS *frame_parms, + PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, + uint64_t payload, + int16_t amp, + int nr_tti_tx, + uint8_t m0, + uint8_t nrofSymbols, + uint8_t startingSymbolIndex, + uint16_t startingPRB, + uint16_t startingPRB_intraSlotHopping, + uint8_t timeDomainOCC, + uint8_t nr_bit) { +#ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d payload=%d m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n", + nr_tti_tx,payload,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit); +#endif + + /* + * Implement TS 38.211 Subclause 6.3.2.4.1 Sequence modulation + * + */ + // complex-valued symbol d_re, d_im containing complex-valued symbol d(0): + int16_t d_re, d_im; + if (nr_bit == 1) { // using BPSK if M_bit=1 according to TC 38.211 Subclause 5.1.2 + d_re = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d_im = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + } + if (nr_bit == 2) { // using QPSK if M_bit=2 according to TC 38.211 Subclause 5.1.2 if (((payload&1)==0) && (((payload>>1)&1)==0)) { d_re = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) d_im = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); @@ -863,6 +827,7 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, if (l%2 == 1) i+=12; } } +#endif //0 inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint32_t B,uint8_t *btilde) __attribute__((always_inline)); inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint32_t B,uint8_t *btilde) { @@ -1153,8 +1118,14 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, // Intra-slot frequency hopping shall be assumed when the higher-layer parameter intraSlotFrequencyHopping is provided, // regardless of whether the frequency-hop distance is zero or not, // otherwise no intra-slot frequency hopping shall be assumed - //uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers. Let's suppose we do not support intra-slot hopping FIXME!! + //uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers uint8_t intraSlotFrequencyHopping = 0; + if (startingPRB != startingPRB_intraSlotHopping){ + intraSlotFrequencyHopping=1; + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] intraSlotFrequencyHopping=%d \n",intraSlotFrequencyHopping); + #endif + } // add_dmrs indicates if we are using or not Additional DM-RS for formats 3 and 4. From higher layers. FIXME!!! uint8_t add_dmrs = 0; nr_uci_encoding(payload,nr_bit,fmt,is_pi_over_2_bpsk_enabled,nrofSymbols,nrofPRB,n_SF_PUCCH_s,intraSlotFrequencyHopping,add_dmrs,&b,&M_bit); @@ -1349,7 +1320,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, } /* - * Implementing TS 38.211 Subclauses 6.3.2.5.3 and 6.3.2.6.5 Mapping to physical resources FIXME! + * Implementing TS 38.211 Subclauses 6.3.2.5.3 and 6.3.2.6.5 Mapping to physical resources */ // the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1 uint8_t u=0,v=0,delta=0; @@ -1381,49 +1352,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, int16_t *r_u_v_base_im = malloc(sizeof(int16_t)*12*nrofPRB); int16_t *r_u_v_alpha_delta_re = malloc(sizeof(int16_t)*12*nrofPRB); int16_t *r_u_v_alpha_delta_im = malloc(sizeof(int16_t)*12*nrofPRB); - nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value - // Next we proceed to calculate base sequence for DM-RS signal, according to TS 38.211 subclause 6.4.1.33 - if (nrofPRB >= 3) { // TS 38.211 subclause 5.2.2.1 (Base sequences of length 36 or larger) applies - uint8_t list_of_prime_numbers[46] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, - 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, - 73, 79, 83, 89, 97, 101,103,107,109,113, - 127,131,137,139,149,151,157,163,167,173, - 179,181,191,193,197,199}; - int i = 4; - while (list_of_prime_numbers[i] < (12*nrofPRB)) i++; - N_ZC = list_of_prime_numbers[i+1]; // N_ZC is given by the largest prime number such that N_ZC < (12*nrofPRB) - double q_base = (N_ZC*(u+1))/31; - int8_t q = (uint8_t)floor(q_base + (1/2)); - q = ((uint8_t)floor(2*q_base)%2 == 0 ? q+v : q-v); - for (int n=0; n<(12*nrofPRB); n++){ - r_u_v_base_re[n] = (int16_t)(((int32_t)amp*(int16_t)(32767*cos(M_PI*q*(n%N_ZC)*((n%N_ZC)+1)/N_ZC)))>>15); - r_u_v_base_im[n] = -(int16_t)(((int32_t)amp*(int16_t)(32767*sin(M_PI*q*(n%N_ZC)*((n%N_ZC)+1)/N_ZC)))>>15); - #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d >= 3: r_u_v_base[n=%d]=(%d,%d)\n", - nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]); - #endif - } - } - if (nrofPRB == 2) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-4) applies - for (int n=0; n<(12*nrofPRB); n++){ - r_u_v_base_re[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_4_Re[u][n])>>15); - r_u_v_base_im[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_4_Im[u][n])>>15); - #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d == 2: r_u_v_base[n=%d]=(%d,%d)\n", - nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]); - #endif - } - } - if (nrofPRB == 1) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-2) applies - for (int n=0; n<(12*nrofPRB); n++){ - r_u_v_base_re[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_2_Re[u][n])>>15); - r_u_v_base_im[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_2_Im[u][n])>>15); - #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d == 1: r_u_v_base[n=%d]=(%d,%d)\n", - nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]); - #endif - } - } + // Next we proceed to mapping to physical resources according to TS 38.211, subclause 6.3.2.6.5 dor PUCCH formats 3 and 4 and subclause 6.4.1.3.3.2 for DM-RS int32_t *txptr; uint32_t re_offset; @@ -1445,9 +1374,57 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, }; uint16_t k=0; for (int l=0; l= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop + nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value + + + // Next we proceed to calculate base sequence for DM-RS signal, according to TS 38.211 subclause 6.4.1.33 + if (nrofPRB >= 3) { // TS 38.211 subclause 5.2.2.1 (Base sequences of length 36 or larger) applies + int i = 4; + while (list_of_prime_numbers[i] < (12*nrofPRB)) i++; + N_ZC = list_of_prime_numbers[i+1]; // N_ZC is given by the largest prime number such that N_ZC < (12*nrofPRB) + double q_base = (N_ZC*(u+1))/31; + int8_t q = (uint8_t)floor(q_base + (1/2)); + q = ((uint8_t)floor(2*q_base)%2 == 0 ? q+v : q-v); + for (int n=0; n<(12*nrofPRB); n++){ + r_u_v_base_re[n] = (int16_t)(((int32_t)amp*(int16_t)(32767*cos(M_PI*q*(n%N_ZC)*((n%N_ZC)+1)/N_ZC)))>>15); + r_u_v_base_im[n] = -(int16_t)(((int32_t)amp*(int16_t)(32767*sin(M_PI*q*(n%N_ZC)*((n%N_ZC)+1)/N_ZC)))>>15); + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d >= 3: r_u_v_base[n=%d]=(%d,%d)\n", + nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]); + #endif + } + } + if (nrofPRB == 2) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-4) applies + for (int n=0; n<(12*nrofPRB); n++){ + r_u_v_base_re[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_4_Re[u][n])>>15); + r_u_v_base_im[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_4_Im[u][n])>>15); + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d == 2: r_u_v_base[n=%d]=(%d,%d)\n", + nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]); + #endif + } + } + if (nrofPRB == 1) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-2) applies + for (int n=0; n<(12*nrofPRB); n++){ + r_u_v_base_re[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_2_Re[u][n])>>15); + r_u_v_base_im[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_2_Im[u][n])>>15); + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d == 1: r_u_v_base[n=%d]=(%d,%d)\n", + nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]); + #endif + } + } + + + uint16_t j=0; alpha = nr_cyclic_shift_hopping(ue,m0,mcs,l,startingSymbolIndex,nr_tti_tx); for (int rb=0; rbN_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h new file mode 100644 index 0000000000..5d3d394b58 --- /dev/null +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h @@ -0,0 +1,423 @@ +/* + * 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 + */ + +/*! \file PHY/NR_UE_TRANSPORT/pucch_nr.c +* \brief Top-level routines for generating and decoding the PUCCH physical channel +* \author A. Mico Pereperez +* \date 2018 +* \version 0.1 +* \company Eurecom +* \email: +* \note +* \warning +*/ +//#include "PHY/defs.h" +#include "PHY/impl_defs_nr.h" +#include "PHY/defs_nr_common.h" +#include "PHY/defs_nr_UE.h" +//#include "PHY/extern.h" +//#include "LAYER2/MAC/extern.h" + +#include "common/utils/LOG/log.h" +#include "common/utils/LOG/vcd_signal_dumper.h" + +#include "T.h" +#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) + +void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_nr.puch_GroupHopping, + //uint8_t PUCCH_GroupHopping, + PHY_VARS_NR_UE *ue, + //uint32_t n_id, + uint8_t n_hop, + int nr_tti_tx, + uint8_t *u, + uint8_t *v); +double nr_cyclic_shift_hopping(PHY_VARS_NR_UE *ue, + uint8_t m0, + uint8_t mcs, + uint8_t lnormal, + uint8_t lprime, + int nr_tti_tx); +void nr_generate_pucch0(PHY_VARS_NR_UE *ue, + int32_t **txdataF, + NR_DL_FRAME_PARMS *frame_parms, + PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, + int16_t amp, + int nr_tti_tx, + uint8_t m0, + uint8_t mcs, + uint8_t nrofSymbols, + uint8_t startingSymbolIndex, + uint16_t startingPRB); +void nr_generate_pucch1(PHY_VARS_NR_UE *ue, + int32_t **txdataF, + NR_DL_FRAME_PARMS *frame_parms, + PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, + uint64_t payload, + int16_t amp, + int nr_tti_tx, + uint8_t m0, + uint8_t nrofSymbols, + uint8_t startingSymbolIndex, + uint16_t startingPRB, + uint16_t startingPRB_intraSlotHopping, + uint8_t timeDomainOCC, + uint8_t nr_bit); +void nr_generate_pucch2(PHY_VARS_NR_UE *ue, + int32_t **txdataF, + NR_DL_FRAME_PARMS *frame_parms, + PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, + uint64_t payload, + int16_t amp, + int nr_tti_tx, + uint8_t nrofSymbols, + uint8_t startingSymbolIndex, + uint8_t nrofPRB, + uint16_t startingPRB, + uint8_t nr_bit); +void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, + int32_t **txdataF, + NR_DL_FRAME_PARMS *frame_parms, + pucch_format_nr_t fmt, + PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, + uint64_t payload, + int16_t amp, + int nr_tti_tx, + uint8_t nrofSymbols, + uint8_t startingSymbolIndex, + uint8_t nrofPRB, + uint16_t startingPRB, + uint16_t startingPRB_intraSlotHopping, + uint8_t nr_bit, + uint8_t occ_length_format4, + uint8_t occ_index_format4); + /* + * The following tables implement TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (rows->u {0,1,..,29} / columns->n {0,1,...,M_ZC-1) + * Where base sequence r_u_v(n)=exp[j*phi(n)*pi/4] 0<=n<=M_ZC-1 and M_ZC={6,12,18,24} + * For M_ZC=30, base sequence r_u_v(n)=exp[-j((pi*[u+1]*[n+1]*[n+2])/31)] + */ + int16_t table_5_2_2_2_1_Re[30][6]={ // Table 5.2.2.2-1 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=6) + {-23170, 23170,-23170,-23170, 23170,-23170}, + {-23170,-23170, 23170, 23170,-23170,-23170}, + {-23170,-23170,-23170,-23170, 23170,-23170}, + { 23170, 23170, 23170,-23170, 23170,-23170}, + { 23170, 23170, 23170,-23170, 23170,-23170}, + {-23170, 23170, 23170,-23170,-23170,-23170}, + {-23170, 23170,-23170,-23170,-23170,-23170}, + {-23170, 23170, 23170,-23170, 23170, 23170}, + {-23170, 23170,-23170, 23170,-23170,-23170}, + {-23170,-23170, 23170,-23170,-23170,-23170}, + {-23170, 23170,-23170, 23170,-23170,-23170}, + {-23170, 23170,-23170, 23170, 23170,-23170}, + { 23170, 23170,-23170, 23170,-23170,-23170}, + { 23170, 23170,-23170,-23170, 23170,-23170}, + { 23170, 23170, 23170,-23170,-23170, 23170}, + { 23170, 23170, 23170, 23170,-23170,-23170}, + {-23170, 23170, 23170, 23170,-23170, 23170}, + {-23170,-23170, 23170, 23170, 23170,-23170}, + {-23170,-23170,-23170, 23170,-23170, 23170}, + {-23170, 23170, 23170,-23170, 23170,-23170}, + {-23170,-23170,-23170, 23170, 23170,-23170}, + {-23170, 23170,-23170,-23170,-23170, 23170}, + { 23170, 23170,-23170,-23170, 23170,-23170}, + { 23170, 23170,-23170,-23170, 23170,-23170}, + { 23170, 23170,-23170, 23170,-23170,-23170}, + { 23170, 23170,-23170, 23170,-23170,-23170}, + { 23170, 23170, 23170, 23170,-23170, 23170}, + { 23170, 23170, 23170,-23170, 23170, 23170}, + { 23170, 23170, 23170,-23170,-23170, 23170}, + { 23170, 23170,-23170, 23170, 23170, 23170} + }; + int16_t table_5_2_2_2_1_Im[30][6]={ // Table 5.2.2.2-1 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=6) + {-23170,-23170, 23170, 23170,-23170,-23170}, + {-23170, 23170,-23170,-23170, 23170,-23170}, + {-23170,-23170,-23170, 23170, 23170,-23170}, + { 23170, 23170, 23170, 23170,-23170,-23170}, + { 23170, 23170, 23170,-23170,-23170, 23170}, + {-23170, 23170,-23170,-23170,-23170,-23170}, + {-23170, 23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170,-23170, 23170,-23170}, + {-23170,-23170,-23170, 23170,-23170,-23170}, + {-23170,-23170, 23170,-23170, 23170,-23170}, + {-23170, 23170, 23170, 23170,-23170,-23170}, + {-23170,-23170,-23170, 23170, 23170,-23170}, + { 23170, 23170, 23170,-23170,-23170, 23170}, + { 23170, 23170, 23170, 23170,-23170, 23170}, + { 23170, 23170, 23170,-23170, 23170,-23170}, + { 23170, 23170, 23170,-23170, 23170,-23170}, + {-23170,-23170,-23170,-23170, 23170,-23170}, + {-23170,-23170,-23170, 23170,-23170,-23170}, + {-23170,-23170,-23170, 23170,-23170,-23170}, + {-23170, 23170, 23170,-23170,-23170,-23170}, + {-23170, 23170,-23170, 23170, 23170,-23170}, + {-23170, 23170,-23170,-23170,-23170,-23170}, + { 23170, 23170,-23170, 23170, 23170, 23170}, + { 23170, 23170,-23170,-23170, 23170,-23170}, + { 23170, 23170, 23170,-23170, 23170, 23170}, + { 23170, 23170,-23170, 23170, 23170, 23170}, + { 23170, 23170,-23170,-23170, 23170,-23170}, + { 23170, 23170,-23170, 23170,-23170,-23170}, + { 23170, 23170,-23170, 23170,-23170,-23170}, + { 23170, 23170,-23170, 23170,-23170,-23170} + }; + int16_t table_5_2_2_2_2_Re[30][12]={ // Table 5.2.2.2-2 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=12) + {-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170}, + {-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170}, + {-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170}, + {-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170}, + {-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170}, + {-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170}, + { 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170}, + { 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170}, + {-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170}, + {-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170}, + {-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170}, + {-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170}, + {-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170}, + {-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170}, + { 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170}, + {-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170}, + { 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170}, + { 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170}, + {-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170}, + {-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170}, + {-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170}, + {-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170}, + {-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170}, + {-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170}, + {-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170}, + { 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170}, + {-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170}, + { 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170}, + {-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170} + }; + int16_t table_5_2_2_2_2_Im[30][12]={ // Table 5.2.2.2-2 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=12) + {-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170}, + {-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170}, + {-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170}, + {-23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170}, + {-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170}, + {-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170}, + { 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170}, + {-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170}, + {-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170}, + {-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170}, + {-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170}, + {-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170}, + {-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170}, + {-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170}, + { 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170}, + {-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170}, + {-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170}, + {-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170}, + {-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170}, + {-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170}, + { 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170}, + {-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170}, + {-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170}, + { 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170}, + {-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170}, + {-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170}, + {-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170}, + { 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170}, + {-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170} + }; + int16_t table_5_2_2_2_3_Re[30][18]={ // Table 5.2.2.2-3 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=18) + { 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170}, + {-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170}, + {-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170}, + { 23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170}, + {-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170}, + {-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170}, + { 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170}, + {-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170}, + {-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170}, + {-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170}, + {-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170}, + {-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170}, + { 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170}, + {-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170}, + {-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170}, + {-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170}, + {-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170}, + {-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170}, + {-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170}, + {-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170}, + { 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170}, + {-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170}, + {-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170}, + {-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170}, + {-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170}, + { 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170}, + {-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170} + }; + int16_t table_5_2_2_2_3_Im[30][18]={ // Table 5.2.2.2-3 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=18) + {-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170}, + { 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170}, + {-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170}, + { 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170}, + { 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170}, + {-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170}, + { 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170}, + {-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170}, + { 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170}, + {-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170}, + {-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170}, + {-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170}, + { 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170}, + {-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170}, + { 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170}, + {-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170}, + {-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170}, + {-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170}, + { 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170}, + {-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170}, + { 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170}, + {-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170}, + { 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170}, + { 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170}, + {-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170}, + {-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170}, + {-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170}, + {-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170} + }; + int16_t table_5_2_2_2_4_Re[30][24]={ // Table 5.2.2.2-4 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=24) + { 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170}, + { 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170}, + { 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170}, + { 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170}, + { 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170}, + {-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170}, + {-23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170}, + {-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170}, + {-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170}, + { 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170}, + {-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170}, + {-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170}, + {-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170}, + {-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170}, + {-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170}, + {-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170}, + {-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170}, + {-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170}, + {-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170}, + {-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170}, + {-23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170}, + {-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170}, + {-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170}, + {-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170}, + {-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170}, + {-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170}, + { 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170}, + {-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170}, + {-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170}, + {-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170} + }; + int16_t table_5_2_2_2_4_Im[30][24]={ // Table 5.2.2.2-4 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=24) + {-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170}, + {-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170}, + { 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170}, + {-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170}, + {-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170}, + {-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170}, + {-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170}, + {-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170}, + { 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170}, + {-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170}, + {-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170}, + { 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170}, + {-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170}, + {-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170}, + {-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170}, + {-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170}, + { 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170}, + {-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170}, + {-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170}, + {-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170}, + { 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170}, + {-23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170}, + {-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170}, + {-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170}, + {-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170}, + {-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170}, + { 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170}, + {-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170}, + { 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170} + }; + + /* + * The following tables implement TS 38.211 table 6.3.2.4.1-1: Number of PUCCH symbols and the corresponding N_SF_mprime_PUCCH_1 + * One table for no intra-slot hopping + * Two tables for intra-slot hopping (mprime=0 and mprime=1) + */ + uint8_t table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[14] = {0,0,0,2,2,3,3,4,4,5,5,6,6,7}; // for index PUCCH-length, we obtain N_SF_mprime_PUCCH_1 when no intra-slot hopping + uint8_t table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[14] = {0,0,0,1,1,1,1,2,2,2,2,3,3,3}; // for index PUCCH-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=0 + uint8_t table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[14] = {0,0,0,1,1,2,2,2,2,3,3,3,3,4}; // for index PUCCH-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=1 + /* + * The following tables implement TS 38.211 table 6.4.1.3.1.1-1: Number of DM-RS symbols and the corresponding N_SF_mprime_PUCCH_1 + * One table for no intra-slot hopping + * Two tables for intra-slot hopping (mprime=0 and mprime=1) + */ + uint8_t table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[14] = {0,0,0,2,3,3,4,4,5,5,6,6,7,7}; // for index PUCCH-DM-RS-length, we obtain N_SF_mprime_PUCCH_1 when no intra-slot hopping + uint8_t table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[14] = {0,0,0,1,1,2,2,2,2,3,3,3,3,4}; // for index PUCCH-DM-RS-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=0 + uint8_t table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m1Hop[14] = {0,0,0,1,2,1,2,2,3,2,3,3,4,3}; // for index PUCCH-DM-RS-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=1 + /* The following tables implement TS 38.211 table 6.3.2.4.1-2: Orthogonal sequences wi(m)=exp(j*2*pi*phi(m)/N_SF) for PUCCH format 1 + uint16_t table_6_3_2_4_1_2_W2[2][2] = {{0,0}, {0,1}}; + uint16_t table_6_3_2_4_1_2_W3[3][3] = {{0,0,0}, {0,1,2}, {0,2,1}}; + uint16_t table_6_3_2_4_1_2_W4[4][4] = {{0,0,0,0}, {0,2,0,2}, {0,0,2,2} , {0,2,2,0}}; + uint16_t table_6_3_2_4_1_2_W5[2][2] = {{0,0,0,0,0}, {0,1,2,3,4}, {0,2,4,1,3}, {0,3,1,4,2}, {0,4,3,2,1}}; + uint16_t table_6_3_2_4_1_2_W6[2][2] = {{0,0,0,0,0,0}, {0,1,2,3,4,5}, {0,2,4,0,2,4}, {0,3,0,3,0,3}, {0,4,2,0,4,2}, {0,5,4,3,2,1}}; + uint16_t table_6_3_2_4_1_2_W7[2][2] = {{0,0,0,0,0,0,0},{0,1,2,3,4,5,6},{0,2,4,6,1,3,5},{0,3,6,2,5,1,4},{0,4,1,5,2,6,3},{0,5,3,1,6,4,2},{0,6,5,4,3,2,1}}; + */ + int16_t table_6_3_2_4_1_2_Wi_Re[8][7][7] = { + {{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{32767,32767,0,0,0,0,0}, {32767,-32767,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{32767,32767,32767,0,0,0,0}, {32767,-16384,-16384,0,0,0,0}, {32767,-16384,-16384,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{32767,32767,32767,32767,0,0,0}, {32767,-32767,32767,-32767,0,0,0}, {32767,32767,-32767,-32767,0,0,0}, {32767,-32767,-32767,32767,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{32767,32767,32767,32767,32767,0,0}, {32767,10126,-26509,-26509,10126,0,0}, {32767,-26509,10126,10126,-26509,0,0}, {32767,-26509,10126,10126,-26509,0,0}, {32767,10126,-26509,-26509,10126,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{32767,32767,32767,32767,32767,32767,0}, {32767,16384,-16384,-32767,-16384,16384,0}, {32767,-16384,-16384,32767,-16384,-16384,0}, {32767,-32767,32767,-32767,32767,-32767,0}, {32767,-16384,-16384,32767,-16384,-16384,0}, {32767,16384,-16384,-32767,-16384,16384,0}, {0,0,0,0,0,0,0}}, + {{32767,32767,32767,32767,32767,32767,32767},{32767,20430,-7291,-29522,-29522,-7291,20430},{32767,-7291,-29522,20430,20430,-29522,-7291},{32767,-29522,20430,-7291,-7291,20430,-29522},{32767,-29522,20430,-7291,-7291,20430,-29522},{32767,-7291,-29522,20430,20430,-29522,-7291},{32767,20430,-7291,-29522,-29522,-7291,20430}} + }; + int16_t table_6_3_2_4_1_2_Wi_Im[8][7][7] = { + {{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{0,0,0,0,0,0,0},{0,28377,-28377,0,0,0,0}, {0,-28377,28377,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{0,0,0,0,0,0,0},{0,31163,19260,-19260,-31163,0,0}, {0,19260,-31163,31163,-19260,0,0}, {0,-19260,31163,-31163,19260,0,0}, {0,-31163,-19260,19260,31163,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}}, + {{0,0,0,0,0,0,0},{0,28377,28377,0,-28377,-28377,0}, {0,28377,-28377,0,28377,-28377,0}, {0,0,0,0,0,0,0}, {0,-28377,28377,0,-28377,28377,0}, {0,-28377,-28377,0,28377,28377,0}, {0,0,0,0,0,0,0}}, + {{0,0,0,0,0,0,0},{0,25618,31945,14217,-14217,-31945,-25618},{0,31945,-14217,-25618,25618,14217,-31945},{0,14217,-25618,31945,-31945,25618,-14217},{0,-14217,25618,-31945,31945,-25618,14217},{0,-31945,14217,25618,-25618,-14217,31945},{0,-25618,-31945,-14217,14217,31945,25618}} + }; + + uint8_t list_of_prime_numbers[46] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, + 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, + 73, 79, 83, 89, 97, 101,103,107,109,113, + 127,131,137,139,149,151,157,163,167,173, + 179,181,191,193,197,199}; diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 70a5735b58..700b3db5b4 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -101,8 +101,7 @@ void nr_feptx_ofdm_2thread(RU_t *ru) { // this copy should be done in the precoding thread (currently inactive) for (int aa=0;aanb_tx;aa++) memcpy((void*)ru->common.txdataF_BF[aa], - (void*)&ru->gNB_list[0]->common_vars.txdataF[aa][subframe*fp->samples_per_subframe_wCP], - fp->samples_per_subframe_wCP*sizeof(int32_t)); + (void*)ru->gNB_list[0]->common_vars.txdataF[aa], fp->samples_per_subframe_wCP*sizeof(int32_t)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index c02c7765f1..7e831ec84b 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -170,8 +170,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, // clear the transmit data array for the current subframe for (aa=0; aarf_config.tx_antenna_ports.value; aa++) { - memset(&gNB->common_vars.txdataF[aa][subframe*fp->samples_per_subframe_wCP], - 0,fp->samples_per_subframe_wCP*sizeof(int32_t)); + memset(gNB->common_vars.txdataF[aa],0,fp->samples_per_subframe_wCP*sizeof(int32_t)); } if (nfapi_mode == 0 || nfapi_mode == 1) {