From 7a4dc8644c77429bcb27c539fa009d4eba26928b Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sun, 11 Nov 2018 09:07:22 +0100 Subject: [PATCH] optimized polar encoder/decoder functions for PBCH and 41-bit DCI --- openair1/PHY/CODING/TESTBENCH/polartest.c | 13 ++- openair1/PHY/CODING/crc_byte.c | 6 +- .../CODING/nrPolar_tools/nr_polar_decoder.c | 24 ++-- .../nrPolar_tools/nr_polar_decoding_tools.c | 33 +++--- .../PHY/CODING/nrPolar_tools/nr_polar_defs.h | 8 +- .../CODING/nrPolar_tools/nr_polar_encoder.c | 106 ++++++++++-------- 6 files changed, 109 insertions(+), 81 deletions(-) diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index bba63405b0..1ced4ba688 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -98,8 +98,8 @@ int main(int argc, char *argv[]) { aggregation_level = NR_POLAR_PBCH_AGGREGATION_LEVEL; } else if (polarMessageType == 1) { //DCI //testLength = nr_get_dci_size(params_rel15->dci_format, params_rel15->rnti_type, &fp->initial_bwp_dl, cfg); - testLength = 64; //20; - coderLength = 108; //to be changed by aggregate level function. + testLength = 41; //20; + coderLength = 108*8; //to be changed by aggregate level function. } else if (polarMessageType == -1) { //UCI //testLength = ; //coderLength = ; @@ -325,8 +325,8 @@ int main(int argc, char *argv[]) { printf("%d\n",(testInput[0]>>i)&1);*/ - - + int len_mod64=currentPtr->payloadBits&63; + ((uint64_t*)testInput)[currentPtr->payloadBits/64]&=((((uint64_t)1)<payloadBits; j++) { if (((estimatedOutput[0]>>j) & 1) != ((testInput[0]>>j) & 1)) nBitError++; - + // printf("bit %d: %d => %d\n",j,(testInput[0]>>j)&1,(estimatedOutput[0]>>j)&1); } @@ -424,7 +424,8 @@ int main(int argc, char *argv[]) { printf("[ListSize=%d, Appr=%d] SNR=%+8.3f, BLER=%9.6f, BER=%12.9f, t_Encoder=%9.3fus, t_Decoder=%9.3fus\n", decoderListSize, pathMetricAppr, SNR, ((double)blockErrorCumulative/iterations), ((double)bitErrorCumulative / (iterations*testLength)), - (timeEncoderCumulative/iterations),timeDecoderCumulative/iterations); + (double)timeEncoder.diff/timeEncoder.trials/(cpu_freq_GHz*1000.0),(double)timeDecoder.diff/timeDecoder.trials/(cpu_freq_GHz*1000.0)); + //(timeEncoderCumulative/iterations),timeDecoderCumulative/iterations); if (blockErrorCumulative==0 && bitErrorCumulative==0) break; diff --git a/openair1/PHY/CODING/crc_byte.c b/openair1/PHY/CODING/crc_byte.c index 6176e1f92f..f2e9557491 100644 --- a/openair1/PHY/CODING/crc_byte.c +++ b/openair1/PHY/CODING/crc_byte.c @@ -168,14 +168,12 @@ unsigned int crc24c (unsigned char * inptr, resbit = (bitlen % 8); while (octetlen-- > 0) { -/*#ifdef DEBUG_CRC24C - printf("crc24c: in %x => crc %x (%x)\n",crc,*inptr,crc24cTable[(*inptr) ^ (crc >> 24)]); -#endif*/ crc = (crc << 8) ^ crc24cTable[(*inptr++) ^ (crc >> 24)]; } - if (resbit > 0) + if (resbit > 0) { crc = (crc << resbit) ^ crc24cTable[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))]; + } return crc; } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index a9dbc1324a..8e5281e1a4 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -1055,6 +1055,9 @@ void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) { else numbits=residue; for (int i=0;iinterleaving_pattern[(8*byte)+i]; +#if 1 + printf("byte %d, i %d => ip %d\n",byte,i,ip); +#endif ipmod64 = ip&63; AssertFatal(ip<128,"ip = %d\n",ip); for (int val=0;val<256;val++) { @@ -1102,32 +1105,39 @@ int8_t polar_decoder_int16(int16_t *input, polarParams->B_tab0[6][Cprimebyte[6]] | polarParams->B_tab0[7][Cprimebyte[7]]; } - if (polarParams->K<129) { - for (int k=0;kK;k++) { + 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]]; } } - + int len=polarParams->payloadBits; int len_mod64=len&63; int quadwpos=len>>6; int crclen = polarParams->crcParityBits; int quadwpos2 = polarParams->K>>6; uint64_t rxcrc; + uint32_t crc; if (len_mod64==0) rxcrc = 0; else rxcrc = B[quadwpos]>>len_mod64; if (quadwpos2>quadwpos) { // there are extra CRC bits in the next quadword rxcrc |= (B[quadwpos2]<<(64-len_mod64)); } + // clear everything but payload bits in last quadword + B[quadwpos]&=((((uint64_t)1)<payloadBits)>>8; #if 0 - printf("Decoded B %llx%llx (crc %x,B>>payloadBits %x)\n",B[1],B[0],crc24c((uint8_t*)&B,polarParams->payloadBits)>>8, - (uint32_t)rxcrc); + printf("A %llx B %llx|%llx Cprime %llx|%llx (crc %x,rxcrc %llx %d)\n", + B[quadwpos]&((((uint64_t)1)<payloadBits); #endif - if ((uint64_t)(crc24c((uint8_t*)&B[0],polarParams->payloadBits)>>8) == rxcrc) { - + if (((uint64_t)crc) == rxcrc) { int k=0; // copy quadwords without CRC directly for (k=0;kpayloadBits/64;k++) out[k]=B[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 1967d3934c..b4159ad68a 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -34,18 +34,18 @@ #include "PHY/sse_intrin.h" #include "PHY/impl_defs_top.h" -//#define DEBUG_NEW_IMPL +//#define DEBUG_NEW_IMPL 1 void updateLLR(double ***llr, - uint8_t **llrU, - uint8_t ***bit, - uint8_t **bitU, - uint8_t listSize, - uint16_t row, - uint16_t col, - uint16_t xlen, - uint8_t ylen, - uint8_t approximation) + uint8_t **llrU, + uint8_t ***bit, + uint8_t **bitU, + uint8_t listSize, + uint16_t row, + uint16_t col, + uint16_t xlen, + uint8_t ylen, + uint8_t approximation) { uint16_t offset = (xlen/(pow(2,(ylen-col-1)))); for (uint8_t i=0; iinformation_bit_pattern[i+first_leaf_index]>0) all_frozen_below=0; } -if (all_frozen_below==0) new_node->left=add_nodes(level-1,first_leaf_index,pp); - else { + if (all_frozen_below==0) new_node->left=add_nodes(level-1,first_leaf_index,pp); + else { #ifdef DEBUG_NEW_IMPL - printf("aggregating frozen bits %d ... %d at level %d (%s)\n",first_leaf_index,first_leaf_index+Nv-1,level,((first_leaf_index/Nv)&1)==0?"left":"right"); + printf("aggregating frozen bits %d ... %d at level %d (%s)\n",first_leaf_index,first_leaf_index+Nv-1,level,((first_leaf_index/Nv)&1)==0?"left":"right"); #endif new_node->leaf=1; new_node->all_frozen=1; } if (all_frozen_below==0) new_node->right=add_nodes(level-1,first_leaf_index+(Nv/2),pp); +#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 return(new_node); } @@ -251,7 +254,9 @@ void build_decoder_tree(t_nrPolar_params *pp) { pp->tree.num_nodes=0; pp->tree.root = add_nodes(pp->n,0,pp); - +#ifdef DEBUG_NEW_IMPL + printf("root : left %p, right %p\n",pp->tree.root->left,pp->tree.root->right); +#endif } #if defined(__arm__) || defined(__aarch64__) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index da8458ee95..6f77e1f084 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -113,10 +113,10 @@ struct nrPolar_params { uint64_t **G_N_tab; int groupsize; int *rm_tab; - uint64_t cprime_tab0[8][256]; - uint64_t cprime_tab1[8][256]; - uint64_t B_tab0[8][256]; - uint64_t B_tab1[8][256]; + uint64_t cprime_tab0[32][256]; + uint64_t cprime_tab1[32][256]; + uint64_t B_tab0[32][256]; + uint64_t B_tab1[32][256]; uint32_t* crc256Table; uint8_t **extended_crc_generator_matrix; //lowercase: bits, Uppercase: Bits stored in bytes diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c index dd983e3098..9b40de4eab 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c @@ -365,7 +365,9 @@ static inline void polar_rate_matching(t_nrPolar_paramsPtr polarParams,void *in, if (polarParams->groupsize == 8) for (int i=0;iencoderLength>>3;i++) ((uint8_t*)out)[i] = ((uint8_t *)in)[polarParams->rm_tab[i]]; else - for (int i=0;iencoderLength>>4;i++) ((uint16_t*)out)[i] = ((uint16_t *)in)[polarParams->rm_tab[i]]; + for (int i=0;iencoderLength>>4;i++) { + ((uint16_t*)out)[i] = ((uint16_t *)in)[polarParams->rm_tab[i]]; + } } void build_polar_tables(t_nrPolar_paramsPtr polarParams) { @@ -390,6 +392,7 @@ void build_polar_tables(t_nrPolar_paramsPtr polarParams) { polarParams->cprime_tab1[byte][val] = 0; for (int i=0;ideinterleaving_pattern[(8*byte)+i]; + if (val==0) printf("%d => %d\n",(8*byte)+i,ip); AssertFatal(ip<128,"ip = %d\n",ip); bit_i=(val>>i)&1; if (ip<64) polarParams->cprime_tab0[byte][val] |= (((uint64_t)bit_i)<K > 32, "K = %d < 33, is not supported yet\n",polarParams->K); - AssertFatal(polarParams->K < 65, "K = %d > 64, is not supported yet\n",polarParams->K); + AssertFatal(polarParams->K < 129, "K = %d > 64, is not supported yet\n",polarParams->K); uint64_t B[4]={0,0,0,0},Cprime[4]={0,0,0,0}; int bitlen = polarParams->payloadBits; @@ -472,16 +475,20 @@ void polar_encoder_fast(int64_t *A, AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n"); int bitlen0=bitlen; - for (int i=0;i<(1+(bitlen>>6));i++) - if (bitlen0<64) - B[i] = ((A[i])&((((uint64_t)1)<>8)))<>8))); + int n; + for (n=0;n<(1+(bitlen>>6));n++) + if (bitlen0<64) B[n] = ((A[n])&((((uint64_t)1)<crcParityBits > (64-bitlen0)) B[n] = tcrc>>(64-bitlen0); uint8_t *Bbyte = (uint8_t*)B; // for each byte of B, lookup in corresponding table for 64-bit word corresponding to that byte and its position - if (bitlen<65) + if (polarParams->K<65) Cprime[0] = polarParams->cprime_tab0[0][Bbyte[0]] | polarParams->cprime_tab0[1][Bbyte[1]] | polarParams->cprime_tab0[2][Bbyte[2]] | @@ -491,30 +498,37 @@ void polar_encoder_fast(int64_t *A, polarParams->cprime_tab0[6][Bbyte[6]] | polarParams->cprime_tab0[7][Bbyte[7]]; - else if (bitlen < 129) { - 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[1] = polarParams->cprime_tab1[0][Bbyte[0]] | - polarParams->cprime_tab1[1][Bbyte[1]] | - polarParams->cprime_tab1[2][Bbyte[2]] | - polarParams->cprime_tab1[3][Bbyte[3]] | - polarParams->cprime_tab1[4][Bbyte[4]] | - polarParams->cprime_tab1[5][Bbyte[5]] | - polarParams->cprime_tab1[6][Bbyte[6]] | - polarParams->cprime_tab1[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]]; + Cprime[1] |= polarParams->cprime_tab1[i][Bbyte[i]]; + } } #ifdef DEBUG_POLAR_ENCODER - printf("A %llx B %llx Cprime %llx (payload bits %d,crc %x)\n", - (unsigned long long)((A[0])&((((uint64_t)1)<payloadBits, - crc24c((uint8_t*)A,bitlen)); + if (polarParams->K<65) + printf("A %llx B %llx Cprime %llx (payload bits %d,crc %x)\n", + (unsigned long long)(A[0]&(((uint64_t)1<payloadBits, + tcrc); + else if (polarParams->K<129) { + if (bitlen<64) + printf("A %llx B %llx|%llx Cprime %llx|%llx (payload bits %d,crc %x)\n", + (unsigned long long)(A[0]&(((uint64_t)1<payloadBits, + tcrc); + else + printf("A %llx|%llx B %llx|%llx Cprime %llx|%llx (payload bits %d,crc %x)\n", + (unsigned long long)(A[1]&(((uint64_t)1<<(bitlen-64))-1)),(unsigned long long)(A[0]), + (unsigned long long)(B[1]),(unsigned long long)(B[0]), + (unsigned long long)(Cprime[1]),(unsigned long long)(Cprime[0]), + polarParams->payloadBits, + crc24c((uint8_t*)A,bitlen)>>8); + } #endif /* printf("Bbytes : %x.%x.%x.%x.%x.%x.%x.%x\n",Bbyte[0],Bbyte[1],Bbyte[2],Bbyte[3],Bbyte[4],Bbyte[5],Bbyte[6],Bbyte[7]); printf("%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",polarParams->cprime_tab[0][Bbyte[0]] , @@ -548,25 +562,25 @@ void polar_encoder_fast(int64_t *A, Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11 #ifdef DEBUG_POLAR_ENCODER printf("%llx Cprime_%d (%llx) G %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n", - Cprime_i,i,(Cprime[j]>>i) &1, - polarParams->G_N_tab[i][0], - polarParams->G_N_tab[i][1], - polarParams->G_N_tab[i][2], - polarParams->G_N_tab[i][3], - polarParams->G_N_tab[i][4], - polarParams->G_N_tab[i][5], - polarParams->G_N_tab[i][6], - polarParams->G_N_tab[i][7]); + Cprime_i,off+i,(Cprime[j]>>i) &1, + polarParams->G_N_tab[off+i][0], + polarParams->G_N_tab[off+i][1], + polarParams->G_N_tab[off+i][2], + polarParams->G_N_tab[off+i][3], + polarParams->G_N_tab[off+i][4], + polarParams->G_N_tab[off+i][5], + polarParams->G_N_tab[off+i][6], + polarParams->G_N_tab[off+i][7]); #endif - - D[0] ^= (Cprime_i & polarParams->G_N_tab[i][0]); - D[1] ^= (Cprime_i & polarParams->G_N_tab[i][1]); - D[2] ^= (Cprime_i & polarParams->G_N_tab[i][2]); - D[3] ^= (Cprime_i & polarParams->G_N_tab[i][3]); - D[4] ^= (Cprime_i & polarParams->G_N_tab[i][4]); - D[5] ^= (Cprime_i & polarParams->G_N_tab[i][5]); - D[6] ^= (Cprime_i & polarParams->G_N_tab[i][6]); - D[7] ^= (Cprime_i & polarParams->G_N_tab[i][7]); + uint64_t *Gi=polarParams->G_N_tab[off+i]; + D[0] ^= (Cprime_i & Gi[0]); + D[1] ^= (Cprime_i & Gi[1]); + D[2] ^= (Cprime_i & Gi[2]); + D[3] ^= (Cprime_i & Gi[3]); + D[4] ^= (Cprime_i & Gi[4]); + D[5] ^= (Cprime_i & Gi[5]); + D[6] ^= (Cprime_i & Gi[6]); + D[7] ^= (Cprime_i & Gi[7]); } } #ifdef DEBUG_POLAR_ENCODER