From 7879afc0106965ffe5625419c178b8fe95db00f3 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Wed, 8 Mar 2023 14:15:35 +0000 Subject: [PATCH 1/3] Improve code readability and fix the nr_polar_params() function --- openair1/PHY/CODING/nr_polar_init.c | 76 ++++++++++++++++------------ openair1/PHY/NR_TRANSPORT/pucch_rx.c | 4 +- 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/openair1/PHY/CODING/nr_polar_init.c b/openair1/PHY/CODING/nr_polar_init.c index 38a1ae86ae..4a88417a13 100644 --- a/openair1/PHY/CODING/nr_polar_init.c +++ b/openair1/PHY/CODING/nr_polar_init.c @@ -85,10 +85,8 @@ static void nr_polar_delete(void) { pthread_mutex_unlock(&PolarListMutex); } -t_nrPolar_params * nr_polar_params(int8_t messageType, - uint16_t messageLength, - uint8_t aggregation_level, - int decoder_flag) { +t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, uint8_t aggregation_level, int decoder_flag) +{ // The lock is weak, because we never delete in the list, only at exit time // therefore, returning t_nrPolar_params * from the list is safe for future usage pthread_mutex_lock(&PolarListMutex); @@ -123,8 +121,8 @@ t_nrPolar_params * nr_polar_params(int8_t messageType, newPolarInitNode->idx = PolarKey; newPolarInitNode->nextPtr = NULL; //printf("newPolarInitNode->idx %d, (%d,%d,%d:%d)\n",newPolarInitNode->idx,messageType,messageLength,aggregation_prime,aggregation_level); - - if (messageType == 0) { //PBCH + + if (messageType == NR_POLAR_PBCH_MESSAGE_TYPE) { newPolarInitNode->n_max = NR_POLAR_PBCH_N_MAX; newPolarInitNode->i_il = NR_POLAR_PBCH_I_IL; newPolarInitNode->i_seg = NR_POLAR_PBCH_I_SEG; @@ -135,9 +133,10 @@ t_nrPolar_params * nr_polar_params(int8_t messageType, newPolarInitNode->payloadBits = NR_POLAR_PBCH_PAYLOAD_BITS; newPolarInitNode->encoderLength = NR_POLAR_PBCH_E; newPolarInitNode->crcCorrectionBits = NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS; - newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits);//G_P + newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits); // G_P //printf("Initializing polar parameters for PBCH (K %d, E %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength); - } else if (messageType == 1) { //DCI + + } else if (messageType == NR_POLAR_DCI_MESSAGE_TYPE) { newPolarInitNode->n_max = NR_POLAR_DCI_N_MAX; newPolarInitNode->i_il = NR_POLAR_DCI_I_IL; newPolarInitNode->i_seg = NR_POLAR_DCI_I_SEG; @@ -146,40 +145,55 @@ t_nrPolar_params * nr_polar_params(int8_t messageType, newPolarInitNode->i_bil = NR_POLAR_DCI_I_BIL; newPolarInitNode->crcParityBits = NR_POLAR_DCI_CRC_PARITY_BITS; newPolarInitNode->payloadBits = messageLength; - newPolarInitNode->encoderLength = aggregation_level*108; + newPolarInitNode->encoderLength = aggregation_level * 108; newPolarInitNode->crcCorrectionBits = NR_POLAR_DCI_CRC_ERROR_CORRECTION_BITS; - newPolarInitNode->crc_generator_matrix=crc24c_generator_matrix(newPolarInitNode->payloadBits+newPolarInitNode->crcParityBits);//G_P + newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits + newPolarInitNode->crcParityBits); // G_P //printf("Initializing polar parameters for DCI (K %d, E %d, L %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength,aggregation_level); - } else if (messageType == 2) { //UCI PUCCH2 - AssertFatal(aggregation_level>2,"Aggregation level (%d) for PUCCH 2 encoding is NPRB and should be > 2\n",aggregation_level); - AssertFatal(messageLength>11,"Message length %d is too short for polar encoding of UCI\n",messageLength); - newPolarInitNode->n_max = NR_POLAR_PUCCH_N_MAX; - newPolarInitNode->i_il = NR_POLAR_PUCCH_I_IL; + + } else if (messageType == NR_POLAR_UCI_PUCCH_MESSAGE_TYPE) { + AssertFatal(aggregation_level > 2, "Aggregation level (%d) for PUCCH 2 encoding is NPRB and should be > 2\n", aggregation_level); + AssertFatal(messageLength > 11, "Message length %d is too short for polar encoding of UCI\n", messageLength); + + // TS 38.212 - Section 6.3.1.2.1 UCI encoded by Polar code + int L = 0; + if (messageLength >= 12 && messageLength <= 19) { + L = 6; + } else if (messageLength >= 20) { + L = 11; + } else { + AssertFatal(1 == 0, "L = %i is an invalid value\n", L); + } newPolarInitNode->encoderLength = aggregation_level * 16; - newPolarInitNode->i_seg = 0; - - if ((messageLength >= 360 && newPolarInitNode->encoderLength >= 1088)|| - (messageLength >= 1013)) newPolarInitNode->i_seg = 1; - - newPolarInitNode->crcParityBits = 11; - newPolarInitNode->n_pc = 0; - newPolarInitNode->n_pc_wm = 0; - - if (messageLength < 20) { - newPolarInitNode->crcParityBits = 6; - newPolarInitNode->n_pc = 3; - if ((newPolarInitNode->encoderLength - messageLength - 6 + 3) < 193) newPolarInitNode->n_pc_wm = 1; + if ((messageLength >= 360 && newPolarInitNode->encoderLength >= 1088) || (messageLength >= 1013)) { + newPolarInitNode->i_seg = 1; + AssertFatal(1 == 0, "Segmentation is not supported yet (i_seg = %i)\n", newPolarInitNode->i_seg); } - + // TS 38.212 - Section 6.3.1.3.1 UCI encoded by Polar code + newPolarInitNode->n_max = NR_POLAR_PUCCH_N_MAX; + newPolarInitNode->i_il = NR_POLAR_PUCCH_I_IL; + newPolarInitNode->crcParityBits = L; + int Kr = messageLength + L; + if (Kr >= 18 && Kr <= 25) { + newPolarInitNode->n_pc = 3; + if ((newPolarInitNode->encoderLength - Kr + 3) > 192) { + newPolarInitNode->n_pc_wm = 1; + } else { + newPolarInitNode->n_pc_wm = 0; + } + } else if (Kr > 30) { + newPolarInitNode->n_pc = 0; + newPolarInitNode->n_pc_wm = 0; + } else { + AssertFatal(1 == 0, "Kr = %i is an invalid value\n", Kr); + } newPolarInitNode->i_bil = NR_POLAR_PUCCH_I_BIL; - newPolarInitNode->payloadBits = messageLength; newPolarInitNode->crcCorrectionBits = NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS; - //newPolarInitNode->crc_generator_matrix=crc24c_generator_matrix(newPolarInitNode->payloadBits+newPolarInitNode->crcParityBits);//G_P //LOG_D(PHY,"New polar node, encoderLength %d, aggregation_level %d\n",newPolarInitNode->encoderLength,aggregation_level); + } else { AssertFatal(1 == 0, "[nr_polar_init] Incorrect Message Type(%d)", messageType); } diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 71db65a14e..2d154ab013 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -1704,8 +1704,10 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, ((int16_t*)&llrs[half_prb])[7]); } // half_prb } // symb + // run polar decoder on llrs - decoderState = polar_decoder_int16((int16_t*)llrs, decodedPayload, 0, 2,nb_bit,pucch_pdu->prb_size); + decoderState = polar_decoder_int16((int16_t *)llrs, decodedPayload, 0, NR_POLAR_UCI_PUCCH_MESSAGE_TYPE, nb_bit, pucch_pdu->prb_size); + LOG_D(PHY,"UCI decoderState %d, payload[0] %llu\n",decoderState,(unsigned long long)decodedPayload[0]); if (decoderState>0) decoderState=1; corr_dB = dB_fixed64(corr); From b307044345b7d84153c18af43e6bad2ab151fd18 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Wed, 8 Mar 2023 15:41:18 +0000 Subject: [PATCH 2/3] Decode PUCCH2 for polarParams->N = 64 --- .../CODING/nrPolar_tools/nr_polar_encoder.c | 43 ++++++++++++++----- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c index 4cba3fe078..ad77a61a02 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c @@ -342,7 +342,8 @@ void build_polar_tables(t_nrPolar_params *polarParams) { } } - AssertFatal(polarParams->N==512 || polarParams->N==256 || polarParams->N==128,"N = %d, not done yet\n",polarParams->N); + AssertFatal(polarParams->N == 512 || polarParams->N == 256 || polarParams->N == 128 || polarParams->N == 64, "N = %d, not done yet\n", polarParams->N); + // build G bit vectors for information bit positions and convert the bit as bytes tables in nr_polar_kronecker_power_matrices.c to 64 bit packed vectors. // keep only rows of G which correspond to information/crc bits polarParams->G_N_tab = (uint64_t **)calloc((polarParams->K + polarParams->n_pc),sizeof(int64_t *)); @@ -410,19 +411,34 @@ void build_polar_tables(t_nrPolar_params *polarParams) { firstingroup_in,firstingroup_in+ccnt, firstingroup_out,firstingroup_out+ccnt); #endif - AssertFatal(mingroupsize==4 || mingroupsize==8 || mingroupsize==16,"mingroupsize %d, needs to be handled\n",mingroupsize); - polarParams->groupsize=mingroupsize; - int shift=3; - if (mingroupsize == 16) shift=4; - else if (mingroupsize == 4) shift=2; + polarParams->groupsize = mingroupsize; + + int shift = 0; + switch (mingroupsize) { + case 2: + shift = 1; + break; + case 4: + shift = 2; + break; + case 8: + shift = 3; + break; + case 16: + shift = 4; + break; + default: + AssertFatal(1 == 0, "mingroupsize = %i is not supported\n", mingroupsize); + break; + } + + polarParams->rm_tab = (int *)malloc(sizeof(int) * (polarParams->encoderLength >> shift)); - polarParams->rm_tab=(int *)malloc(sizeof(int)*polarParams->encoderLength/mingroupsize); // rerun again to create groups - int tcnt=0; - - for (int outpos=0; outposencoderLength; outpos+=mingroupsize,tcnt++) - polarParams->rm_tab[tcnt] = polarParams->rate_matching_pattern[outpos]>>shift; + int tcnt = 0; + for (int outpos = 0; outpos < polarParams->encoderLength; outpos += mingroupsize, tcnt++) + polarParams->rm_tab[tcnt] = polarParams->rate_matching_pattern[outpos] >> shift; } void polar_encoder_fast(uint64_t *A, @@ -699,6 +715,11 @@ void polar_encoder_fast(uint64_t *A, #endif } } + } else if (polarParams->N == 64) { + for (int i = 0; i < ((len > 63) ? 64 : len); i++) { + Cprime_i = -((Cprime[0] >> i) & 1); + D[0] ^= (Cprime_i & polarParams->G_N_tab[off + i][0]); + } } memset((void*)out,0,polarParams->encoderLength>>3); polar_rate_matching(polarParams,(void *)D, out); From e140ac4bf7fdccd220e309b0d18c13a7e7b9c170 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Wed, 8 Mar 2023 15:46:42 +0000 Subject: [PATCH 3/3] Add CI test for PUCCH2 and polarParams->N = 64 --- cmake_targets/autotests/test_case_list.xml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 7840e89e28..d4086fc9e6 100755 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -289,11 +289,13 @@ (Test10: Format 2 9-bit 2/106 PRB), (Test11: Format 2 10-bit 2/106 PRB), (Test12: Format 2 11-bit 2/106 PRB), - (Test13: Format 2 12-bit 8/106 PRB), - (Test14: Format 2 19-bit 8/106 PRB), - (Test15: Format 2 32-bit 8/106 PRB), - (Test16: Format 2 32-bit 16/106 PRB), - (Test17: Format 2 64-bit 16/106 PRB) + (Test13: Format 2 12-bit 4/106 PRB), + (Test14: Format 2 19-bit 4/106 PRB), + (Test15: Format 2 12-bit 8/106 PRB), + (Test16: Format 2 19-bit 8/106 PRB), + (Test17: Format 2 32-bit 8/106 PRB), + (Test18: Format 2 32-bit 16/106 PRB), + (Test19: Format 2 64-bit 16/106 PRB) nr_pucchsim -R 106 -i 1 -P 0 -b 1 -s-2 -n1000 -R 106 -i 1 -P 0 -b 2 -s-2 -n1000 @@ -307,12 +309,14 @@ -R 106 -i 1 -P 2 -b 9 -s5 -n1000 -R 106 -i 1 -P 2 -b 10 -s6 -n1000 -R 106 -i 1 -P 2 -b 11 -s6 -n1000 + -R 106 -i 1 -P 2 -q4 -b 12 -s-3 -n1000 + -R 106 -i 1 -P 2 -q4 -b 19 -s-3 -n1000 -R 106 -i 1 -P 2 -q8 -b 12 -s-3 -n1000 -R 106 -i 1 -P 2 -q8 -b 19 -s-3 -n1000 -R 106 -i 1 -P 2 -q8 -b 32 -s-3 -n1000 -R 106 -i 1 -P 2 -q16 -b 32 -s-3 -n1000 -R 106 -i 1 -P 2 -q16 -b 64 -s-3 -n1000 - test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 test12 test13 test14 test15 test16 test17 + test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 test12 test13 test14 test15 test16 test17 test18 test19 PUCCH test OK segmentation fault|assertion|exiting|fatal 3