From d57ea715c0f7ef85bf1ec712eaf69e87a2ef872a Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 4 Sep 2024 12:19:11 +0200 Subject: [PATCH 1/8] Improve polar decoder/encoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Ensure packed struct through bitfield - decoder tree buffer increase: i don't find evidence in the 3GPP standard of the max size of polar coded PDU. even with this max size, the way this tree is built is not trivial. so, it is hard to predict, i just put 8 system pages (32KB) that looks enough [1] - a lot of reformatting [1] https://arxiv.org/pdf/1804.04389 according to this paper, the largest polar code in 5G is in UL, so likely the biggest problem will be in gNB, not the UE. in DL, the max output coded block is 512, in UL 1024. probably the tree we discuss is related to this size. "frozen bits" means only bits we don't encode/decode because polar code size is only by power of 2. We see this in OAI code: NR_POLAR_PUCCH_N_MAX is 10, so 2^10 is 1024, that is the maximum size for 5G polar code length. in the code, we assert if N > 512: "N = %d, not done yet\n", polarParams->N". so, the today OAI code can't do PUCCH large blocks. using current oai limitation of 2⁹ max code size, we can create up to 2^9+2⁸... nodes, so 1023 nodes in the tree. the problem then is that each node have variable size, depending on the 'level' (the power of 2 we are currently). the algo provision large alpha and beta to be able to store all lower levels in the tree (int leaf_sz = 1 << level) therefore upper tree nodes are large (the top level for n=9 uses about 1.5KB) and the bottom nodes uses 64 bytes. if all nodes are populated, the size will be very large: 1.5KB + 2 * 800 + .... but, we create nodes in the tree only for the "information bits", so the payload, that is limited to 128 bits (else we assert, the code is not "finished"). 1.5KB * 128 is >> 8KB i allocated. but, we can't create more than one mode at top level, so there is maximum 1.5KB + 2 * 800, + 4 * 400 + 8 * 200 + 16 * 100 + remaining of 128-32 nodes of 64 bytes. about 14KB. i allocated 1024*sizeof(__m256i) bytes = 32KB that looks good. --- openair1/PHY/CODING/TESTBENCH/polartest.c | 68 ++-- .../CODING/nrPolar_tools/nr_polar_decoder.c | 166 ++++++--- .../nrPolar_tools/nr_polar_decoding_tools.c | 330 +++++++++--------- .../PHY/CODING/nrPolar_tools/nr_polar_defs.h | 108 ++++-- .../CODING/nrPolar_tools/nr_polar_encoder.c | 6 +- .../nr_polar_interleaving_pattern.c | 6 +- .../nrPolar_tools/nr_polar_procedures.c | 107 ------ openair1/PHY/CODING/nr_polar_init.c | 20 +- 8 files changed, 404 insertions(+), 407 deletions(-) diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index cd280c236e..266f829efa 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -91,11 +91,12 @@ int main(int argc, char *argv[]) case 'L': aggregation_level=atoi(optarg); - if (aggregation_level != 1 && aggregation_level != 2 && aggregation_level != 4 && aggregation_level != 8 && aggregation_level != 16) { - printf("Illegal aggregation level %d \n",aggregation_level); - exit(-1); - } - break; + if (aggregation_level != 1 && aggregation_level != 2 && aggregation_level != 4 && aggregation_level != 8 + && aggregation_level != 16) { + printf("Illegal aggregation level %d \n", aggregation_level); + exit(-1); + } + break; case 'k': testLength=atoi(optarg); @@ -106,9 +107,10 @@ int main(int argc, char *argv[]) break; case 'h': - printf("./polartest\nOptions\n-h Print this help\n-s SNRstart (dB)\n-d SNRinc (dB)\n-f SNRstop (dB)\n-m [0=PBCH|1=DCI|2=UCI]\n" - "-i Number of iterations\n-l decoderListSize\n-q Flag for optimized coders usage\n-F Flag for test results logging\n" - "-L aggregation level (for DCI)\n-k packet_length (bits) for DCI/UCI\n"); + printf( + "./polartest\nOptions\n-h Print this help\n-s SNRstart (dB)\n-d SNRinc (dB)\n-f SNRstop (dB)\n-m [0=PBCH|1=DCI|2=UCI]\n" + "-i Number of iterations\n-l decoderListSize\n-q Flag for optimized coders usage\n-F Flag for test results logging\n" + "-L aggregation level (for DCI)\n-k packet_length (bits) for DCI/UCI\n"); exit(-1); break; @@ -186,7 +188,7 @@ int main(int argc, char *argv[]) double channelOutput[coderLength]; //add noise int16_t channelOutput_int16[coderLength]; - t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level, true); + t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level); #ifdef DEBUG_DCI_POLAR_PARAMS uint32_t dci_pdu[4]; @@ -283,30 +285,37 @@ int main(int argc, char *argv[]) channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin))); if (decoder_int16==1) { - if (channelOutput[i] > 15) channelOutput_int16[i] = 127; - else if (channelOutput[i] < -16) channelOutput_int16[i] = -128; - else channelOutput_int16[i] = (int16_t) (8*channelOutput[i]); - } + if (channelOutput[i] > 15) + channelOutput_int16[i] = 127; + else if (channelOutput[i] < -16) + channelOutput_int16[i] = -128; + else + channelOutput_int16[i] = (int16_t)(8 * channelOutput[i]); + } } start_meas(&timeDecoder); if (decoder_int16==1) { - decoderState = polar_decoder_int16(channelOutput_int16, (uint64_t *)estimatedOutput, 0, - polarMessageType, testLength, aggregation_level); + decoderState = polar_decoder_int16(channelOutput_int16, + (uint64_t *)estimatedOutput, + 0, + polarMessageType, + testLength, + aggregation_level); } else { //0 --> PBCH, 1 --> DCI, -1 --> UCI if (polarMessageType == 0) { - decoderState = polar_decoder(channelOutput, - estimatedOutput, - decoderListSize, - polarMessageType, testLength, aggregation_level); - } else if (polarMessageType == 1) { - decoderState = polar_decoder_dci(channelOutput, - estimatedOutput, - decoderListSize, - rnti, - polarMessageType, testLength, aggregation_level); - } + decoderState = + polar_decoder(channelOutput, estimatedOutput, decoderListSize, polarMessageType, testLength, aggregation_level); + } else if (polarMessageType == 1) { + decoderState = polar_decoder_dci(channelOutput, + estimatedOutput, + decoderListSize, + rnti, + polarMessageType, + testLength, + aggregation_level); + } } stop_meas(&timeDecoder); @@ -332,7 +341,12 @@ int main(int argc, char *argv[]) if (nBitError>0) blockErrorState=1; #ifdef DEBUG_POLARTEST for (int i = 0; i < testArrayLength; i++) - printf("[polartest/decoderState=%u] testInput[%d]=0x%08x, estimatedOutput[%d]=0x%08x\n",decoderState, i, testInput[i], i, estimatedOutput[i]); + printf("[polartest/decoderState=%u] testInput[%d]=0x%08x, estimatedOutput[%d]=0x%08x\n", + decoderState, + i, + testInput[i], + i, + estimatedOutput[i]); #endif //Iteration times are in microseconds. diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 5704a9e0d4..1d7e7e8373 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -66,7 +66,7 @@ int8_t polar_decoder(double *input, uint8_t aggregation_level ) { - t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, true); + t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level); //Assumes no a priori knowledge. uint8_t bit[polarParams->N][polarParams->n + 1][2 * listSize]; memset(bit, 0, sizeof bit); @@ -329,7 +329,7 @@ int8_t polar_decoder_dci(double *input, int8_t messageType, uint16_t messageLength, uint8_t aggregation_level ) { - t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, true); + t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level); uint8_t bit[polarParams->N][polarParams->n+1][2*listSize]; memset(bit,0,sizeof bit); @@ -595,25 +595,17 @@ int8_t polar_decoder_dci(double *input, void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) { AssertFatal(polarParams->K > 17, "K = %d < 18, is not allowed\n",polarParams->K); AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K); - int bit_i,ip,ipmod64; - int numbytes = polarParams->K>>3; - int residue = polarParams->K & 7; - - if (residue > 0) - numbytes++; - + int numbytes = (polarParams->K + 7) / 8; for (int byte=0; byteK >> 3) ? 8 : residue; + int numbits = byte < (polarParams->K >> 3) ? 8 : polarParams->K & 7; - for (int i=0; iK - 1 - polarParams->interleaving_pattern[(8 * byte) + i]; - ipmod64 = ip&63; - AssertFatal(ip<128,"ip = %d\n",ip); - + int ip = polarParams->K - 1 - polarParams->interleaving_pattern[(8 * byte) + bit]; + int ipmod64 = ip & 63; + AssertFatal(ip < 128, "ip = %d\n", ip); for (int val=0; val<256; val++) { - bit_i=(val>>i)&1; - + int bit_i = (val >> bit) & 1; if (ip < 64) polarParams->B_tab0[byte][val] |= ((uint64_t)bit_i) << ipmod64; else @@ -623,6 +615,64 @@ void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) { } } +static inline 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 (E >= N) { // repetition + memset(output, 0, N * sizeof(*output)); + for (int i = 0; i <= E - 1; i++) + output[rmp[i]] += input[i]; + } else { + if ((K / (double)E) <= (7.0 / 16)) + memset(output, 0, N * sizeof(*output)); // 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]; + } +} + +static inline 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++; + } + } + } +} + uint32_t polar_decoder_int16(int16_t *input, uint64_t *out, uint8_t ones_flag, @@ -630,12 +680,12 @@ uint32_t polar_decoder_int16(int16_t *input, uint16_t messageLength, uint8_t aggregation_level) { - t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, true); - + t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level); + const uint N = polarParams->N; #ifdef POLAR_CODING_DEBUG printf("\nRX\n"); printf("rm:"); - for (int i = 0; i < polarParams->N; i++) { + for (int i = 0; i < N; i++) { if (i % 4 == 0) { printf(" "); } @@ -644,25 +694,28 @@ uint32_t polar_decoder_int16(int16_t *input, printf("\n"); #endif - int16_t d_tilde[polarParams->N]; - nr_polar_rate_matching_int16(input, + int16_t d_tilde[N]; + const uint E = polarParams->encoderLength; + int16_t inbis[E]; + int16_t *input_deinterleaved; + if (polarParams->i_bil) { + for (int i = 0; i < E; i++) + inbis[i] = input[polarParams->i_bil_pattern[i]]; + input_deinterleaved = inbis; + } else { + input_deinterleaved = input; + } + + nr_polar_rate_matching_int16(input_deinterleaved, d_tilde, polarParams->rate_matching_pattern, polarParams->K, - polarParams->N, - polarParams->encoderLength, + N, + E, polarParams->i_bil); - - 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; - } - #ifdef POLAR_CODING_DEBUG printf("d: "); - for (int i = 0; i < polarParams->N; i++) { + for (int i = 0; i < N; i++) { if (i % 4 == 0) { printf(" "); } @@ -670,15 +723,23 @@ uint32_t polar_decoder_int16(int16_t *input, } printf("\n"); #endif - - memcpy(polarParams->tree.root->alpha, d_tilde, sizeof(d_tilde)); - uint8_t nr_polar_U[polarParams->N]; + uint8_t nr_polar_U[N]; memset(nr_polar_U, 0, sizeof(nr_polar_U)); - generic_polar_decoder(polarParams, polarParams->tree.root, nr_polar_U); - + static uint64_t cnt = 0, timeTree = 0, timeDecoder = 0; + uint64_t a = rdtsc_oai(); + decoder_tree_t tree; + build_decoder_tree(&tree, polarParams); + uint64_t b = rdtsc_oai(); + memcpy(treeAlpha(tree.root), d_tilde, sizeof(d_tilde)); + generic_polar_decoder(polarParams, tree.root, nr_polar_U); + uint64_t c = rdtsc_oai(); + timeTree += b - a; + timeDecoder += c - b; + if (cnt++ % 1000 == 0) + printf("tree: %ld, dec %ld\n", timeTree / (cnt), timeDecoder / (cnt)); #ifdef POLAR_CODING_DEBUG printf("u: "); - for (int i = 0; i < polarParams->N; i++) { + for (int i = 0; i < N; i++) { if (i % 4 == 0) { printf(" "); } @@ -693,7 +754,7 @@ uint32_t polar_decoder_int16(int16_t *input, nr_polar_U, polarParams->information_bit_pattern, polarParams->parity_check_bit_pattern, - polarParams->N, + N, polarParams->n_pc); #ifdef POLAR_CODING_DEBUG @@ -718,17 +779,30 @@ uint32_t polar_decoder_int16(int16_t *input, | polarParams->B_tab0[3][Cprimebyte[3]] | polarParams->B_tab0[4][Cprimebyte[4]] | polarParams->B_tab0[5][Cprimebyte[5]] | polarParams->B_tab0[6][Cprimebyte[6]] | polarParams->B_tab0[7][Cprimebyte[7]]; } else if (polarParams->K<129) { - int len = polarParams->K/8; - - if ((polarParams->K & 7) > 0) - len++; - - for (int k=0; kB_tab0[k][Cprimebyte[k]]; B[1] |= polarParams->B_tab1[k][Cprimebyte[k]]; } } + uint128_t Cprime128 = *(uint128_t *)Cprime; + uint128_t res = 0; + uint deinterleaving_pattern[polarParams->K]; + + for (int i = 0; i < polarParams->K; i++) + deinterleaving_pattern[polarParams->interleaving_pattern[i]] = i; + for (int i = 0; i < polarParams->K; i++) { + uint128_t bit = (Cprime128 >> i) & 1; + res |= bit << (polarParams->K - 1 - deinterleaving_pattern[i]); + } + uint128_t B128 = *(uint128_t *)B; + printf("old:(k=%d)", polarParams->K); + for (int i = 0; i < polarParams->K; i++) + printf("%lld", (B128 >> i) & 1); + printf("\nnew:(k=%d)", polarParams->K); + for (int i = 0; i < polarParams->K; i++) + printf("%lld", (res >> i) & 1); + printf("\n\n"); #ifdef POLAR_CODING_DEBUG int B_array = (polarParams->K + 63) >> 6; int n_start = (B_array << 6) - polarParams->K; 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 8180f5ebeb..aa7f835291 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -149,100 +149,79 @@ void updatePathMetric2(double *pathMetric, pathMetric[i] = tempPM[(i - listSize)] + log(1 + exp(multiplier * llr[row][0][(i - listSize)])); // eq. (11b) } -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)); - +static inline decoder_node_t *new_decoder_node(simde__m256i **buffer, + const int level, + const int first_leaf_index, + const bool leaf, + const bool frozen) +{ + int leaf_sz = 1 << level; + // we will use SIMD128 minimum + leaf_sz = (leaf_sz + 7) & ~7; + if (leaf_sz > 15) // we will use SIMD256 + leaf_sz = (leaf_sz + 15) & ~15; + const int tree_sz = (sizeof(decoder_node_t) + 31) & ~31; + decoder_node_t *node = (decoder_node_t *)*buffer; + *buffer = *buffer + (tree_sz + leaf_sz * sizeof(int16_t) + leaf_sz + sizeof(**buffer) - 1) / sizeof(**buffer); + *node = (decoder_node_t){.first_leaf_index = first_leaf_index, + .level = level, + .leaf = leaf, + .all_frozen = frozen, + .alpha = tree_sz, + .beta = tree_sz + leaf_sz * sizeof(int16_t), + .betaInit = false}; return(node); } -decoder_node_t *add_nodes(int level, int first_leaf_index, t_nrPolar_params *polarParams) { - - int all_frozen_below = 1; - int Nv = 1<tree.num_nodes,Nv,level); -#endif - polarParams->tree.num_nodes++; +static inline decoder_node_t *add_nodes(decoder_tree_t *tree, + int level, + int first_leaf_index, + const uint8_t *information_bit_pattern, + simde__m256i **buffer) +{ if (level==0) { #ifdef DEBUG_NEW_IMPL - printf("leaf %d (%s)\n", first_leaf_index, polarParams->information_bit_pattern[first_leaf_index]==1 ? "information or crc" : "frozen"); + printf("leaf %d (%s)\n", first_leaf_index, information_bit_pattern[first_leaf_index] == 1 ? "information or crc" : "frozen"); #endif - new_node->leaf=1; - new_node->all_frozen = polarParams->information_bit_pattern[first_leaf_index]==0 ? 1 : 0; - return new_node; // this is a leaf node + return new_decoder_node(buffer, level, first_leaf_index, true, information_bit_pattern[first_leaf_index] == 0); } - for (int i=0;iinformation_bit_pattern[i+first_leaf_index]>0) { - all_frozen_below = 0; - break; - } + int Nv = 1 << level; + const uint8_t *ptr = information_bit_pattern + first_leaf_index; + const uint8_t *end = ptr + Nv; + bool all_frozen_below = true; + while (ptr < end && all_frozen_below) { + all_frozen_below = *ptr++ <= 0; } - if (all_frozen_below==0) - new_node->left = add_nodes(level - 1, first_leaf_index, polarParams); - 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) { + return new_decoder_node(buffer, level, first_leaf_index, true, true); } - if (all_frozen_below==0) - new_node->right = add_nodes(level - 1, first_leaf_index + (Nv / 2), polarParams); - -#ifdef DEBUG_NEW_IMPL - printf("new_node (%d): first_leaf_index %d, left %p, right %p\n",Nv,first_leaf_index,new_node->left,new_node->right); -#endif + decoder_node_t *new_node = new_decoder_node(buffer, level, first_leaf_index, false, false); + new_node->left = add_nodes(tree, level - 1, first_leaf_index, information_bit_pattern, buffer); + new_node->right = add_nodes(tree, level - 1, first_leaf_index + (Nv / 2), information_bit_pattern, buffer); return(new_node); } -void delete_nodes(decoder_node_t * n) { - if (n) { - if(n->left) - delete_nodes(n->left); - if(n->right) - delete_nodes(n->right); - free(n->alpha); - free(n->beta); - free(n); - } -} - -void delete_decoder_tree(t_nrPolar_params *polarParams) { - if (polarParams->tree.root) - delete_nodes(polarParams->tree.root); -} - -void build_decoder_tree(t_nrPolar_params *polarParams) +void build_decoder_tree(decoder_tree_t *tree, const t_nrPolar_params *pp) { - polarParams->tree.num_nodes=0; - polarParams->tree.root = add_nodes(polarParams->n,0,polarParams); + simde__m256i *buffer = tree->buffer; + tree->root = add_nodes(tree, pp->n, 0, pp->information_bit_pattern, &buffer); + AssertFatal(buffer < tree->buffer + sizeofArray(tree->buffer), + "Arbitrary size too small (also check arbitrary max size of the entire polar decoder) %ld instead of max %ld\n", + buffer - tree->buffer, + sizeofArray(tree->buffer)); #ifdef DEBUG_NEW_IMPL - printf("root : left %p, right %p\n",polarParams->tree.root->left,polarParams->tree.root->right); + printf("root : left %p, right %p\n", tree->root->left, tree->root->right); #endif } -static void applyFtoleft(const t_nrPolar_params *pp, decoder_node_t *node, uint8_t *output) +static inline void applyFtoleft(const t_nrPolar_params *pp, decoder_node_t *node, uint8_t *output) { - 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; + int16_t *alpha_v = treeAlpha(node); + int16_t *alpha_l = treeAlpha(node->left); + int8_t *betal = treeBeta(node->left); #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); @@ -250,61 +229,59 @@ static void applyFtoleft(const t_nrPolar_params *pp, decoder_node_t *node, uint8 for (int i = 0; i < node->Nv; 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 - + assert(node->level); + const int sz = 1 << (node->level - 1); if (node->left->all_frozen == 0) { - int avx2mod = (node->Nv/2)&15; + int avx2mod = sz & 15; if (avx2mod == 0) { - simde__m256i a256,b256,absa256,absb256,minabs256; - int avx2len = node->Nv/2/16; + int avx2len = sz / 16; // printf("avx2len %d\n",avx2len); for (int i=0;i> 15; + int16_t maskb = b >> 15; + int16_t absa = (a + maska) ^ maska; + int16_t absb = (b + maskb) ^ maskb; + int16_t minabs = absa < absb ? absa : absb; + alpha_l[i] = (maska ^ maskb) == 0 ? minabs : -minabs; + // printf("alphal[%d] %d (%d,%d)\n",i,alpha_l[i],a,b); + } } - else - { // equivalent scalar code to above, activated only on non x86/ARM architectures - 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; + if (sz == 1) { // apply hard decision on left node + const int tmp = alpha_l[0] <= 0; + betal[0] = tmp * 2 - 1; + node->left->betaInit = true; #ifdef DEBUG_NEW_IMPL printf("betal[0] %d (%p)\n",betal[0],&betal[0]); #endif - output[node->first_leaf_index] = (1 + betal[0]) >> 1; + output[node->first_leaf_index] = tmp; #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 @@ -312,39 +289,47 @@ static void applyFtoleft(const t_nrPolar_params *pp, decoder_node_t *node, uint8 } } -static void applyGtoright(const t_nrPolar_params *pp, decoder_node_t *node, uint8_t *output) +static inline void applyGtoright(const t_nrPolar_params *pp, decoder_node_t *node, uint8_t *output) { - 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; + int16_t *alpha_v = treeAlpha(node); + int16_t *alpha_r = treeAlpha(node->right); + int8_t *betal = treeBeta(node->left); + int8_t *betar = treeBeta(node->right); #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) { - int avx2mod = (node->Nv/2)&15; - if (avx2mod == 0) { - int avx2len = node->Nv/2/16; - - for (int i=0;ilevel); + const int sz = 1 << (node->level - 1); + if (node->right->all_frozen == 0) { + if (!node->left->betaInit) { + for (int i = 0; i < sz; i++) { + int temp_alpha_r = alpha_v[i + sz] + alpha_v[i]; + if (temp_alpha_r > SHRT_MAX) { + alpha_r[i] = SHRT_MAX; + } else if (temp_alpha_r < -SHRT_MAX) { + alpha_r[i] = -SHRT_MAX; + } else { + alpha_r[i] = temp_alpha_r; + } } - } - else if (avx2mod == 8) { - ((simde__m128i *)alpha_r)[0] = simde_mm_subs_epi16(((simde__m128i *)alpha_v)[1],simde_mm_sign_epi16(((simde__m128i *)alpha_v)[0],((simde__m128i *)betal)[0])); - } - else if (avx2mod == 4) { - ((simde__m64 *)alpha_r)[0] = simde_mm_subs_pi16(((simde__m64 *)alpha_v)[1],simde_mm_sign_pi16(((simde__m64 *)alpha_v)[0],((simde__m64 *)betal)[0])); - } - else - { - int temp_alpha_r; - for (int i = 0; i < node->Nv / 2; i++) { - temp_alpha_r = alpha_v[i + (node->Nv / 2)] - (betal[i] * alpha_v[i]); + } else { + int avx2mod = sz & 15; + if (avx2mod == 0) { + int avx2len = sz / 16; + + for (int i = 0; i < avx2len; i++) { + simde__m256i tmp = simde_mm256_sign_epi16(((simde__m256i *)alpha_v)[i], _mm256_cvtepi8_epi16(((simde__m128i *)betal)[i])); + ((simde__m256i *)alpha_r)[i] = + + simde_mm256_subs_epi16(((simde__m256i *)alpha_v)[i + avx2len], tmp); + } + } else if (avx2mod == 8) { + simde__m128i tmp = simde_mm_sign_epi16(((simde__m128i *)alpha_v)[0], _mm_cvtepi8_epi16(((simde__m128i *)betal)[0])); + ((simde__m128i *)alpha_r)[0] = simde_mm_subs_epi16(((simde__m128i *)alpha_v)[1], tmp); + } else { + for (int i = 0; i < sz; i++) { + int temp_alpha_r = alpha_v[i + sz] - (betal[i] * alpha_v[i]); if (temp_alpha_r > SHRT_MAX) { alpha_r[i] = SHRT_MAX; } else if (temp_alpha_r < -SHRT_MAX) { @@ -352,55 +337,56 @@ static void applyGtoright(const t_nrPolar_params *pp, decoder_node_t *node, uint } else { alpha_r[i] = temp_alpha_r; } - } + } } - if (node->Nv == 2) { // apply hard decision on right node - betar[0] = (alpha_r[0]>0) ? -1 : 1; - output[node->first_leaf_index + 1] = (1 + betar[0]) >> 1; + } + if (sz == 1) { // apply hard decision on right node + int tmp = alpha_r[0] <= 0; + betar[0] = tmp * 2 - 1; + node->right->betaInit = true; + output[node->first_leaf_index + 1] = tmp; + #ifdef DEBUG_NEW_IMPL printf("Setting bit %d to %d (LLR %d)\n",node->first_leaf_index+1,(betar[0]+1)>>1,alpha_r[0]); #endif - } + } } } -static const int16_t all1[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; +static const int64_t all11[4] = {-1, -1, -1, -1}; -void computeBeta(const 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; +static inline void computeBeta(decoder_node_t *node) +{ + int8_t *betav = treeBeta(node); + int8_t *betal = treeBeta(node->left); + int8_t *betar = treeBeta(node->right); #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 + assert(node->level); + const int sz = 1 << (node->level - 1); if (node->left->all_frozen==0) { // if left node is not aggregation of frozen bits - int avx2mod = (node->Nv/2)&15; - register simde__m256i allones=*((simde__m256i*)all1); + assert(node->left->betaInit && node->right->betaInit); + int avx2mod = sz & 31; if (avx2mod == 0) { - int avx2len = node->Nv/2/16; + int avx2len = sz / 16; for (int i=0;iNv/2;i++) { - betav[i] = (betal[i] != betar[i]) ? 1 : -1; - } - } + } else { + assert(node->right->betaInit); + memcpy(betav, betar, sz * sizeof(*betav)); + node->betaInit = true; } - 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)); + assert(node->right->betaInit); + memcpy(&betav[sz], betar, sz * sizeof(*betav)); + node->betaInit = true; } void generic_polar_decoder(const t_nrPolar_params *pp, decoder_node_t *node, uint8_t *nr_polar_U) @@ -415,5 +401,5 @@ void generic_polar_decoder(const t_nrPolar_params *pp, decoder_node_t *node, uin if (node->right->leaf == 0) generic_polar_decoder(pp, node->right, nr_polar_U); - computeBeta(pp, node); + computeBeta(node); } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index 84b3241e68..82292fb8fe 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -63,18 +63,18 @@ static const uint8_t nr_polar_subblock_interleaver_pattern[32] = {0,1,2,4,3,5,6, 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; + uint64_t level: 16; + uint64_t leaf: 16; + uint64_t first_leaf_index: 16; + uint64_t all_frozen: 1; + uint64_t betaInit: 1; + uint32_t alpha; + uint32_t beta; } decoder_node_t; typedef struct decoder_tree_t_s { decoder_node_t *root; - int num_nodes; + simde__m256i buffer[1024]; // seems enough but to be refined } decoder_tree_t; typedef struct nrPolar_params { @@ -100,6 +100,7 @@ typedef struct nrPolar_params { uint16_t *interleaving_pattern; uint16_t *rate_matching_pattern; + uint16_t *i_bil_pattern; const uint16_t *Q_0_Nminus1; int16_t *Q_I_N; int16_t *Q_F_N; @@ -110,13 +111,10 @@ typedef struct nrPolar_params { const uint8_t **G_N; int groupsize; int *rm_tab; - uint64_t cprime_tab0[32][256]; - uint64_t cprime_tab1[32][256]; - uint64_t B_tab0[32][256]; - uint64_t B_tab1[32][256]; - // lowercase: bits, Uppercase: Bits stored in bytes - // polar_encoder vectors - decoder_tree_t tree; + uint64_t cprime_tab0[16][256]; + uint64_t cprime_tab1[16][256]; + uint64_t B_tab0[16][256]; + uint64_t B_tab1[16][256]; } t_nrPolar_params; void polar_encoder(uint32_t *input, @@ -164,19 +162,23 @@ int8_t polar_decoder_dci(double *input, void generic_polar_decoder(const t_nrPolar_params *pp, decoder_node_t *node, uint8_t *nr_polar_U); -void computeBeta(const t_nrPolar_params *pp, - decoder_node_t *node); +static inline int16_t *treeAlpha(decoder_node_t *node) +{ + return (int16_t *)((uint8_t *)node + node->alpha); +} -void build_decoder_tree(t_nrPolar_params *pp); +static inline int8_t *treeBeta(decoder_node_t *node) +{ + return (int8_t *)node + node->beta; +} + +void build_decoder_tree(decoder_tree_t *tree, const t_nrPolar_params *pp); void build_polar_tables(t_nrPolar_params *polarParams); void init_polar_deinterleaver_table(t_nrPolar_params *polarParams); void nr_polar_print_polarParams(void); -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); uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level); @@ -207,14 +209,6 @@ void nr_polar_rate_matching(double *input, uint16_t N, uint16_t E); -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); - void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_); @@ -256,13 +250,6 @@ void nr_polar_generate_u(uint64_t *u, void nr_polar_uxG(uint8_t const* u, size_t N, uint8_t* D); -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, @@ -328,7 +315,52 @@ static inline void nr_polar_deinterleaver(uint8_t *input, uint8_t *output, uint1 output[pattern[i]] = input[i]; } -void delete_decoder_tree(t_nrPolar_params *); +/* + * De-interleaving of coded bits implementation + * TS 138.212: Section 5.4.1.3 - Interleaving of coded bits + */ +static inline void nr_polar_rm_deinterleaving_lut(uint16_t *out, const uint E) +{ + int16_t in[E]; + for (int i = 0; i < E; i++) + in[i] = i; + int T = ceil((sqrt(8 * E + 1) - 1) / 2); + int v_tab[T][T]; + memset(v_tab, 0, sizeof(v_tab)); + int k = 0; + for (int i = 0; i < T; i++) { + for (int j = 0; j < T - i; j++) { + if (k < E) { + v_tab[i][j] = k + 1; + } + k++; + } + } + + 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[k]; + k++; + } else { + v[i][j] = INT_MAX; + } + } + } + + k = 0; + memset(out, 0, E * sizeof(*out)); + for (int i = 0; i < T; i++) { + for (int j = 0; j < T - i; j++) { + if (v[i][j] != INT_MAX) { + out[k] = v[i][j]; + k++; + } + } + } +} extern pthread_mutex_t PolarListMutex; static inline void polarReturn(t_nrPolar_params *polarParams) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c index c23513bdf6..285f936085 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c @@ -47,7 +47,7 @@ void polar_encoder(uint32_t *in, int8_t messageType, uint16_t messageLength, uint8_t aggregation_level) { - t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, false); + t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level); uint8_t nr_polar_A[polarParams->payloadBits]; nr_bit2byte_uint32_8(in, polarParams->payloadBits, nr_polar_A); /* @@ -146,7 +146,7 @@ void polar_encoder_dci(uint32_t *in, int8_t messageType, uint16_t messageLength, uint8_t aggregation_level) { - t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, false); + t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level); #ifdef DEBUG_POLAR_ENCODER_DCI printf("[polar_encoder_dci] in: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", in[0], in[1], in[2], in[3]); @@ -463,7 +463,7 @@ void polar_encoder_fast(uint64_t *A, uint16_t messageLength, uint8_t aggregation_level) { - t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, false); + t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level); #ifdef POLAR_CODING_DEBUG printf("polarParams->payloadBits = %i\n", polarParams->payloadBits); diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_interleaving_pattern.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_interleaving_pattern.c index 264ef9731d..97450d9dbf 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_interleaving_pattern.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_interleaving_pattern.c @@ -33,7 +33,7 @@ #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_){ - uint K_IL_max = 164, k = 0; + uint K_IL_max = 164; uint8_t interleaving_pattern_table[164] = { 0, 2, 4, 7, 9, 14, 19, 20, 24, 25, 26, 28, 31, 34, 42, 45, 49, 50, 51, 53, 54, 56, 58, 59, 61, 62, 65, 66, 67, 69, 70, 71, 72, 76, 77, 81, 82, 83, 87, 88, 89, 91, 93, 95, 98, 101, 104, 106, @@ -44,10 +44,10 @@ void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_){ 40, 146, 41, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163}; if (I_IL == 0) { - for (; k <= K - 1; k++) + for (int k = 0; k < K; k++) PI_k_[k] = k; } else { - for (int m = 0; m <= (K_IL_max - 1); m++) { + for (int m = 0, k = 0; m < K_IL_max; m++) { if (interleaving_pattern_table[m] >= (K_IL_max - K)) { PI_k_[k] = interleaving_pattern_table[m] - (K_IL_max - K); k++; diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c index a4d3bb301e..1a1a3fb830 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c @@ -89,40 +89,6 @@ 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++; - } - } - } -} - - static void encode_packed_byte(uint8_t* in_out) { @@ -442,76 +408,3 @@ void nr_polar_rate_matching(double *input, } } } - -/* - * 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) -{ - int T = ceil((sqrt(8 * E + 1) - 1) / 2); - int v_tab[T][T]; - memset(v_tab, 0, sizeof(v_tab)); - int k = 0; - for (int i = 0; i < T; i++) { - for (int j = 0; j < T - i; j++) { - if (k < E) { - v_tab[i][j] = k + 1; - } - k++; - } - } - - 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[k]; - k++; - } else { - v[i][j] = INT_MAX; - } - } - } - - k = 0; - memset(out, 0, E * sizeof(*out)); - for (int i = 0; i < T; i++) { - for (int j = 0; j < T - i; j++) { - if (v[i][j] != INT_MAX) { - out[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(output, 0, N * sizeof(*output)); - for (int i = 0; i <= E - 1; i++) - output[rmp[i]] += input[i]; - } else { - if ((K / (double)E) <= (7.0 / 16)) - memset(output, 0, N * sizeof(*output)); // 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]; - } -} diff --git a/openair1/PHY/CODING/nr_polar_init.c b/openair1/PHY/CODING/nr_polar_init.c index 1d12aae23e..d0c9dc3c60 100644 --- a/openair1/PHY/CODING/nr_polar_init.c +++ b/openair1/PHY/CODING/nr_polar_init.c @@ -47,8 +47,7 @@ static void nr_polar_delete_list(t_nrPolar_params * polarParams) { return; if (polarParams->nextPtr) nr_polar_delete_list(polarParams->nextPtr); - - delete_decoder_tree(polarParams); + // From build_polar_tables() free(polarParams->rm_tab); if (polarParams->crc_generator_matrix) @@ -71,7 +70,7 @@ 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) { // 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 @@ -87,8 +86,6 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui if (currentPtr->busy == false && currentPtr->idx == PolarKey ) { currentPtr->busy=true; pthread_mutex_unlock(&PolarListMutex); - if (decoder_flag && !currentPtr->tree.root) - build_decoder_tree(currentPtr); return currentPtr ; } else @@ -97,11 +94,10 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui // printf("currentPtr %p (polarParams %p)\n",currentPtr,polarParams); //Else, initialize and add node to the end of the linked list. - t_nrPolar_params *newPolarInitNode = calloc(sizeof(t_nrPolar_params),1); + t_nrPolar_params *newPolarInitNode = malloc(sizeof(t_nrPolar_params)); + AssertFatal(newPolarInitNode, "[nr_polar_init] New t_nrPolar_params * could not be created"); - newPolarInitNode->busy = true; - newPolarInitNode->nextPtr = NULL; - newPolarInitNode->nextPtr = PolarList; + *newPolarInitNode = (t_nrPolar_params){.busy = true, .nextPtr = PolarList}; PolarList = newPolarInitNode; pthread_mutex_unlock(&PolarListMutex); // LOG_D(PHY,"Setting new polarParams index %d, messageType %d, messageLength %d, aggregation_prime %d\n",(messageType * messageLength * aggregation_prime),messageType,messageLength,aggregation_prime); @@ -220,6 +216,10 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui newPolarInitNode->K, newPolarInitNode->N, newPolarInitNode->encoderLength); + if (newPolarInitNode->i_bil) { + newPolarInitNode->i_bil_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength); + nr_polar_rm_deinterleaving_lut(newPolarInitNode->i_bil_pattern, 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)); @@ -245,8 +245,6 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui // sort the Q_I_N array in ascending order (first K positions) qsort((void *)newPolarInitNode->Q_I_N,newPolarInitNode->K,sizeof(int16_t),intcmp); - if (decoder_flag == 1) - build_decoder_tree(newPolarInitNode); build_polar_tables(newPolarInitNode); init_polar_deinterleaver_table(newPolarInitNode); From 3e019af4d98bd6edfd06e6cc3724a90c40942cd8 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 4 Sep 2024 14:09:45 +0200 Subject: [PATCH 2/8] remove the big LUT for decoder de-interleaver no performance degradation some reformatting --- openair1/PHY/CODING/TESTBENCH/polartest.c | 200 +++++++++--------- .../CODING/nrPolar_tools/nr_polar_decoder.c | 118 ++--------- .../nrPolar_tools/nr_polar_decoding_tools.c | 23 +- .../PHY/CODING/nrPolar_tools/nr_polar_defs.h | 6 +- .../CODING/nrPolar_tools/nr_polar_encoder.c | 2 + openair1/PHY/CODING/nr_polar_init.c | 2 - 6 files changed, 136 insertions(+), 215 deletions(-) diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index 266f829efa..f39da2eb6d 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -48,49 +48,49 @@ int main(int argc, char *argv[]) printf("handling optarg %c\n",arguments); switch (arguments) { case 's': - SNRstart = atof(optarg); - SNRstop = SNRstart + 2; - break; + SNRstart = atof(optarg); + SNRstop = SNRstart + 2; + break; case 'd': - SNRinc = atof(optarg); - break; + SNRinc = atof(optarg); + break; case 'f': - SNRstop = atof(optarg); - break; + SNRstop = atof(optarg); + break; case 'm': - polarMessageType = atoi(optarg); - if (polarMessageType!=0 && polarMessageType!=1 && polarMessageType!=2) - printf("Illegal polar message type %d (should be 0,1 or 2)\n", polarMessageType); - break; + polarMessageType = atoi(optarg); + if (polarMessageType!=0 && polarMessageType!=1 && polarMessageType!=2) + printf("Illegal polar message type %d (should be 0,1 or 2)\n", polarMessageType); + break; case 'i': - iterations = atoi(optarg); - break; + iterations = atoi(optarg); + break; case 'l': decoderListSize = (uint8_t) atoi(optarg); break; case 'q': - decoder_int16 = 1; - break; + decoder_int16 = 1; + break; case 'g': - iterations = 1; - SNRstart = -6.0; - SNRstop = -6.0; - decoder_int16 = 1; - break; + iterations = 1; + SNRstart = -6.0; + SNRstop = -6.0; + decoder_int16 = 1; + break; case 'F': - logFlag = 1; - break; + logFlag = 1; + break; case 'L': - aggregation_level=atoi(optarg); + aggregation_level=atoi(optarg); if (aggregation_level != 1 && aggregation_level != 2 && aggregation_level != 4 && aggregation_level != 8 && aggregation_level != 16) { printf("Illegal aggregation level %d \n", aggregation_level); @@ -99,18 +99,18 @@ int main(int argc, char *argv[]) break; case 'k': - testLength=atoi(optarg); - if (testLength < 12 || testLength > 127) { - printf("Illegal packet bitlength %d \n",testLength); - exit(-1); - } - break; + testLength=atoi(optarg); + if (testLength < 12 || testLength > 127) { + printf("Illegal packet bitlength %d \n",testLength); + exit(-1); + } + break; case 'h': printf( - "./polartest\nOptions\n-h Print this help\n-s SNRstart (dB)\n-d SNRinc (dB)\n-f SNRstop (dB)\n-m [0=PBCH|1=DCI|2=UCI]\n" - "-i Number of iterations\n-l decoderListSize\n-q Flag for optimized coders usage\n-F Flag for test results logging\n" - "-L aggregation level (for DCI)\n-k packet_length (bits) for DCI/UCI\n"); + "./polartest\nOptions\n-h Print this help\n-s SNRstart (dB)\n-d SNRinc (dB)\n-f SNRstop (dB)\n-m [0=PBCH|1=DCI|2=UCI]\n" + "-i Number of iterations\n-l decoderListSize\n-q Flag for optimized coders usage\n-F Flag for test results logging\n" + "-L aggregation level (for DCI)\n-k packet_length (bits) for DCI/UCI\n"); exit(-1); break; @@ -155,7 +155,7 @@ int main(int argc, char *argv[]) strcat(fileName,currentTimeInfo); //Create "~/Desktop/polartestResults" folder if it doesn't already exist. /*struct stat folder = {0}; - if (stat(folderName, &folder) == -1) mkdir(folderName, S_IRWXU | S_IRWXG | S_IRWXO);*/ + if (stat(folderName, &folder) == -1) mkdir(folderName, S_IRWXU | S_IRWXG | S_IRWXO);*/ logFile = fopen(fileName, "w"); if (logFile==NULL) { @@ -203,25 +203,25 @@ int main(int argc, char *argv[]) t_nrPolar_params *currentPtrDCI=nr_polar_params(1, size, aggregation_level); polar_encoder_dci(dci_pdu, encoder_output, currentPtrDCI, rnti); - for (int i=0; i<54; i++) printf("encoder_output: [%2d]->0x%08x \n", i, encoder_output[i]); + for (int i=0; i<54; i++) + printf("encoder_output: [%2d]->0x%08x \n", i, encoder_output[i]); uint8_t *encoder_outputByte = malloc(sizeof(uint8_t) * currentPtrDCI->encoderLength); double *modulated_input = malloc (sizeof(double) * currentPtrDCI->encoderLength); double *channel_output = malloc (sizeof(double) * currentPtrDCI->encoderLength); uint32_t dci_est[4]; - memset(dci_est,0,sizeof(uint32_t)*4); - printf("dci_est: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", dci_est[0], dci_est[1], dci_est[2], dci_est[3]); + memset(dci_est,0,sizeof(dci_est)); nr_bit2byte_uint32_8(encoder_output, currentPtrDCI->encoderLength, encoder_outputByte); printf("[polartest] encoder_outputByte: "); for (int i = 0; i < currentPtrDCI->encoderLength; i++) printf("%d-", encoder_outputByte[i]); printf("\n"); SNR_lin = pow(10, 0/10); //SNR = 0 dB for(int i=0; iencoderLength; i++) { - if (encoder_outputByte[i] == 0) - modulated_input[i]=1/sqrt(2); - else - modulated_input[i]=(-1)/sqrt(2); - channel_output[i] = modulated_input[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin))); + if (encoder_outputByte[i] == 0) + modulated_input[i]=1/sqrt(2); + else + modulated_input[i]=(-1)/sqrt(2); + channel_output[i] = modulated_input[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin))); } decoderState = polar_decoder_dci(channel_output, dci_est, NR_POLAR_DECODER_LISTSIZE, rnti, 1, size, aggregation_level); @@ -235,41 +235,41 @@ int main(int argc, char *argv[]) #endif for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) { - printf("SNR %f\n",SNR); - SNR_lin = pow(10, SNR/10); + printf("SNR %f\n",SNR); + SNR_lin = pow(10, SNR/10); - for (itr = 1; itr <= iterations; itr++) { - //Generate random values for all the bits of "testInput", not just as much as "currentPtr->payloadBits". - for (int i = 0; i < testArrayLength; i++) { - for (int j = 0; j < (sizeof(testInput[0])*8)-1; j++) { - testInput[i] |= ( ((uint32_t) (rand()%2)) &1); - testInput[i]<<=1; - } - testInput[i] |= ( ((uint32_t) (rand()%2)) &1); - } + for (itr = 1; itr <= iterations; itr++) { + //Generate random values for all the bits of "testInput", not just as much as "currentPtr->payloadBits". + for (int i = 0; i < testArrayLength; i++) { + for (int j = 0; j < (sizeof(testInput[0])*8)-1; j++) { + testInput[i] |= ( ((uint32_t) (rand()%2)) &1); + testInput[i]<<=1; + } + testInput[i] |= ( ((uint32_t) (rand()%2)) &1); + } #ifdef DEBUG_POLARTEST - //testInput[0] = 0x360f8a5c; - printf("testInput: [0]->0x%08x\n", testInput[0]); + //testInput[0] = 0x360f8a5c; + printf("testInput: [0]->0x%08x\n", testInput[0]); #endif - int len_mod64=currentPtr->payloadBits&63; - ((uint64_t *)testInput)[currentPtr->payloadBits/64]&=((((uint64_t)1)<payloadBits&63; + ((uint64_t *)testInput)[currentPtr->payloadBits/64]&=((((uint64_t)1)< PBCH, 1 --> DCI, -1 --> UCI - if (polarMessageType == 0) - polar_encoder(testInput, encoderOutput, polarMessageType, testLength, aggregation_level); - else if (polarMessageType == 1) - polar_encoder_dci(testInput, encoderOutput, rnti, polarMessageType, testLength, aggregation_level); - } - stop_meas(&timeEncoder); + start_meas(&timeEncoder); + if (decoder_int16==1) { + polar_encoder_fast((uint64_t *)testInput, encoderOutput, 0, 0, polarMessageType, testLength, aggregation_level); + //polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0,0,currentPtr); + } else { //0 --> PBCH, 1 --> DCI, -1 --> UCI + if (polarMessageType == 0) + polar_encoder(testInput, encoderOutput, polarMessageType, testLength, aggregation_level); + else if (polarMessageType == 1) + polar_encoder_dci(testInput, encoderOutput, rnti, polarMessageType, testLength, aggregation_level); + } + stop_meas(&timeEncoder); #ifdef DEBUG_POLARTEST - printf("encoderOutput: [0]->0x%08x\n", encoderOutput[0]); - //for (int i=1;i0x%08x\n", i, encoderOutput[1]); + printf("encoderOutput: [0]->0x%08x\n", encoderOutput[0]); + //for (int i=1;i0x%08x\n", i, encoderOutput[1]); #endif //Bit-to-byte: @@ -277,14 +277,14 @@ int main(int argc, char *argv[]) //BPSK modulation for(int i=0; i 15) channelOutput_int16[i] = 127; else if (channelOutput[i] < -16) @@ -296,17 +296,17 @@ int main(int argc, char *argv[]) start_meas(&timeDecoder); - if (decoder_int16==1) { + if (decoder_int16 == 1) { decoderState = polar_decoder_int16(channelOutput_int16, (uint64_t *)estimatedOutput, 0, polarMessageType, testLength, aggregation_level); - } else { //0 --> PBCH, 1 --> DCI, -1 --> UCI - if (polarMessageType == 0) { + } else { // 0 --> PBCH, 1 --> DCI, -1 --> UCI + if (polarMessageType == 0) { decoderState = - polar_decoder(channelOutput, estimatedOutput, decoderListSize, polarMessageType, testLength, aggregation_level); + polar_decoder(channelOutput, estimatedOutput, decoderListSize, polarMessageType, testLength, aggregation_level); } else if (polarMessageType == 1) { decoderState = polar_decoder_dci(channelOutput, estimatedOutput, @@ -325,28 +325,28 @@ int main(int argc, char *argv[]) //calculate errors if (decoderState!=0) { - blockErrorState=-1; - nBitError=-1; + blockErrorState=-1; + nBitError=-1; } else { - for (int i = 0; i < (testArrayLength-1); i++) { - for (int j = 0; j < 32; j++) { - if ( ((estimatedOutput[i]>>j) & 1) != ((testInput[i]>>j) & 1) ) - nBitError++; - } - } - for (int j = 0; j < testLength - ((testArrayLength-1) * 32); j++) - if ( ((estimatedOutput[(testArrayLength-1)]>>j) & 1) != ((testInput[(testArrayLength-1)]>>j) & 1) ) - nBitError++; + for (int i = 0; i < (testArrayLength-1); i++) { + for (int j = 0; j < 32; j++) { + if ( ((estimatedOutput[i]>>j) & 1) != ((testInput[i]>>j) & 1) ) + nBitError++; + } + } + for (int j = 0; j < testLength - ((testArrayLength-1) * 32); j++) + if ( ((estimatedOutput[(testArrayLength-1)]>>j) & 1) != ((testInput[(testArrayLength-1)]>>j) & 1) ) + nBitError++; } if (nBitError>0) blockErrorState=1; #ifdef DEBUG_POLARTEST - for (int i = 0; i < testArrayLength; i++) - printf("[polartest/decoderState=%u] testInput[%d]=0x%08x, estimatedOutput[%d]=0x%08x\n", - decoderState, - i, - testInput[i], - i, - estimatedOutput[i]); + for (int i = 0; i < testArrayLength; i++) + printf("[polartest/decoderState=%u] testInput[%d]=0x%08x, estimatedOutput[%d]=0x%08x\n", + decoderState, + i, + testInput[i], + i, + estimatedOutput[i]); #endif //Iteration times are in microseconds. @@ -363,9 +363,9 @@ int main(int argc, char *argv[]) decoderState=0; nBitError=0; blockErrorState=0; - memset(testInput,0,sizeof(uint32_t) * realArrayLength); - memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength); - memset(estimatedOutput,0,sizeof(uint32_t) * realArrayLength); + memset(testInput,0,sizeof(uint32_t) * realArrayLength); + memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength); + memset(estimatedOutput,0,sizeof(uint32_t) * realArrayLength); } //Calculate error statistics for the SNR. diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 1d7e7e8373..5a61eebb3d 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -592,29 +592,6 @@ int8_t polar_decoder_dci(double *input, return 0; } -void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) { - AssertFatal(polarParams->K > 17, "K = %d < 18, is not allowed\n",polarParams->K); - AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K); - int numbytes = (polarParams->K + 7) / 8; - for (int byte=0; byteK >> 3) ? 8 : polarParams->K & 7; - - for (int bit = 0; bit < numbits; bit++) { - // flip bit endian for B - int ip = polarParams->K - 1 - polarParams->interleaving_pattern[(8 * byte) + bit]; - int ipmod64 = ip & 63; - AssertFatal(ip < 128, "ip = %d\n", ip); - for (int val=0; val<256; val++) { - int bit_i = (val >> bit) & 1; - if (ip < 64) - polarParams->B_tab0[byte][val] |= ((uint64_t)bit_i) << ipmod64; - else - polarParams->B_tab1[byte][val] |= ((uint64_t)bit_i) << ipmod64; - } - } - } -} - static inline void nr_polar_rate_matching_int16(int16_t *input, int16_t *output, const uint16_t *rmp, @@ -644,28 +621,29 @@ static inline 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, + const uint16_t *interleaving_pattern, uint16_t N, - uint8_t n_pc) + uint8_t n_pc, + int K) { 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++; - } + if (information_bit_pattern[n] == 1 && parity_check_bit_pattern[n] == 0) { + int targetBit = K - 1 - interleaving_pattern[k]; + int k1 = targetBit >> 6; + int k2 = targetBit & 63; + 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); + int targetBit = K - 1 - interleaving_pattern[k]; + int k1 = targetBit >> 6; + int k2 = targetBit & 63; Cprime[k1] |= (uint64_t)u[n] << k2; k++; } @@ -725,18 +703,8 @@ uint32_t polar_decoder_int16(int16_t *input, #endif uint8_t nr_polar_U[N]; memset(nr_polar_U, 0, sizeof(nr_polar_U)); - static uint64_t cnt = 0, timeTree = 0, timeDecoder = 0; - uint64_t a = rdtsc_oai(); - decoder_tree_t tree; - build_decoder_tree(&tree, polarParams); - uint64_t b = rdtsc_oai(); - memcpy(treeAlpha(tree.root), d_tilde, sizeof(d_tilde)); - generic_polar_decoder(polarParams, tree.root, nr_polar_U); - uint64_t c = rdtsc_oai(); - timeTree += b - a; - timeDecoder += c - b; - if (cnt++ % 1000 == 0) - printf("tree: %ld, dec %ld\n", timeTree / (cnt), timeDecoder / (cnt)); + memcpy(treeAlpha(polarParams->decoder.root), d_tilde, sizeof(d_tilde)); + generic_polar_decoder(polarParams, polarParams->decoder.root, nr_polar_U); #ifdef POLAR_CODING_DEBUG printf("u: "); for (int i = 0; i < N; i++) { @@ -749,13 +717,15 @@ uint32_t polar_decoder_int16(int16_t *input, #endif // Extract the information bits (û to ĉ) - uint64_t Cprime[4]= {0}; - nr_polar_info_extraction_from_u(Cprime, + uint64_t B[4] = {0}; + nr_polar_info_extraction_from_u(B, nr_polar_U, polarParams->information_bit_pattern, polarParams->parity_check_bit_pattern, + polarParams->interleaving_pattern, N, - polarParams->n_pc); + polarParams->n_pc, + polarParams->K); #ifdef POLAR_CODING_DEBUG printf("c: "); @@ -765,55 +735,7 @@ uint32_t polar_decoder_int16(int16_t *input, } 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]] | polarParams->B_tab0[1][Cprimebyte[1]] | polarParams->B_tab0[2][Cprimebyte[2]] - | polarParams->B_tab0[3][Cprimebyte[3]] | polarParams->B_tab0[4][Cprimebyte[4]] | polarParams->B_tab0[5][Cprimebyte[5]] - | polarParams->B_tab0[6][Cprimebyte[6]] | polarParams->B_tab0[7][Cprimebyte[7]]; - } else if (polarParams->K<129) { - for (int k = 0; k < 8; k++) { - B[0] |= polarParams->B_tab0[k][Cprimebyte[k]]; - B[1] |= polarParams->B_tab1[k][Cprimebyte[k]]; - } - } - - uint128_t Cprime128 = *(uint128_t *)Cprime; - uint128_t res = 0; - uint deinterleaving_pattern[polarParams->K]; - - for (int i = 0; i < polarParams->K; i++) - deinterleaving_pattern[polarParams->interleaving_pattern[i]] = i; - for (int i = 0; i < polarParams->K; i++) { - uint128_t bit = (Cprime128 >> i) & 1; - res |= bit << (polarParams->K - 1 - deinterleaving_pattern[i]); - } - uint128_t B128 = *(uint128_t *)B; - printf("old:(k=%d)", polarParams->K); - for (int i = 0; i < polarParams->K; i++) - printf("%lld", (B128 >> i) & 1); - printf("\nnew:(k=%d)", polarParams->K); - for (int i = 0; i < polarParams->K; i++) - printf("%lld", (res >> i) & 1); - printf("\n\n"); -#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("%lu", (B[n1] >> n2) & 1); } printf("\n"); #endif 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 aa7f835291..a3d20a37c7 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -161,8 +161,10 @@ static inline decoder_node_t *new_decoder_node(simde__m256i **buffer, if (leaf_sz > 15) // we will use SIMD256 leaf_sz = (leaf_sz + 15) & ~15; const int tree_sz = (sizeof(decoder_node_t) + 31) & ~31; - decoder_node_t *node = (decoder_node_t *)*buffer; - *buffer = *buffer + (tree_sz + leaf_sz * sizeof(int16_t) + leaf_sz + sizeof(**buffer) - 1) / sizeof(**buffer); + uintptr_t tmp = (uintptr_t)*buffer; + tmp = (tmp + sizeof(**buffer) - 1) & ~(sizeof(**buffer) - 1); + decoder_node_t *node = (decoder_node_t *)tmp; + *buffer = (simde__m256i *)(tmp + tree_sz + leaf_sz * sizeof(int16_t) + leaf_sz); *node = (decoder_node_t){.first_leaf_index = first_leaf_index, .level = level, .leaf = leaf, @@ -204,17 +206,16 @@ static inline decoder_node_t *add_nodes(decoder_tree_t *tree, return(new_node); } -void build_decoder_tree(decoder_tree_t *tree, const t_nrPolar_params *pp) +void build_decoder_tree(t_nrPolar_params *pp) { - simde__m256i *buffer = tree->buffer; - tree->root = add_nodes(tree, pp->n, 0, pp->information_bit_pattern, &buffer); - AssertFatal(buffer < tree->buffer + sizeofArray(tree->buffer), + uintptr_t tmp = (uintptr_t)pp->decoder.buffer; + tmp = (tmp + sizeof(*pp->decoder.buffer) - 1) & ~(sizeof(*pp->decoder.buffer) - 1); + simde__m256i *buffer = (simde__m256i *)tmp; + pp->decoder.root = add_nodes(&pp->decoder, pp->n, 0, pp->information_bit_pattern, &buffer); + AssertFatal(buffer < pp->decoder.buffer + sizeofArray(pp->decoder.buffer), "Arbitrary size too small (also check arbitrary max size of the entire polar decoder) %ld instead of max %ld\n", - buffer - tree->buffer, - sizeofArray(tree->buffer)); -#ifdef DEBUG_NEW_IMPL - printf("root : left %p, right %p\n", tree->root->left, tree->root->right); -#endif + buffer - pp->decoder.buffer, + sizeofArray(pp->decoder.buffer)); } static inline void applyFtoleft(const t_nrPolar_params *pp, decoder_node_t *node, uint8_t *output) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index 82292fb8fe..83819018a9 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -113,8 +113,7 @@ typedef struct nrPolar_params { int *rm_tab; uint64_t cprime_tab0[16][256]; uint64_t cprime_tab1[16][256]; - uint64_t B_tab0[16][256]; - uint64_t B_tab1[16][256]; + decoder_tree_t decoder; } t_nrPolar_params; void polar_encoder(uint32_t *input, @@ -172,9 +171,8 @@ static inline int8_t *treeBeta(decoder_node_t *node) return (int8_t *)node + node->beta; } -void build_decoder_tree(decoder_tree_t *tree, const t_nrPolar_params *pp); +void build_decoder_tree(t_nrPolar_params *pp); void build_polar_tables(t_nrPolar_params *polarParams); -void init_polar_deinterleaver_table(t_nrPolar_params *polarParams); void nr_polar_print_polarParams(void); diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c index 285f936085..cc85216f23 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c @@ -452,6 +452,8 @@ void build_polar_tables(t_nrPolar_params *polarParams) { // rerun again to create groups for (int outpos = 0, tcnt = 0; outpos < polarParams->encoderLength; outpos += mingroupsize, tcnt++) polarParams->rm_tab[tcnt] = polarParams->rate_matching_pattern[outpos] >> shift; + + build_decoder_tree(polarParams); } diff --git a/openair1/PHY/CODING/nr_polar_init.c b/openair1/PHY/CODING/nr_polar_init.c index d0c9dc3c60..dda293a07e 100644 --- a/openair1/PHY/CODING/nr_polar_init.c +++ b/openair1/PHY/CODING/nr_polar_init.c @@ -246,8 +246,6 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui qsort((void *)newPolarInitNode->Q_I_N,newPolarInitNode->K,sizeof(int16_t),intcmp); build_polar_tables(newPolarInitNode); - - init_polar_deinterleaver_table(newPolarInitNode); return newPolarInitNode; } From a23520664767f51c2e9d31b8a08d6e5d607e080a Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 4 Sep 2024 18:20:49 +0200 Subject: [PATCH 3/8] minor improvements for memory and SIMDE --- openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c | 4 ++-- openair1/PHY/CODING/nr_polar_init.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) 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 a3d20a37c7..412f1a9a48 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -320,13 +320,13 @@ static inline void applyGtoright(const t_nrPolar_params *pp, decoder_node_t *nod int avx2len = sz / 16; for (int i = 0; i < avx2len; i++) { - simde__m256i tmp = simde_mm256_sign_epi16(((simde__m256i *)alpha_v)[i], _mm256_cvtepi8_epi16(((simde__m128i *)betal)[i])); + simde__m256i tmp = simde_mm256_sign_epi16(((simde__m256i *)alpha_v)[i], simde_mm256_cvtepi8_epi16(((simde__m128i *)betal)[i])); ((simde__m256i *)alpha_r)[i] = simde_mm256_subs_epi16(((simde__m256i *)alpha_v)[i + avx2len], tmp); } } else if (avx2mod == 8) { - simde__m128i tmp = simde_mm_sign_epi16(((simde__m128i *)alpha_v)[0], _mm_cvtepi8_epi16(((simde__m128i *)betal)[0])); + simde__m128i tmp = simde_mm_sign_epi16(((simde__m128i *)alpha_v)[0], simde_mm_cvtepi8_epi16(((simde__m128i *)betal)[0])); ((simde__m128i *)alpha_r)[0] = simde_mm_subs_epi16(((simde__m128i *)alpha_v)[1], tmp); } else { for (int i = 0; i < sz; i++) { diff --git a/openair1/PHY/CODING/nr_polar_init.c b/openair1/PHY/CODING/nr_polar_init.c index dda293a07e..1b04f76da3 100644 --- a/openair1/PHY/CODING/nr_polar_init.c +++ b/openair1/PHY/CODING/nr_polar_init.c @@ -57,6 +57,7 @@ static void nr_polar_delete_list(t_nrPolar_params * polarParams) { free(polarParams->rate_matching_pattern); free(polarParams->information_bit_pattern); free(polarParams->parity_check_bit_pattern); + free(polarParams->i_bil_pattern); free(polarParams->Q_I_N); free(polarParams->Q_F_N); free(polarParams->Q_PC_N); From 00e50f082d9a0ca7f04c92896e6589c5c8509a7e Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 10 Sep 2024 10:38:48 +0200 Subject: [PATCH 4/8] Limit recursion in polar decoder Use non-recursive polar decoder after traversing the tree once. Maximum number of nodes is set to 600 (unsure of the maximum). This is more performant than the recursive version. --- .../nrPolar_tools/nr_polar_decoding_tools.c | 46 +++++++++++++++++-- .../PHY/CODING/nrPolar_tools/nr_polar_defs.h | 14 +++++- openair1/PHY/CODING/nr_polar_init.c | 2 +- 3 files changed, 56 insertions(+), 6 deletions(-) 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 412f1a9a48..21827c4bc5 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -390,17 +390,55 @@ static inline void computeBeta(decoder_node_t *node) node->betaInit = true; } -void generic_polar_decoder(const t_nrPolar_params *pp, decoder_node_t *node, uint8_t *nr_polar_U) -{ +void generic_polar_decoder_recursive(t_nrPolar_params *pp, decoder_node_t *node, uint8_t *nr_polar_U) { // Apply F to left applyFtoleft(pp, node, nr_polar_U); + int iter = pp->tree_linearization.iter++; + pp->tree_linearization.op_list[iter].op_code = POLAR_OP_CODE_LEFT; + pp->tree_linearization.op_list[iter].node = node; + // if left is not a leaf recurse down to the left if (node->left->leaf==0) - generic_polar_decoder(pp, node->left, nr_polar_U); + generic_polar_decoder_recursive(pp, node->left, nr_polar_U); applyGtoright(pp, node, nr_polar_U); + iter = pp->tree_linearization.iter++; + pp->tree_linearization.op_list[iter].op_code = POLAR_OP_CODE_RIGHT; + pp->tree_linearization.op_list[iter].node = node; + if (node->right->leaf == 0) - generic_polar_decoder(pp, node->right, nr_polar_U); + generic_polar_decoder_recursive(pp, node->right, nr_polar_U); computeBeta(node); + + iter = pp->tree_linearization.iter++; + pp->tree_linearization.op_list[iter].op_code = POLAR_OP_CODE_BETA; + pp->tree_linearization.op_list[iter].node = node; +} + +void generic_polar_decoder(t_nrPolar_params *pp, decoder_node_t *node, uint8_t *nr_polar_U) +{ + if (pp->tree_linearization.is_initialized == false) { + pp->tree_linearization.iter = 0; + generic_polar_decoder_recursive(pp, node, nr_polar_U); + pp->tree_linearization.is_initialized = true; + AssertFatal(pp->tree_linearization.iter < sizeofArray(pp->tree_linearization.op_list), + "Arbitrary size %lu is too small, number of operations is %d", + sizeofArray(pp->tree_linearization.op_list), + pp->tree_linearization.iter); + } else { + for (int i = 0; i < pp->tree_linearization.iter; i++) { + decoder_node_t *n = pp->tree_linearization.op_list[i].node; + switch (pp->tree_linearization.op_list[i].op_code) { + case POLAR_OP_CODE_LEFT: + applyFtoleft(pp, n, nr_polar_U); + break; + case POLAR_OP_CODE_RIGHT: + applyGtoright(pp, n, nr_polar_U); + break; + case POLAR_OP_CODE_BETA: + computeBeta(n); + } + } + } } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index 83819018a9..546260a5f2 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -60,6 +60,10 @@ static const uint8_t nr_polar_subblock_interleaver_pattern[32] = {0,1,2,4,3,5,6, #define uint128_t __uint128_t +#define POLAR_OP_CODE_LEFT 0 +#define POLAR_OP_CODE_RIGHT 1 +#define POLAR_OP_CODE_BETA 2 + typedef struct decoder_node_t_s { struct decoder_node_t_s *left; struct decoder_node_t_s *right; @@ -114,6 +118,14 @@ typedef struct nrPolar_params { uint64_t cprime_tab0[16][256]; uint64_t cprime_tab1[16][256]; decoder_tree_t decoder; + struct { + int iter; + bool is_initialized; + struct { + int op_code; + decoder_node_t* node; + } op_list[600]; + } tree_linearization; } t_nrPolar_params; void polar_encoder(uint32_t *input, @@ -159,7 +171,7 @@ int8_t polar_decoder_dci(double *input, uint16_t messageLength, uint8_t aggregation_level); -void generic_polar_decoder(const t_nrPolar_params *pp, decoder_node_t *node, uint8_t *nr_polar_U); +void generic_polar_decoder(t_nrPolar_params *pp, decoder_node_t *node, uint8_t *nr_polar_U); static inline int16_t *treeAlpha(decoder_node_t *node) { diff --git a/openair1/PHY/CODING/nr_polar_init.c b/openair1/PHY/CODING/nr_polar_init.c index 1b04f76da3..899aa5447f 100644 --- a/openair1/PHY/CODING/nr_polar_init.c +++ b/openair1/PHY/CODING/nr_polar_init.c @@ -98,7 +98,7 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui t_nrPolar_params *newPolarInitNode = malloc(sizeof(t_nrPolar_params)); AssertFatal(newPolarInitNode, "[nr_polar_init] New t_nrPolar_params * could not be created"); - *newPolarInitNode = (t_nrPolar_params){.busy = true, .nextPtr = PolarList}; + *newPolarInitNode = (t_nrPolar_params){.busy = true, .nextPtr = PolarList, .tree_linearization.is_initialized = false}; PolarList = newPolarInitNode; pthread_mutex_unlock(&PolarListMutex); // LOG_D(PHY,"Setting new polarParams index %d, messageType %d, messageLength %d, aggregation_prime %d\n",(messageType * messageLength * aggregation_prime),messageType,messageLength,aggregation_prime); From 4a971caf9f2e161958caa98da7308ac89118ae43 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 4 Oct 2024 15:24:35 +0200 Subject: [PATCH 5/8] use SIMD in the highest cpu part the version in develop is difficult to understand, and surprizing design it loops only when avx2mod == 0 because when this test is false, the size is always small i also spent time to understand, but i think i have not changed it by not looping over the array. --- .../nrPolar_tools/nr_polar_decoding_tools.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) 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 21827c4bc5..434c8a420d 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -321,24 +321,16 @@ static inline void applyGtoright(const t_nrPolar_params *pp, decoder_node_t *nod for (int i = 0; i < avx2len; i++) { simde__m256i tmp = simde_mm256_sign_epi16(((simde__m256i *)alpha_v)[i], simde_mm256_cvtepi8_epi16(((simde__m128i *)betal)[i])); - ((simde__m256i *)alpha_r)[i] = - - simde_mm256_subs_epi16(((simde__m256i *)alpha_v)[i + avx2len], tmp); + ((simde__m256i *)alpha_r)[i] = simde_mm256_subs_epi16(((simde__m256i *)alpha_v)[i + avx2len], tmp); } } else if (avx2mod == 8) { simde__m128i tmp = simde_mm_sign_epi16(((simde__m128i *)alpha_v)[0], simde_mm_cvtepi8_epi16(((simde__m128i *)betal)[0])); ((simde__m128i *)alpha_r)[0] = simde_mm_subs_epi16(((simde__m128i *)alpha_v)[1], tmp); } else { - for (int i = 0; i < sz; i++) { - int temp_alpha_r = alpha_v[i + sz] - (betal[i] * alpha_v[i]); - if (temp_alpha_r > SHRT_MAX) { - alpha_r[i] = SHRT_MAX; - } else if (temp_alpha_r < -SHRT_MAX) { - alpha_r[i] = -SHRT_MAX; - } else { - alpha_r[i] = temp_alpha_r; - } - } + simde__m128i tmp = simde_mm_sign_epi16(*(simde__m128i *)alpha_v, simde_mm_cvtepi8_epi16(*(simde__m128i *)betal)); + simde__m128i tmp2 = simde_mm_loadu_si128((simde__m128i *)(alpha_v + sz)); + simde__m128i res = simde_mm_subs_epi16(tmp2, tmp); + simde_mm_storeu_si128(alpha_r, res); } } if (sz == 1) { // apply hard decision on right node From 28234893f79dd0eaa32aad46c2c651c050c147dd Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 18 Oct 2024 11:29:32 +0200 Subject: [PATCH 6/8] add default value setting instead of assert if we process uninitialized beta --- .../CODING/nrPolar_tools/nr_polar_decoding_tools.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) 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 434c8a420d..85fb382102 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -358,8 +358,15 @@ static inline void computeBeta(decoder_node_t *node) #endif assert(node->level); const int sz = 1 << (node->level - 1); - if (node->left->all_frozen==0) { // if left node is not aggregation of frozen bits - assert(node->left->betaInit && node->right->betaInit); + if (node->left->all_frozen == 0) { // if left node is not aggregation of frozen bits + if (!node->left->betaInit) { + memset(betal, -1, sz); + node->left->betaInit = true; + } + if (!node->right->betaInit) { + memset(betar, -1, sz); + node->right->betaInit = true; + } int avx2mod = sz & 31; if (avx2mod == 0) { int avx2len = sz / 16; From 16535f3de411c4a47cb814a82dda1b0ca8387366 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 7 Nov 2024 09:43:16 +0100 Subject: [PATCH 7/8] Reformat all polar code Commands used: clang-format -i openair1/PHY/CODING/TESTBENCH/polartest.c clang-format -i openair1/PHY/CODING/nr_polar_init.c clang-format -i openair1/PHY/CODING/nrPolar_tools/* --- openair1/PHY/CODING/TESTBENCH/polartest.c | 397 +++++++++-------- .../nrPolar_tools/nr_bitwise_operations.c | 8 +- .../PHY/CODING/nrPolar_tools/nr_crc_byte.c | 14 +- .../CODING/nrPolar_tools/nr_polar_dci_defs.h | 36 +- .../CODING/nrPolar_tools/nr_polar_decoder.c | 406 ++++++++++-------- .../nrPolar_tools/nr_polar_decoding_tools.c | 110 ++--- .../PHY/CODING/nrPolar_tools/nr_polar_defs.h | 133 +++--- .../CODING/nrPolar_tools/nr_polar_encoder.c | 278 ++++++------ .../nr_polar_interleaving_pattern.c | 5 +- .../nrPolar_tools/nr_polar_kernal_operation.c | 79 ++-- .../nrPolar_tools/nr_polar_matrix_and_array.c | 5 +- .../CODING/nrPolar_tools/nr_polar_pbch_defs.h | 72 ++-- .../nrPolar_tools/nr_polar_procedures.c | 143 +++--- .../nrPolar_tools/nr_polar_pucch_defs.h | 23 +- .../nrPolar_tools/nr_polar_rate_match.c | 7 +- .../nrPolar_tools/nr_polar_sequence_pattern.c | 112 ++++- .../CODING/nrPolar_tools/nr_polar_uci_defs.h | 28 +- openair1/PHY/CODING/nr_polar_init.c | 111 +++-- 18 files changed, 1041 insertions(+), 926 deletions(-) diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index f39da2eb6d..beab44c689 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -12,161 +12,162 @@ #include "PHY/CODING/coding_defs.h" #include "SIMULATION/TOOLS/sim.h" #include "common/config/config_userapi.h" -//#include "common/utils/LOG/log.h" +// #include "common/utils/LOG/log.h" #include "coding_unitary_defs.h" -//#define DEBUG_DCI_POLAR_PARAMS -//#define DEBUG_POLAR_TIMING -//#define DEBUG_POLARTEST +// #define DEBUG_DCI_POLAR_PARAMS +// #define DEBUG_POLAR_TIMING +// #define DEBUG_POLARTEST configmodule_interface_t *uniqCfg = NULL; int main(int argc, char *argv[]) { - //Default simulation values (Aim for iterations = 1000000.) - int decoder_int16=0; - int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, 2=UCI - double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB + // Default simulation values (Aim for iterations = 1000000.) + int decoder_int16 = 0; + int itr, iterations = 1000, arguments, polarMessageType = 0; // 0=PBCH, 1=DCI, 2=UCI + double SNRstart = -20.0, SNRstop = 0.0, SNRinc = 0.5; // dB double SNR, SNR_lin; int16_t nBitError = 0; // -1 = Decoding failed (All list entries have failed the CRC checks). - uint32_t decoderState=0, blockErrorState=0; //0 = Success, -1 = Decoding failed, 1 = Block Error. + uint32_t decoderState = 0, blockErrorState = 0; // 0 = Success, -1 = Decoding failed, 1 = Block Error. uint16_t testLength = NR_POLAR_PBCH_PAYLOAD_BITS, coderLength = NR_POLAR_PBCH_E; - uint16_t blockErrorCumulative=0, bitErrorCumulative=0; + uint16_t blockErrorCumulative = 0, bitErrorCumulative = 0; uint8_t aggregation_level = 8, decoderListSize = 8, logFlag = 0; - uint16_t rnti=0; + uint16_t rnti = 0; if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == 0) { exit_fun("[POLARTEST] Error, configuration module init failed\n"); } logInit(); - while ((arguments = getopt (argc, argv, "--:O:s:d:f:m:i:l:a:p:hqgFL:k:")) != -1) { - + while ((arguments = getopt(argc, argv, "--:O:s:d:f:m:i:l:a:p:hqgFL:k:")) != -1) { /* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */ /* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */ if (arguments == 1 || arguments == '-' || arguments == 'O') continue; - printf("handling optarg %c\n",arguments); + printf("handling optarg %c\n", arguments); switch (arguments) { - case 's': - SNRstart = atof(optarg); - SNRstop = SNRstart + 2; - break; + case 's': + SNRstart = atof(optarg); + SNRstop = SNRstart + 2; + break; - case 'd': - SNRinc = atof(optarg); - break; + case 'd': + SNRinc = atof(optarg); + break; - case 'f': - SNRstop = atof(optarg); - break; + case 'f': + SNRstop = atof(optarg); + break; - case 'm': - polarMessageType = atoi(optarg); - if (polarMessageType!=0 && polarMessageType!=1 && polarMessageType!=2) - printf("Illegal polar message type %d (should be 0,1 or 2)\n", polarMessageType); - break; + case 'm': + polarMessageType = atoi(optarg); + if (polarMessageType != 0 && polarMessageType != 1 && polarMessageType != 2) + printf("Illegal polar message type %d (should be 0,1 or 2)\n", polarMessageType); + break; - case 'i': - iterations = atoi(optarg); - break; + case 'i': + iterations = atoi(optarg); + break; - case 'l': - decoderListSize = (uint8_t) atoi(optarg); - break; + case 'l': + decoderListSize = (uint8_t)atoi(optarg); + break; - case 'q': - decoder_int16 = 1; - break; + case 'q': + decoder_int16 = 1; + break; - case 'g': - iterations = 1; - SNRstart = -6.0; - SNRstop = -6.0; - decoder_int16 = 1; - break; + case 'g': + iterations = 1; + SNRstart = -6.0; + SNRstop = -6.0; + decoder_int16 = 1; + break; - case 'F': - logFlag = 1; - break; + case 'F': + logFlag = 1; + break; - case 'L': - aggregation_level=atoi(optarg); - if (aggregation_level != 1 && aggregation_level != 2 && aggregation_level != 4 && aggregation_level != 8 - && aggregation_level != 16) { - printf("Illegal aggregation level %d \n", aggregation_level); + case 'L': + aggregation_level = atoi(optarg); + if (aggregation_level != 1 && aggregation_level != 2 && aggregation_level != 4 && aggregation_level != 8 + && aggregation_level != 16) { + printf("Illegal aggregation level %d \n", aggregation_level); + exit(-1); + } + break; + + case 'k': + testLength = atoi(optarg); + if (testLength < 12 || testLength > 127) { + printf("Illegal packet bitlength %d \n", testLength); + exit(-1); + } + break; + + case 'h': + printf( + "./polartest\nOptions\n-h Print this help\n-s SNRstart (dB)\n-d SNRinc (dB)\n-f SNRstop (dB)\n-m [0=PBCH|1=DCI|2=UCI]\n" + "-i Number of iterations\n-l decoderListSize\n-q Flag for optimized coders usage\n-F Flag for test results logging\n" + "-L aggregation level (for DCI)\n-k packet_length (bits) for DCI/UCI\n"); exit(-1); - } - break; + break; - case 'k': - testLength=atoi(optarg); - if (testLength < 12 || testLength > 127) { - printf("Illegal packet bitlength %d \n",testLength); - exit(-1); - } - break; - - case 'h': - printf( - "./polartest\nOptions\n-h Print this help\n-s SNRstart (dB)\n-d SNRinc (dB)\n-f SNRstop (dB)\n-m [0=PBCH|1=DCI|2=UCI]\n" - "-i Number of iterations\n-l decoderListSize\n-q Flag for optimized coders usage\n-F Flag for test results logging\n" - "-L aggregation level (for DCI)\n-k packet_length (bits) for DCI/UCI\n"); - exit(-1); - break; - - default: - perror("[polartest.c] Problem at argument parsing with getopt"); - exit(-1); - break; + default: + perror("[polartest.c] Problem at argument parsing with getopt"); + exit(-1); + break; } } - //Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.) - time_stats_t timeEncoder,timeDecoder; + // Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.) + time_stats_t timeEncoder, timeDecoder; cpu_meas_enabled = 1; reset_meas(&timeEncoder); reset_meas(&timeDecoder); randominit(0); crcTableInit(); - if (polarMessageType == 0) { //PBCH + if (polarMessageType == 0) { // PBCH aggregation_level = NR_POLAR_PBCH_AGGREGATION_LEVEL; - } else if (polarMessageType == 1) { //DCI - coderLength = 108*aggregation_level; - } else if (polarMessageType == 2) { //UCI - //pucch2 parameters, 1 symbol, aggregation_level = NPRB - AssertFatal(aggregation_level>2,"For UCI formats, aggregation (N_RB) should be > 2\n"); - coderLength = 16*aggregation_level; + } else if (polarMessageType == 1) { // DCI + coderLength = 108 * aggregation_level; + } else if (polarMessageType == 2) { // UCI + // pucch2 parameters, 1 symbol, aggregation_level = NPRB + AssertFatal(aggregation_level > 2, "For UCI formats, aggregation (N_RB) should be > 2\n"); + coderLength = 16 * aggregation_level; } - //Logging + // Logging time_t currentTime; char fileName[512], currentTimeInfo[25]; char folderName[] = "."; FILE *logFile = NULL; - if (logFlag){ - time (¤tTime); + if (logFlag) { + time(¤tTime); #ifdef DEBUG_POLAR_TIMING - sprintf(fileName,"%s/TIMING_ListSize_%d_Payload_%d_Itr_%d", folderName, decoderListSize, testLength, iterations); + sprintf(fileName, "%s/TIMING_ListSize_%d_Payload_%d_Itr_%d", folderName, decoderListSize, testLength, iterations); #else - sprintf(fileName,"%s/_ListSize_%d_Payload_%d_Itr_%d", folderName, decoderListSize, testLength, iterations); + sprintf(fileName, "%s/_ListSize_%d_Payload_%d_Itr_%d", folderName, decoderListSize, testLength, iterations); #endif strftime(currentTimeInfo, 25, "_%Y-%m-%d-%H-%M-%S.csv", localtime(¤tTime)); - strcat(fileName,currentTimeInfo); - //Create "~/Desktop/polartestResults" folder if it doesn't already exist. + strcat(fileName, currentTimeInfo); + // Create "~/Desktop/polartestResults" folder if it doesn't already exist. /*struct stat folder = {0}; if (stat(folderName, &folder) == -1) mkdir(folderName, S_IRWXU | S_IRWXG | S_IRWXO);*/ logFile = fopen(fileName, "w"); - if (logFile==NULL) { - fprintf(stderr,"[polartest.c] Problem creating file %s with fopen\n",fileName); + if (logFile == NULL) { + fprintf(stderr, "[polartest.c] Problem creating file %s with fopen\n", fileName); exit(-1); } #ifdef DEBUG_POLAR_TIMING - fprintf(logFile,",timeEncoderCRCByte[us],timeEncoderCRCBit[us],timeEncoderInterleaver[us],timeEncoderBitInsertion[us],timeEncoder1[us],timeEncoder2[us],timeEncoderRateMatching[us],timeEncoderByte2Bit[us]\n"); + fprintf(logFile, + ",timeEncoderCRCByte[us],timeEncoderCRCBit[us],timeEncoderInterleaver[us],timeEncoderBitInsertion[us],timeEncoder1[us]," + "timeEncoder2[us],timeEncoderRateMatching[us],timeEncoderByte2Bit[us]\n"); #else - fprintf(logFile,",SNR,nBitError,blockErrorState,t_encoder[us],t_decoder[us]\n"); + fprintf(logFile, ",SNR,nBitError,blockErrorState,t_encoder[us],t_decoder[us]\n"); #endif } @@ -177,54 +178,55 @@ int main(int argc, char *argv[]) // satisfies uint64_t array length const uint8_t realArrayLength = ((testArrayLength + 1) / 2) * 2; printf("testArrayLength %d realArrayLength %d\n", testArrayLength, realArrayLength); - uint32_t testInput[realArrayLength]; //generate randomly + uint32_t testInput[realArrayLength]; // generate randomly uint32_t encoderOutput[coderArrayLength]; - uint32_t estimatedOutput[realArrayLength]; //decoder output - memset(testInput,0,sizeof(uint32_t) * realArrayLength); // does not reset all - memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength); - memset(estimatedOutput,0,sizeof(uint32_t) * realArrayLength); + uint32_t estimatedOutput[realArrayLength]; // decoder output + memset(testInput, 0, sizeof(uint32_t) * realArrayLength); // does not reset all + memset(encoderOutput, 0, sizeof(uint32_t) * coderArrayLength); + memset(estimatedOutput, 0, sizeof(uint32_t) * realArrayLength); uint8_t encoderOutputByte[coderLength]; - double modulatedInput[coderLength]; //channel input - double channelOutput[coderLength]; //add noise + double modulatedInput[coderLength]; // channel input + double channelOutput[coderLength]; // add noise int16_t channelOutput_int16[coderLength]; t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level); #ifdef DEBUG_DCI_POLAR_PARAMS uint32_t dci_pdu[4]; - memset(dci_pdu,0,sizeof(uint32_t)*4); - dci_pdu[0]=0x01189400; + memset(dci_pdu, 0, sizeof(uint32_t) * 4); + dci_pdu[0] = 0x01189400; printf("dci_pdu: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", dci_pdu[0], dci_pdu[1], dci_pdu[2], dci_pdu[3]); - uint16_t size=41; - rnti=3; - aggregation_level=8; + uint16_t size = 41; + rnti = 3; + aggregation_level = 8; uint32_t encoder_output[54]; - memset(encoder_output,0,sizeof(uint32_t)*54); - t_nrPolar_params *currentPtrDCI=nr_polar_params(1, size, aggregation_level); + memset(encoder_output, 0, sizeof(uint32_t) * 54); + t_nrPolar_params *currentPtrDCI = nr_polar_params(1, size, aggregation_level); polar_encoder_dci(dci_pdu, encoder_output, currentPtrDCI, rnti); - for (int i=0; i<54; i++) + for (int i = 0; i < 54; i++) printf("encoder_output: [%2d]->0x%08x \n", i, encoder_output[i]); uint8_t *encoder_outputByte = malloc(sizeof(uint8_t) * currentPtrDCI->encoderLength); - double *modulated_input = malloc (sizeof(double) * currentPtrDCI->encoderLength); - double *channel_output = malloc (sizeof(double) * currentPtrDCI->encoderLength); + double *modulated_input = malloc(sizeof(double) * currentPtrDCI->encoderLength); + double *channel_output = malloc(sizeof(double) * currentPtrDCI->encoderLength); uint32_t dci_est[4]; - memset(dci_est,0,sizeof(dci_est)); + memset(dci_est, 0, sizeof(dci_est)); nr_bit2byte_uint32_8(encoder_output, currentPtrDCI->encoderLength, encoder_outputByte); printf("[polartest] encoder_outputByte: "); - for (int i = 0; i < currentPtrDCI->encoderLength; i++) printf("%d-", encoder_outputByte[i]); printf("\n"); + for (int i = 0; i < currentPtrDCI->encoderLength; i++) + printf("%d-", encoder_outputByte[i]); + printf("\n"); - SNR_lin = pow(10, 0/10); //SNR = 0 dB - for(int i=0; iencoderLength; i++) { + SNR_lin = pow(10, 0 / 10); // SNR = 0 dB + for (int i = 0; i < currentPtrDCI->encoderLength; i++) { if (encoder_outputByte[i] == 0) - modulated_input[i]=1/sqrt(2); + modulated_input[i] = 1 / sqrt(2); else - modulated_input[i]=(-1)/sqrt(2); - channel_output[i] = modulated_input[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin))); + modulated_input[i] = (-1) / sqrt(2); + channel_output[i] = modulated_input[i] + (gaussdouble(0.0, 1.0) * (1 / sqrt(2 * SNR_lin))); } - decoderState = polar_decoder_dci(channel_output, dci_est, NR_POLAR_DECODER_LISTSIZE, rnti, - 1, size, aggregation_level); + decoderState = polar_decoder_dci(channel_output, dci_est, NR_POLAR_DECODER_LISTSIZE, rnti, 1, size, aggregation_level); printf("dci_est: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", dci_est[0], dci_est[1], dci_est[2], dci_est[3]); free(encoder_outputByte); free(channel_output); @@ -235,56 +237,56 @@ int main(int argc, char *argv[]) #endif for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) { - printf("SNR %f\n",SNR); - SNR_lin = pow(10, SNR/10); + printf("SNR %f\n", SNR); + SNR_lin = pow(10, SNR / 10); for (itr = 1; itr <= iterations; itr++) { - //Generate random values for all the bits of "testInput", not just as much as "currentPtr->payloadBits". + // Generate random values for all the bits of "testInput", not just as much as "currentPtr->payloadBits". for (int i = 0; i < testArrayLength; i++) { - for (int j = 0; j < (sizeof(testInput[0])*8)-1; j++) { - testInput[i] |= ( ((uint32_t) (rand()%2)) &1); - testInput[i]<<=1; - } - testInput[i] |= ( ((uint32_t) (rand()%2)) &1); + for (int j = 0; j < (sizeof(testInput[0]) * 8) - 1; j++) { + testInput[i] |= (((uint32_t)(rand() % 2)) & 1); + testInput[i] <<= 1; + } + testInput[i] |= (((uint32_t)(rand() % 2)) & 1); } #ifdef DEBUG_POLARTEST - //testInput[0] = 0x360f8a5c; + // testInput[0] = 0x360f8a5c; printf("testInput: [0]->0x%08x\n", testInput[0]); #endif - int len_mod64=currentPtr->payloadBits&63; - ((uint64_t *)testInput)[currentPtr->payloadBits/64]&=((((uint64_t)1)<payloadBits & 63; + ((uint64_t *)testInput)[currentPtr->payloadBits / 64] &= ((((uint64_t)1) << len_mod64) - 1); start_meas(&timeEncoder); - if (decoder_int16==1) { - polar_encoder_fast((uint64_t *)testInput, encoderOutput, 0, 0, polarMessageType, testLength, aggregation_level); - //polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0,0,currentPtr); - } else { //0 --> PBCH, 1 --> DCI, -1 --> UCI - if (polarMessageType == 0) - polar_encoder(testInput, encoderOutput, polarMessageType, testLength, aggregation_level); - else if (polarMessageType == 1) - polar_encoder_dci(testInput, encoderOutput, rnti, polarMessageType, testLength, aggregation_level); + if (decoder_int16 == 1) { + polar_encoder_fast((uint64_t *)testInput, encoderOutput, 0, 0, polarMessageType, testLength, aggregation_level); + // polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0,0,currentPtr); + } else { // 0 --> PBCH, 1 --> DCI, -1 --> UCI + if (polarMessageType == 0) + polar_encoder(testInput, encoderOutput, polarMessageType, testLength, aggregation_level); + else if (polarMessageType == 1) + polar_encoder_dci(testInput, encoderOutput, rnti, polarMessageType, testLength, aggregation_level); } stop_meas(&timeEncoder); #ifdef DEBUG_POLARTEST printf("encoderOutput: [0]->0x%08x\n", encoderOutput[0]); - //for (int i=1;i0x%08x\n", i, encoderOutput[1]); + // for (int i=1;i0x%08x\n", i, encoderOutput[1]); #endif - //Bit-to-byte: + // Bit-to-byte: nr_bit2byte_uint32_8(encoderOutput, coderLength, encoderOutputByte); - //BPSK modulation - for(int i=0; i 15) channelOutput_int16[i] = 127; else if (channelOutput[i] < -16) @@ -306,7 +308,7 @@ int main(int argc, char *argv[]) } else { // 0 --> PBCH, 1 --> DCI, -1 --> UCI if (polarMessageType == 0) { decoderState = - polar_decoder(channelOutput, estimatedOutput, decoderListSize, polarMessageType, testLength, aggregation_level); + polar_decoder(channelOutput, estimatedOutput, decoderListSize, polarMessageType, testLength, aggregation_level); } else if (polarMessageType == 1) { decoderState = polar_decoder_dci(channelOutput, estimatedOutput, @@ -318,70 +320,83 @@ int main(int argc, char *argv[]) } } stop_meas(&timeDecoder); - + #ifdef DEBUG_POLARTEST printf("estimatedOutput: [0]->0x%08x\n", estimatedOutput[0]); #endif - //calculate errors - if (decoderState!=0) { - blockErrorState=-1; - nBitError=-1; + // calculate errors + if (decoderState != 0) { + blockErrorState = -1; + nBitError = -1; } else { - for (int i = 0; i < (testArrayLength-1); i++) { - for (int j = 0; j < 32; j++) { - if ( ((estimatedOutput[i]>>j) & 1) != ((testInput[i]>>j) & 1) ) - nBitError++; - } - } - for (int j = 0; j < testLength - ((testArrayLength-1) * 32); j++) - if ( ((estimatedOutput[(testArrayLength-1)]>>j) & 1) != ((testInput[(testArrayLength-1)]>>j) & 1) ) - nBitError++; + for (int i = 0; i < (testArrayLength - 1); i++) { + for (int j = 0; j < 32; j++) { + if (((estimatedOutput[i] >> j) & 1) != ((testInput[i] >> j) & 1)) + nBitError++; + } + } + for (int j = 0; j < testLength - ((testArrayLength - 1) * 32); j++) + if (((estimatedOutput[(testArrayLength - 1)] >> j) & 1) != ((testInput[(testArrayLength - 1)] >> j) & 1)) + nBitError++; } - if (nBitError>0) blockErrorState=1; + if (nBitError > 0) + blockErrorState = 1; #ifdef DEBUG_POLARTEST for (int i = 0; i < testArrayLength; i++) - printf("[polartest/decoderState=%u] testInput[%d]=0x%08x, estimatedOutput[%d]=0x%08x\n", - decoderState, - i, - testInput[i], - i, - estimatedOutput[i]); + printf("[polartest/decoderState=%u] testInput[%d]=0x%08x, estimatedOutput[%d]=0x%08x\n", + decoderState, + i, + testInput[i], + i, + estimatedOutput[i]); #endif - //Iteration times are in microseconds. - if (logFlag) fprintf(logFile,",%f,%d,%u,%f,%f\n", SNR, nBitError, blockErrorState, (timeEncoder.diff/(get_cpu_freq_GHz()*1000.0)), (timeDecoder.diff/(get_cpu_freq_GHz()*1000.0))); + // Iteration times are in microseconds. + if (logFlag) + fprintf(logFile, + ",%f,%d,%u,%f,%f\n", + SNR, + nBitError, + blockErrorState, + (timeEncoder.diff / (get_cpu_freq_GHz() * 1000.0)), + (timeDecoder.diff / (get_cpu_freq_GHz() * 1000.0))); - if (nBitError<0) { + if (nBitError < 0) { blockErrorCumulative++; - bitErrorCumulative+=testLength; + bitErrorCumulative += testLength; } else { - blockErrorCumulative+=blockErrorState; - bitErrorCumulative+=nBitError; + blockErrorCumulative += blockErrorState; + bitErrorCumulative += nBitError; } - decoderState=0; - nBitError=0; - blockErrorState=0; - memset(testInput,0,sizeof(uint32_t) * realArrayLength); - memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength); - memset(estimatedOutput,0,sizeof(uint32_t) * realArrayLength); + decoderState = 0; + nBitError = 0; + blockErrorState = 0; + memset(testInput, 0, sizeof(uint32_t) * realArrayLength); + memset(encoderOutput, 0, sizeof(uint32_t) * coderArrayLength); + memset(estimatedOutput, 0, sizeof(uint32_t) * realArrayLength); } - //Calculate error statistics for the SNR. + // Calculate error statistics for the SNR. printf("[ListSize=%d] SNR=%+8.3f, BLER=%9.6f, BER=%12.9f, t_Encoder=%9.3fus, t_Decoder=%9.3fus\n", - decoderListSize, SNR, ((double)blockErrorCumulative/iterations), - ((double)bitErrorCumulative / (iterations*testLength)), - (double)timeEncoder.diff/timeEncoder.trials/(get_cpu_freq_GHz()*1000.0),(double)timeDecoder.diff/timeDecoder.trials/(get_cpu_freq_GHz()*1000.0)); + decoderListSize, + SNR, + ((double)blockErrorCumulative / iterations), + ((double)bitErrorCumulative / (iterations * testLength)), + (double)timeEncoder.diff / timeEncoder.trials / (get_cpu_freq_GHz() * 1000.0), + (double)timeDecoder.diff / timeDecoder.trials / (get_cpu_freq_GHz() * 1000.0)); - if (blockErrorCumulative==0 && bitErrorCumulative==0) break; + if (blockErrorCumulative == 0 && bitErrorCumulative == 0) + break; blockErrorCumulative = 0; bitErrorCumulative = 0; } - print_meas(&timeEncoder,"polar_encoder",NULL,NULL); - print_meas(&timeDecoder,"polar_decoder",NULL,NULL); - if (logFlag) fclose(logFile); + print_meas(&timeEncoder, "polar_encoder", NULL, NULL); + print_meas(&timeDecoder, "polar_decoder", NULL, NULL); + if (logFlag) + fclose(logFile); return (0); } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_bitwise_operations.c b/openair1/PHY/CODING/nrPolar_tools/nr_bitwise_operations.c index d489183d9a..205c94f748 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_bitwise_operations.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_bitwise_operations.c @@ -28,11 +28,12 @@ * \email turker.yilmaz@eurecom.fr * \note * \warning -*/ + */ #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" -void nr_bit2byte_uint32_8(uint32_t *in, uint16_t arraySize, uint8_t *out) { +void nr_bit2byte_uint32_8(uint32_t *in, uint16_t arraySize, uint8_t *out) +{ const uint arrayInd = ceil(arraySize / 32.0); for (int i = 0; i < (arrayInd - 1); i++) { for (int j = 0; j < 32; j++) { @@ -44,7 +45,8 @@ void nr_bit2byte_uint32_8(uint32_t *in, uint16_t arraySize, uint8_t *out) { out[j + ((arrayInd - 1) * 32)] = (in[(arrayInd - 1)] >> j) & 1; } -void nr_byte2bit_uint8_32(uint8_t *in, uint16_t arraySize, uint32_t *out) { +void nr_byte2bit_uint8_32(uint8_t *in, uint16_t arraySize, uint32_t *out) +{ const uint arrayInd = ceil(arraySize / 32.0); for (int i = 0; i < arrayInd; i++) { out[i] = 0; diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_crc_byte.c b/openair1/PHY/CODING/nrPolar_tools/nr_crc_byte.c index d04dde62e7..1908aa654c 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_crc_byte.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_crc_byte.c @@ -29,7 +29,8 @@ const uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits) uint8_t crcPolynomialSize = 24; uint8_t temp1[crcPolynomialSize], temp2[crcPolynomialSize]; - uint8_t **crc_generator_matrix = malloc(payloadSizeBits*sizeof(uint8_t *) + payloadSizeBits*crcPolynomialSize*sizeof(uint8_t)); + uint8_t **crc_generator_matrix = + malloc(payloadSizeBits * sizeof(uint8_t *) + payloadSizeBits * crcPolynomialSize * sizeof(uint8_t)); if (crc_generator_matrix) for (int i = 0; i < payloadSizeBits; i++) crc_generator_matrix[i] = ((uint8_t *)&crc_generator_matrix[payloadSizeBits]) + i * crcPolynomialSize; @@ -38,7 +39,8 @@ const uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits) crc_generator_matrix[payloadSizeBits - 1][i] = crcPolynomialPattern[i + 1]; for (int i = payloadSizeBits - 2; i >= 0; i--) { - for (int j = 0; j < crcPolynomialSize-1; j++) temp1[j]=crc_generator_matrix[i+1][j+1]; + for (int j = 0; j < crcPolynomialSize - 1; j++) + temp1[j] = crc_generator_matrix[i + 1][j + 1]; temp1[crcPolynomialSize - 1] = 0; @@ -46,10 +48,10 @@ const uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits) temp2[j] = crc_generator_matrix[i + 1][0] * crcPolynomialPattern[j + 1]; for (int j = 0; j < crcPolynomialSize; j++) { - if(temp1[j]+temp2[j] == 1) - crc_generator_matrix[i][j]=1; - else - crc_generator_matrix[i][j]=0; + if (temp1[j] + temp2[j] == 1) + crc_generator_matrix[i][j] = 1; + else + crc_generator_matrix[i][j] = 0; } } return (const uint8_t **)crc_generator_matrix; diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_dci_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_dci_defs.h index 842088b26c..871f4f57b0 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_dci_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_dci_defs.h @@ -20,31 +20,31 @@ */ /*! \file PHY/CODING/nrPolar_tools/nr_polar_dci_defs.h -* \brief Defines the constant variables for polar coding of the DCI from 38-212, V15.1.1 2018-04. -* \author -* \date 2018 -* \version 0.1 -* \company Eurecom -* \email: -* \note -* \warning -*/ + * \brief Defines the constant variables for polar coding of the DCI from 38-212, V15.1.1 2018-04. + * \author + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: + * \note + * \warning + */ #ifndef __NR_POLAR_DCI_DEFS__H__ #define __NR_POLAR_DCI_DEFS__H__ -#define NR_POLAR_DCI_MESSAGE_TYPE 1 //int8_t +#define NR_POLAR_DCI_MESSAGE_TYPE 1 // int8_t #define NR_POLAR_DCI_CRC_PARITY_BITS 24 #define NR_POLAR_DCI_CRC_ERROR_CORRECTION_BITS 3 -//Sec. 7.3.3: Channel Coding -#define NR_POLAR_DCI_N_MAX 9 //uint8_t -#define NR_POLAR_DCI_I_IL 1 //uint8_t -#define NR_POLAR_DCI_I_SEG 0 //uint8_t -#define NR_POLAR_DCI_N_PC 0 //uint8_t -#define NR_POLAR_DCI_N_PC_WM 0 //uint8_t +// Sec. 7.3.3: Channel Coding +#define NR_POLAR_DCI_N_MAX 9 // uint8_t +#define NR_POLAR_DCI_I_IL 1 // uint8_t +#define NR_POLAR_DCI_I_SEG 0 // uint8_t +#define NR_POLAR_DCI_N_PC 0 // uint8_t +#define NR_POLAR_DCI_N_PC_WM 0 // uint8_t -//Sec. 7.3.4: Rate Matching -#define NR_POLAR_DCI_I_BIL 0 //uint8_t +// Sec. 7.3.4: Rate Matching +#define NR_POLAR_DCI_I_BIL 0 // uint8_t #endif diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 5a61eebb3d..14013681b0 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -39,17 +39,17 @@ #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "assertions.h" -//#define POLAR_CODING_DEBUG +// #define POLAR_CODING_DEBUG static inline void updateCrcChecksum2(int xlen, - int ylen, - uint8_t crcChecksum[xlen][ylen], - int gxlen, - int gylen, - uint8_t crcGen[gxlen][gylen], - uint8_t listSize, - uint32_t i2, - uint8_t len) + int ylen, + uint8_t crcChecksum[xlen][ylen], + int gxlen, + int gylen, + uint8_t crcGen[gxlen][gylen], + uint8_t listSize, + uint32_t i2, + uint8_t len) { for (uint i = 0; i < listSize; i++) { for (uint j = 0; j < len; j++) { @@ -63,67 +63,71 @@ int8_t polar_decoder(double *input, uint8_t listSize, int8_t messageType, uint16_t messageLength, - uint8_t aggregation_level - ) + uint8_t aggregation_level) { t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level); - //Assumes no a priori knowledge. + // Assumes no a priori knowledge. uint8_t bit[polarParams->N][polarParams->n + 1][2 * listSize]; memset(bit, 0, sizeof bit); - uint8_t bitUpdated[polarParams->N][polarParams->n+1]; //0=False, 1=True - memset(bitUpdated,0,sizeof bitUpdated); - uint8_t llrUpdated[polarParams->N][polarParams->n+1]; //0=False, 1=True - memset(llrUpdated,0,sizeof llrUpdated); + uint8_t bitUpdated[polarParams->N][polarParams->n + 1]; // 0=False, 1=True + memset(bitUpdated, 0, sizeof bitUpdated); + uint8_t llrUpdated[polarParams->N][polarParams->n + 1]; // 0=False, 1=True + memset(llrUpdated, 0, sizeof llrUpdated); double llr[polarParams->N][polarParams->n + 1][2 * listSize]; - uint8_t crcChecksum[polarParams->crcParityBits][2*listSize]; - memset(crcChecksum,0,sizeof crcChecksum); - double pathMetric[2*listSize]; - uint8_t crcState[2*listSize]; //0=False, 1=True + uint8_t crcChecksum[polarParams->crcParityBits][2 * listSize]; + memset(crcChecksum, 0, sizeof crcChecksum); + double pathMetric[2 * listSize]; + uint8_t crcState[2 * listSize]; // 0=False, 1=True - for (int i=0; i<(2*listSize); i++) { + for (int i = 0; i < (2 * listSize); i++) { pathMetric[i] = 0; - crcState[i]=1; + crcState[i] = 1; } - for (int i=0; iN; i++) { - llrUpdated[i][polarParams->n]=1; + for (int i = 0; i < polarParams->N; i++) { + llrUpdated[i][polarParams->n] = 1; bitUpdated[i][0] = (polarParams->information_bit_pattern[i] + 1) % 2; } - uint8_t extended_crc_generator_matrix[polarParams->K][polarParams->crcParityBits]; //G_P3 - uint8_t tempECGM[polarParams->K][polarParams->crcParityBits]; //G_P2 + uint8_t extended_crc_generator_matrix[polarParams->K][polarParams->crcParityBits]; // G_P3 + uint8_t tempECGM[polarParams->K][polarParams->crcParityBits]; // G_P2 - for (int i=0; ipayloadBits; i++) { - for (int j=0; jcrcParityBits; j++) { - tempECGM[i][j]=polarParams->crc_generator_matrix[i][j]; + for (int i = 0; i < polarParams->payloadBits; i++) { + for (int j = 0; j < polarParams->crcParityBits; j++) { + tempECGM[i][j] = polarParams->crc_generator_matrix[i][j]; } } - for (int i=polarParams->payloadBits; iK; i++) { - for (int j=0; jcrcParityBits; j++) { + for (int i = polarParams->payloadBits; i < polarParams->K; i++) { + for (int j = 0; j < polarParams->crcParityBits; j++) { tempECGM[i][j] = (i - polarParams->payloadBits) == j; } } - for (int i=0; iK; i++) { - for (int j=0; jcrcParityBits; j++) { - extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j]; + for (int i = 0; i < polarParams->K; i++) { + for (int j = 0; j < polarParams->crcParityBits; j++) { + extended_crc_generator_matrix[i][j] = tempECGM[polarParams->interleaving_pattern[i]][j]; } } - //The index of the last 1-valued bit that appears in each column. - AssertFatal(polarParams->crcParityBits > 0, "UB for VLA. crcParityBits negative\n"); + // The index of the last 1-valued bit that appears in each column. + AssertFatal(polarParams->crcParityBits > 0, "UB for VLA. crcParityBits negative\n"); uint16_t last1ind[polarParams->crcParityBits]; - for (int j=0; jcrcParityBits; j++) { - for (int i=0; iK; i++) { + for (int j = 0; j < polarParams->crcParityBits; j++) { + for (int i = 0; i < polarParams->K; i++) { if (extended_crc_generator_matrix[i][j] == 1) last1ind[j] = i; } } double d_tilde[polarParams->N]; - nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); + 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]; @@ -131,18 +135,18 @@ int8_t polar_decoder(double *input, /* * SCL polar decoder. */ - uint32_t nonFrozenBit=0; + uint32_t nonFrozenBit = 0; uint currentListSize = 1; uint decoderIterationCheck = 0; int checkCrcBits = -1; - uint8_t listIndex[2*listSize], copyIndex; + uint8_t listIndex[2 * listSize], copyIndex; for (uint currentBit = 0; currentBit < polarParams->N; currentBit++) { updateLLR(currentListSize, currentBit, 0, polarParams->N, polarParams->n + 1, 2 * listSize, llr, llrUpdated, bit, bitUpdated); - if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. + if (polarParams->information_bit_pattern[currentBit] == 0) { // Frozen bit. updatePathMetric(pathMetric, currentListSize, 0, currentBit, polarParams->N, polarParams->n + 1, 2 * listSize, llr); - } else { //Information or CRC bit. + } else { // Information or CRC bit. updatePathMetric2(pathMetric, currentListSize, currentBit, polarParams->N, polarParams->n + 1, 2 * listSize, llr); for (int i = 0; i < currentListSize; i++) { @@ -198,30 +202,30 @@ int8_t polar_decoder(double *input, 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++) { + // First, backup the best "listSize" number of entries. + for (int k = (listSize - 1); k > 0; k--) { + for (int i = 0; i < polarParams->N; 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 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]]; + 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. + // 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[(2 * listSize - 1) - k]; + } else { // Use the backup. copyIndex = listIndex[k]; } @@ -235,40 +239,40 @@ int8_t polar_decoder(double *input, for (int k = 0; k < listSize; k++) { if (k > listIndex[k]) { - copyIndex = listIndex[(2*listSize-1)-k]; - } else { //Use the backup. + 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]; + 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[(2 * listSize - 1) - k]; + } else { // Use the backup. copyIndex = listIndex[k]; } - crcState[k]=crcState[copyIndex]; + crcState[k] = crcState[copyIndex]; } currentListSize = listSize; } - for (int i=0; icrcParityBits; i++) { - if (last1ind[i]==nonFrozenBit) { - checkCrcBits=i; + for (int i = 0; i < polarParams->crcParityBits; i++) { + if (last1ind[i] == nonFrozenBit) { + checkCrcBits = i; break; } } - if ( checkCrcBits > (-1) ) { + if (checkCrcBits > (-1)) { for (uint i = 0; i < currentListSize; i++) { - if (crcChecksum[checkCrcBits][i]==1) { - crcState[i]=0; //0=False, 1=True + if (crcChecksum[checkCrcBits][i] == 1) { + crcState[i] = 0; // 0=False, 1=True } } } @@ -276,15 +280,15 @@ int8_t polar_decoder(double *input, for (uint i = 0; i < currentListSize; i++) decoderIterationCheck += crcState[i]; - if (decoderIterationCheck==0) { - //perror("[SCL polar decoder] All list entries have failed the CRC checks."); + if (decoderIterationCheck == 0) { + // perror("[SCL polar decoder] All list entries have failed the CRC checks."); polarReturn(polarParams); return -1; } nonFrozenBit++; - decoderIterationCheck=0; - checkCrcBits=-1; + decoderIterationCheck = 0; + checkCrcBits = -1; } } @@ -294,19 +298,19 @@ int8_t polar_decoder(double *input, nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize); uint8_t nr_polar_A[polarParams->payloadBits]; for (uint i = 0; i < fmin(listSize, (pow(2, polarParams->crcCorrectionBits))); i++) { - if ( crcState[listIndex[i]] == 1 ) { + if (crcState[listIndex[i]] == 1) { uint8_t nr_polar_U[polarParams->N]; for (int j = 0; j < polarParams->N; j++) nr_polar_U[j] = bit[j][0][listIndex[i]]; - //Extract the information bits (û to ĉ) + // Extract the information bits (û to ĉ) uint8_t nr_polar_CPrime[polarParams->N]; nr_polar_info_bit_extraction(nr_polar_U, nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N); - //Deinterleaving (ĉ to b) + // Deinterleaving (ĉ to b) uint8_t nr_polar_B[polarParams->K]; nr_polar_deinterleaver(nr_polar_CPrime, nr_polar_B, polarParams->interleaving_pattern, polarParams->K); - //Remove the CRC (â) + // Remove the CRC (â) memcpy(nr_polar_A, nr_polar_B, polarParams->payloadBits); break; @@ -328,123 +332,137 @@ int8_t polar_decoder_dci(double *input, uint16_t n_RNTI, int8_t messageType, uint16_t messageLength, - uint8_t aggregation_level ) { + uint8_t aggregation_level) +{ t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level); - uint8_t bit[polarParams->N][polarParams->n+1][2*listSize]; - memset(bit,0,sizeof bit); - uint8_t bitUpdated[polarParams->N][polarParams->n+1]; //0=False, 1=True - memset(bitUpdated,0,sizeof bitUpdated); - uint8_t llrUpdated[polarParams->N][polarParams->n+1]; //0=False, 1=True - memset(llrUpdated,0,sizeof llrUpdated); - double llr[polarParams->N][polarParams->n+1][2*listSize]; - uint8_t crcChecksum[polarParams->crcParityBits][2*listSize]; - memset(crcChecksum,0,sizeof crcChecksum); - double pathMetric[2*listSize]; - uint8_t crcState[2*listSize]; //0=False, 1=True + uint8_t bit[polarParams->N][polarParams->n + 1][2 * listSize]; + memset(bit, 0, sizeof bit); + uint8_t bitUpdated[polarParams->N][polarParams->n + 1]; // 0=False, 1=True + memset(bitUpdated, 0, sizeof bitUpdated); + uint8_t llrUpdated[polarParams->N][polarParams->n + 1]; // 0=False, 1=True + memset(llrUpdated, 0, sizeof llrUpdated); + double llr[polarParams->N][polarParams->n + 1][2 * listSize]; + uint8_t crcChecksum[polarParams->crcParityBits][2 * listSize]; + memset(crcChecksum, 0, sizeof crcChecksum); + double pathMetric[2 * listSize]; + uint8_t crcState[2 * listSize]; // 0=False, 1=True uint8_t extended_crc_scrambling_pattern[polarParams->crcParityBits]; - for (int i=0; i<(2*listSize); i++) { + for (int i = 0; i < (2 * listSize); i++) { pathMetric[i] = 0; - crcState[i]=1; + crcState[i] = 1; } - for (int i=0; iN; i++) { - llrUpdated[i][polarParams->n]=1; + for (int i = 0; i < polarParams->N; i++) { + llrUpdated[i][polarParams->n] = 1; bitUpdated[i][0] = (polarParams->information_bit_pattern[i] + 1) % 2; } - uint8_t extended_crc_generator_matrix[polarParams->K][polarParams->crcParityBits]; //G_P3: K-by-P - uint8_t tempECGM[polarParams->K][polarParams->crcParityBits]; //G_P2: K-by-P + uint8_t extended_crc_generator_matrix[polarParams->K][polarParams->crcParityBits]; // G_P3: K-by-P + uint8_t tempECGM[polarParams->K][polarParams->crcParityBits]; // G_P2: K-by-P - for (int i=0; ipayloadBits; i++) { - for (int j=0; jcrcParityBits; j++) { - tempECGM[i][j]=polarParams->crc_generator_matrix[i+polarParams->crcParityBits][j]; + for (int i = 0; i < polarParams->payloadBits; i++) { + for (int j = 0; j < polarParams->crcParityBits; j++) { + tempECGM[i][j] = polarParams->crc_generator_matrix[i + polarParams->crcParityBits][j]; } } - for (int i=polarParams->payloadBits; iK; i++) { - for (int j=0; jcrcParityBits; j++) { + for (int i = polarParams->payloadBits; i < polarParams->K; i++) { + for (int j = 0; j < polarParams->crcParityBits; j++) { tempECGM[i][j] = (i - polarParams->payloadBits) == j; } } - for (int i=0; iK; i++) { - for (int j=0; jcrcParityBits; j++) { - extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j]; + for (int i = 0; i < polarParams->K; i++) { + for (int j = 0; j < polarParams->crcParityBits; j++) { + extended_crc_generator_matrix[i][j] = tempECGM[polarParams->interleaving_pattern[i]][j]; } } - //The index of the last 1-valued bit that appears in each column. + // The index of the last 1-valued bit that appears in each column. uint16_t last1ind[polarParams->crcParityBits]; - for (int j=0; jcrcParityBits; j++) { - for (int i=0; iK; i++) { - if (extended_crc_generator_matrix[i][j]==1) last1ind[j]=i; + for (int j = 0; j < polarParams->crcParityBits; j++) { + for (int i = 0; i < polarParams->K; i++) { + if (extended_crc_generator_matrix[i][j] == 1) + last1ind[j] = i; } } for (int i = 0; i < 8; i++) extended_crc_scrambling_pattern[i] = 0; - for (int i=8; icrcParityBits; i++) { - extended_crc_scrambling_pattern[i]=(n_RNTI>>(23-i))&1; + for (int i = 8; i < polarParams->crcParityBits; i++) { + extended_crc_scrambling_pattern[i] = (n_RNTI >> (23 - i)) & 1; } double d_tilde[polarParams->N]; - nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); + 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]; + llr[j][polarParams->n][0] = d_tilde[j]; /* * SCL polar decoder. */ - for (int i=0; icrcParityBits; i++) { - for (int j=0; jcrcParityBits; j++) - crcChecksum[i][0]=crcChecksum[i][0]+polarParams->crc_generator_matrix[j][i]; + for (int i = 0; i < polarParams->crcParityBits; i++) { + for (int j = 0; j < polarParams->crcParityBits; j++) + crcChecksum[i][0] = crcChecksum[i][0] + polarParams->crc_generator_matrix[j][i]; - crcChecksum[i][0]=(crcChecksum[i][0]%2); + crcChecksum[i][0] = (crcChecksum[i][0] % 2); } - uint32_t nonFrozenBit=0; + uint32_t nonFrozenBit = 0; uint currentListSize = 1; uint decoderIterationCheck = 0; int checkCrcBits = -1; - uint8_t listIndex[2*listSize], copyIndex; + uint8_t listIndex[2 * listSize], copyIndex; for (uint currentBit = 0; currentBit < polarParams->N; currentBit++) { - updateLLR(currentListSize, currentBit, 0, polarParams->N, polarParams->n+1, 2*listSize, llr, llrUpdated, bit, bitUpdated); + updateLLR(currentListSize, currentBit, 0, polarParams->N, polarParams->n + 1, 2 * listSize, llr, llrUpdated, bit, bitUpdated); - if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. - updatePathMetric(pathMetric, currentListSize, 0, currentBit,polarParams->N, polarParams->n+1, 2*listSize, llr); - } else { //Information or CRC bit. - updatePathMetric2(pathMetric, currentListSize, currentBit, polarParams->N, polarParams->n+1, 2*listSize, llr); + if (polarParams->information_bit_pattern[currentBit] == 0) { // Frozen bit. + updatePathMetric(pathMetric, currentListSize, 0, currentBit, polarParams->N, polarParams->n + 1, 2 * listSize, llr); + } else { // Information or CRC bit. + updatePathMetric2(pathMetric, currentListSize, currentBit, polarParams->N, polarParams->n + 1, 2 * listSize, llr); 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 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]; + bit[currentBit][0][i] = 0; + crcState[i + currentListSize] = crcState[i]; } - for (int i = currentListSize; i < 2*currentListSize; i++) bit[currentBit][0][i]=1; + for (int i = currentListSize; i < 2 * currentListSize; i++) + bit[currentBit][0][i] = 1; - bitUpdated[currentBit][0]=1; - updateCrcChecksum2(polarParams->crcParityBits, 2*listSize, crcChecksum, - polarParams->K, polarParams->crcParityBits, extended_crc_generator_matrix, - currentListSize, nonFrozenBit, polarParams->crcParityBits); - currentListSize*=2; + bitUpdated[currentBit][0] = 1; + updateCrcChecksum2(polarParams->crcParityBits, + 2 * listSize, + crcChecksum, + polarParams->K, + polarParams->crcParityBits, + extended_crc_generator_matrix, + currentListSize, + nonFrozenBit, + polarParams->crcParityBits); + currentListSize *= 2; - //Keep only the best "listSize" number of entries. + // Keep only the best "listSize" number of entries. if (currentListSize > listSize) { for (uint i = 0; i < 2 * listSize; i++) listIndex[i] = i; @@ -456,7 +474,7 @@ int8_t polar_decoder_dci(double *input, int swaps = 0; for (uint j = listSize; j < (2 * listSize - i) - 1; j++) { - if (listIndex[j+1] > listIndex[j]) { + if (listIndex[j + 1] > listIndex[j]) { int tempInd = listIndex[j]; listIndex[j] = listIndex[j + 1]; listIndex[j + 1] = tempInd; @@ -468,30 +486,30 @@ int8_t polar_decoder_dci(double *input, 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]]; + // First, backup the best "listSize" number of entries. + for (int k = (listSize - 1); k > 0; k--) { + for (int i = 0; i < polarParams->N; 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 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]]; + 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. + // 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[(2 * listSize - 1) - k]; + } else { // Use the backup. copyIndex = listIndex[k]; } @@ -505,40 +523,40 @@ int8_t polar_decoder_dci(double *input, for (int k = 0; k < listSize; k++) { if (k > listIndex[k]) { - copyIndex = listIndex[(2*listSize-1)-k]; - } else { //Use the backup. + 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]; + 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[(2 * listSize - 1) - k]; + } else { // Use the backup. copyIndex = listIndex[k]; } - crcState[k]=crcState[copyIndex]; + crcState[k] = crcState[copyIndex]; } currentListSize = listSize; } - for (int i=0; icrcParityBits; i++) { - if (last1ind[i]==nonFrozenBit) { - checkCrcBits=i; + for (int i = 0; i < polarParams->crcParityBits; i++) { + if (last1ind[i] == nonFrozenBit) { + checkCrcBits = i; break; } } - if ( checkCrcBits > (-1) ) { + if (checkCrcBits > (-1)) { for (uint i = 0; i < currentListSize; i++) { - if (crcChecksum[checkCrcBits][i]!=extended_crc_scrambling_pattern[checkCrcBits]) { - crcState[i]=0; //0=False, 1=True + if (crcChecksum[checkCrcBits][i] != extended_crc_scrambling_pattern[checkCrcBits]) { + crcState[i] = 0; // 0=False, 1=True } } } @@ -546,15 +564,15 @@ int8_t polar_decoder_dci(double *input, for (uint i = 0; i < currentListSize; i++) decoderIterationCheck += crcState[i]; - if (decoderIterationCheck==0) { - //perror("[SCL polar decoder] All list entries have failed the CRC checks."); + if (decoderIterationCheck == 0) { + // perror("[SCL polar decoder] All list entries have failed the CRC checks."); polarReturn(polarParams); return -1; } nonFrozenBit++; - decoderIterationCheck=0; - checkCrcBits=-1; + decoderIterationCheck = 0; + checkCrcBits = -1; } } @@ -565,19 +583,19 @@ int8_t polar_decoder_dci(double *input, uint8_t nr_polar_A[polarParams->payloadBits]; for (uint i = 0; i < fmin(listSize, (pow(2, polarParams->crcCorrectionBits))); i++) { - if ( crcState[listIndex[i]] == 1 ) { + if (crcState[listIndex[i]] == 1) { uint8_t nr_polar_U[polarParams->N]; for (int j = 0; j < polarParams->N; j++) nr_polar_U[j] = bit[j][0][listIndex[i]]; - //Extract the information bits (û to ĉ) + // Extract the information bits (û to ĉ) uint8_t nr_polar_CPrime[polarParams->N]; nr_polar_info_bit_extraction(nr_polar_U, nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N); - //Deinterleaving (ĉ to b) + // Deinterleaving (ĉ to b) uint8_t nr_polar_B[polarParams->K]; nr_polar_deinterleaver(nr_polar_CPrime, nr_polar_B, polarParams->interleaving_pattern, polarParams->K); - //Remove the CRC (â) + // Remove the CRC (â) memcpy(nr_polar_A, nr_polar_B, polarParams->payloadBits); break; } @@ -740,55 +758,61 @@ uint32_t polar_decoder_int16(int16_t *input, printf("\n"); #endif - int len=polarParams->payloadBits; - //int len_mod64=len&63; + int len = polarParams->payloadBits; + // int len_mod64=len&63; int crclen = polarParams->crcParityBits; - uint64_t rxcrc=B[0]&((1<>crclen); - uint8_t A32_flip[4+offset]; + if (len <= 32) { + Ar = (uint32_t)(B[0] >> crclen); + uint8_t A32_flip[4 + offset]; if (ones_flag) { A32_flip[0] = 0xff; A32_flip[1] = 0xff; A32_flip[2] = 0xff; } - uint32_t Aprime= (uint32_t)(Ar<<(32-len)); - A32_flip[0+offset]=((uint8_t *)&Aprime)[3]; - A32_flip[1+offset]=((uint8_t *)&Aprime)[2]; - A32_flip[2+offset]=((uint8_t *)&Aprime)[1]; - A32_flip[3+offset]=((uint8_t *)&Aprime)[0]; - if (crclen == 24) crc = (uint64_t)((crc24c(A32_flip,8*offset+len)>>8)&0xffffff); - else if (crclen == 11) crc = (uint64_t)((crc11(A32_flip,8*offset+len)>>21)&0x7ff); - else if (crclen == 6) crc = (uint64_t)((crc6(A32_flip,8*offset+len)>>26)&0x3f); - } else if (len<=64) { + uint32_t Aprime = (uint32_t)(Ar << (32 - len)); + A32_flip[0 + offset] = ((uint8_t *)&Aprime)[3]; + A32_flip[1 + offset] = ((uint8_t *)&Aprime)[2]; + A32_flip[2 + offset] = ((uint8_t *)&Aprime)[1]; + A32_flip[3 + offset] = ((uint8_t *)&Aprime)[0]; + if (crclen == 24) + crc = (uint64_t)((crc24c(A32_flip, 8 * offset + len) >> 8) & 0xffffff); + else if (crclen == 11) + crc = (uint64_t)((crc11(A32_flip, 8 * offset + len) >> 21) & 0x7ff); + else if (crclen == 6) + crc = (uint64_t)((crc6(A32_flip, 8 * offset + len) >> 26) & 0x3f); + } else if (len <= 64) { Ar = (B[0] >> crclen) | (B[1] << (64 - crclen)); - uint8_t A64_flip[8+offset]; + uint8_t A64_flip[8 + offset]; if (ones_flag) { A64_flip[0] = 0xff; A64_flip[1] = 0xff; A64_flip[2] = 0xff; } - uint64_t Aprime= (uint64_t)(Ar<<(64-len)); - A64_flip[0+offset]=((uint8_t *)&Aprime)[7]; - A64_flip[1+offset]=((uint8_t *)&Aprime)[6]; - A64_flip[2+offset]=((uint8_t *)&Aprime)[5]; - A64_flip[3+offset]=((uint8_t *)&Aprime)[4]; - A64_flip[4+offset]=((uint8_t *)&Aprime)[3]; - A64_flip[5+offset]=((uint8_t *)&Aprime)[2]; - A64_flip[6+offset]=((uint8_t *)&Aprime)[1]; - A64_flip[7+offset]=((uint8_t *)&Aprime)[0]; - if (crclen==24) crc = (uint64_t)(crc24c(A64_flip,8*offset+len)>>8)&0xffffff; - else if (crclen==11) crc = (uint64_t)(crc11(A64_flip,8*offset+len)>>21)&0x7ff; - else if (crclen==6) crc = (uint64_t)(crc6(A64_flip,8*offset+len)>>26)&0x3f; + uint64_t Aprime = (uint64_t)(Ar << (64 - len)); + A64_flip[0 + offset] = ((uint8_t *)&Aprime)[7]; + A64_flip[1 + offset] = ((uint8_t *)&Aprime)[6]; + A64_flip[2 + offset] = ((uint8_t *)&Aprime)[5]; + A64_flip[3 + offset] = ((uint8_t *)&Aprime)[4]; + A64_flip[4 + offset] = ((uint8_t *)&Aprime)[3]; + A64_flip[5 + offset] = ((uint8_t *)&Aprime)[2]; + A64_flip[6 + offset] = ((uint8_t *)&Aprime)[1]; + A64_flip[7 + offset] = ((uint8_t *)&Aprime)[0]; + if (crclen == 24) + crc = (uint64_t)(crc24c(A64_flip, 8 * offset + len) >> 8) & 0xffffff; + else if (crclen == 11) + crc = (uint64_t)(crc11(A64_flip, 8 * offset + len) >> 21) & 0x7ff; + else if (crclen == 6) + crc = (uint64_t)(crc6(A64_flip, 8 * offset + len) >> 26) & 0x3f; } #ifdef POLAR_CODING_DEBUG @@ -815,7 +839,7 @@ uint32_t polar_decoder_int16(int16_t *input, Cprime[0], crc, rxcrc, - crc^rxcrc, + crc ^ rxcrc, polarParams->payloadBits); #endif 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 85fb382102..cc0f31f1de 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -28,22 +28,22 @@ * \email turker.yilmaz@eurecom.fr * \note * \warning -*/ + */ #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/sse_intrin.h" #include "PHY/impl_defs_top.h" -//#define DEBUG_NEW_IMPL 1 +// #define DEBUG_NEW_IMPL 1 static inline void updateBit(uint8_t listSize, - uint16_t row, - uint16_t col, - uint16_t xlen, - uint8_t ylen, - int zlen, - uint8_t bit[xlen][ylen][zlen], - uint8_t bitU[xlen][ylen]) + uint16_t row, + uint16_t col, + uint16_t xlen, + uint8_t ylen, + int zlen, + uint8_t bit[xlen][ylen][zlen], + uint8_t bitU[xlen][ylen]) { const uint offset = (xlen / (pow(2, (ylen - col)))); @@ -64,18 +64,12 @@ static inline void updateBit(uint8_t listSize, bitU[row][col] = 1; } -static inline void computeLLR(uint16_t row, - uint16_t col, - uint8_t i, - uint16_t offset, - int xlen, - int ylen, - int zlen, - double llr[xlen][ylen][zlen]) +static inline void +computeLLR(uint16_t row, uint16_t col, uint8_t i, uint16_t offset, int xlen, int ylen, int zlen, double llr[xlen][ylen][zlen]) { double a = llr[row][col + 1][i]; double b = llr[row + offset][col + 1][i]; - llr[row][col][i] = log((exp(a + b) + 1) / (exp(a) + exp(b))); //eq. (8a) + llr[row][col][i] = log((exp(a + b) + 1) / (exp(a) + exp(b))); // eq. (8a) } void updateLLR(uint8_t listSize, @@ -113,14 +107,13 @@ void updateLLR(uint8_t listSize, } void updatePathMetric(double *pathMetric, - uint8_t listSize, - uint8_t bitValue, - uint16_t row, - int xlen, - int ylen, - int zlen, - double llr[xlen][ylen][zlen] - ) + uint8_t listSize, + uint8_t bitValue, + uint16_t row, + int xlen, + int ylen, + int zlen, + double llr[xlen][ylen][zlen]) { const int multiplier = (2 * bitValue) - 1; for (uint i = 0; i < listSize; i++) @@ -128,12 +121,12 @@ void updatePathMetric(double *pathMetric, } void updatePathMetric2(double *pathMetric, - uint8_t listSize, - uint16_t row, - int xlen, - int ylen, - int zlen, - double llr[xlen][ylen][zlen]) + uint8_t listSize, + uint16_t row, + int xlen, + int ylen, + int zlen, + double llr[xlen][ylen][zlen]) { double tempPM[listSize]; memcpy(tempPM, pathMetric, (sizeof(double) * listSize)); @@ -172,7 +165,7 @@ static inline decoder_node_t *new_decoder_node(simde__m256i **buffer, .alpha = tree_sz, .beta = tree_sz + leaf_sz * sizeof(int16_t), .betaInit = false}; - return(node); + return (node); } static inline decoder_node_t *add_nodes(decoder_tree_t *tree, @@ -181,7 +174,7 @@ static inline decoder_node_t *add_nodes(decoder_tree_t *tree, const uint8_t *information_bit_pattern, simde__m256i **buffer) { - if (level==0) { + if (level == 0) { #ifdef DEBUG_NEW_IMPL printf("leaf %d (%s)\n", first_leaf_index, information_bit_pattern[first_leaf_index] == 1 ? "information or crc" : "frozen"); #endif @@ -203,7 +196,7 @@ static inline decoder_node_t *add_nodes(decoder_tree_t *tree, decoder_node_t *new_node = new_decoder_node(buffer, level, first_leaf_index, false, false); new_node->left = add_nodes(tree, level - 1, first_leaf_index, information_bit_pattern, buffer); new_node->right = add_nodes(tree, level - 1, first_leaf_index + (Nv / 2), information_bit_pattern, buffer); - return(new_node); + return (new_node); } void build_decoder_tree(t_nrPolar_params *pp) @@ -225,7 +218,12 @@ static inline void applyFtoleft(const t_nrPolar_params *pp, decoder_node_t *node int8_t *betal = treeBeta(node->left); #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); + 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; i < node->Nv; 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]); @@ -238,7 +236,7 @@ static inline void applyFtoleft(const t_nrPolar_params *pp, decoder_node_t *node int avx2len = sz / 16; // printf("avx2len %d\n",avx2len); - for (int i=0;ileft->betaInit = true; #ifdef DEBUG_NEW_IMPL - printf("betal[0] %d (%p)\n",betal[0],&betal[0]); + printf("betal[0] %d (%p)\n", betal[0], &betal[0]); #endif output[node->first_leaf_index] = tmp; #ifdef DEBUG_NEW_IMPL - printf("Setting bit %d to %d (LLR %d)\n",node->first_leaf_index,(betal[0]+1)>>1,alpha_l[0]); + printf("Setting bit %d to %d (LLR %d)\n", node->first_leaf_index, (betal[0] + 1) >> 1, alpha_l[0]); #endif } } @@ -298,7 +294,12 @@ static inline void applyGtoright(const t_nrPolar_params *pp, decoder_node_t *nod int8_t *betar = treeBeta(node->right); #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); + 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 assert(node->level); const int sz = 1 << (node->level - 1); @@ -320,7 +321,8 @@ static inline void applyGtoright(const t_nrPolar_params *pp, decoder_node_t *nod int avx2len = sz / 16; for (int i = 0; i < avx2len; i++) { - simde__m256i tmp = simde_mm256_sign_epi16(((simde__m256i *)alpha_v)[i], simde_mm256_cvtepi8_epi16(((simde__m128i *)betal)[i])); + simde__m256i tmp = + simde_mm256_sign_epi16(((simde__m256i *)alpha_v)[i], simde_mm256_cvtepi8_epi16(((simde__m128i *)betal)[i])); ((simde__m256i *)alpha_r)[i] = simde_mm256_subs_epi16(((simde__m256i *)alpha_v)[i + avx2len], tmp); } } else if (avx2mod == 8) { @@ -340,7 +342,7 @@ static inline void applyGtoright(const t_nrPolar_params *pp, decoder_node_t *nod output[node->first_leaf_index + 1] = tmp; #ifdef DEBUG_NEW_IMPL - printf("Setting bit %d to %d (LLR %d)\n",node->first_leaf_index+1,(betar[0]+1)>>1,alpha_r[0]); + printf("Setting bit %d to %d (LLR %d)\n", node->first_leaf_index + 1, (betar[0] + 1) >> 1, alpha_r[0]); #endif } } @@ -354,7 +356,10 @@ static inline void computeBeta(decoder_node_t *node) int8_t *betal = treeBeta(node->left); int8_t *betar = treeBeta(node->right); #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); + printf("Computing beta @ level %d first_leaf_index %d (all_frozen %d)\n", + node->level, + node->first_leaf_index, + node->left->all_frozen); #endif assert(node->level); const int sz = 1 << (node->level - 1); @@ -370,7 +375,7 @@ static inline void computeBeta(decoder_node_t *node) int avx2mod = sz & 31; if (avx2mod == 0) { int avx2len = sz / 16; - for (int i=0;ibetaInit = true; } -void generic_polar_decoder_recursive(t_nrPolar_params *pp, decoder_node_t *node, uint8_t *nr_polar_U) { +void generic_polar_decoder_recursive(t_nrPolar_params *pp, decoder_node_t *node, uint8_t *nr_polar_U) +{ // Apply F to left applyFtoleft(pp, node, nr_polar_U); int iter = pp->tree_linearization.iter++; @@ -397,7 +403,7 @@ void generic_polar_decoder_recursive(t_nrPolar_params *pp, decoder_node_t *node, pp->tree_linearization.op_list[iter].node = node; // if left is not a leaf recurse down to the left - if (node->left->leaf==0) + if (node->left->leaf == 0) generic_polar_decoder_recursive(pp, node->left, nr_polar_U); applyGtoright(pp, node, nr_polar_U); diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index 546260a5f2..5210dbec6d 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -28,7 +28,7 @@ * \email raymond.knopp@eurecom.fr, turker.yilmaz@eurecom.fr * \note * \warning -*/ + */ #ifndef __NR_POLAR_DEFS__H__ #define __NR_POLAR_DEFS__H__ @@ -43,17 +43,18 @@ #include "PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h" #include "PHY/CODING/coding_defs.h" -//#include "SIMULATION/TOOLS/sim.h" +// #include "SIMULATION/TOOLS/sim.h" -#define NR_POLAR_DECODER_LISTSIZE 8 //uint8_t +#define NR_POLAR_DECODER_LISTSIZE 8 // uint8_t -#define NR_POLAR_AGGREGATION_LEVEL_1_PRIME 149 //uint16_t -#define NR_POLAR_AGGREGATION_LEVEL_2_PRIME 151 //uint16_t -#define NR_POLAR_AGGREGATION_LEVEL_4_PRIME 157 //uint16_t -#define NR_POLAR_AGGREGATION_LEVEL_8_PRIME 163 //uint16_t -#define NR_POLAR_AGGREGATION_LEVEL_16_PRIME 167 //uint16_t +#define NR_POLAR_AGGREGATION_LEVEL_1_PRIME 149 // uint16_t +#define NR_POLAR_AGGREGATION_LEVEL_2_PRIME 151 // uint16_t +#define NR_POLAR_AGGREGATION_LEVEL_4_PRIME 157 // uint16_t +#define NR_POLAR_AGGREGATION_LEVEL_8_PRIME 163 // uint16_t +#define NR_POLAR_AGGREGATION_LEVEL_16_PRIME 167 // uint16_t -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}; +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 @@ -82,7 +83,7 @@ typedef struct decoder_tree_t_s { } decoder_tree_t; typedef struct nrPolar_params { - //messageType: 0=PBCH, 1=DCI, -1=UCI + // messageType: 0=PBCH, 1=DCI, -1=UCI struct nrPolar_params *nextPtr __attribute__((aligned(16))); bool busy; @@ -123,16 +124,12 @@ typedef struct nrPolar_params { bool is_initialized; struct { int op_code; - decoder_node_t* node; + decoder_node_t *node; } op_list[600]; } tree_linearization; } t_nrPolar_params; -void polar_encoder(uint32_t *input, - uint32_t *output, - int8_t messageType, - uint16_t messageLength, - uint8_t aggregation_level); +void polar_encoder(uint32_t *input, uint32_t *output, int8_t messageType, uint16_t messageLength, uint8_t aggregation_level); void polar_encoder_dci(uint32_t *in, uint32_t *out, @@ -190,7 +187,7 @@ void nr_polar_print_polarParams(void); t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, uint8_t aggregation_level); -uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level); +uint16_t nr_polar_aggregation_prime(uint8_t aggregation_level); const uint8_t **nr_polar_kronecker_power_matrices(uint8_t n); @@ -201,27 +198,13 @@ const uint16_t *nr_polar_sequence_pattern(uint8_t n); * @param K Number of bits to encode (=payloadBits+crcParityBits) * @param E * @param n_max */ -uint32_t nr_polar_output_length(uint16_t K, - uint16_t E, - uint8_t n_max); +uint32_t nr_polar_output_length(uint16_t K, uint16_t E, uint8_t n_max); -void nr_polar_rate_matching_pattern(uint16_t *rmp, - uint16_t *J, - const uint8_t *P_i_, - uint16_t K, - uint16_t N, - uint16_t E); +void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P_i_, uint16_t K, uint16_t N, uint16_t E); -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(double *input, double *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_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_); void nr_polar_info_bit_pattern(uint8_t *ibp, uint8_t *pcbp, @@ -236,18 +219,11 @@ void nr_polar_info_bit_pattern(uint8_t *ibp, const uint8_t n_PC, const uint8_t n_pc_wm); -void nr_polar_info_bit_extraction(uint8_t *input, - uint8_t *output, - uint8_t *pattern, - uint16_t size); +void nr_polar_info_bit_extraction(uint8_t *input, uint8_t *output, uint8_t *pattern, uint16_t size); -void nr_bit2byte_uint32_8(uint32_t *in, - uint16_t arraySize, - uint8_t *out); +void nr_bit2byte_uint32_8(uint32_t *in, uint16_t arraySize, uint8_t *out); -void nr_byte2bit_uint8_32(uint8_t *in, - uint16_t arraySize, - uint32_t *out); +void nr_byte2bit_uint8_32(uint8_t *in, uint16_t arraySize, uint32_t *out); const uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits); @@ -258,15 +234,9 @@ void nr_polar_generate_u(uint64_t *u, uint16_t N, uint8_t n_pc); -void nr_polar_uxG(uint8_t const* u, size_t N, uint8_t* D); +void nr_polar_uxG(uint8_t const *u, size_t N, uint8_t *D); -void nr_polar_bit_insertion(uint8_t *input, - uint8_t *output, - uint16_t N, - uint16_t K, - int16_t *Q_I_N, - int16_t *Q_PC_N, - uint8_t n_PC); +void nr_polar_bit_insertion(uint8_t *input, uint8_t *output, uint16_t N, uint16_t K, int16_t *Q_I_N, int16_t *Q_PC_N, uint8_t n_PC); void nr_matrix_multiplication_uint8_1D_uint8_2D(const uint8_t *matrix1, const uint8_t **matrix2, @@ -274,46 +244,39 @@ void nr_matrix_multiplication_uint8_1D_uint8_2D(const uint8_t *matrix1, uint16_t row, uint16_t col); -void nr_sort_asc_double_1D_array_ind(double *matrix, - uint8_t *ind, - uint8_t len); +void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len); void nr_free_double_2D_array(double **input, uint16_t xlen); #ifndef __cplusplus void updateLLR(uint8_t listSize, - uint16_t row, - uint16_t col, - uint16_t xlen, - uint8_t ylen, - int zlen, - double llr[xlen][ylen][zlen], - uint8_t llrU[xlen][ylen], - uint8_t bit[xlen][ylen][zlen], - uint8_t bitU[xlen][ylen] - ); + uint16_t row, + uint16_t col, + uint16_t xlen, + uint8_t ylen, + int zlen, + double llr[xlen][ylen][zlen], + uint8_t llrU[xlen][ylen], + uint8_t bit[xlen][ylen][zlen], + uint8_t bitU[xlen][ylen]); void updatePathMetric(double *pathMetric, - uint8_t listSize, - uint8_t bitValue, - uint16_t row, - int xlen, - int ylen, - int zlen, - double llr[xlen][ylen][zlen] - ); + uint8_t listSize, + uint8_t bitValue, + uint16_t row, + int xlen, + int ylen, + int zlen, + double llr[xlen][ylen][zlen]); void updatePathMetric2(double *pathMetric, - uint8_t listSize, - uint16_t row, - int xlen, - int ylen, - int zlen, - double llr[xlen][ylen][zlen]); + uint8_t listSize, + uint16_t row, + int xlen, + int ylen, + int zlen, + double llr[xlen][ylen][zlen]); #endif -//Also nr_polar_rate_matcher -static inline void nr_polar_interleaver(uint8_t *input, - uint8_t *output, - uint16_t *pattern, - uint16_t size) +// Also nr_polar_rate_matcher +static inline void nr_polar_interleaver(uint8_t *input, uint8_t *output, uint16_t *pattern, uint16_t size) { for (int i = 0; i < size; i++) output[i] = input[pattern[i]]; diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c index cc85216f23..0f22900d72 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c @@ -30,23 +30,20 @@ * \warning */ -//#define DEBUG_POLAR_ENCODER -//#define DEBUG_POLAR_ENCODER_DCI -//#define DEBUG_POLAR_MATLAB -//#define POLAR_CODING_DEBUG +// #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" #include -//input [a_31 a_30 ... a_0] -//output [f_31 f_30 ... f_0] [f_63 f_62 ... f_32] ... +// input [a_31 a_30 ... a_0] +// output [f_31 f_30 ... f_0] [f_63 f_62 ... f_32] ... -void polar_encoder(uint32_t *in, - uint32_t *out, - int8_t messageType, - uint16_t messageLength, - uint8_t aggregation_level) { +void polar_encoder(uint32_t *in, uint32_t *out, int8_t messageType, uint16_t messageLength, uint8_t aggregation_level) +{ t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level); uint8_t nr_polar_A[polarParams->payloadBits]; nr_bit2byte_uint32_8(in, polarParams->payloadBits, nr_polar_A); @@ -83,21 +80,21 @@ void polar_encoder(uint32_t *in, printf("b[%d]=%d\n", i, nr_polar_B[i]); #endif - //Interleaving (c to c') + // Interleaving (c to c') uint8_t nr_polar_CPrime[polarParams->K]; nr_polar_interleaver(nr_polar_B, nr_polar_CPrime, polarParams->interleaving_pattern, polarParams->K); #ifdef DEBUG_POLAR_ENCODER - uint64_t Cprime=0; + uint64_t Cprime = 0; - for (int i = 0; iK; i++) { + for (int i = 0; i < polarParams->K; i++) { Cprime = Cprime | ((uint64_t)nr_polar_CPrime[i] << i); if (nr_polar_CPrime[i] == 1) printf("pos %d : %lx\n", i, Cprime); } - printf("polar_Cprime %lx\n",Cprime); + printf("polar_Cprime %lx\n", Cprime); #endif - //Bit insertion (c' to u) + // Bit insertion (c' to u) uint8_t nr_polar_U[polarParams->N]; nr_polar_bit_insertion(nr_polar_CPrime, nr_polar_U, @@ -119,11 +116,10 @@ void polar_encoder(uint32_t *in, for (int i = 0; i < polarParams->N; i++) D[i / 64] |= ((uint64_t)nr_polar_D[i]) << (i & 63); - 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]); + 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 - //Rate matching - //Sub-block interleaving (d to y) and Bit selection (y to e) + // Rate matching + // Sub-block interleaving (d to y) and Bit selection (y to e) uint8_t nr_polar_E[polarParams->encoderLength]; nr_polar_interleaver(nr_polar_D, nr_polar_E, polarParams->rate_matching_pattern, polarParams->encoderLength); /* @@ -145,7 +141,8 @@ void polar_encoder_dci(uint32_t *in, uint16_t n_RNTI, int8_t messageType, uint16_t messageLength, - uint8_t aggregation_level) { + uint8_t aggregation_level) +{ t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level); #ifdef DEBUG_POLAR_ENCODER_DCI @@ -176,10 +173,11 @@ void polar_encoder_dci(uint32_t *in, printf("\n"); printf("[polar_encoder_dci] GP: "); - for (int i=0; icrcParityBits; i++) printf("%d-", polarParams->crc_generator_matrix[0][i]); + for (int i = 0; i < polarParams->crcParityBits; i++) + printf("%d-", polarParams->crc_generator_matrix[0][i]); printf("\n"); #endif - //Calculate CRC. + // Calculate CRC. uint8_t nr_polar_crc[polarParams->crcParityBits]; nr_matrix_multiplication_uint8_1D_uint8_2D(nr_polar_APrime, polarParams->crc_generator_matrix, @@ -197,14 +195,14 @@ void polar_encoder_dci(uint32_t *in, printf("\n"); #endif uint8_t nr_polar_B[polarParams->payloadBits + 8 + 16]; - //Attach CRC to the Transport Block. (a to b) + // Attach CRC to the Transport Block. (a to b) memcpy(nr_polar_B, nr_polar_A, polarParams->payloadBits); for (uint i = polarParams->payloadBits; i < polarParams->K; i++) nr_polar_B[i] = nr_polar_crc[i - polarParams->payloadBits]; - //Scrambling (b to c) - for (int i=0; i<16; i++) + // Scrambling (b to c) + for (int i = 0; i < 16; i++) nr_polar_B[polarParams->payloadBits + 8 + i] = (nr_polar_B[polarParams->payloadBits + 8 + i] + ((n_RNTI >> (15 - i)) & 1)) % 2; #ifdef DEBUG_POLAR_ENCODER_DCI @@ -213,10 +211,10 @@ void polar_encoder_dci(uint32_t *in, printf("%d-", nr_polar_B[i]); printf("\n"); #endif - //Interleaving (c to c') + // Interleaving (c to c') uint8_t nr_polar_CPrime[polarParams->K]; nr_polar_interleaver(nr_polar_B, nr_polar_CPrime, polarParams->interleaving_pattern, polarParams->K); - //Bit insertion (c' to u) + // Bit insertion (c' to u) uint8_t nr_polar_U[polarParams->N]; nr_polar_bit_insertion(nr_polar_CPrime, nr_polar_U, @@ -225,14 +223,14 @@ void polar_encoder_dci(uint32_t *in, polarParams->Q_I_N, polarParams->Q_PC_N, polarParams->n_pc); - //Encoding (u to d) + // Encoding (u to d) uint8_t nr_polar_D[polarParams->N]; nr_matrix_multiplication_uint8_1D_uint8_2D(nr_polar_U, polarParams->G_N, nr_polar_D, polarParams->N, polarParams->N); for (uint i = 0; i < polarParams->N; i++) nr_polar_D[i] %= 2; - //Rate matching - //Sub-block interleaving (d to y) and Bit selection (y to e) + // Rate matching + // Sub-block interleaving (d to y) and Bit selection (y to e) uint8_t nr_polar_E[polarParams->encoderLength]; nr_polar_interleaver(nr_polar_D, nr_polar_E, polarParams->rate_matching_pattern, polarParams->encoderLength); /* @@ -294,44 +292,50 @@ __attribute__((always_inline)) static inline void polar_rate_matching(const t_nr { // handle rate matching with a single 128 bit word using bit shuffling // can be done with SIMD intrisics if needed - if (polarParams->groupsize < 8) { - AssertFatal(polarParams->encoderLength<=512,"Need to handle groupsize(%d)<8 and N(%d)>512\n",polarParams->groupsize,polarParams->encoderLength); - uint128_t *out128=(uint128_t*)out; - uint128_t *in128=(uint128_t*)in; - for (int i=0;iencoderLength>>7;i++) + if (polarParams->groupsize < 8) { + AssertFatal(polarParams->encoderLength <= 512, + "Need to handle groupsize(%d)<8 and N(%d)>512\n", + polarParams->groupsize, + polarParams->encoderLength); + uint128_t *out128 = (uint128_t *)out; + uint128_t *in128 = (uint128_t *)in; + for (int i = 0; i < polarParams->encoderLength >> 7; i++) out128[i] = 0; #ifdef DEBUG_POLAR_ENCODER uint128_t tmp1; #endif - for (int i=0; iencoderLength; i++) { + for (int i = 0; i < polarParams->encoderLength; i++) { #ifdef DEBUG_POLAR_ENCODER - printf("%d<-%u : %llx.%llx =>",i,polarParams->rate_matching_pattern[i],((uint64_t *)out)[1],((uint64_t *)out)[0]); + printf("%d<-%u : %llx.%llx =>", i, polarParams->rate_matching_pattern[i], ((uint64_t *)out)[1], ((uint64_t *)out)[0]); #endif - uint8_t pi=polarParams->rate_matching_pattern[i]; - uint8_t pi7=pi>>7; - uint8_t pimod128=pi&127; - uint8_t imod128=i&127; - uint8_t i7=i>>7; + uint8_t pi = polarParams->rate_matching_pattern[i]; + uint8_t pi7 = pi >> 7; + uint8_t pimod128 = pi & 127; + uint8_t imod128 = i & 127; + uint8_t i7 = i >> 7; uint128_t tmp0 = (in128[pi7] & (((uint128_t)1) << (pimod128))); - if (tmp0!=0) { - out128[i7] = out128[i7] | ((uint128_t)1)<%llx.%llx => %llx.%llx\n", - ((uint64_t *)&tmp0)[1],((uint64_t *)&tmp0)[0], - ((uint64_t *)&tmp1)[1],((uint64_t *)&tmp1)[0], - ((uint64_t *)out)[1],((uint64_t *)out)[0]); + ((uint64_t *)&tmp0)[1], + ((uint64_t *)&tmp0)[0], + ((uint64_t *)&tmp1)[1], + ((uint64_t *)&tmp1)[0], + ((uint64_t *)out)[1], + ((uint64_t *)out)[0]); #endif } } - } + } // These are based on LUTs for byte and short word groups else if (polarParams->groupsize == 8) for (int i = 0; i < polarParams->encoderLength >> 3; i++) ((uint8_t *)out)[i] = ((uint8_t *)in)[polarParams->rm_tab[i]]; else // groupsize==16 - for (int i=0; iencoderLength>>4; i++) { + for (int i = 0; i < polarParams->encoderLength >> 4; i++) { ((uint16_t *)out)[i] = ((uint16_t *)in)[polarParams->rm_tab[i]]; } @@ -340,19 +344,20 @@ __attribute__((always_inline)) static inline void polar_rate_matching(const t_nr } } -void build_polar_tables(t_nrPolar_params *polarParams) { +void build_polar_tables(t_nrPolar_params *polarParams) +{ // build table b -> c' - AssertFatal(polarParams->K > 17, "K = %d < 18, is not possible\n",polarParams->K); + AssertFatal(polarParams->K > 17, "K = %d < 18, is not possible\n", polarParams->K); AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n", polarParams->K); - const int numbytes = (polarParams->K+7)/8; - const int residue = polarParams->K&7; + const int numbytes = (polarParams->K + 7) / 8; + const int residue = polarParams->K & 7; uint deinterleaving_pattern[polarParams->K]; for (int i = 0; i < polarParams->K; i++) deinterleaving_pattern[polarParams->interleaving_pattern[i]] = i; - for (int byte=0; byteK>>3) ? 8 : residue; + for (int byte = 0; byte < numbytes; byte++) { + int numbits = byte < (polarParams->K >> 3) ? 8 : residue; for (uint64_t val = 0; val < 256LU; val++) { // uint16_t * tmp=polarParams->deinterleaving_pattern+polarParams->K - 1 - 8 * byte; union { @@ -360,10 +365,10 @@ void build_polar_tables(t_nrPolar_params *polarParams) { uint64_t pieces[2]; } tab = {0}; uint *tmp = deinterleaving_pattern + polarParams->K - 8 * byte - 1; - for (int i=0; i> i) & 1; tab.full |= bit_i << ip; } @@ -372,50 +377,57 @@ 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); + AssertFatal(polarParams->N == 512 || polarParams->N == 256 || polarParams->N == 128 || polarParams->N == 64, + "N = %d, not done yet\n", + polarParams->N); // rate matching table - int iplast=polarParams->rate_matching_pattern[0]; - int ccnt=0; + int iplast = polarParams->rate_matching_pattern[0]; + int ccnt = 0; #ifdef DEBUG_POLAR_ENCODER - int groupcnt=0; - int firstingroup_out=0; - int firstingroup_in=iplast; + int groupcnt = 0; + int firstingroup_out = 0; + int firstingroup_in = iplast; #endif int mingroupsize = 1024; // compute minimum group size of rate-matching pattern - for (int outpos=1; outposencoderLength; outpos++) { + for (int outpos = 1; outpos < polarParams->encoderLength; outpos++) { int ip = polarParams->rate_matching_pattern[outpos]; #ifdef DEBUG_POLAR_ENCODER - printf("rm: outpos %d, inpos %d\n",outpos,ip); + printf("rm: outpos %d, inpos %d\n", outpos, ip); #endif if ((ip - iplast) == 1) ccnt++; else { #ifdef DEBUG_POLAR_ENCODER groupcnt++; - printf("group %d (size %d): (%d:%d) => (%d:%d)\n",groupcnt,ccnt+1, - firstingroup_in,firstingroup_in+ccnt, - firstingroup_out,firstingroup_out+ccnt); + printf("group %d (size %d): (%d:%d) => (%d:%d)\n", + groupcnt, + ccnt + 1, + firstingroup_in, + firstingroup_in + ccnt, + firstingroup_out, + firstingroup_out + ccnt); #endif if ((ccnt + 1) < mingroupsize) mingroupsize = ccnt + 1; - ccnt=0; + ccnt = 0; #ifdef DEBUG_POLAR_ENCODER - firstingroup_out=outpos; - firstingroup_in=ip; + firstingroup_out = outpos; + firstingroup_in = ip; #endif } - iplast=ip; + iplast = ip; } #ifdef DEBUG_POLAR_ENCODER groupcnt++; #endif - if ((ccnt+1) (%d:%d)\n", groupcnt, @@ -456,7 +468,6 @@ void build_polar_tables(t_nrPolar_params *polarParams) { build_decoder_tree(polarParams); } - void polar_encoder_fast(uint64_t *A, void *out, int32_t crcmask, @@ -482,27 +493,27 @@ void polar_encoder_fast(uint64_t *A, #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); + 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); int bitlen = polarParams->payloadBits; // append crc - AssertFatal(bitlen<129,"support for payloads <= 128 bits\n"); + 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; + // int bitlen0=bitlen; #ifdef POLAR_CODING_DEBUG printf("\nTX\n"); printf("a: "); - for (int n = (bitlen + 63)/64 ; n >=0; n--) { - if (n % 4 == 0) - printf(" "); - if (n < bitlen) - printf("%lu", (A[n/64] >> (n%64)) & 1); + for (int n = (bitlen + 63) / 64; n >= 0; n--) { + if (n % 4 == 0) + printf(" "); + if (n < bitlen) + printf("%lu", (A[n / 64] >> (n % 64)) & 1); } printf("\n"); #endif - uint64_t tcrc=0; + uint64_t tcrc = 0; uint offset = 0; // appending 24 ones before a0 for DCI as stated in 38.212 7.3.2 @@ -513,76 +524,76 @@ void polar_encoder_fast(uint64_t *A, //???a'_{N-1} a'_{N-2} ... a'_{N-A} 0 .... 0, where N=64,128,192,..., N is smallest multiple of 64 greater than or equal to A // First flip A bitstring byte endian for CRC routines (optimized for DLSCH/ULSCH, not PBCH/PDCCH) - // CRC reads in each byte in bit positions 7 down to 0, for PBCH/PDCCH we need to read in a_{A-1} down to a_{0}, A = length of bit string (e.g. 32 for PBCH) - if (bitlen<=32) { - uint8_t A32_flip[4+offset]; + // CRC reads in each byte in bit positions 7 down to 0, for PBCH/PDCCH we need to read in a_{A-1} down to a_{0}, A = length of bit + // string (e.g. 32 for PBCH) + if (bitlen <= 32) { + uint8_t A32_flip[4 + offset]; if (ones_flag) { A32_flip[0] = 0xff; A32_flip[1] = 0xff; A32_flip[2] = 0xff; } - uint32_t Aprime= (uint32_t)(((uint32_t)*A)<<(32-bitlen)); - A32_flip[0+offset]=((uint8_t *)&Aprime)[3]; - A32_flip[1+offset]=((uint8_t *)&Aprime)[2]; - A32_flip[2+offset]=((uint8_t *)&Aprime)[1]; - A32_flip[3+offset]=((uint8_t *)&Aprime)[0]; - if (polarParams->crcParityBits == 24) - tcrc = (uint64_t)(((crcmask^(crc24c(A32_flip,8*offset+bitlen)>>8)))&0xffffff); + uint32_t Aprime = (uint32_t)(((uint32_t)*A) << (32 - bitlen)); + A32_flip[0 + offset] = ((uint8_t *)&Aprime)[3]; + A32_flip[1 + offset] = ((uint8_t *)&Aprime)[2]; + A32_flip[2 + offset] = ((uint8_t *)&Aprime)[1]; + A32_flip[3 + offset] = ((uint8_t *)&Aprime)[0]; + if (polarParams->crcParityBits == 24) + tcrc = (uint64_t)(((crcmask ^ (crc24c(A32_flip, 8 * offset + bitlen) >> 8))) & 0xffffff); else if (polarParams->crcParityBits == 11) - tcrc = (uint64_t)(((crcmask^(crc11(A32_flip,bitlen)>>21)))&0x7ff); + tcrc = (uint64_t)(((crcmask ^ (crc11(A32_flip, bitlen) >> 21))) & 0x7ff); else if (polarParams->crcParityBits == 6) - tcrc = (uint64_t)(((crcmask^(crc6(A32_flip,bitlen)>>26)))&0x3f); - } else if (bitlen<=64) { - uint8_t A64_flip[8+offset]; + tcrc = (uint64_t)(((crcmask ^ (crc6(A32_flip, bitlen) >> 26))) & 0x3f); + } else if (bitlen <= 64) { + uint8_t A64_flip[8 + offset]; if (ones_flag) { A64_flip[0] = 0xff; A64_flip[1] = 0xff; A64_flip[2] = 0xff; } - uint64_t Aprime= (uint64_t)(((uint64_t)*A)<<(64-bitlen)); - A64_flip[0+offset]=((uint8_t *)&Aprime)[7]; - A64_flip[1+offset]=((uint8_t *)&Aprime)[6]; - A64_flip[2+offset]=((uint8_t *)&Aprime)[5]; - A64_flip[3+offset]=((uint8_t *)&Aprime)[4]; - A64_flip[4+offset]=((uint8_t *)&Aprime)[3]; - A64_flip[5+offset]=((uint8_t *)&Aprime)[2]; - A64_flip[6+offset]=((uint8_t *)&Aprime)[1]; - A64_flip[7+offset]=((uint8_t *)&Aprime)[0]; + uint64_t Aprime = (uint64_t)(((uint64_t)*A) << (64 - bitlen)); + A64_flip[0 + offset] = ((uint8_t *)&Aprime)[7]; + A64_flip[1 + offset] = ((uint8_t *)&Aprime)[6]; + A64_flip[2 + offset] = ((uint8_t *)&Aprime)[5]; + A64_flip[3 + offset] = ((uint8_t *)&Aprime)[4]; + A64_flip[4 + offset] = ((uint8_t *)&Aprime)[3]; + A64_flip[5 + offset] = ((uint8_t *)&Aprime)[2]; + A64_flip[6 + offset] = ((uint8_t *)&Aprime)[1]; + A64_flip[7 + offset] = ((uint8_t *)&Aprime)[0]; if (polarParams->crcParityBits == 24) - tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,8*offset+bitlen)>>8)))&0xffffff; + tcrc = (uint64_t)((crcmask ^ (crc24c(A64_flip, 8 * offset + bitlen) >> 8))) & 0xffffff; else if (polarParams->crcParityBits == 11) - tcrc = (uint64_t)((crcmask^(crc11(A64_flip,bitlen)>>21)))&0x7ff; - } - else if (bitlen<=128) { - uint8_t A128_flip[16+offset]; + tcrc = (uint64_t)((crcmask ^ (crc11(A64_flip, bitlen) >> 21))) & 0x7ff; + } else if (bitlen <= 128) { + uint8_t A128_flip[16 + offset]; if (ones_flag) { A128_flip[0] = 0xff; A128_flip[1] = 0xff; A128_flip[2] = 0xff; } - uint128_t Aprime= (uint128_t)(((uint128_t)*A)<<(128-bitlen)); - for (int i=0; i<16 ; i++) - A128_flip[i+offset]=((uint8_t*)&Aprime)[15-i]; + uint128_t Aprime = (uint128_t)(((uint128_t)*A) << (128 - bitlen)); + for (int i = 0; i < 16; i++) + A128_flip[i + offset] = ((uint8_t *)&Aprime)[15 - i]; if (polarParams->crcParityBits == 24) - tcrc = (uint64_t)((crcmask^(crc24c(A128_flip,8*offset+bitlen)>>8)))&0xffffff; + tcrc = (uint64_t)((crcmask ^ (crc24c(A128_flip, 8 * offset + bitlen) >> 8))) & 0xffffff; else if (polarParams->crcParityBits == 11) - tcrc = (uint64_t)((crcmask^(crc11(A128_flip,bitlen)>>21)))&0x7ff; + tcrc = (uint64_t)((crcmask ^ (crc11(A128_flip, bitlen) >> 21))) & 0x7ff; } // this is number of quadwords in the bit string - int quadwlen = (polarParams->K+63)/64; + int quadwlen = (polarParams->K + 63) / 64; // Create the B bit string as // 0, 0, ..., 0, a'_0, a'_1, ..., a'_A-1, p_0, p_1, ..., p_{N_parity-1} //??? 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}; + uint64_t B[4] = {0}; B[0] = (A[0] << polarParams->crcParityBits) | tcrc; for (int n = 1; n < quadwlen; n++) - if ((bitlen+63)/64 > n) - B[n] = (A[n] << polarParams->crcParityBits) | (A[n-1]>>(64-polarParams->crcParityBits)); + if ((bitlen + 63) / 64 > n) + B[n] = (A[n] << polarParams->crcParityBits) | (A[n - 1] >> (64 - polarParams->crcParityBits)); else - B[n] = (A[n-1]>>(64-polarParams->crcParityBits)); + B[n] = (A[n - 1] >> (64 - polarParams->crcParityBits)); #ifdef POLAR_CODING_DEBUG int bitlen_B = bitlen + polarParams->crcParityBits; @@ -602,17 +613,13 @@ void polar_encoder_fast(uint64_t *A, // 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}; + uint64_t Cprime[4] = {0}; 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[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]]; + Cprime[0] = polarParams->cprime_tab0[0][Bbyte[0]] | 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++) { Cprime[0] |= polarParams->cprime_tab0[i][Bbyte[i]]; @@ -622,7 +629,8 @@ void polar_encoder_fast(uint64_t *A, #ifdef DEBUG_POLAR_MATLAB // Cprime = pbchCprime - for (int i = 0; i < quadwlen; i++) printf("[polar_encoder_fast]C'[%d]= 0x%llx\n", i, (unsigned long long)(Cprime[i])); + 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 @@ -677,8 +685,8 @@ void polar_encoder_fast(uint64_t *A, fflush(stdout); #endif - memset((void*)out,0,polarParams->encoderLength>>3); - polar_rate_matching(polarParams,(void *)D, out); + memset((void *)out, 0, polarParams->encoderLength >> 3); + polar_rate_matching(polarParams, (void *)D, out); #ifdef POLAR_CODING_DEBUG uint64_t *out64 = (uint64_t *)out; diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_interleaving_pattern.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_interleaving_pattern.c index 97450d9dbf..6002c1ed82 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_interleaving_pattern.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_interleaving_pattern.c @@ -28,11 +28,12 @@ * \email turker.yilmaz@eurecom.fr * \note * \warning -*/ + */ #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" -void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_){ +void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_) +{ uint K_IL_max = 164; uint8_t interleaving_pattern_table[164] = { 0, 2, 4, 7, 9, 14, 19, 20, 24, 25, 26, 28, 31, 34, 42, 45, 49, 50, 51, 53, 54, 56, 58, 59, diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_kernal_operation.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_kernal_operation.c index 81e7bb99f7..03f546a6e9 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_kernal_operation.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_kernal_operation.c @@ -7,53 +7,48 @@ void nr_polar_kernal_operation(uint8_t *u, uint8_t *d, uint16_t N) { - // Martino's algorithm to avoid multiplication for the generating matrix of polar codes - - uint32_t i,j; + // Martino's algorithm to avoid multiplication for the generating matrix of polar codes - simde__m256i A,B,C,D,E,U,zerosOnly, OUT; - simde__m256i inc; - uint32_t dTest[8]; - uint32_t uArray[8]; - uint32_t k; - uint32_t incArray[8]; - - //initialisation - for(k=0; k<8; k++) - incArray[k]=k; - inc=simde_mm256_loadu_si256((simde__m256i const*)incArray); // 0, 1, ..., 7 to increase - - zerosOnly=simde_mm256_setzero_si256(); // for comparison + uint32_t i, j; - for(i=0; i If zero, then XOR with the u(j) - D=simde_mm256_cmpeq_epi32(C, zerosOnly); // compare with zero and use the result as mask - - E=simde_mm256_maskload_epi32((int const*)uArray, D); // load only some u(j)s for the XOR - OUT=simde_mm256_xor_si256(OUT, E); //32 bit x 8 + // initialisation + for (k = 0; k < 8; k++) + incArray[k] = k; + inc = simde_mm256_loadu_si256((simde__m256i const *)incArray); // 0, 1, ..., 7 to increase - } - simde_mm256_storeu_si256((simde__m256i*)dTest, OUT); + zerosOnly = simde_mm256_setzero_si256(); // for comparison - for(k=0; k<8; k++) // Conversion from 32 bits to 8 bits - { - d[i+k]=(uint8_t)dTest[k]; // With AVX512 there is an intrinsic to do it - } + for (i = 0; i < N; i += 8) { + B = simde_mm256_set1_epi32((int)i); // i, ..., i + B = simde_mm256_add_epi32(B, inc); // i, i+1, ..., i+7 - } + OUT = simde_mm256_setzero_si256(); // it will contain the result of all the XORs for the d(i)s + for (j = 0; j < N; j++) { + A = simde_mm256_set1_epi32((int)(j)); // j, j, ..., j + A = simde_mm256_sub_epi32(A, B); //(j-i), (j-(i+1)), ... (j-(i+7)) + + U = simde_mm256_set1_epi32((int)u[j]); + simde_mm256_storeu_si256((simde__m256i *)uArray, U); // u(j) ... u(j) for the maskload + + C = simde_mm256_and_si256(A, B); //(j-i)&i -> If zero, then XOR with the u(j) + D = simde_mm256_cmpeq_epi32(C, zerosOnly); // compare with zero and use the result as mask + + E = simde_mm256_maskload_epi32((int const *)uArray, D); // load only some u(j)s for the XOR + OUT = simde_mm256_xor_si256(OUT, E); // 32 bit x 8 + } + simde_mm256_storeu_si256((simde__m256i *)dTest, OUT); + + for (k = 0; k < 8; k++) // Conversion from 32 bits to 8 bits + { + d[i + k] = (uint8_t)dTest[k]; // With AVX512 there is an intrinsic to do it + } + } } 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 0db423260f..d96be2ec25 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 @@ -28,7 +28,7 @@ * \email turker.yilmaz@eurecom.fr * \note * \warning -*/ + */ #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" @@ -47,7 +47,8 @@ void nr_matrix_multiplication_uint8_1D_uint8_2D(const uint8_t *matrix1, } // Modified Bubble Sort. -void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len) { +void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len) +{ for (int i = 0; i < len; i++) { int swaps = 0; for (int j = 0; j < (len - i) - 1; j++) { diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h index 1904d1bd83..a9e59556bd 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h @@ -28,46 +28,70 @@ * \email turker.yilmaz@eurecom.fr * \note * \warning -*/ + */ #ifndef __NR_POLAR_PBCH_DEFS__H__ #define __NR_POLAR_PBCH_DEFS__H__ -#define NR_POLAR_PBCH_AGGREGATION_LEVEL 0 //uint8_t -#define NR_POLAR_PBCH_MESSAGE_TYPE 0 //int8_t -#define NR_POLAR_PSBCH_MESSAGE_TYPE 3 //int8_t -#define NR_POLAR_PBCH_PAYLOAD_BITS 32 //uint16_t +#define NR_POLAR_PBCH_AGGREGATION_LEVEL 0 // uint8_t +#define NR_POLAR_PBCH_MESSAGE_TYPE 0 // int8_t +#define NR_POLAR_PSBCH_MESSAGE_TYPE 3 // int8_t +#define NR_POLAR_PBCH_PAYLOAD_BITS 32 // uint16_t #define NR_POLAR_PBCH_CRC_PARITY_BITS 24 #define NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS 3 -//Assumed 3 by 3GPP when NR_POLAR_PBCH_L>8 to meet false alarm rate requirements. +// Assumed 3 by 3GPP when NR_POLAR_PBCH_L>8 to meet false alarm rate requirements. -//Sec. 7.1.4: Channel Coding -#define NR_POLAR_PBCH_N_MAX 9 //uint8_t -#define NR_POLAR_PBCH_I_IL 1 //uint8_t -#define NR_POLAR_PBCH_I_SEG 0 //uint8_t -#define NR_POLAR_PBCH_N_PC 0 //uint8_t -#define NR_POLAR_PBCH_N_PC_WM 0 //uint8_t -//#define NR_POLAR_PBCH_N 512 //uint16_t +// Sec. 7.1.4: Channel Coding +#define NR_POLAR_PBCH_N_MAX 9 // uint8_t +#define NR_POLAR_PBCH_I_IL 1 // uint8_t +#define NR_POLAR_PBCH_I_SEG 0 // uint8_t +#define NR_POLAR_PBCH_N_PC 0 // uint8_t +#define NR_POLAR_PBCH_N_PC_WM 0 // uint8_t +// #define NR_POLAR_PBCH_N 512 //uint16_t -//Sec. 7.1.5: Rate Matching -#define NR_POLAR_PBCH_I_BIL 0 //uint8_t -#define NR_POLAR_PBCH_E 864 //uint16_t +// Sec. 7.1.5: Rate Matching +#define NR_POLAR_PBCH_I_BIL 0 // uint8_t +#define NR_POLAR_PBCH_E 864 // uint16_t #define NR_POLAR_PBCH_E_DWORD 27 // NR_POLAR_PBCH_E/32 -#define NR_POLAR_PSBCH_E 1792 //uint16_t +#define NR_POLAR_PSBCH_E 1792 // uint16_t #define NR_POLAR_PSBCH_E_DWORD 56 // NR_POLAR_PSBCH_E/32 /* * TEST CODE */ -//#define DEBUG_POLAR -// Usage in code: -//#ifdef DEBUG_POLAR +// #define DEBUG_POLAR +// Usage in code: +// #ifdef DEBUG_POLAR //... -//#endif +// #endif -//unsigned int testPayload0=0x00000000, testPayload1=0xffffffff; //payload1=~payload0; -//unsigned int testPayload2=0xa5a5a5a5; //testPayload3=0xb3f02c82; +// unsigned int testPayload0=0x00000000, testPayload1=0xffffffff; //payload1=~payload0; +// unsigned int testPayload2=0xa5a5a5a5; //testPayload3=0xb3f02c82; -//double testReceivedPayload3[NR_POLAR_PBCH_E] = {-1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1}; +// double testReceivedPayload3[NR_POLAR_PBCH_E] = {-1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, +// -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, +// -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, +// -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, +// -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, +// -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, +// -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, +// -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, +// 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, +// -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, +// -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, +// -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, +// -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, +// -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, +// -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, +// 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, +// -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, +// -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, +// -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, +// 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, +// -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, +// -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, +// -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, +// 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, +// 1, -1, -1}; #endif diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c index 1a1a3fb830..cf1df52ac0 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_procedures.c @@ -89,8 +89,7 @@ void nr_polar_generate_u(uint64_t *u, } } -static -void encode_packed_byte(uint8_t* in_out) +static void encode_packed_byte(uint8_t *in_out) { // *in_out ^= 0xAA & (*in_out << 1); // *in_out ^= 0xCC & (*in_out << 2); @@ -101,36 +100,33 @@ void encode_packed_byte(uint8_t* in_out) *in_out ^= *in_out >> 4; } -static -void polar_encode_bits(uint8_t* in_out, size_t N) +static void polar_encode_bits(uint8_t *in_out, size_t N) { size_t const num_bytes_per_block = N >> 3; - for(size_t i = 0; i < num_bytes_per_block; ++i){ + for (size_t i = 0; i < num_bytes_per_block; ++i) { encode_packed_byte(&in_out[i]); } } -static -uint32_t log2_floor(uint32_t x) +static uint32_t log2_floor(uint32_t x) { - if(x == 0) - return 0; + if (x == 0) + return 0; uint32_t clz = __builtin_clz(x); return 31U - clz; } -static -void polar_encode_bytes(uint8_t* in_out, size_t N) +static void polar_encode_bytes(uint8_t *in_out, size_t N) { size_t brnch_sz = 1; size_t n_brnch = N >> 4; - size_t const blck_pwr = log2_floor(N); + size_t const blck_pwr = log2_floor(N); for (size_t stage = 3; stage < blck_pwr; ++stage) { for (size_t brnch = 0; brnch < n_brnch; ++brnch) { - for(size_t byte = 0; byte < brnch_sz; ++byte){ - size_t const dst = 2*brnch_sz*brnch + byte; - in_out[dst] ^= in_out[dst + brnch_sz]; - } + for (size_t byte = 0; byte < brnch_sz; ++byte) { + size_t const dst = 2 * brnch_sz * brnch + byte; + in_out[dst] ^= in_out[dst + brnch_sz]; + } } n_brnch >>= 1; brnch_sz <<= 1; @@ -139,12 +135,12 @@ void polar_encode_bytes(uint8_t* in_out, size_t N) void nr_polar_uxG(uint8_t const *u, size_t N, uint8_t *D2) { - assert(N > 7); - uint8_t tmp[N/8]; - for(int i = 0; i < N/8; ++i) - tmp[i] = u[N/8 - 1 - i]; + assert(N > 7); + uint8_t tmp[N / 8]; + for (int i = 0; i < N / 8; ++i) + tmp[i] = u[N / 8 - 1 - i]; - reverse_bits_u8(tmp, N/8, D2); + reverse_bits_u8(tmp, N / 8, D2); // Do the encoding/xor for the bottom 3 levels of the tree. // Thus, data remaining to encode, is in 2^3 type. @@ -153,49 +149,40 @@ void nr_polar_uxG(uint8_t const *u, size_t N, uint8_t *D2) polar_encode_bytes(D2, N); } -void nr_polar_bit_insertion(uint8_t *input, - uint8_t *output, - uint16_t N, - uint16_t K, - int16_t *Q_I_N, - int16_t *Q_PC_N, - uint8_t n_PC) +void nr_polar_bit_insertion(uint8_t *input, uint8_t *output, uint16_t N, uint16_t K, int16_t *Q_I_N, int16_t *Q_PC_N, uint8_t n_PC) { int k = 0; - if (n_PC>0) { + if (n_PC > 0) { /* * */ } else { - for (int n=0; n<=N-1; n++) { + for (int n = 0; n <= N - 1; n++) { output[n] = 0; - for (int m=0; m<=(K+n_PC)-1; m++) { - if ( n == Q_I_N[m]) { + for (int m = 0; m <= (K + n_PC) - 1; m++) { + if (n == Q_I_N[m]) { output[n] = input[k]; k++; break; - } + } } } } } - -uint32_t nr_polar_output_length(uint16_t K, - uint16_t E, - uint8_t n_max) +uint32_t nr_polar_output_length(uint16_t K, uint16_t E, uint8_t n_max) { int n_1, n_2, n_min = 5; - double R_min=1.0/8; - - if ( (E <= (9.0/8)*pow(2,ceil(log2(E))-1)) && (K/E < 9.0/16) ) { - n_1 = ceil(log2(E))-1; + double R_min = 1.0 / 8; + + if ((E <= (9.0 / 8) * pow(2, ceil(log2(E)) - 1)) && (K / E < 9.0 / 16)) { + n_1 = ceil(log2(E)) - 1; } else { n_1 = ceil(log2(E)); } - - n_2 = ceil(log2(K/R_min)); + + n_2 = ceil(log2(K / R_min)); int n = n_max; if (n > n_1) @@ -206,9 +193,9 @@ uint32_t nr_polar_output_length(uint16_t K, n = n_min; /*printf("nr_polar_output_length: K %d, E %d, n %d (n_max %d,n_min %d, n_1 %d,n_2 %d)\n", - K,E,n,n_max,n_min,n_1,n_2); - exit(-1);*/ - return ((uint32_t) pow(2.0,n)); //=polar_code_output_length + K,E,n,n_max,n_min,n_1,n_2); + exit(-1);*/ + return ((uint32_t)pow(2.0, n)); //=polar_code_output_length } void nr_polar_info_bit_pattern(uint8_t *ibp, @@ -269,7 +256,7 @@ void nr_polar_info_bit_pattern(uint8_t *ibp, const int end = Q_Ftmp_N[N]; int m; for (m = 0; m <= end; m++) { - AssertFatal(m < N+1, "Buffer boundary overflow"); + AssertFatal(m < N + 1, "Buffer boundary overflow"); if (Q_0_Nminus1[n] == Q_Ftmp_N[m]) { break; } @@ -309,7 +296,6 @@ void nr_polar_info_bit_pattern(uint8_t *ibp, // Information and Parity Chack 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]) { @@ -328,11 +314,7 @@ void nr_polar_info_bit_pattern(uint8_t *ibp, } } - -void nr_polar_info_bit_extraction(uint8_t *input, - uint8_t *output, - uint8_t *pattern, - uint16_t size) +void nr_polar_info_bit_extraction(uint8_t *input, uint8_t *output, uint8_t *pattern, uint16_t size) { uint16_t j = 0; for (int i = 0; i < size; i++) { @@ -343,13 +325,7 @@ void nr_polar_info_bit_extraction(uint8_t *input, } } - -void nr_polar_rate_matching_pattern(uint16_t *rmp, - uint16_t *J, - const uint8_t *P_i_, - uint16_t K, - uint16_t N, - uint16_t E) +void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P_i_, uint16_t K, uint16_t N, uint16_t E) { uint16_t d[N]; for (int m = 0; m < N; m++) @@ -357,54 +333,49 @@ void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t y[N]; memset(y, 0, sizeof(y)); - for (int m=0; m<=N-1; m++){ + for (int m = 0; m <= N - 1; m++) { int i = floor((32 * m) / N); - J[m] = (P_i_[i]*(N/32)) + (m%(N/32)); + J[m] = (P_i_[i] * (N / 32)) + (m % (N / 32)); y[m] = d[J[m]]; } - if (E>=N) { //repetition - for (int k=0; k<=E-1; k++) { + if (E >= N) { // repetition + for (int k = 0; k <= E - 1; k++) { int ind = (k % N); - rmp[k]=y[ind]; + rmp[k] = y[ind]; } } else { - if ( (K/(double)E) <= (7.0/16) ) { //puncturing - for (int k=0; k<=E-1; k++) { - rmp[k]=y[k+N-E]; + if ((K / (double)E) <= (7.0 / 16)) { // puncturing + for (int k = 0; k <= E - 1; k++) { + rmp[k] = y[k + N - E]; } - } else { //shortening - for (int k=0; k<=E-1; k++) { - rmp[k]=y[k]; + } else { // shortening + for (int k = 0; k <= E - 1; k++) { + rmp[k] = y[k]; } } } } - -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(double *input, double *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]; + 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 + if ((K / (double)E) <= (7.0 / 16)) { // puncturing for (int i = 0; i <= N - 1; i++) output[i] = 0; - } else { //shortening + } 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]; + for (int i = 0; i <= E - 1; i++) { + output[rmp[i]] = input[i]; } } } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_pucch_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_pucch_defs.h index cf23982752..2b1fa8c6a7 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_pucch_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_pucch_defs.h @@ -7,22 +7,21 @@ #define NR_POLAR_PUCCH_PAYLOAD_BITS 16 -//Ref. 38-212 v15.0.1 -#define NR_POLAR_PUCCH_N_MAX 10 //uint8_t <------ -#define NR_POLAR_PUCCH_I_IL 1 //uint8_t <--- interleaving: if 0 no interleaving -#define NR_POLAR_PUCCH_N_PC 3 //uint8_t <-- or zero ?? -#define NR_POLAR_PUCCH_N_PC_WM 0 //uint8_t -//#define NR_POLAR_PUCCH_N 512 //uint16_t - -//Ref. 38-212 v15.0.1, Section 7.1.5: Rate Matching -#define NR_POLAR_PUCCH_I_BIL 0 //uint8_t -#define NR_POLAR_PUCCH_E 864 //uint16_t +// Ref. 38-212 v15.0.1 +#define NR_POLAR_PUCCH_N_MAX 10 // uint8_t <------ +#define NR_POLAR_PUCCH_I_IL 1 // uint8_t <--- interleaving: if 0 no interleaving +#define NR_POLAR_PUCCH_N_PC 3 // uint8_t <-- or zero ?? +#define NR_POLAR_PUCCH_N_PC_WM 0 // uint8_t +// #define NR_POLAR_PUCCH_N 512 //uint16_t +// Ref. 38-212 v15.0.1, Section 7.1.5: Rate Matching +#define NR_POLAR_PUCCH_I_BIL 0 // uint8_t +#define NR_POLAR_PUCCH_E 864 // uint16_t /* * TEST CODE */ -//unsigned int testPayload0=0x00000000, testPayload1=0xffffffff; //payload1=~payload0; -//unsigned int testPayload2=0xa5a5a5a5, testPayload3=0xb3f02c82; +// unsigned int testPayload0=0x00000000, testPayload1=0xffffffff; //payload1=~payload0; +// unsigned int testPayload2=0xa5a5a5a5, testPayload3=0xb3f02c82; #endif 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 ffa37c9549..f5bca4a9b7 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_rate_match.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_rate_match.c @@ -22,7 +22,8 @@ #include #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" -void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P_i_, uint16_t K, uint16_t N, uint16_t E){ +void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P_i_, uint16_t K, uint16_t N, uint16_t E) +{ int d[N]; int y[N]; @@ -53,8 +54,8 @@ 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(double *input, double *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; diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_sequence_pattern.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_sequence_pattern.c index 2a64925fde..e4633c91a3 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_sequence_pattern.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_sequence_pattern.c @@ -21,16 +21,103 @@ #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" -static const uint16_t Q_0_Nminus1_1[2] = { 0, 1 }; -static const uint16_t Q_0_Nminus1_2[4] = { 0, 1, 2, 3 }; -static const uint16_t Q_0_Nminus1_3[8] = { 0, 1, 2, 4, 3, 5, 6, 7 }; -static const uint16_t Q_0_Nminus1_4[16] = { 0, 1, 2, 4, 8, 3, 5, 9, 6, 10, 12, 7, 11, 13, 14, 15 }; -static const uint16_t Q_0_Nminus1_5[32] = { 0, 1, 2, 4, 8, 16, 3, 5, 9, 6, 17, 10, 18, 12, 20, 24, 7, 11, 19, 13, 14, 21, 26, 25, 22, 28, 15, 23, 27, 29, 30, 31 }; -static const uint16_t Q_0_Nminus1_6[64] = { 0, 1, 2, 4, 8, 16, 32, 3, 5, 9, 6, 17, 10, 18, 12, 33, 20, 34, 24, 36, 7, 11, 40, 19, 13, 48, 14, 21, 35, 26, 37, 25, 22, 38, 41, 28, 42, 49, 44, 50, 15, 52, 23, 56, 27, 39, 29, 43, 30, 45, 51, 46, 53, 54, 57, 58, 60, 31, 47, 55, 59, 61, 62, 63 }; -static const uint16_t Q_0_Nminus1_7[128] = { 0, 1, 2, 4, 8, 16, 32, 3, 5, 64, 9, 6, 17, 10, 18, 12, 33, 65, 20, 34, 24, 36, 7, 66, 11, 40, 68, 19, 13, 48, 14, 72, 21, 35, 26, 80, 37, 25, 22, 38, 96, 67, 41, 28, 69, 42, 49, 74, 70, 44, 81, 50, 73, 15, 52, 23, 76, 82, 56, 27, 97, 39, 84, 29, 43, 98, 88, 30, 71, 45, 100, 51, 46, 75, 104, 53, 77, 54, 83, 57, 112, 78, 85, 58, 99, 86, 60, 89, 101, 31, 90, 102, 105, 92, 47, 106, 55, 113, 79, 108, 59, 114, 87, 116, 61, 91, 120, 62, 103, 93, 107, 94, 109, 115, 110, 117, 118, 121, 122, 63, 124, 95, 111, 119, 123, 125, 126, 127 }; -static const uint16_t Q_0_Nminus1_8[256] = { 0, 1, 2, 4, 8, 16, 32, 3, 5, 64, 9, 6, 17, 10, 18, 128, 12, 33, 65, 20, 34, 24, 36, 7, 129, 66, 11, 40, 68, 130, 19, 13, 48, 14, 72, 21, 132, 35, 26, 80, 37, 25, 22, 136, 38, 96, 67, 41, 144, 28, 69, 42, 49, 74, 160, 192, 70, 44, 131, 81, 50, 73, 15, 133, 52, 23, 134, 76, 137, 82, 56, 27, 97, 39, 84, 138, 145, 29, 43, 98, 88, 140, 30, 146, 71, 161, 45, 100, 51, 148, 46, 75, 104, 162, 53, 193, 152, 77, 164, 54, 83, 57, 112, 135, 78, 194, 85, 58, 168, 139, 99, 86, 60, 89, 196, 141, 101, 147, 176, 142, 31, 200, 90, 149, 102, 105, 163, 92, 47, 208, 150, 153, 165, 106, 55, 113, 154, 79, 108, 224, 166, 195, 59, 169, 114, 156, 87, 197, 116, 170, 61, 177, 91, 198, 172, 120, 201, 62, 143, 103, 178, 93, 202, 107, 180, 151, 209, 94, 204, 155, 210, 109, 184, 115, 167, 225, 157, 110, 117, 212, 171, 226, 216, 158, 118, 173, 121, 199, 179, 228, 174, 122, 203, 63, 181, 232, 124, 205, 182, 211, 185, 240, 206, 95, 213, 186, 227, 111, 214, 188, 217, 229, 159, 119, 218, 230, 233, 175, 123, 220, 183, 234, 125, 241, 207, 187, 236, 126, 242, 244, 189, 215, 219, 231, 248, 190, 221, 235, 222, 237, 243, 238, 245, 127, 191, 246, 249, 250, 252, 223, 239, 251, 247, 253, 254, 255 }; -static const uint16_t Q_0_Nminus1_9[512] = { 0, 1, 2, 4, 8, 16, 32, 3, 5, 64, 9, 6, 17, 10, 18, 128, 12, 33, 65, 20, 256, 34, 24, 36, 7, 129, 66, 11, 40, 68, 130, 19, 13, 48, 14, 72, 257, 21, 132, 35, 258, 26, 80, 37, 25, 22, 136, 260, 264, 38, 96, 67, 41, 144, 28, 69, 42, 49, 74, 272, 160, 288, 192, 70, 44, 131, 81, 50, 73, 15, 320, 133, 52, 23, 134, 384, 76, 137, 82, 56, 27, 97, 39, 259, 84, 138, 145, 261, 29, 43, 98, 88, 140, 30, 146, 71, 262, 265, 161, 45, 100, 51, 148, 46, 75, 266, 273, 104, 162, 53, 193, 152, 77, 164, 268, 274, 54, 83, 57, 112, 135, 78, 289, 194, 85, 276, 58, 168, 139, 99, 86, 60, 280, 89, 290, 196, 141, 101, 147, 176, 142, 321, 31, 200, 90, 292, 322, 263, 149, 102, 105, 304, 296, 163, 92, 47, 267, 385, 324, 208, 386, 150, 153, 165, 106, 55, 328, 113, 154, 79, 269, 108, 224, 166, 195, 270, 275, 291, 59, 169, 114, 277, 156, 87, 197, 116, 170, 61, 281, 278, 177, 293, 388, 91, 198, 172, 120, 201, 336, 62, 282, 143, 103, 178, 294, 93, 202, 323, 392, 297, 107, 180, 151, 209, 284, 94, 204, 298, 400, 352, 325, 155, 210, 305, 300, 109, 184, 115, 167, 225, 326, 306, 157, 329, 110, 117, 212, 171, 330, 226, 387, 308, 216, 416, 271, 279, 158, 337, 118, 332, 389, 173, 121, 199, 179, 228, 338, 312, 390, 174, 393, 283, 122, 448, 353, 203, 63, 340, 394, 181, 295, 285, 232, 124, 205, 182, 286, 299, 354, 211, 401, 185, 396, 344, 240, 206, 95, 327, 402, 356, 307, 301, 417, 213, 186, 404, 227, 418, 302, 360, 111, 331, 214, 309, 188, 449, 217, 408, 229, 159, 420, 310, 333, 119, 339, 218, 368, 230, 391, 313, 450, 334, 233, 175, 123, 341, 220, 314, 424, 395, 355, 287, 183, 234, 125, 342, 316, 241, 345, 452, 397, 403, 207, 432, 357, 187, 236, 126, 242, 398, 346, 456, 358, 405, 303, 244, 189, 361, 215, 348, 419, 406, 464, 362, 409, 219, 311, 421, 410, 231, 248, 369, 190, 364, 335, 480, 315, 221, 370, 422, 425, 451, 235, 412, 343, 372, 317, 222, 426, 453, 237, 433, 347, 243, 454, 318, 376, 428, 238, 359, 457, 399, 434, 349, 245, 458, 363, 127, 191, 407, 436, 465, 246, 350, 460, 249, 411, 365, 440, 374, 423, 466, 250, 371, 481, 413, 366, 468, 429, 252, 373, 482, 427, 414, 223, 472, 455, 377, 435, 319, 484, 430, 488, 239, 378, 459, 437, 380, 461, 496, 351, 467, 438, 251, 462, 442, 441, 469, 247, 367, 253, 375, 444, 470, 483, 415, 485, 473, 474, 254, 379, 431, 489, 486, 476, 439, 490, 463, 381, 497, 492, 443, 382, 498, 445, 471, 500, 446, 475, 487, 504, 255, 477, 491, 478, 383, 493, 499, 502, 494, 501, 447, 505, 506, 479, 508, 495, 503, 507, 509, 510, 511 }; -static const uint16_t Q_0_Nminus1_10[1024] = { 0, 1, 2, 4, 8, 16, 32, 3, 5, 64, 9, 6, 17, 10, 18, 128, 12, 33, 65, 20, 256, 34, 24, 36, 7, 129, 66, 512, 11, 40, 68, 130, 19, 13, 48, 14, 72, 257, 21, 132, 35, 258, 26, 513, 80, 37, 25, 22, 136, 260, 264, 38, 514, 96, 67, 41, 144, 28, 69, 42, 516, 49, 74, 272, 160, 520, 288, 528, 192, 544, 70, 44, 131, 81, 50, 73, 15, 320, 133, 52, 23, 134, 384, 76, 137, 82, 56, 27, 97, 39, 259, 84, 138, 145, 261, 29, 43, 98, 515, 88, 140, 30, 146, 71, 262, 265, 161, 576, 45, 100, 640, 51, 148, 46, 75, 266, 273, 517, 104, 162, 53, 193, 152, 77, 164, 768, 268, 274, 518, 54, 83, 57, 521, 112, 135, 78, 289, 194, 85, 276, 522, 58, 168, 139, 99, 86, 60, 280, 89, 290, 529, 524, 196, 141, 101, 147, 176, 142, 530, 321, 31, 200, 90, 545, 292, 322, 532, 263, 149, 102, 105, 304, 296, 163, 92, 47, 267, 385, 546, 324, 208, 386, 150, 153, 165, 106, 55, 328, 536, 577, 548, 113, 154, 79, 269, 108, 578, 224, 166, 519, 552, 195, 270, 641, 523, 275, 580, 291, 59, 169, 560, 114, 277, 156, 87, 197, 116, 170, 61, 531, 525, 642, 281, 278, 526, 177, 293, 388, 91, 584, 769, 198, 172, 120, 201, 336, 62, 282, 143, 103, 178, 294, 93, 644, 202, 592, 323, 392, 297, 770, 107, 180, 151, 209, 284, 648, 94, 204, 298, 400, 608, 352, 325, 533, 155, 210, 305, 547, 300, 109, 184, 534, 537, 115, 167, 225, 326, 306, 772, 157, 656, 329, 110, 117, 212, 171, 776, 330, 226, 549, 538, 387, 308, 216, 416, 271, 279, 158, 337, 550, 672, 118, 332, 579, 540, 389, 173, 121, 553, 199, 784, 179, 228, 338, 312, 704, 390, 174, 554, 581, 393, 283, 122, 448, 353, 561, 203, 63, 340, 394, 527, 582, 556, 181, 295, 285, 232, 124, 205, 182, 643, 562, 286, 585, 299, 354, 211, 401, 185, 396, 344, 586, 645, 593, 535, 240, 206, 95, 327, 564, 800, 402, 356, 307, 301, 417, 213, 568, 832, 588, 186, 646, 404, 227, 896, 594, 418, 302, 649, 771, 360, 539, 111, 331, 214, 309, 188, 449, 217, 408, 609, 596, 551, 650, 229, 159, 420, 310, 541, 773, 610, 657, 333, 119, 600, 339, 218, 368, 652, 230, 391, 313, 450, 542, 334, 233, 555, 774, 175, 123, 658, 612, 341, 777, 220, 314, 424, 395, 673, 583, 355, 287, 183, 234, 125, 557, 660, 616, 342, 316, 241, 778, 563, 345, 452, 397, 403, 207, 674, 558, 785, 432, 357, 187, 236, 664, 624, 587, 780, 705, 126, 242, 565, 398, 346, 456, 358, 405, 303, 569, 244, 595, 189, 566, 676, 361, 706, 589, 215, 786, 647, 348, 419, 406, 464, 680, 801, 362, 590, 409, 570, 788, 597, 572, 219, 311, 708, 598, 601, 651, 421, 792, 802, 611, 602, 410, 231, 688, 653, 248, 369, 190, 364, 654, 659, 335, 480, 315, 221, 370, 613, 422, 425, 451, 614, 543, 235, 412, 343, 372, 775, 317, 222, 426, 453, 237, 559, 833, 804, 712, 834, 661, 808, 779, 617, 604, 433, 720, 816, 836, 347, 897, 243, 662, 454, 318, 675, 618, 898, 781, 376, 428, 665, 736, 567, 840, 625, 238, 359, 457, 399, 787, 591, 678, 434, 677, 349, 245, 458, 666, 620, 363, 127, 191, 782, 407, 436, 626, 571, 465, 681, 246, 707, 350, 599, 668, 790, 460, 249, 682, 573, 411, 803, 789, 709, 365, 440, 628, 689, 374, 423, 466, 793, 250, 371, 481, 574, 413, 603, 366, 468, 655, 900, 805, 615, 684, 710, 429, 794, 252, 373, 605, 848, 690, 713, 632, 482, 806, 427, 904, 414, 223, 663, 692, 835, 619, 472, 455, 796, 809, 714, 721, 837, 716, 864, 810, 606, 912, 722, 696, 377, 435, 817, 319, 621, 812, 484, 430, 838, 667, 488, 239, 378, 459, 622, 627, 437, 380, 818, 461, 496, 669, 679, 724, 841, 629, 351, 467, 438, 737, 251, 462, 442, 441, 469, 247, 683, 842, 738, 899, 670, 783, 849, 820, 728, 928, 791, 367, 901, 630, 685, 844, 633, 711, 253, 691, 824, 902, 686, 740, 850, 375, 444, 470, 483, 415, 485, 905, 795, 473, 634, 744, 852, 960, 865, 693, 797, 906, 715, 807, 474, 636, 694, 254, 717, 575, 913, 798, 811, 379, 697, 431, 607, 489, 866, 723, 486, 908, 718, 813, 476, 856, 839, 725, 698, 914, 752, 868, 819, 814, 439, 929, 490, 623, 671, 739, 916, 463, 843, 381, 497, 930, 821, 726, 961, 872, 492, 631, 729, 700, 443, 741, 845, 920, 382, 822, 851, 730, 498, 880, 742, 445, 471, 635, 932, 687, 903, 825, 500, 846, 745, 826, 732, 446, 962, 936, 475, 853, 867, 637, 907, 487, 695, 746, 828, 753, 854, 857, 504, 799, 255, 964, 909, 719, 477, 915, 638, 748, 944, 869, 491, 699, 754, 858, 478, 968, 383, 910, 815, 976, 870, 917, 727, 493, 873, 701, 931, 756, 860, 499, 731, 823, 922, 874, 918, 502, 933, 743, 760, 881, 494, 702, 921, 501, 876, 847, 992, 447, 733, 827, 934, 882, 937, 963, 747, 505, 855, 924, 734, 829, 965, 938, 884, 506, 749, 945, 966, 755, 859, 940, 830, 911, 871, 639, 888, 479, 946, 750, 969, 508, 861, 757, 970, 919, 875, 862, 758, 948, 977, 923, 972, 761, 877, 952, 495, 703, 935, 978, 883, 762, 503, 925, 878, 735, 993, 885, 939, 994, 980, 926, 764, 941, 967, 886, 831, 947, 507, 889, 984, 751, 942, 996, 971, 890, 509, 949, 973, 1000, 892, 950, 863, 759, 1008, 510, 979, 953, 763, 974, 954, 879, 981, 982, 927, 995, 765, 956, 887, 985, 997, 986, 943, 891, 998, 766, 511, 988, 1001, 951, 1002, 893, 975, 894, 1009, 955, 1004, 1010, 957, 983, 958, 987, 1012, 999, 1016, 767, 989, 1003, 990, 1005, 959, 1011, 1013, 895, 1006, 1014, 1017, 1018, 991, 1020, 1007, 1015, 1019, 1021, 1022, 1023 }; +static const uint16_t Q_0_Nminus1_1[2] = {0, 1}; +static const uint16_t Q_0_Nminus1_2[4] = {0, 1, 2, 3}; +static const uint16_t Q_0_Nminus1_3[8] = {0, 1, 2, 4, 3, 5, 6, 7}; +static const uint16_t Q_0_Nminus1_4[16] = {0, 1, 2, 4, 8, 3, 5, 9, 6, 10, 12, 7, 11, 13, 14, 15}; +static const uint16_t Q_0_Nminus1_5[32] = {0, 1, 2, 4, 8, 16, 3, 5, 9, 6, 17, 10, 18, 12, 20, 24, + 7, 11, 19, 13, 14, 21, 26, 25, 22, 28, 15, 23, 27, 29, 30, 31}; +static const uint16_t Q_0_Nminus1_6[64] = {0, 1, 2, 4, 8, 16, 32, 3, 5, 9, 6, 17, 10, 18, 12, 33, 20, 34, 24, 36, 7, 11, + 40, 19, 13, 48, 14, 21, 35, 26, 37, 25, 22, 38, 41, 28, 42, 49, 44, 50, 15, 52, 23, 56, + 27, 39, 29, 43, 30, 45, 51, 46, 53, 54, 57, 58, 60, 31, 47, 55, 59, 61, 62, 63}; +static const uint16_t Q_0_Nminus1_7[128] = { + 0, 1, 2, 4, 8, 16, 32, 3, 5, 64, 9, 6, 17, 10, 18, 12, 33, 65, 20, 34, 24, 36, 7, 66, 11, 40, + 68, 19, 13, 48, 14, 72, 21, 35, 26, 80, 37, 25, 22, 38, 96, 67, 41, 28, 69, 42, 49, 74, 70, 44, 81, 50, + 73, 15, 52, 23, 76, 82, 56, 27, 97, 39, 84, 29, 43, 98, 88, 30, 71, 45, 100, 51, 46, 75, 104, 53, 77, 54, + 83, 57, 112, 78, 85, 58, 99, 86, 60, 89, 101, 31, 90, 102, 105, 92, 47, 106, 55, 113, 79, 108, 59, 114, 87, 116, + 61, 91, 120, 62, 103, 93, 107, 94, 109, 115, 110, 117, 118, 121, 122, 63, 124, 95, 111, 119, 123, 125, 126, 127}; +static const uint16_t Q_0_Nminus1_8[256] = { + 0, 1, 2, 4, 8, 16, 32, 3, 5, 64, 9, 6, 17, 10, 18, 128, 12, 33, 65, 20, 34, 24, 36, 7, + 129, 66, 11, 40, 68, 130, 19, 13, 48, 14, 72, 21, 132, 35, 26, 80, 37, 25, 22, 136, 38, 96, 67, 41, + 144, 28, 69, 42, 49, 74, 160, 192, 70, 44, 131, 81, 50, 73, 15, 133, 52, 23, 134, 76, 137, 82, 56, 27, + 97, 39, 84, 138, 145, 29, 43, 98, 88, 140, 30, 146, 71, 161, 45, 100, 51, 148, 46, 75, 104, 162, 53, 193, + 152, 77, 164, 54, 83, 57, 112, 135, 78, 194, 85, 58, 168, 139, 99, 86, 60, 89, 196, 141, 101, 147, 176, 142, + 31, 200, 90, 149, 102, 105, 163, 92, 47, 208, 150, 153, 165, 106, 55, 113, 154, 79, 108, 224, 166, 195, 59, 169, + 114, 156, 87, 197, 116, 170, 61, 177, 91, 198, 172, 120, 201, 62, 143, 103, 178, 93, 202, 107, 180, 151, 209, 94, + 204, 155, 210, 109, 184, 115, 167, 225, 157, 110, 117, 212, 171, 226, 216, 158, 118, 173, 121, 199, 179, 228, 174, 122, + 203, 63, 181, 232, 124, 205, 182, 211, 185, 240, 206, 95, 213, 186, 227, 111, 214, 188, 217, 229, 159, 119, 218, 230, + 233, 175, 123, 220, 183, 234, 125, 241, 207, 187, 236, 126, 242, 244, 189, 215, 219, 231, 248, 190, 221, 235, 222, 237, + 243, 238, 245, 127, 191, 246, 249, 250, 252, 223, 239, 251, 247, 253, 254, 255}; +static const uint16_t Q_0_Nminus1_9[512] = { + 0, 1, 2, 4, 8, 16, 32, 3, 5, 64, 9, 6, 17, 10, 18, 128, 12, 33, 65, 20, 256, 34, 24, 36, 7, + 129, 66, 11, 40, 68, 130, 19, 13, 48, 14, 72, 257, 21, 132, 35, 258, 26, 80, 37, 25, 22, 136, 260, 264, 38, + 96, 67, 41, 144, 28, 69, 42, 49, 74, 272, 160, 288, 192, 70, 44, 131, 81, 50, 73, 15, 320, 133, 52, 23, 134, + 384, 76, 137, 82, 56, 27, 97, 39, 259, 84, 138, 145, 261, 29, 43, 98, 88, 140, 30, 146, 71, 262, 265, 161, 45, + 100, 51, 148, 46, 75, 266, 273, 104, 162, 53, 193, 152, 77, 164, 268, 274, 54, 83, 57, 112, 135, 78, 289, 194, 85, + 276, 58, 168, 139, 99, 86, 60, 280, 89, 290, 196, 141, 101, 147, 176, 142, 321, 31, 200, 90, 292, 322, 263, 149, 102, + 105, 304, 296, 163, 92, 47, 267, 385, 324, 208, 386, 150, 153, 165, 106, 55, 328, 113, 154, 79, 269, 108, 224, 166, 195, + 270, 275, 291, 59, 169, 114, 277, 156, 87, 197, 116, 170, 61, 281, 278, 177, 293, 388, 91, 198, 172, 120, 201, 336, 62, + 282, 143, 103, 178, 294, 93, 202, 323, 392, 297, 107, 180, 151, 209, 284, 94, 204, 298, 400, 352, 325, 155, 210, 305, 300, + 109, 184, 115, 167, 225, 326, 306, 157, 329, 110, 117, 212, 171, 330, 226, 387, 308, 216, 416, 271, 279, 158, 337, 118, 332, + 389, 173, 121, 199, 179, 228, 338, 312, 390, 174, 393, 283, 122, 448, 353, 203, 63, 340, 394, 181, 295, 285, 232, 124, 205, + 182, 286, 299, 354, 211, 401, 185, 396, 344, 240, 206, 95, 327, 402, 356, 307, 301, 417, 213, 186, 404, 227, 418, 302, 360, + 111, 331, 214, 309, 188, 449, 217, 408, 229, 159, 420, 310, 333, 119, 339, 218, 368, 230, 391, 313, 450, 334, 233, 175, 123, + 341, 220, 314, 424, 395, 355, 287, 183, 234, 125, 342, 316, 241, 345, 452, 397, 403, 207, 432, 357, 187, 236, 126, 242, 398, + 346, 456, 358, 405, 303, 244, 189, 361, 215, 348, 419, 406, 464, 362, 409, 219, 311, 421, 410, 231, 248, 369, 190, 364, 335, + 480, 315, 221, 370, 422, 425, 451, 235, 412, 343, 372, 317, 222, 426, 453, 237, 433, 347, 243, 454, 318, 376, 428, 238, 359, + 457, 399, 434, 349, 245, 458, 363, 127, 191, 407, 436, 465, 246, 350, 460, 249, 411, 365, 440, 374, 423, 466, 250, 371, 481, + 413, 366, 468, 429, 252, 373, 482, 427, 414, 223, 472, 455, 377, 435, 319, 484, 430, 488, 239, 378, 459, 437, 380, 461, 496, + 351, 467, 438, 251, 462, 442, 441, 469, 247, 367, 253, 375, 444, 470, 483, 415, 485, 473, 474, 254, 379, 431, 489, 486, 476, + 439, 490, 463, 381, 497, 492, 443, 382, 498, 445, 471, 500, 446, 475, 487, 504, 255, 477, 491, 478, 383, 493, 499, 502, 494, + 501, 447, 505, 506, 479, 508, 495, 503, 507, 509, 510, 511}; +static const uint16_t Q_0_Nminus1_10[1024] = { + 0, 1, 2, 4, 8, 16, 32, 3, 5, 64, 9, 6, 17, 10, 18, 128, 12, 33, 65, 20, 256, 34, + 24, 36, 7, 129, 66, 512, 11, 40, 68, 130, 19, 13, 48, 14, 72, 257, 21, 132, 35, 258, 26, 513, + 80, 37, 25, 22, 136, 260, 264, 38, 514, 96, 67, 41, 144, 28, 69, 42, 516, 49, 74, 272, 160, 520, + 288, 528, 192, 544, 70, 44, 131, 81, 50, 73, 15, 320, 133, 52, 23, 134, 384, 76, 137, 82, 56, 27, + 97, 39, 259, 84, 138, 145, 261, 29, 43, 98, 515, 88, 140, 30, 146, 71, 262, 265, 161, 576, 45, 100, + 640, 51, 148, 46, 75, 266, 273, 517, 104, 162, 53, 193, 152, 77, 164, 768, 268, 274, 518, 54, 83, 57, + 521, 112, 135, 78, 289, 194, 85, 276, 522, 58, 168, 139, 99, 86, 60, 280, 89, 290, 529, 524, 196, 141, + 101, 147, 176, 142, 530, 321, 31, 200, 90, 545, 292, 322, 532, 263, 149, 102, 105, 304, 296, 163, 92, 47, + 267, 385, 546, 324, 208, 386, 150, 153, 165, 106, 55, 328, 536, 577, 548, 113, 154, 79, 269, 108, 578, 224, + 166, 519, 552, 195, 270, 641, 523, 275, 580, 291, 59, 169, 560, 114, 277, 156, 87, 197, 116, 170, 61, 531, + 525, 642, 281, 278, 526, 177, 293, 388, 91, 584, 769, 198, 172, 120, 201, 336, 62, 282, 143, 103, 178, 294, + 93, 644, 202, 592, 323, 392, 297, 770, 107, 180, 151, 209, 284, 648, 94, 204, 298, 400, 608, 352, 325, 533, + 155, 210, 305, 547, 300, 109, 184, 534, 537, 115, 167, 225, 326, 306, 772, 157, 656, 329, 110, 117, 212, 171, + 776, 330, 226, 549, 538, 387, 308, 216, 416, 271, 279, 158, 337, 550, 672, 118, 332, 579, 540, 389, 173, 121, + 553, 199, 784, 179, 228, 338, 312, 704, 390, 174, 554, 581, 393, 283, 122, 448, 353, 561, 203, 63, 340, 394, + 527, 582, 556, 181, 295, 285, 232, 124, 205, 182, 643, 562, 286, 585, 299, 354, 211, 401, 185, 396, 344, 586, + 645, 593, 535, 240, 206, 95, 327, 564, 800, 402, 356, 307, 301, 417, 213, 568, 832, 588, 186, 646, 404, 227, + 896, 594, 418, 302, 649, 771, 360, 539, 111, 331, 214, 309, 188, 449, 217, 408, 609, 596, 551, 650, 229, 159, + 420, 310, 541, 773, 610, 657, 333, 119, 600, 339, 218, 368, 652, 230, 391, 313, 450, 542, 334, 233, 555, 774, + 175, 123, 658, 612, 341, 777, 220, 314, 424, 395, 673, 583, 355, 287, 183, 234, 125, 557, 660, 616, 342, 316, + 241, 778, 563, 345, 452, 397, 403, 207, 674, 558, 785, 432, 357, 187, 236, 664, 624, 587, 780, 705, 126, 242, + 565, 398, 346, 456, 358, 405, 303, 569, 244, 595, 189, 566, 676, 361, 706, 589, 215, 786, 647, 348, 419, 406, + 464, 680, 801, 362, 590, 409, 570, 788, 597, 572, 219, 311, 708, 598, 601, 651, 421, 792, 802, 611, 602, 410, + 231, 688, 653, 248, 369, 190, 364, 654, 659, 335, 480, 315, 221, 370, 613, 422, 425, 451, 614, 543, 235, 412, + 343, 372, 775, 317, 222, 426, 453, 237, 559, 833, 804, 712, 834, 661, 808, 779, 617, 604, 433, 720, 816, 836, + 347, 897, 243, 662, 454, 318, 675, 618, 898, 781, 376, 428, 665, 736, 567, 840, 625, 238, 359, 457, 399, 787, + 591, 678, 434, 677, 349, 245, 458, 666, 620, 363, 127, 191, 782, 407, 436, 626, 571, 465, 681, 246, 707, 350, + 599, 668, 790, 460, 249, 682, 573, 411, 803, 789, 709, 365, 440, 628, 689, 374, 423, 466, 793, 250, 371, 481, + 574, 413, 603, 366, 468, 655, 900, 805, 615, 684, 710, 429, 794, 252, 373, 605, 848, 690, 713, 632, 482, 806, + 427, 904, 414, 223, 663, 692, 835, 619, 472, 455, 796, 809, 714, 721, 837, 716, 864, 810, 606, 912, 722, 696, + 377, 435, 817, 319, 621, 812, 484, 430, 838, 667, 488, 239, 378, 459, 622, 627, 437, 380, 818, 461, 496, 669, + 679, 724, 841, 629, 351, 467, 438, 737, 251, 462, 442, 441, 469, 247, 683, 842, 738, 899, 670, 783, 849, 820, + 728, 928, 791, 367, 901, 630, 685, 844, 633, 711, 253, 691, 824, 902, 686, 740, 850, 375, 444, 470, 483, 415, + 485, 905, 795, 473, 634, 744, 852, 960, 865, 693, 797, 906, 715, 807, 474, 636, 694, 254, 717, 575, 913, 798, + 811, 379, 697, 431, 607, 489, 866, 723, 486, 908, 718, 813, 476, 856, 839, 725, 698, 914, 752, 868, 819, 814, + 439, 929, 490, 623, 671, 739, 916, 463, 843, 381, 497, 930, 821, 726, 961, 872, 492, 631, 729, 700, 443, 741, + 845, 920, 382, 822, 851, 730, 498, 880, 742, 445, 471, 635, 932, 687, 903, 825, 500, 846, 745, 826, 732, 446, + 962, 936, 475, 853, 867, 637, 907, 487, 695, 746, 828, 753, 854, 857, 504, 799, 255, 964, 909, 719, 477, 915, + 638, 748, 944, 869, 491, 699, 754, 858, 478, 968, 383, 910, 815, 976, 870, 917, 727, 493, 873, 701, 931, 756, + 860, 499, 731, 823, 922, 874, 918, 502, 933, 743, 760, 881, 494, 702, 921, 501, 876, 847, 992, 447, 733, 827, + 934, 882, 937, 963, 747, 505, 855, 924, 734, 829, 965, 938, 884, 506, 749, 945, 966, 755, 859, 940, 830, 911, + 871, 639, 888, 479, 946, 750, 969, 508, 861, 757, 970, 919, 875, 862, 758, 948, 977, 923, 972, 761, 877, 952, + 495, 703, 935, 978, 883, 762, 503, 925, 878, 735, 993, 885, 939, 994, 980, 926, 764, 941, 967, 886, 831, 947, + 507, 889, 984, 751, 942, 996, 971, 890, 509, 949, 973, 1000, 892, 950, 863, 759, 1008, 510, 979, 953, 763, 974, + 954, 879, 981, 982, 927, 995, 765, 956, 887, 985, 997, 986, 943, 891, 998, 766, 511, 988, 1001, 951, 1002, 893, + 975, 894, 1009, 955, 1004, 1010, 957, 983, 958, 987, 1012, 999, 1016, 767, 989, 1003, 990, 1005, 959, 1011, 1013, 895, + 1006, 1014, 1017, 1018, 991, 1020, 1007, 1015, 1019, 1021, 1022, 1023}; static const uint16_t* const Q_0_Nminus1[11] = {NULL, Q_0_Nminus1_1, @@ -44,6 +131,7 @@ static const uint16_t* const Q_0_Nminus1[11] = {NULL, Q_0_Nminus1_9, Q_0_Nminus1_10}; -const uint16_t* nr_polar_sequence_pattern(uint8_t n){ - return Q_0_Nminus1[n]; +const uint16_t* nr_polar_sequence_pattern(uint8_t n) +{ + return Q_0_Nminus1[n]; } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h index 1ab664e5a2..d08862bb13 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h @@ -20,32 +20,32 @@ */ /*! \file PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h -* \brief Defines the constant variables for polar coding of the UCI from 38-212, V15.1.1 2018-04. -* \author -* \date 2018 -* \version 0.1 -* \company Eurecom -* \email: -* \note -* \warning -*/ + * \brief Defines the constant variables for polar coding of the UCI from 38-212, V15.1.1 2018-04. + * \author + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: + * \note + * \warning + */ #ifndef __NR_POLAR_UCI_DEFS__H__ #define __NR_POLAR_UCI_DEFS__H__ -#define NR_POLAR_UCI_PUCCH_MESSAGE_TYPE 2 //int8_t +#define NR_POLAR_UCI_PUCCH_MESSAGE_TYPE 2 // int8_t #define NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS 3 #define NR_POLAR_PUCCH_PAYLOAD_BITS 32 #define NR_POLAR_PUCCH_E 32 -//Ref. 38-212, Section 6.3.1.2.1 +// Ref. 38-212, Section 6.3.1.2.1 #define NR_POLAR_PUCCH_CRC_PARITY_BITS_SHORT 6 #define NR_POLAR_PUCCH_CRC_PARITY_BITS_LONG 11 #define NR_POLAR_PUCCH_I_SEG_LONG 1 #define NR_POLAR_PUCCH_I_SEG_SHORT 0 -//Ref. 38-212, Section 6.3.1.3.1 +// Ref. 38-212, Section 6.3.1.3.1 #define NR_POLAR_PUCCH_N_MAX 10 #define NR_POLAR_PUCCH_I_IL 0 #define NR_POLAR_PUCCH_N_PC_SHORT 3 @@ -53,9 +53,7 @@ #define NR_POLAR_PUCCH_N_PC_WM_LONG 0 #define NR_POLAR_PUCCH_N_PC_WM_SHORT 1 -//Ref. 38-212, Section 6.3.1.4.1 +// Ref. 38-212, Section 6.3.1.4.1 #define NR_POLAR_PUCCH_I_BIL 1 - - #endif diff --git a/openair1/PHY/CODING/nr_polar_init.c b/openair1/PHY/CODING/nr_polar_init.c index 899aa5447f..ca982d79bf 100644 --- a/openair1/PHY/CODING/nr_polar_init.c +++ b/openair1/PHY/CODING/nr_polar_init.c @@ -34,15 +34,17 @@ #include "PHY/NR_TRANSPORT/nr_dci.h" #include "nrPolar_tools/nr_polar_psbch_defs.h" -#define PolarKey ((messageType<<24)|(messageLength<<8)|aggregation_level) -static t_nrPolar_params * PolarList=NULL; -pthread_mutex_t PolarListMutex=PTHREAD_MUTEX_INITIALIZER; +#define PolarKey ((messageType << 24) | (messageLength << 8) | aggregation_level) +static t_nrPolar_params *PolarList = NULL; +pthread_mutex_t PolarListMutex = PTHREAD_MUTEX_INITIALIZER; -static int intcmp(const void *p1,const void *p2) { - return(*(int16_t *)p1 > *(int16_t *)p2); +static int intcmp(const void *p1, const void *p2) +{ + return (*(int16_t *)p1 > *(int16_t *)p2); } -static void nr_polar_delete_list(t_nrPolar_params * polarParams) { +static void nr_polar_delete_list(t_nrPolar_params *polarParams) +{ if (!polarParams) return; if (polarParams->nextPtr) @@ -64,11 +66,12 @@ static void nr_polar_delete_list(t_nrPolar_params * polarParams) { free(polarParams); } -static void nr_polar_delete(void) { +static void nr_polar_delete(void) +{ pthread_mutex_lock(&PolarListMutex); nr_polar_delete_list(PolarList); - PolarList=NULL; - pthread_mutex_unlock(&PolarListMutex); + PolarList = NULL; + pthread_mutex_unlock(&PolarListMutex); } t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, uint8_t aggregation_level) @@ -76,34 +79,35 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui // 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); - if(!PolarList) + if (!PolarList) atexit(nr_polar_delete); - + t_nrPolar_params *currentPtr = PolarList; - //Parse the list. If the node is already created, return without initialization. + // Parse the list. If the node is already created, return without initialization. while (currentPtr != NULL) { - //printf("currentPtr->idx %d, (%d,%d)\n",currentPtr->idx,currentPtr->payloadBits,currentPtr->encoderLength); - //LOG_D(PHY,"Looking for index %d\n",(messageType * messageLength * aggregation_prime)); - if (currentPtr->busy == false && currentPtr->idx == PolarKey ) { - currentPtr->busy=true; + // printf("currentPtr->idx %d, (%d,%d)\n",currentPtr->idx,currentPtr->payloadBits,currentPtr->encoderLength); + // LOG_D(PHY,"Looking for index %d\n",(messageType * messageLength * aggregation_prime)); + if (currentPtr->busy == false && currentPtr->idx == PolarKey) { + currentPtr->busy = true; pthread_mutex_unlock(&PolarListMutex); - return currentPtr ; - } - else + return currentPtr; + } else currentPtr = currentPtr->nextPtr; } // printf("currentPtr %p (polarParams %p)\n",currentPtr,polarParams); - //Else, initialize and add node to the end of the linked list. + // Else, initialize and add node to the end of the linked list. t_nrPolar_params *newPolarInitNode = malloc(sizeof(t_nrPolar_params)); AssertFatal(newPolarInitNode, "[nr_polar_init] New t_nrPolar_params * could not be created"); *newPolarInitNode = (t_nrPolar_params){.busy = true, .nextPtr = PolarList, .tree_linearization.is_initialized = false}; PolarList = newPolarInitNode; pthread_mutex_unlock(&PolarListMutex); - // LOG_D(PHY,"Setting new polarParams index %d, messageType %d, messageLength %d, aggregation_prime %d\n",(messageType * messageLength * aggregation_prime),messageType,messageLength,aggregation_prime); + // LOG_D(PHY,"Setting new polarParams index %d, messageType %d, messageLength %d, aggregation_prime %d\n",(messageType * + // messageLength * aggregation_prime),messageType,messageLength,aggregation_prime); newPolarInitNode->idx = PolarKey; - //printf("newPolarInitNode->idx %d, (%d,%d,%d:%d)\n",newPolarInitNode->idx,messageType,messageLength,aggregation_prime,aggregation_level); + // printf("newPolarInitNode->idx %d, + // (%d,%d,%d:%d)\n",newPolarInitNode->idx,messageType,messageLength,aggregation_prime,aggregation_level); if (messageType == NR_POLAR_PBCH_MESSAGE_TYPE) { newPolarInitNode->n_max = NR_POLAR_PBCH_N_MAX; @@ -117,7 +121,8 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui 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 - //printf("Initializing polar parameters for PBCH (K %d, E %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength); + // printf("Initializing polar parameters for PBCH (K %d, E + // %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength); } else if (messageType == NR_POLAR_DCI_MESSAGE_TYPE) { newPolarInitNode->n_max = NR_POLAR_DCI_N_MAX; @@ -130,11 +135,15 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui newPolarInitNode->payloadBits = messageLength; 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 - //printf("Initializing polar parameters for DCI (K %d, E %d, L %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength,aggregation_level); + 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 == 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(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 @@ -175,7 +184,7 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui newPolarInitNode->i_bil = NR_POLAR_PUCCH_I_BIL; newPolarInitNode->payloadBits = messageLength; newPolarInitNode->crcCorrectionBits = NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS; - //LOG_D(PHY,"New polar node, encoderLength %d, aggregation_level %d\n",newPolarInitNode->encoderLength,aggregation_level); + // LOG_D(PHY,"New polar node, encoderLength %d, aggregation_level %d\n",newPolarInitNode->encoderLength,aggregation_level); } else if (messageType == SL_NR_POLAR_PSBCH_MESSAGE_TYPE) { // PSBCH newPolarInitNode->n_max = SL_NR_POLAR_PSBCH_N_MAX; newPolarInitNode->i_il = SL_NR_POLAR_PSBCH_I_IL; @@ -197,17 +206,13 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui } newPolarInitNode->K = newPolarInitNode->payloadBits + newPolarInitNode->crcParityBits; // Number of bits to encode. - newPolarInitNode->N = nr_polar_output_length(newPolarInitNode->K, - newPolarInitNode->encoderLength, - newPolarInitNode->n_max); + newPolarInitNode->N = nr_polar_output_length(newPolarInitNode->K, newPolarInitNode->encoderLength, newPolarInitNode->n_max); newPolarInitNode->n = log2(newPolarInitNode->N); newPolarInitNode->G_N = nr_polar_kronecker_power_matrices(newPolarInitNode->n); // polar_encoder vectors: newPolarInitNode->Q_0_Nminus1 = nr_polar_sequence_pattern(newPolarInitNode->n); newPolarInitNode->interleaving_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->K); - nr_polar_interleaving_pattern(newPolarInitNode->K, - newPolarInitNode->i_il, - newPolarInitNode->interleaving_pattern); + nr_polar_interleaving_pattern(newPolarInitNode->K, newPolarInitNode->i_il, newPolarInitNode->interleaving_pattern); newPolarInitNode->rate_matching_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength); uint16_t J[newPolarInitNode->N]; @@ -224,8 +229,9 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui 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)); + 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)); for (int i = 0; i <= newPolarInitNode->N; i++) newPolarInitNode->Q_F_N[i] = -1; // Empty array. @@ -244,22 +250,26 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui 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); + qsort((void *)newPolarInitNode->Q_I_N, newPolarInitNode->K, sizeof(int16_t), intcmp); build_polar_tables(newPolarInitNode); return newPolarInitNode; } -void nr_polar_print_polarParams() { +void nr_polar_print_polarParams() +{ uint8_t i = 0; if (PolarList == NULL) { printf("polarParams is empty.\n"); } else { - t_nrPolar_params * polarParams=PolarList; + t_nrPolar_params *polarParams = PolarList; while (polarParams != NULL) { - printf("polarParams[%d] = %d, %d, %d\n", i, - polarParams->idx>>24, (polarParams->idx>>8)&0xFFFF, polarParams->idx&0xFF); + printf("polarParams[%d] = %d, %d, %d\n", + i, + polarParams->idx >> 24, + (polarParams->idx >> 8) & 0xFFFF, + polarParams->idx & 0xFF); polarParams = polarParams->nextPtr; i++; } @@ -268,11 +278,18 @@ void nr_polar_print_polarParams() { return; } -uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level) { - if (aggregation_level == 0) return 0; - else if (aggregation_level == 1) return NR_POLAR_AGGREGATION_LEVEL_1_PRIME; - else if (aggregation_level == 2) return NR_POLAR_AGGREGATION_LEVEL_2_PRIME; - else if (aggregation_level == 4) return NR_POLAR_AGGREGATION_LEVEL_4_PRIME; - else if (aggregation_level == 8) return NR_POLAR_AGGREGATION_LEVEL_8_PRIME; - else return NR_POLAR_AGGREGATION_LEVEL_16_PRIME; //aggregation_level == 16 +uint16_t nr_polar_aggregation_prime(uint8_t aggregation_level) +{ + if (aggregation_level == 0) + return 0; + else if (aggregation_level == 1) + return NR_POLAR_AGGREGATION_LEVEL_1_PRIME; + else if (aggregation_level == 2) + return NR_POLAR_AGGREGATION_LEVEL_2_PRIME; + else if (aggregation_level == 4) + return NR_POLAR_AGGREGATION_LEVEL_4_PRIME; + else if (aggregation_level == 8) + return NR_POLAR_AGGREGATION_LEVEL_8_PRIME; + else + return NR_POLAR_AGGREGATION_LEVEL_16_PRIME; // aggregation_level == 16 } From 0e93a8b4cfe6ba88089d00413fa84a42bc1074d9 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 7 Nov 2024 09:45:01 +0100 Subject: [PATCH 8/8] Move nr_polar_init.c to nrPolar_tools/ --- CMakeLists.txt | 2 +- openair1/PHY/CODING/{ => nrPolar_tools}/nr_polar_init.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename openair1/PHY/CODING/{ => nrPolar_tools}/nr_polar_init.c (99%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ac21ab5d5..e4ab080a2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -772,7 +772,7 @@ set(PHY_TURBOSRC ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder.c ) set(PHY_POLARSRC - ${OPENAIR1_DIR}/PHY/CODING/nr_polar_init.c + ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_init.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_bitwise_operations.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_crc_byte.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_decoder.c diff --git a/openair1/PHY/CODING/nr_polar_init.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_init.c similarity index 99% rename from openair1/PHY/CODING/nr_polar_init.c rename to openair1/PHY/CODING/nrPolar_tools/nr_polar_init.c index ca982d79bf..609f4b4a8f 100644 --- a/openair1/PHY/CODING/nr_polar_init.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_init.c @@ -30,9 +30,9 @@ * \warning */ -#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" +#include "nr_polar_defs.h" +#include "nr_polar_psbch_defs.h" #include "PHY/NR_TRANSPORT/nr_dci.h" -#include "nrPolar_tools/nr_polar_psbch_defs.h" #define PolarKey ((messageType << 24) | (messageLength << 8) | aggregation_level) static t_nrPolar_params *PolarList = NULL;