Commit 7a4dc864 authored by Raymond Knopp's avatar Raymond Knopp

optimized polar encoder/decoder functions for PBCH and 41-bit DCI

parent 7bc96c61
......@@ -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)<<len_mod64)-1);
start_meas(&timeEncoder);
if (decoder_int16==0)
......@@ -391,7 +391,7 @@ int main(int argc, char *argv[]) {
} else {
for (int j = 0; j < currentPtr->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;
......
......@@ -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;
}
......
......@@ -1055,6 +1055,9 @@ void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) {
else numbits=residue;
for (int i=0;i<numbits;i++) {
ip=polarParams->interleaving_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;k<polarParams->K;k++) {
else if (polarParams->K<129) {
int len = polarParams->K/8;
if ((polarParams->K&7) > 0) len++;
for (int k=0;k<len;k++) {
B[0] |= polarParams->B_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)<<len_mod64)-1);
crc = crc24c((uint8_t*)B,polarParams->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)<<len_mod64)-1),
B[1],B[0],Cprime[1],Cprime[0],crc,
rxcrc,polarParams->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;k<polarParams->payloadBits/64;k++) out[k]=B[k];
......
......@@ -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; i<listSize; i++) {
......@@ -233,16 +233,19 @@ decoder_node_t *add_nodes(int level,int first_leaf_index,t_nrPolar_params *pp) {
for (int i=0;i<Nv;i++) {
if (pp->information_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__)
......
......@@ -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
......
......@@ -365,7 +365,9 @@ static inline void polar_rate_matching(t_nrPolar_paramsPtr polarParams,void *in,
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
for (int i=0;i<polarParams->encoderLength>>4;i++) ((uint16_t*)out)[i] = ((uint16_t *)in)[polarParams->rm_tab[i]];
for (int i=0;i<polarParams->encoderLength>>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;i<numbits;i++) {
ip=polarParams->deinterleaving_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)<<ip);
......@@ -461,7 +464,7 @@ void polar_encoder_fast(int64_t *A,
t_nrPolar_paramsPtr polarParams) {
AssertFatal(polarParams->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)<<bitlen0)-1)) |((uint64_t)((crcmask^(crc24c((uint8_t*)A,bitlen0)>>8)))<<bitlen0);
uint64_t tcrc = (uint64_t)((crcmask^(crc24c((uint8_t*)A,bitlen)>>8)));
int n;
for (n=0;n<(1+(bitlen>>6));n++)
if (bitlen0<64) B[n] = ((A[n])&((((uint64_t)1)<<bitlen0)-1)) | (tcrc<<bitlen0);
else {
B[i] = A[i];
B[n] = A[n];
bitlen0-=64;
}
// handle residual part of CRC in next quadword
if (polarParams->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)<<bitlen)-1)),
(unsigned long long)B[0],(unsigned long long)Cprime[0],polarParams->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<<bitlen)-1)),
(unsigned long long)(B[0]),
(unsigned long long)(Cprime[0]),
polarParams->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<<bitlen)-1)),
(unsigned long long)(B[1]),(unsigned long long)(B[0]),
(unsigned long long)(Cprime[1]),(unsigned long long)(Cprime[0]),
polarParams->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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment