From e5825139d72bb5778748234a344901371562acd8 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Mon, 8 May 2023 17:30:30 +0100 Subject: [PATCH 1/8] Implementation for interleaving of coded bits --- .../CODING/nrPolar_tools/nr_polar_encoder.c | 119 +++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c index 1a4137fb29..b22cc97ccc 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c @@ -33,6 +33,7 @@ //#define DEBUG_POLAR_ENCODER //#define DEBUG_POLAR_ENCODER_DCI //#define DEBUG_POLAR_MATLAB +//#define POLAR_CODING_DEBUG #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "assertions.h" @@ -262,6 +263,44 @@ void polar_encoder_dci(uint32_t *in, polarReturn; } +/* + * Interleaving of coded bits implementation + * TS 138.212: Section 5.4.1.3 - Interleaving of coded bits + */ +void nr_polar_rm_interleaving_cb(void *in, void *out, uint16_t E) +{ + int T = ceil((sqrt(8 * E + 1) - 1) / 2); + int v[T][T]; + int k = 0; + uint64_t *in64 = (uint64_t *)in; + for (int i = 0; i < T; i++) { + for (int j = 0; j < T - i; j++) { + if (k < E) { + int k1 = k >> 6; + int k2 = k - (k1 << 6); + v[i][j] = (in64[k1] >> k2) & 1; + } else { + v[i][j] = -1; + } + k++; + } + } + + k = 0; + uint64_t *out64 = (uint64_t *)out; + memset(out64, 0, E >> 3); + for (int j = 0; j < T; j++) { + for (int i = 0; i < T - j; i++) { + if (v[i][j] != -1) { + int k1 = k >> 6; + int k2 = k - (k1 << 6); + out64[k1] |= (uint64_t)v[i][j] << k2; + k++; + } + } + } +} + static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void *in,void *out) __attribute__((always_inline)); static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void *in,void *out) { @@ -309,6 +348,10 @@ static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void for (int i=0; iencoderLength>>4; i++) { ((uint16_t *)out)[i] = ((uint16_t *)in)[polarParams->rm_tab[i]]; } + + if (polarParams->i_bil == 1) { + nr_polar_rm_interleaving_cb(out, out, polarParams->encoderLength); + } } void build_polar_tables(t_nrPolar_params *polarParams) { @@ -452,6 +495,21 @@ void polar_encoder_fast(uint64_t *A, uint8_t aggregation_level) { t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, false); + +#ifdef POLAR_CODING_DEBUG + printf("polarParams->payloadBits = %i\n", polarParams->payloadBits); + printf("polarParams->crcParityBits = %i\n", polarParams->crcParityBits); + printf("polarParams->K = %i\n", polarParams->K); + printf("polarParams->N = %i\n", polarParams->N); + printf("polarParams->encoderLength = %i\n", polarParams->encoderLength); + printf("polarParams->n_pc = %i\n", polarParams->n_pc); + printf("polarParams->n_pc_wm = %i\n", polarParams->n_pc_wm); + printf("polarParams->groupsize = %i\n", polarParams->groupsize); + printf("polarParams->i_il = %i\n", polarParams->i_il); + printf("polarParams->i_bil = %i\n", polarParams->i_bil); + printf("polarParams->n_max = %i\n", polarParams->n_max); +#endif + // AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K); AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K); AssertFatal(polarParams->payloadBits < 65, "payload bits = %d > 64, is not supported yet\n",polarParams->payloadBits); @@ -460,6 +518,23 @@ void polar_encoder_fast(uint64_t *A, AssertFatal(bitlen<129,"support for payloads <= 128 bits\n"); // AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n"); //int bitlen0=bitlen; + +#ifdef POLAR_CODING_DEBUG + int A_array = (bitlen + 63) >> 6; + printf("\nTX\n"); + printf("a: "); + for (int n = 0; n < bitlen; n++) { + if (n % 4 == 0) { + printf(" "); + } + int n1 = n >> 6; + int n2 = n - (n1 << 6); + int alen = n1 == 0 ? bitlen - (A_array << 6) : 64; + printf("%lu", (A[A_array - 1 - n1] >> (alen - 1 - n2)) & 1); + } + printf("\n"); +#endif + uint64_t tcrc=0; uint8_t offset = 0; @@ -542,6 +617,22 @@ void polar_encoder_fast(uint64_t *A, else B[n] = (A[n-1]>>(64-polarParams->crcParityBits)); +#ifdef POLAR_CODING_DEBUG + int bitlen_B = bitlen + polarParams->crcParityBits; + int B_array = (bitlen_B + 63) >> 6; + int n_start = (B_array << 6) - bitlen_B; + printf("b: "); + for (int n = 0; n < bitlen_B; n++) { + if (n % 4 == 0) { + printf(" "); + } + int n1 = (n + n_start) >> 6; + int n2 = (n + n_start) - (n1 << 6); + printf("%lu", (B[B_array - 1 - n1] >> (63 - n2)) & 1); + } + printf("\n"); +#endif + uint8_t *Bbyte = (uint8_t *)B; // for each byte of B, lookup in corresponding table for 64-bit word corresponding to that byte and its position @@ -567,6 +658,19 @@ void polar_encoder_fast(uint64_t *A, for (int i = 0; i < quadwlen; i++) printf("[polar_encoder_fast]C'[%d]= 0x%llx\n", i, (unsigned long long)(Cprime[i])); #endif +#ifdef POLAR_CODING_DEBUG + printf("c: "); + for (int n = 0; n < bitlen_B; n++) { + if (n % 4 == 0) { + printf(" "); + } + int n1 = n >> 6; + int n2 = n - (n1 << 6); + printf("%lu", (Cprime[n1] >> n2) & 1); + } + printf("\n"); +#endif + #ifdef DEBUG_POLAR_ENCODER printf("Polar encoder: (N,K) : (%d,%d)\n",polarParams->N,polarParams->K); @@ -726,6 +830,19 @@ void polar_encoder_fast(uint64_t *A, memset((void*)out,0,polarParams->encoderLength>>3); polar_rate_matching(polarParams,(void *)D, out); - polarReturn; +#ifdef POLAR_CODING_DEBUG + uint64_t *out64 = (uint64_t *)out; + printf("rm:"); + for (int n = 0; n < polarParams->encoderLength; n++) { + if (n % 4 == 0) { + printf(" "); + } + int n1 = n >> 6; + int n2 = n - (n1 << 6); + printf("%lu", (out64[n1] >> n2) & 1); + } + printf("\n"); +#endif + polarReturn; } From 98ed514cab0e538d53888ed5e10a640eefde884c Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Tue, 9 May 2023 11:09:40 +0100 Subject: [PATCH 2/8] Implementation for de-interleaving of coded bits --- .../CODING/nrPolar_tools/nr_polar_decoder.c | 2 +- .../PHY/CODING/nrPolar_tools/nr_polar_defs.h | 9 +- .../nrPolar_tools/nr_polar_procedures.c | 82 +++++++++++++++---- 3 files changed, 73 insertions(+), 20 deletions(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 62ce034f59..289a9fe51d 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -612,7 +612,7 @@ uint32_t polar_decoder_int16(int16_t *input, { t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, true); int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); - nr_polar_rate_matching_int16(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); + nr_polar_rate_matching_int16(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength, polarParams->i_bil); for (int i=0; iN; i++) { if (d_tilde[i]<-128) d_tilde[i]=-128; diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index 8a86661cf5..225990133e 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -238,10 +238,11 @@ void nr_polar_rate_matching(double *input, void nr_polar_rate_matching_int16(int16_t *input, int16_t *output, - uint16_t *rmp, - uint16_t K, - uint16_t N, - uint16_t E); + const uint16_t *rmp, + const uint16_t K, + const uint16_t N, + const uint16_t E, + const uint8_t i_bil); void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c index 26832fd70c..75ae8805ab 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c @@ -325,23 +325,75 @@ void nr_polar_rate_matching(double *input, } } -void nr_polar_rate_matching_int16(int16_t *input, - int16_t *output, - uint16_t *rmp, - uint16_t K, - uint16_t N, - uint16_t E) +/* + * De-interleaving of coded bits implementation + * TS 138.212: Section 5.4.1.3 - Interleaving of coded bits + */ +void nr_polar_rm_deinterleaving_cb(const int16_t *in, int16_t *out, const uint16_t E) { - if (E>=N) { //repetition - memset((void*)output,0,N*sizeof(int16_t)); - for (int i=0; i<=E-1; i++) output[rmp[i]]+=input[i]; - } else { - if ( (K/(double)E) <= (7.0/16) ) memset((void*)output,0,N*sizeof(int16_t)); //puncturing - else { //shortening - for (int i=0; i<=N-1; i++) output[i]=32767;//instead of INFINITY, to prevent [-Woverflow] + int T = ceil((sqrt(8 * E + 1) - 1) / 2); + int v_tab[T][T]; + int k = 0; + for (int i = 0; i < T; i++) { + memset(v_tab[i], 0, T * sizeof(int)); + for (int j = 0; j < T - i; j++) { + if (k < E) { + v_tab[i][j] = k + 1; + } + k++; } + } - for (int i=0; i<=E-1; i++) output[rmp[i]]=input[i]; - + int v[T][T]; + k = 0; + for (int j = 0; j < T; j++) { + for (int i = 0; i < T - j; i++) { + if (k < E && v_tab[i][j] != 0) { + v[i][j] = in[E - 1 - k]; + k++; + } else { + v[i][j] = INT_MAX; + } + } + } + + k = 0; + memset(out, 0, E * sizeof(int16_t)); + for (int i = 0; i < T; i++) { + for (int j = 0; j < T - i; j++) { + if (v[i][j] != INT_MAX) { + out[E - 1 - k] = v[i][j]; + k++; + } + } + } +} + +void nr_polar_rate_matching_int16(int16_t *input, + int16_t *output, + const uint16_t *rmp, + const uint16_t K, + const uint16_t N, + const uint16_t E, + const uint8_t i_bil) +{ + if (i_bil == 1) { + nr_polar_rm_deinterleaving_cb(input, input, E); + } + + if (E >= N) { // repetition + memset((void *)output, 0, N * sizeof(int16_t)); + for (int i = 0; i <= E - 1; i++) + output[rmp[i]] += input[i]; + } else { + if ((K / (double)E) <= (7.0 / 16)) + memset((void *)output, 0, N * sizeof(int16_t)); // puncturing + else { // shortening + for (int i = 0; i <= N - 1; i++) + output[i] = 32767; // instead of INFINITY, to prevent [-Woverflow] + } + + for (int i = 0; i <= E - 1; i++) + output[rmp[i]] = input[i]; } } From d6b7b6b91882e4784e3c4b807853bec12984e3a6 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Tue, 23 May 2023 14:56:10 +0100 Subject: [PATCH 3/8] Q_PC_N computation for n_pc_wm = 0 --- .../PHY/CODING/nrPolar_tools/nr_polar_defs.h | 6 +- .../nrPolar_tools/nr_polar_procedures.c | 87 ++++++++++--------- openair1/PHY/CODING/nr_polar_init.c | 5 +- 3 files changed, 56 insertions(+), 42 deletions(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index 225990133e..a2413d75b9 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -251,12 +251,14 @@ void nr_polar_interleaving_pattern(uint16_t K, void nr_polar_info_bit_pattern(uint8_t *ibp, int16_t *Q_I_N, int16_t *Q_F_N, - uint16_t *J, + int16_t *Q_PC_N, + const uint16_t *J, const uint16_t *Q_0_Nminus1, uint16_t K, uint16_t N, uint16_t E, - uint8_t n_PC); + uint8_t n_PC, + uint8_t n_pc_wm); void nr_polar_info_bit_extraction(uint8_t *input, uint8_t *output, diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c index 75ae8805ab..91e4ef3158 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c @@ -138,14 +138,16 @@ void nr_polar_channel_interleaver_pattern(uint16_t *cip, void nr_polar_info_bit_pattern(uint8_t *ibp, - int16_t *Q_I_N, - int16_t *Q_F_N, - uint16_t *J, - const uint16_t *Q_0_Nminus1, - uint16_t K, - uint16_t N, - uint16_t E, - uint8_t n_PC) + int16_t *Q_I_N, + int16_t *Q_F_N, + int16_t *Q_PC_N, + const uint16_t *J, + const uint16_t *Q_0_Nminus1, + uint16_t K, + uint16_t N, + uint16_t E, + uint8_t n_PC, + uint8_t n_pc_wm) { int16_t *Q_Ftmp_N = malloc(sizeof(int16_t) * (N + 1)); // Last element shows the final int16_t *Q_Itmp_N = malloc(sizeof(int16_t) * (N + 1)); // array index assigned a value. @@ -159,44 +161,44 @@ void nr_polar_info_bit_pattern(uint8_t *ibp, uint16_t limit, ind; if (E < N) { - if ((K / (double) E) <= (7.0 / 16)) { //puncturing + if ((K / (double)E) <= (7.0 / 16)) { // puncturing for (int n = 0; n <= N - E - 1; n++) { - ind = Q_Ftmp_N[N] + 1; - Q_Ftmp_N[ind] = J[n]; - Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1; + ind = Q_Ftmp_N[N] + 1; + Q_Ftmp_N[ind] = J[n]; + Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1; } - if ((E / (double) N) >= (3.0 / 4)) { - limit = ceil((double) (3 * N - 2 * E) / 4); - for (int n = 0; n <= limit - 1; n++) { - ind = Q_Ftmp_N[N] + 1; - Q_Ftmp_N[ind] = n; - Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1; - } + if ((E / (double)N) >= (3.0 / 4)) { + limit = ceil((double)(3 * N - 2 * E) / 4); + for (int n = 0; n <= limit - 1; n++) { + ind = Q_Ftmp_N[N] + 1; + Q_Ftmp_N[ind] = n; + Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1; + } } else { - limit = ceil((double) (9 * N - 4 * E) / 16); - for (int n = 0; n <= limit - 1; n++) { - ind = Q_Ftmp_N[N] + 1; - Q_Ftmp_N[ind] = n; - Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1; - } + limit = ceil((double)(9 * N - 4 * E) / 16); + for (int n = 0; n <= limit - 1; n++) { + ind = Q_Ftmp_N[N] + 1; + Q_Ftmp_N[ind] = n; + Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1; + } } - } else { //shortening + } else { // shortening for (int n = E; n <= N - 1; n++) { - ind = Q_Ftmp_N[N] + 1; - Q_Ftmp_N[ind] = J[n]; - Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1; + ind = Q_Ftmp_N[N] + 1; + Q_Ftmp_N[ind] = J[n]; + Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1; } } } - //Q_I,tmp_N = Q_0_N-1 \ Q_F,tmp_N + // Q_I,tmp_N = Q_0_N-1 \ Q_F,tmp_N for (int n = 0; n <= N - 1; n++) { flag = 1; for (int m = 0; m <= Q_Ftmp_N[N]; m++) { if (Q_0_Nminus1[n] == Q_Ftmp_N[m]) { - flag = 0; - break; + flag = 0; + break; } } if (flag) { @@ -205,19 +207,26 @@ void nr_polar_info_bit_pattern(uint8_t *ibp, } } - //Q_I_N comprises (K+n_PC) most reliable bit indices in Q_I,tmp_N + // Q_I_N comprises (K+n_PC) most reliable bit indices in Q_I,tmp_N for (int n = 0; n <= (K + n_PC) - 1; n++) { ind = Q_Itmp_N[N] + n - ((K + n_PC) - 1); Q_I_N[n] = Q_Itmp_N[ind]; } - //Q_F_N = Q_0_N-1 \ Q_I_N + if (n_PC > 0) { + AssertFatal(n_pc_wm == 0, "Q_PC_N computation for n_pc_wm = %i is not implemented yet!\n", n_pc_wm); + for (int n = 0; n < n_PC - n_pc_wm; n++) { + Q_PC_N[n] = Q_I_N[n]; + } + } + + // Q_F_N = Q_0_N-1 \ Q_I_N for (int n = 0; n <= N - 1; n++) { flag = 1; for (int m = 0; m <= (K + n_PC) - 1; m++) { if (Q_0_Nminus1[n] == Q_I_N[m]) { - flag = 0; - break; + flag = 0; + break; } } if (flag) { @@ -226,14 +235,14 @@ void nr_polar_info_bit_pattern(uint8_t *ibp, } } - //Information Bit Pattern + // Information Bit Pattern for (int n = 0; n <= N - 1; n++) { ibp[n] = 0; for (int m = 0; m <= (K + n_PC) - 1; m++) { if (n == Q_I_N[m]) { - ibp[n] = 1; - break; + ibp[n] = 1; + break; } } } diff --git a/openair1/PHY/CODING/nr_polar_init.c b/openair1/PHY/CODING/nr_polar_init.c index 4a88417a13..ea01177c58 100644 --- a/openair1/PHY/CODING/nr_polar_init.c +++ b/openair1/PHY/CODING/nr_polar_init.c @@ -244,12 +244,15 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui nr_polar_info_bit_pattern(newPolarInitNode->information_bit_pattern, newPolarInitNode->Q_I_N, newPolarInitNode->Q_F_N, + newPolarInitNode->Q_PC_N, J, newPolarInitNode->Q_0_Nminus1, newPolarInitNode->K, newPolarInitNode->N, newPolarInitNode->encoderLength, - newPolarInitNode->n_pc); + newPolarInitNode->n_pc, + newPolarInitNode->n_pc_wm); + // sort the Q_I_N array in ascending order (first K positions) qsort((void *)newPolarInitNode->Q_I_N,newPolarInitNode->K,sizeof(int16_t),intcmp); newPolarInitNode->channel_interleaver_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength); From fb7d4dc4dffd8cc6d80b6e3b709c9ac55533a5e5 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Wed, 24 May 2023 15:01:58 +0100 Subject: [PATCH 4/8] Compute parity_check_bit_pattern and implementation of function nr_polar_generate_u() and nr_polar_uxG() --- .../PHY/CODING/nrPolar_tools/nr_polar_defs.h | 11 + .../CODING/nrPolar_tools/nr_polar_encoder.c | 226 ++++-------------- .../nrPolar_tools/nr_polar_procedures.c | 92 ++++++- openair1/PHY/CODING/nr_polar_init.c | 9 +- 4 files changed, 160 insertions(+), 178 deletions(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index a2413d75b9..4d389e9468 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -106,6 +106,7 @@ struct nrPolar_params { int16_t *Q_F_N; int16_t *Q_PC_N; uint8_t *information_bit_pattern; + uint8_t *parity_check_bit_pattern; uint16_t *channel_interleaver_pattern; //uint32_t crc_polynomial; @@ -249,6 +250,7 @@ void nr_polar_interleaving_pattern(uint16_t K, uint16_t *PI_k_); void nr_polar_info_bit_pattern(uint8_t *ibp, + uint8_t *pcbp, int16_t *Q_I_N, int16_t *Q_F_N, int16_t *Q_PC_N, @@ -275,6 +277,15 @@ void nr_byte2bit_uint8_32(uint8_t *in, const uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits); +void nr_polar_generate_u(uint64_t *u, + const uint64_t *Cprime, + const uint8_t *information_bit_pattern, + const uint8_t *parity_check_bit_pattern, + uint16_t N, + uint8_t n_pc); + +void nr_polar_uxG(uint64_t *D, const uint64_t *u, const uint64_t **G_N_tab, uint16_t N); + void nr_polar_bit_insertion(uint8_t *input, uint8_t *output, uint16_t N, diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c index b22cc97ccc..ea476c0d38 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c @@ -387,28 +387,27 @@ void build_polar_tables(t_nrPolar_params *polarParams) { 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 *)); - int k=0; + // 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. + polarParams->G_N_tab = (uint64_t **)calloc(polarParams->N, sizeof(int64_t *)); - for (int i=0; iN; i++) { - if (polarParams->information_bit_pattern[i] > 0) { - polarParams->G_N_tab[k] = (uint64_t *)memalign(32,(polarParams->N/64)*sizeof(uint64_t)); - memset((void *)polarParams->G_N_tab[k],0,(polarParams->N/64)*sizeof(uint64_t)); + for (int i = 0; i < polarParams->N; i++) { + polarParams->G_N_tab[i] = (uint64_t *)memalign(32, (polarParams->N / 64) * sizeof(uint64_t)); + memset((void *)polarParams->G_N_tab[i], 0, (polarParams->N / 64) * sizeof(uint64_t)); - for (int j=0; jN; j++) - polarParams->G_N_tab[k][j/64] |= ((uint64_t)polarParams->G_N[i][j])<<(j&63); + for (int j = 0; j < polarParams->N; j++) + polarParams->G_N_tab[i][j / 64] |= ((uint64_t)polarParams->G_N[i][j]) << (j & 63); #ifdef DEBUG_POLAR_ENCODER - printf("Bit %d Selecting row %d of G : ",k,i); + printf("Bit %d Selecting row %d of G : ", i, i); - for (int j=0; jN; j+=4) printf("%1x",polarParams->G_N[i][j]+(polarParams->G_N[i][j+1]*2)+(polarParams->G_N[i][j+2]*4)+(polarParams->G_N[i][j+3]*8)); + for (int j = 0; j < polarParams->N; j += 4) + printf("%1x", + polarParams->G_N[i][j] + (polarParams->G_N[i][j + 1] * 2) + (polarParams->G_N[i][j + 2] * 4) + + (polarParams->G_N[i][j + 3] * 8)); - printf("\n"); + printf("\n"); #endif - k++; - } } // rate matching table @@ -601,7 +600,6 @@ void polar_encoder_fast(uint64_t *A, tcrc = (uint64_t)((crcmask^(crc11(A128_flip,bitlen)>>21)))&0x7ff; } - int n; // this is number of quadwords in the bit string int quadwlen = (polarParams->K+63)/64; @@ -611,7 +609,7 @@ void polar_encoder_fast(uint64_t *A, //??? b_{N'-1} b_{N'-2} ... b_{N'-A} b_{N'-A-1} ... b_{N'-A-Nparity} = a_{N-1} a_{N-2} ... a_{N-A} p_{N_parity-1} ... p_0 uint64_t B[4]= {0}; B[0] = (A[0] << polarParams->crcParityBits) | tcrc; - for (n=1; n n) B[n] = (A[n] << polarParams->crcParityBits) | (A[n-1]>>(64-polarParams->crcParityBits)); else @@ -633,21 +631,21 @@ void polar_encoder_fast(uint64_t *A, printf("\n"); #endif - uint8_t *Bbyte = (uint8_t *)B; - - // for each byte of B, lookup in corresponding table for 64-bit word corresponding to that byte and its position + // TS 38.212 - Section 5.3.1.1 Interleaving + // For each byte of B, lookup in corresponding table for 64-bit word corresponding to that byte and its position uint64_t Cprime[4]= {0}; - if (polarParams->K<65) + uint8_t *Bbyte = (uint8_t *)B; + if (polarParams->K < 65) { Cprime[0] = polarParams->cprime_tab0[0][Bbyte[0]] | - polarParams->cprime_tab0[1][Bbyte[1]] | + polarParams->cprime_tab0[1][Bbyte[1]] | polarParams->cprime_tab0[2][Bbyte[2]] | polarParams->cprime_tab0[3][Bbyte[3]] | polarParams->cprime_tab0[4][Bbyte[4]] | polarParams->cprime_tab0[5][Bbyte[5]] | polarParams->cprime_tab0[6][Bbyte[6]] | polarParams->cprime_tab0[7][Bbyte[7]]; - else if (polarParams->K < 129) { - for (int i=0; i<1+(polarParams->K/8); i++) { + } else if (polarParams->K < 129) { + for (int i = 0; i < 1 + (polarParams->K / 8); i++) { Cprime[0] |= polarParams->cprime_tab0[i][Bbyte[i]]; Cprime[1] |= polarParams->cprime_tab1[i][Bbyte[i]]; } @@ -671,162 +669,44 @@ void polar_encoder_fast(uint64_t *A, printf("\n"); #endif -#ifdef DEBUG_POLAR_ENCODER + uint64_t u[16] = {0}; + nr_polar_generate_u(u, + Cprime, + polarParams->information_bit_pattern, + polarParams->parity_check_bit_pattern, + polarParams->N, + polarParams->n_pc); - printf("Polar encoder: (N,K) : (%d,%d)\n",polarParams->N,polarParams->K); - if (polarParams->K<65) - printf("A %llx B %llx Cprime %llx (payload bits %d,crc %lx)\n", - (unsigned long long)(A[0]&(((uint64_t)1<payloadBits, - tcrc); - else if (polarParams->K<129) { - if (bitlen<64) - printf("A %llx B %llx|%llx Cprime %llx|%llx (payload bits %d,crc %lx)\n", - (unsigned long long)(A[0]&(((uint64_t)1<payloadBits, - tcrc); - else - printf("A %llx|%llx B %llx|%llx Cprime %llx|%llx (payload bits %d,crc %x)\n", - (unsigned long long)(A[1]&(((uint64_t)1<<(bitlen-64))-1)),(unsigned long long)(A[0]), - (unsigned long long)(B[1]),(unsigned long long)(B[0]), - (unsigned long long)(Cprime[1]),(unsigned long long)(Cprime[0]), - polarParams->payloadBits, - crc24c((uint8_t *)A,bitlen)>>8); +#ifdef POLAR_CODING_DEBUG + int N_array = polarParams->N >> 6; + printf("u: "); + for (int n = 0; n < polarParams->N; n++) { + if (n % 4 == 0) { + printf(" "); + } + int n1 = n >> 6; + int n2 = n - (n1 << 6); + printf("%lu", (u[N_array - 1 - n1] >> (63 - n2)) & 1); } + printf("\n"); +#endif - #endif - /* printf("Bbytes : %x.%x.%x.%x.%x.%x.%x.%x\n",Bbyte[0],Bbyte[1],Bbyte[2],Bbyte[3],Bbyte[4],Bbyte[5],Bbyte[6],Bbyte[7]); - printf("%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",polarParams->cprime_tab[0][Bbyte[0]] , - polarParams->cprime_tab[1][Bbyte[1]] , - polarParams->cprime_tab[2][Bbyte[2]] , - polarParams->cprime_tab[3][Bbyte[3]] , - polarParams->cprime_tab[4][Bbyte[4]] , - polarParams->cprime_tab[5][Bbyte[5]] , - polarParams->cprime_tab[6][Bbyte[6]] , - polarParams->cprime_tab[7][Bbyte[7]]);*/ - // now do Gu product (here using 64-bit XORs, we can also do with SIMD after) - // here we're reading out the bits LSB -> MSB, is this correct w.r.t. 3GPP ? - uint64_t Cprime_i; - /* printf("%llx Cprime_0 (%llx) G %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",Cprime_i,Cprime &1, - polarParams->G_N_tab[0][0], - polarParams->G_N_tab[0][1], - polarParams->G_N_tab[0][2], - polarParams->G_N_tab[0][3], - polarParams->G_N_tab[0][4], - polarParams->G_N_tab[0][5], - polarParams->G_N_tab[0][6], - polarParams->G_N_tab[0][7]);*/ - uint64_t D[8]= {0,0,0,0,0,0,0,0}; - int off=0; - int len=polarParams->K; + uint64_t D[8] = {0}; + nr_polar_uxG(D, u, (const uint64_t **)polarParams->G_N_tab, polarParams->N); - if (polarParams->N==512) { - for (int j=0; j<(1+(polarParams->K>>6)); j++,off+=64,len-=64) { - for (int i=0; i<((len>63) ? 64 : len); i++) { - Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11 - /* - #ifdef DEBUG_POLAR_ENCODER - printf("%llx Cprime_%d (%llx) G %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n", - Cprime_i,off+i,(Cprime[j]>>i) &1, - polarParams->G_N_tab[off+i][0], - polarParams->G_N_tab[off+i][1], - polarParams->G_N_tab[off+i][2], - polarParams->G_N_tab[off+i][3], - polarParams->G_N_tab[off+i][4], - polarParams->G_N_tab[off+i][5], - polarParams->G_N_tab[off+i][6], - polarParams->G_N_tab[off+i][7]); - #endif - */ - uint64_t *Gi=polarParams->G_N_tab[off+i]; - D[0] ^= (Cprime_i & Gi[0]); - D[1] ^= (Cprime_i & Gi[1]); - D[2] ^= (Cprime_i & Gi[2]); - D[3] ^= (Cprime_i & Gi[3]); - D[4] ^= (Cprime_i & Gi[4]); - D[5] ^= (Cprime_i & Gi[5]); - D[6] ^= (Cprime_i & Gi[6]); - D[7] ^= (Cprime_i & Gi[7]); - -#ifdef DEBUG_POLAR_ENCODER - printf("D %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n", - D[0], - D[1], - D[2], - D[3], - D[4], - D[5], - D[6], - D[7]); -#endif - } +#ifdef POLAR_CODING_DEBUG + printf("d: "); + for (int n = 0; n < polarParams->N; n++) { + if (n % 4 == 0) { + printf(" "); } + int n1 = n >> 6; + int n2 = n - (n1 << 6); + printf("%lu", (D[n1] >> n2) & 1); } - else if (polarParams->N==256) { - for (int j=0; j<(1+(polarParams->K>>6)); j++,off+=64,len-=64) { - for (int i=0; i<((len>63) ? 64 : len); i++) { - Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11 - /* - #ifdef DEBUG_POLAR_ENCODER - printf("%llx Cprime_%d (%llx) G %llx,%llx,%llx,%llx\n", - Cprime_i,off+i,(Cprime[j]>>i) &1, - polarParams->G_N_tab[off+i][0], - polarParams->G_N_tab[off+i][1], - polarParams->G_N_tab[off+i][2], - polarParams->G_N_tab[off+i][3], - #endif - */ - uint64_t *Gi=polarParams->G_N_tab[off+i]; - D[0] ^= (Cprime_i & Gi[0]); - D[1] ^= (Cprime_i & Gi[1]); - D[2] ^= (Cprime_i & Gi[2]); - D[3] ^= (Cprime_i & Gi[3]); - - -#ifdef DEBUG_POLAR_ENCODER - printf("D %llx,%llx,%llx,%llx\n", - D[0], - D[1], - D[2], - D[3]); + printf("\n"); #endif - } - } - } - else if (polarParams->N==128) { - for (int j=0; j<(1+(polarParams->K>>6)); j++,off+=64,len-=64) { - for (int i=0; i<((len>63) ? 64 : len); i++) { - Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11 - - #ifdef DEBUG_POLAR_ENCODER - printf("%lx Cprime_%d (%d+%d) (%llx) G %llx,%llx\n", - Cprime_i,off+i,off,i,(Cprime[j]>>i) &1, - polarParams->G_N_tab[off+i][0], - polarParams->G_N_tab[off+i][1]); - #endif - - uint64_t *Gi=polarParams->G_N_tab[off+i]; - D[0] ^= (Cprime_i & Gi[0]); - D[1] ^= (Cprime_i & Gi[1]); - - -#ifdef DEBUG_POLAR_ENCODER - printf("D %llx,%llx\n", - D[0], - D[1]); -#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); diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c index 91e4ef3158..85e32a033f 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c @@ -32,6 +32,84 @@ #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" + +// TS 38.212 - Section 5.3.1.2 Polar encoding +void nr_polar_generate_u(uint64_t *u, + const uint64_t *Cprime, + const uint8_t *information_bit_pattern, + const uint8_t *parity_check_bit_pattern, + uint16_t N, + uint8_t n_pc) +{ + int N_array = N >> 6; + int k = 0; + + if (n_pc > 0) { + uint64_t y0 = 0, y1 = 0, y2 = 0, y3 = 0, y4 = 0; + + for (int n = 0; n < N; n++) { + uint64_t yt = y0; + y0 = y1; + y1 = y2; + y2 = y3; + y3 = y4; + y4 = yt; + + if (information_bit_pattern[n] == 1) { + int n1 = n >> 6; + int n2 = n - (n1 << 6); + if (parity_check_bit_pattern[n] == 1) { + u[N_array - 1 - n1] |= y0 << (63 - n2); + } else { + int k1 = k >> 6; + int k2 = k - (k1 << 6); + uint64_t bit = (Cprime[k1] >> k2) & 1; + u[N_array - 1 - n1] |= bit << (63 - n2); + k++; + y0 = y0 ^ (int)bit; + } + } + } + + } else { + for (int n = 0; n < N; n++) { + if (information_bit_pattern[n] == 1) { + int n1 = n >> 6; + int n2 = n - (n1 << 6); + int k1 = k >> 6; + int k2 = k - (k1 << 6); + uint64_t bit = (Cprime[k1] >> k2) & 1; + u[N_array - 1 - n1] |= bit << (63 - n2); + k++; + } + } + } +} + +void nr_polar_uxG(uint64_t *D, const uint64_t *u, const uint64_t **G_N_tab, uint16_t N) +{ + int N_array = N >> 6; + + for (int n = 0; n < N; n++) { + const uint64_t *Gn = G_N_tab[N - 1 - n]; + + int n_ones = 0; + for (int a = 0; a < N_array; a++) { + uint64_t uxG = u[a] & Gn[a]; + for (int m = 0; m < 64; m++) { + if (((uxG >> m) & 1) == 1) { + n_ones++; + } + } + } + uint64_t bit = n_ones % 2; + + int n1 = n >> 6; + int n2 = n - (n1 << 6); + D[n1] |= bit << n2; + } +} + void nr_polar_bit_insertion(uint8_t *input, uint8_t *output, uint16_t N, @@ -138,6 +216,7 @@ void nr_polar_channel_interleaver_pattern(uint16_t *cip, void nr_polar_info_bit_pattern(uint8_t *ibp, + uint8_t *pcbp, int16_t *Q_I_N, int16_t *Q_F_N, int16_t *Q_PC_N, @@ -235,16 +314,25 @@ void nr_polar_info_bit_pattern(uint8_t *ibp, } } - // Information Bit Pattern + // Information and Parity Chack Bit Pattern for (int n = 0; n <= N - 1; n++) { - ibp[n] = 0; + ibp[n] = 0; for (int m = 0; m <= (K + n_PC) - 1; m++) { if (n == Q_I_N[m]) { ibp[n] = 1; break; } } + + pcbp[n] = 0; + for (int m = 0; m < n_PC - n_pc_wm; m++) { + if (n == Q_PC_N[m]) { + pcbp[n] = 1; + break; + } + } + } free(Q_Ftmp_N); diff --git a/openair1/PHY/CODING/nr_polar_init.c b/openair1/PHY/CODING/nr_polar_init.c index ea01177c58..bbc51f416b 100644 --- a/openair1/PHY/CODING/nr_polar_init.c +++ b/openair1/PHY/CODING/nr_polar_init.c @@ -49,9 +49,9 @@ static void nr_polar_delete_list(t_nrPolar_params * polarParams) { delete_decoder_tree(polarParams); //From build_polar_tables() - for (int k=0; k < polarParams->K + polarParams->n_pc; k++) - if (polarParams->G_N_tab[k]) - free(polarParams->G_N_tab[k]); + for (int n=0; n < polarParams->N; n++) + if (polarParams->G_N_tab[n]) + free(polarParams->G_N_tab[n]); free(polarParams->G_N_tab); free(polarParams->rm_tab); if (polarParams->crc_generator_matrix) @@ -71,6 +71,7 @@ static void nr_polar_delete_list(t_nrPolar_params * polarParams) { free(polarParams->deinterleaving_pattern); free(polarParams->rate_matching_pattern); free(polarParams->information_bit_pattern); + free(polarParams->parity_check_bit_pattern); free(polarParams->Q_I_N); free(polarParams->Q_F_N); free(polarParams->Q_PC_N); @@ -234,6 +235,7 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui newPolarInitNode->N, newPolarInitNode->encoderLength); newPolarInitNode->information_bit_pattern = malloc(sizeof(uint8_t) * newPolarInitNode->N); + newPolarInitNode->parity_check_bit_pattern = malloc(sizeof(uint8_t) * newPolarInitNode->N); newPolarInitNode->Q_I_N = malloc(sizeof(int16_t) * (newPolarInitNode->K + newPolarInitNode->n_pc)); newPolarInitNode->Q_F_N = malloc( sizeof(int16_t) * (newPolarInitNode->N + 1)); // Last element shows the final array index assigned a value. newPolarInitNode->Q_PC_N = malloc( sizeof(int16_t) * (newPolarInitNode->n_pc)); @@ -242,6 +244,7 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui newPolarInitNode->Q_F_N[i] = -1; // Empty array. nr_polar_info_bit_pattern(newPolarInitNode->information_bit_pattern, + newPolarInitNode->parity_check_bit_pattern, newPolarInitNode->Q_I_N, newPolarInitNode->Q_F_N, newPolarInitNode->Q_PC_N, From b722d92fa0a9cdd553b45d5b7c4f3194930f2780 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Thu, 25 May 2023 19:15:18 +0100 Subject: [PATCH 5/8] Extract the information bits from U --- .../CODING/nrPolar_tools/nr_polar_decoder.c | 98 +++++++++++++++++-- .../PHY/CODING/nrPolar_tools/nr_polar_defs.h | 7 ++ .../nrPolar_tools/nr_polar_procedures.c | 37 ++++++- openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c | 15 ++- 4 files changed, 148 insertions(+), 9 deletions(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 289a9fe51d..18de88db79 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -39,6 +39,8 @@ #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "assertions.h" +//#define POLAR_CODING_DEBUG + static inline void updateCrcChecksum2(int xlen, int ylen, uint8_t crcChecksum[xlen][ylen], @@ -611,6 +613,19 @@ uint32_t polar_decoder_int16(int16_t *input, uint8_t aggregation_level ) { t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, true); + +#ifdef POLAR_CODING_DEBUG + printf("\nRX\n"); + printf("rm:"); + for (int i = 0; i < polarParams->N; i++) { + if (i % 4 == 0) { + printf(" "); + } + printf("%i", input[i] < 0 ? 1 : 0); + } + printf("\n"); +#endif + int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); nr_polar_rate_matching_int16(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength, polarParams->i_bil); @@ -619,16 +634,57 @@ uint32_t polar_decoder_int16(int16_t *input, 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); - generic_polar_decoder(polarParams,polarParams->tree.root); - //Extract the information bits (û to ĉ) - uint64_t Cprime[4]= {0,0,0,0}; - uint64_t B[4]= {0,0,0,0}; +#ifdef POLAR_CODING_DEBUG + printf("d: "); + for (int i = 0; i < polarParams->N; i++) { + if (i % 4 == 0) { + printf(" "); + } + printf("%i", d_tilde[i] < 0 ? 1 : 0); + } + printf("\n"); +#endif - for (int i=0; iK; i++) Cprime[i>>6] = Cprime[i>>6] | ((uint64_t)polarParams->nr_polar_U[polarParams->Q_I_N[i]])<<(i&63); + memcpy((void *)&polarParams->tree.root->alpha[0], (void *)&d_tilde[0], sizeof(int16_t) * polarParams->N); + memset(polarParams->nr_polar_U, 0, polarParams->N * sizeof(uint8_t)); + generic_polar_decoder(polarParams, polarParams->tree.root); + +#ifdef POLAR_CODING_DEBUG + printf("u: "); + for (int i = 0; i < polarParams->N; i++) { + if (i % 4 == 0) { + printf(" "); + } + printf("%i", polarParams->nr_polar_U[i]); + } + printf("\n"); +#endif + + // Extract the information bits (û to ĉ) + uint64_t Cprime[4]= {0}; + nr_polar_info_extraction_from_u(Cprime, + polarParams->nr_polar_U, + polarParams->information_bit_pattern, + polarParams->parity_check_bit_pattern, + polarParams->N, + polarParams->n_pc); + +#ifdef POLAR_CODING_DEBUG + printf("c: "); + for (int n = 0; n < polarParams->K; n++) { + if (n % 4 == 0) { + printf(" "); + } + int n1 = n >> 6; + int n2 = n - (n1 << 6); + printf("%lu", (Cprime[n1] >> n2) & 1); + } + printf("\n"); +#endif //Deinterleaving (ĉ to b) uint8_t *Cprimebyte = (uint8_t *)Cprime; + uint64_t B[4] = {0}; if (polarParams->K<65) { B[0] = polarParams->B_tab0[0][Cprimebyte[0]] | @@ -650,6 +706,21 @@ uint32_t polar_decoder_int16(int16_t *input, } } +#ifdef POLAR_CODING_DEBUG + int B_array = (polarParams->K + 63) >> 6; + int n_start = (B_array << 6) - polarParams->K; + printf("b: "); + for (int n = 0; n < polarParams->K; n++) { + if (n % 4 == 0) { + printf(" "); + } + int n1 = (n + n_start) >> 6; + int n2 = (n + n_start) - (n1 << 6); + printf("%lu", (B[B_array - 1 - n1] >> (63 - n2)) & 1); + } + printf("\n"); +#endif + int len=polarParams->payloadBits; //int len_mod64=len&63; int crclen = polarParams->crcParityBits; @@ -700,6 +771,21 @@ uint32_t polar_decoder_int16(int16_t *input, else if (crclen==6) crc = (uint64_t)(crc6(A64_flip,8*offset+len)>>26)&0x3f; } +#ifdef POLAR_CODING_DEBUG + int A_array = (len + 63) >> 6; + printf("a: "); + for (int n = 0; n < len; n++) { + if (n % 4 == 0) { + printf(" "); + } + int n1 = n >> 6; + int n2 = n - (n1 << 6); + int alen = n1 == 0 ? len - (A_array << 6) : 64; + printf("%lu", (Ar >> (alen - 1 - n2)) & 1); + } + printf("\n\n"); +#endif + #if 0 printf("A %llx B %llx|%llx Cprime %llx|%llx (crc %x,rxcrc %llx %d)\n", Ar, diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index 4d389e9468..e48a205889 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -286,6 +286,13 @@ void nr_polar_generate_u(uint64_t *u, void nr_polar_uxG(uint64_t *D, const uint64_t *u, const uint64_t **G_N_tab, uint16_t N); +void nr_polar_info_extraction_from_u(uint64_t *Cprime, + const uint8_t *u, + const uint8_t *information_bit_pattern, + const uint8_t *parity_check_bit_pattern, + uint16_t N, + uint8_t n_pc); + void nr_polar_bit_insertion(uint8_t *input, uint8_t *output, uint16_t N, diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c index 85e32a033f..4df7557495 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c @@ -86,6 +86,39 @@ void nr_polar_generate_u(uint64_t *u, } } +void nr_polar_info_extraction_from_u(uint64_t *Cprime, + const uint8_t *u, + const uint8_t *information_bit_pattern, + const uint8_t *parity_check_bit_pattern, + uint16_t N, + uint8_t n_pc) +{ + int k = 0; + + if (n_pc > 0) { + for (int n = 0; n < N; n++) { + if (information_bit_pattern[n] == 1) { + if (parity_check_bit_pattern[n] == 0) { + int k1 = k >> 6; + int k2 = k - (k1 << 6); + Cprime[k1] |= (uint64_t)u[n] << k2; + k++; + } + } + } + + } else { + for (int n = 0; n < N; n++) { + if (information_bit_pattern[n] == 1) { + int k1 = k >> 6; + int k2 = k - (k1 << 6); + Cprime[k1] |= (uint64_t)u[n] << k2; + k++; + } + } + } +} + void nr_polar_uxG(uint64_t *D, const uint64_t *u, const uint64_t **G_N_tab, uint16_t N) { int N_array = N >> 6; @@ -446,7 +479,7 @@ void nr_polar_rm_deinterleaving_cb(const int16_t *in, int16_t *out, const uint16 for (int j = 0; j < T; j++) { for (int i = 0; i < T - j; i++) { if (k < E && v_tab[i][j] != 0) { - v[i][j] = in[E - 1 - k]; + v[i][j] = in[k]; k++; } else { v[i][j] = INT_MAX; @@ -459,7 +492,7 @@ void nr_polar_rm_deinterleaving_cb(const int16_t *in, int16_t *out, const uint16 for (int i = 0; i < T; i++) { for (int j = 0; j < T - i; j++) { if (v[i][j] != INT_MAX) { - out[E - 1 - k] = v[i][j]; + out[k] = v[i][j]; k++; } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c index 818954bc29..139f1b7005 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c @@ -49,6 +49,7 @@ #endif //#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) +//#define POLAR_CODING_DEBUG void nr_generate_pucch0(PHY_VARS_NR_UE *ue, c16_t **txdataF, @@ -692,7 +693,19 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue, /* * Implementing TS 38.211 Subclause 6.3.2.5.1 scrambling format 2 */ - nr_pucch2_3_4_scrambling(M_bit,rnti,pucch_pdu->data_scrambling_id,&b[0],btilde); + nr_pucch2_3_4_scrambling(M_bit, rnti, pucch_pdu->data_scrambling_id, b, btilde); + +#ifdef POLAR_CODING_DEBUG + printf("bt:"); + for (int n = 0; n < M_bit; n++) { + if (n % 4 == 0) { + printf(" "); + } + printf("%u", btilde[n]); + } + printf("\n"); +#endif + /* * Implementing TS 38.211 Subclause 6.3.2.5.2 modulation format 2 * btilde shall be modulated as described in subclause 5.1 using QPSK From 79d6a48f4794e44bab2b0003fea3996c325543c6 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Tue, 20 Jun 2023 12:49:56 +0100 Subject: [PATCH 6/8] Remove limitation related to schedule more than 11 bits in PUCCH2 --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index d7f461d231..ca59142949 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -1154,9 +1154,6 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac, if(curr_pucch->csi_bits > 0 && !curr_pucch->simultaneous_harqcsi) continue; - // TODO we can't schedule more than 11 bits in PUCCH2 for now - if (curr_pucch->csi_bits + curr_pucch->dai_c >= 10) - continue; // otherwise we can schedule in this active PUCCH // no need to check VRB occupation because already done when PUCCH has been activated From f35d613f7df52d10b62a25c9f965603fe10c1036 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Tue, 20 Jun 2023 12:50:40 +0100 Subject: [PATCH 7/8] Decrease maxCodeRate of PUCCH2 --- openair2/RRC/NR/nr_rrc_config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 789980ae36..266d842276 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -850,7 +850,7 @@ static void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config, const NR_UE_NR pucchfmt2->interslotFrequencyHopping = NULL; pucchfmt2->additionalDMRS = NULL; pucchfmt2->maxCodeRate = calloc(1,sizeof(*pucchfmt2->maxCodeRate)); - *pucchfmt2->maxCodeRate = NR_PUCCH_MaxCodeRate_zeroDot35; + *pucchfmt2->maxCodeRate = NR_PUCCH_MaxCodeRate_zeroDot15; pucchfmt2->nrofSlots = NULL; pucchfmt2->pi2BPSK = NULL; From 1d6f740cb02d30867d4e377999c3c5bf7b10c97c Mon Sep 17 00:00:00 2001 From: rmagueta Date: Fri, 30 Jun 2023 11:12:38 +0100 Subject: [PATCH 8/8] Update FEATURE_SET.md --- doc/FEATURE_SET.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index d9606c1265..f8d9c460d4 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -271,7 +271,7 @@ The following features are valid for the gNB and the 5G-NR UE. - Support for 256 QAM * NR-PUCCH - Format 0 (2 bits, for ACK/NACK and SR) - - Format 2 (up to 11 bits, mainly for CSI feedback) + - Format 2 (mainly for CSI feedback) * NR-SRS - SRS signal reception - Channel estimation (with T tracer real time monitoring) @@ -443,7 +443,7 @@ The following features are valid for the gNB and the 5G-NR UE. - Support for up to 2 layers * NR-PUCCH - Format 0 (2 bits for ACK/NACK and SR) - - Format 2 (up to 11 bits, mainly for CSI feedback) + - Format 2 (mainly for CSI feedback) - Format 1 (limited testing) - Format 3 and 4 present but old code never tested (need restructuring before verification) * NR-SRS