optimized polar encoder/decoder functions for PBCH and 41-bit DCI
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user