From 1c68695655d27feb8b71a2d074dd8554cdbb15c9 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Wed, 28 Nov 2018 22:53:52 +0100 Subject: [PATCH] bit endian corrections for a,b sequences in polar encoder/decoder. CRC computations need to be compared to reference models --- openair1/PHY/CODING/crc_byte.c | 4 +- .../CODING/nrPolar_tools/nr_polar_decoder.c | 56 ++++++++++++------- .../CODING/nrPolar_tools/nr_polar_encoder.c | 56 +++++++++++++++---- 3 files changed, 83 insertions(+), 33 deletions(-) diff --git a/openair1/PHY/CODING/crc_byte.c b/openair1/PHY/CODING/crc_byte.c index f2e9557491..c2b016920a 100644 --- a/openair1/PHY/CODING/crc_byte.c +++ b/openair1/PHY/CODING/crc_byte.c @@ -56,8 +56,8 @@ The first bit is in the MSB of each byte *********************************************************/ unsigned int crcbit (unsigned char * inputptr, - int octetlen, - unsigned int poly) + int octetlen, + unsigned int poly) { unsigned int i, crc = 0, c; diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 691b2191b6..344bbb92de 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -1054,8 +1054,9 @@ void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) { if (byte<(polarParams->K>>3)) numbits=8; else numbits=residue; for (int i=0;iinterleaving_pattern[(8*byte)+i]; -#if 0 + // flip bit endian for B + ip=polarParams->K - 1 - polarParams->interleaving_pattern[(8*byte)+i]; +#if 1 printf("byte %d, i %d => ip %d\n",byte,i,ip); #endif ipmod64 = ip&63; @@ -1067,7 +1068,7 @@ void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) { } } } - + } uint32_t polar_decoder_int16(int16_t *input, @@ -1117,31 +1118,46 @@ uint32_t polar_decoder_int16(int16_t *input, 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; + uint64_t rxcrc=B[0]&((1<>len_mod64; + uint64_t Ar; - if (quadwpos2>quadwpos) { // there are extra CRC bits in the next quadword - rxcrc |= (B[quadwpos2]<<(64-len_mod64)); + AssertFatal(len<65,"A must be less than 65 bits\n"); + if (len<=32) { + Ar = (uint32_t)(B[0]>>crclen); + uint8_t A32_flip[4]; + uint32_t Aprime= (uint32_t)(Ar<<(32-len)); + A32_flip[0]=((uint8_t*)&Aprime)[3]; + A32_flip[1]=((uint8_t*)&Aprime)[2]; + A32_flip[2]=((uint8_t*)&Aprime)[1]; + A32_flip[3]=((uint8_t*)&Aprime)[0]; + crc = (uint64_t)(crc24c(A32_flip,len)>>8); } - // clear everything but payload bits in last quadword - B[quadwpos]&=((((uint64_t)1)<payloadBits)>>8; -#if 0 + else if (len<=64) { + Ar = (B[0]>>crclen) | (B[1]<<(64-crclen));; + uint8_t A64_flip[4]; + uint64_t Aprime= (uint32_t)(Ar<<(64-len)); + A64_flip[0]=((uint8_t*)&Aprime)[7]; + A64_flip[1]=((uint8_t*)&Aprime)[6]; + A64_flip[2]=((uint8_t*)&Aprime)[5]; + A64_flip[3]=((uint8_t*)&Aprime)[4]; + A64_flip[4]=((uint8_t*)&Aprime)[3]; + A64_flip[5]=((uint8_t*)&Aprime)[2]; + A64_flip[6]=((uint8_t*)&Aprime)[1]; + A64_flip[7]=((uint8_t*)&Aprime)[0]; + crc = (uint64_t)(crc24c(A64_flip,len)>>8); + } + +#if 1 printf("A %llx B %llx|%llx Cprime %llx|%llx (crc %x,rxcrc %llx %d)\n", - B[quadwpos]&((((uint64_t)1)<payloadBits); #endif - int k=0; - // copy quadwords without CRC directly - for (k=0;kpayloadBits/64;k++) out[k]=B[k]; - // copy last one - out[k] = B[k] & (((uint64_t)1<<(polarParams->payloadBits&63))-1); + + out[0]=Ar; + return(crc^rxcrc); diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c index d25b96a7d6..dc573aa3ec 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c @@ -30,7 +30,7 @@ * \warning */ -//#define DEBUG_POLAR_ENCODER +#define DEBUG_POLAR_ENCODER //#define DEBUG_POLAR_ENCODER_DCI //#define DEBUG_POLAR_ENCODER_TIMING @@ -316,7 +316,8 @@ void build_polar_tables(t_nrPolar_paramsPtr polarParams) { polarParams->cprime_tab0[byte][val] = 0; polarParams->cprime_tab1[byte][val] = 0; for (int i=0;ideinterleaving_pattern[(8*byte)+i]; + // flip bit endian of B bitstring + ip=polarParams->deinterleaving_pattern[polarParams->K-1-((8*byte)+i)]; AssertFatal(ip<128,"ip = %d\n",ip); bit_i=(val>>i)&1; if (ip<64) polarParams->cprime_tab0[byte][val] |= (((uint64_t)bit_i)<>8))); + uint64_t tcrc=0; + + // A bitstring should be stored as 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 downto 0, for PBCH/PDCCH we need to read in a_{A-1} downto a_{0}, A = length of bit string (e.g. 32 for PBCH) + if (bitlen<=32) { + uint8_t A32_flip[4]; + uint32_t Aprime= (uint32_t)(((uint32_t)*A)<<(32-bitlen)); + A32_flip[0]=((uint8_t*)&Aprime)[3]; + A32_flip[1]=((uint8_t*)&Aprime)[2]; + A32_flip[2]=((uint8_t*)&Aprime)[1]; + A32_flip[3]=((uint8_t*)&Aprime)[0]; + tcrc = (uint64_t)((crcmask^(crc24c(A32_flip,bitlen)>>8))); + } + else if (bitlen<=64) { + uint8_t A64_flip[4]; + uint64_t Aprime= (uint32_t)(((uint64_t)*A)<<(64-bitlen)); + A64_flip[0]=((uint8_t*)&Aprime)[7]; + A64_flip[1]=((uint8_t*)&Aprime)[6]; + A64_flip[2]=((uint8_t*)&Aprime)[5]; + A64_flip[3]=((uint8_t*)&Aprime)[4]; + A64_flip[4]=((uint8_t*)&Aprime)[3]; + A64_flip[5]=((uint8_t*)&Aprime)[2]; + A64_flip[6]=((uint8_t*)&Aprime)[1]; + A64_flip[7]=((uint8_t*)&Aprime)[0]; + tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,bitlen)>>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); + // this is number of quadwords in the bit string + int quadwlen = (polarParams->K>>6); + if ((polarParams->K&63) > 0) quadwlen++; + + // Create the B bitstring as + // 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 + + for (n=0;ncrcParityBits) | tcrc; + else B[n] = (A[n] << polarParams->crcParityBits) | (A[n-1]>>64-polarParams->crcParityBits); + + 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 (polarParams->K<65) @@ -486,6 +518,7 @@ void polar_encoder_fast(uint64_t *A, for (int i=0;i<((len>63) ? 64 : len);i++) { Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11 + /* #ifdef DEBUG_POLAR_ENCODER printf("%llx Cprime_%d (%llx) G %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n", Cprime_i,off+i,(Cprime[j]>>i) &1, @@ -498,6 +531,7 @@ void polar_encoder_fast(uint64_t *A, polarParams->G_N_tab[off+i][6], polarParams->G_N_tab[off+i][7]); #endif + */ uint64_t *Gi=polarParams->G_N_tab[off+i]; D[0] ^= (Cprime_i & Gi[0]); D[1] ^= (Cprime_i & Gi[1]);