added all optimizations except rate matching for N=512 polar-encoder.
This commit is contained in:
@@ -78,54 +78,56 @@ typedef struct decoder_tree_t_s {
|
||||
} decoder_tree_t;
|
||||
|
||||
struct nrPolar_params {
|
||||
//messageType: 0=PBCH, 1=DCI, -1=UCI
|
||||
int idx; //idx = (messageType * messageLength * aggregation_prime);
|
||||
struct nrPolar_params *nextPtr;
|
||||
|
||||
uint8_t n_max;
|
||||
uint8_t i_il;
|
||||
uint8_t i_seg;
|
||||
uint8_t n_pc;
|
||||
uint8_t n_pc_wm;
|
||||
uint8_t i_bil;
|
||||
uint16_t payloadBits;
|
||||
uint16_t encoderLength;
|
||||
uint8_t crcParityBits;
|
||||
uint8_t crcCorrectionBits;
|
||||
uint16_t K;
|
||||
uint16_t N;
|
||||
uint8_t n;
|
||||
uint32_t crcBit;
|
||||
|
||||
uint16_t *interleaving_pattern;
|
||||
uint16_t *rate_matching_pattern;
|
||||
const uint16_t *Q_0_Nminus1;
|
||||
int16_t *Q_I_N;
|
||||
int16_t *Q_F_N;
|
||||
int16_t *Q_PC_N;
|
||||
uint8_t *information_bit_pattern;
|
||||
uint16_t *channel_interleaver_pattern;
|
||||
uint32_t crc_polynomial;
|
||||
|
||||
uint8_t **crc_generator_matrix; //G_P
|
||||
uint8_t **G_N;
|
||||
uint32_t* crc256Table;
|
||||
//messageType: 0=PBCH, 1=DCI, -1=UCI
|
||||
int idx; //idx = (messageType * messageLength * aggregation_prime);
|
||||
struct nrPolar_params *nextPtr;
|
||||
|
||||
uint8_t n_max;
|
||||
uint8_t i_il;
|
||||
uint8_t i_seg;
|
||||
uint8_t n_pc;
|
||||
uint8_t n_pc_wm;
|
||||
uint8_t i_bil;
|
||||
uint16_t payloadBits;
|
||||
uint16_t encoderLength;
|
||||
uint8_t crcParityBits;
|
||||
uint8_t crcCorrectionBits;
|
||||
uint16_t K;
|
||||
uint16_t N;
|
||||
uint8_t n;
|
||||
uint32_t crcBit;
|
||||
|
||||
uint16_t *interleaving_pattern;
|
||||
uint16_t *rate_matching_pattern;
|
||||
const uint16_t *Q_0_Nminus1;
|
||||
int16_t *Q_I_N;
|
||||
int16_t *Q_F_N;
|
||||
int16_t *Q_PC_N;
|
||||
uint8_t *information_bit_pattern;
|
||||
uint16_t *channel_interleaver_pattern;
|
||||
uint32_t crc_polynomial;
|
||||
|
||||
uint8_t **crc_generator_matrix; //G_P
|
||||
uint8_t **G_N;
|
||||
uint64_t **G_N_tab;
|
||||
uint64_t cprime_tab[8][256];
|
||||
uint32_t* crc256Table;
|
||||
uint8_t **extended_crc_generator_matrix;
|
||||
//lowercase: bits, Uppercase: Bits stored in bytes
|
||||
//polar_encoder vectors
|
||||
uint8_t *nr_polar_crc;
|
||||
uint8_t *nr_polar_aPrime;
|
||||
uint8_t *nr_polar_APrime;
|
||||
uint8_t *nr_polar_D;
|
||||
uint8_t *nr_polar_E;
|
||||
|
||||
//Polar Coding vectors
|
||||
uint8_t *nr_polar_A;
|
||||
uint8_t *nr_polar_CPrime;
|
||||
uint8_t *nr_polar_B;
|
||||
uint8_t *nr_polar_U;
|
||||
|
||||
decoder_tree_t tree;
|
||||
//lowercase: bits, Uppercase: Bits stored in bytes
|
||||
//polar_encoder vectors
|
||||
uint8_t *nr_polar_crc;
|
||||
uint8_t *nr_polar_aPrime;
|
||||
uint8_t *nr_polar_APrime;
|
||||
uint8_t *nr_polar_D;
|
||||
uint8_t *nr_polar_E;
|
||||
|
||||
//Polar Coding vectors
|
||||
uint8_t *nr_polar_A;
|
||||
uint8_t *nr_polar_CPrime;
|
||||
uint8_t *nr_polar_B;
|
||||
uint8_t *nr_polar_U;
|
||||
|
||||
decoder_tree_t tree;
|
||||
} __attribute__ ((__packed__));
|
||||
typedef struct nrPolar_params t_nrPolar_params;
|
||||
typedef t_nrPolar_params *t_nrPolar_paramsPtr;
|
||||
|
||||
@@ -28,289 +28,376 @@
|
||||
* \email turker.yilmaz@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
*/
|
||||
|
||||
//#define DEBUG_POLAR_ENCODER
|
||||
//#define DEBUG_POLAR_ENCODER_DCI
|
||||
//#define DEBUG_POLAR_ENCODER_TIMING
|
||||
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||
#include "assertions.h"
|
||||
|
||||
//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,
|
||||
t_nrPolar_paramsPtr polarParams)
|
||||
uint32_t *out,
|
||||
t_nrPolar_paramsPtr polarParams)
|
||||
{
|
||||
if (polarParams->idx == 0){//PBCH
|
||||
nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_A);
|
||||
/*
|
||||
* Bytewise operations
|
||||
*/
|
||||
//Calculate CRC.
|
||||
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_A,
|
||||
polarParams->crc_generator_matrix,
|
||||
polarParams->nr_polar_crc,
|
||||
polarParams->payloadBits,
|
||||
polarParams->crcParityBits);
|
||||
for (uint8_t i = 0; i < polarParams->crcParityBits; i++)
|
||||
polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
|
||||
if (polarParams->idx == 0){//PBCH
|
||||
nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_A);
|
||||
/*
|
||||
* Bytewise operations
|
||||
*/
|
||||
//Calculate CRC.
|
||||
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_A,
|
||||
polarParams->crc_generator_matrix,
|
||||
polarParams->nr_polar_crc,
|
||||
polarParams->payloadBits,
|
||||
polarParams->crcParityBits);
|
||||
for (uint8_t i = 0; i < polarParams->crcParityBits; i++)
|
||||
polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
|
||||
|
||||
//Attach CRC to the Transport Block. (a to b)
|
||||
for (uint16_t i = 0; i < polarParams->payloadBits; i++)
|
||||
polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i];
|
||||
for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++)
|
||||
polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
|
||||
} else { //UCI
|
||||
//Attach CRC to the Transport Block. (a to b)
|
||||
for (uint16_t i = 0; i < polarParams->payloadBits; i++)
|
||||
polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i];
|
||||
for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++)
|
||||
polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
|
||||
} else { //UCI
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//Interleaving (c to c')
|
||||
nr_polar_interleaver(polarParams->nr_polar_B,
|
||||
polarParams->nr_polar_CPrime,
|
||||
polarParams->interleaving_pattern,
|
||||
polarParams->K);
|
||||
//Interleaving (c to c')
|
||||
nr_polar_interleaver(polarParams->nr_polar_B,
|
||||
polarParams->nr_polar_CPrime,
|
||||
polarParams->interleaving_pattern,
|
||||
polarParams->K);
|
||||
|
||||
//Bit insertion (c' to u)
|
||||
nr_polar_bit_insertion(polarParams->nr_polar_CPrime,
|
||||
polarParams->nr_polar_U,
|
||||
polarParams->N,
|
||||
polarParams->K,
|
||||
polarParams->Q_I_N,
|
||||
polarParams->Q_PC_N,
|
||||
polarParams->n_pc);
|
||||
//Bit insertion (c' to u)
|
||||
nr_polar_bit_insertion(polarParams->nr_polar_CPrime,
|
||||
polarParams->nr_polar_U,
|
||||
polarParams->N,
|
||||
polarParams->K,
|
||||
polarParams->Q_I_N,
|
||||
polarParams->Q_PC_N,
|
||||
polarParams->n_pc);
|
||||
|
||||
//Encoding (u to d)
|
||||
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_U,
|
||||
polarParams->G_N,
|
||||
polarParams->nr_polar_D,
|
||||
polarParams->N,
|
||||
polarParams->N);
|
||||
for (uint16_t i = 0; i < polarParams->N; i++)
|
||||
polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
|
||||
//Encoding (u to d)
|
||||
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_U,
|
||||
polarParams->G_N,
|
||||
polarParams->nr_polar_D,
|
||||
polarParams->N,
|
||||
polarParams->N);
|
||||
for (uint16_t i = 0; i < polarParams->N; i++)
|
||||
polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
|
||||
|
||||
//Rate matching
|
||||
//Sub-block interleaving (d to y) and Bit selection (y to e)
|
||||
nr_polar_interleaver(polarParams->nr_polar_D,
|
||||
polarParams->nr_polar_E,
|
||||
polarParams->rate_matching_pattern,
|
||||
polarParams->encoderLength);
|
||||
//Rate matching
|
||||
//Sub-block interleaving (d to y) and Bit selection (y to e)
|
||||
nr_polar_interleaver(polarParams->nr_polar_D,
|
||||
polarParams->nr_polar_E,
|
||||
polarParams->rate_matching_pattern,
|
||||
polarParams->encoderLength);
|
||||
|
||||
/*
|
||||
* Return bits.
|
||||
*/
|
||||
/*
|
||||
* Return bits.
|
||||
*/
|
||||
#ifdef DEBUG_POLAR_ENCODER
|
||||
for (int i=0; i< polarParams->encoderLength;i++) printf("f[%d]=%d\n", i, polarParams->nr_polar_E[i]);
|
||||
for (int i=0; i< polarParams->encoderLength;i++) printf("f[%d]=%d\n", i, polarParams->nr_polar_E[i]);
|
||||
#endif
|
||||
|
||||
nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
|
||||
nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
|
||||
}
|
||||
|
||||
void polar_encoder_dci(uint32_t *in,
|
||||
uint32_t *out,
|
||||
t_nrPolar_paramsPtr polarParams,
|
||||
uint16_t n_RNTI)
|
||||
uint32_t *out,
|
||||
t_nrPolar_paramsPtr polarParams,
|
||||
uint16_t n_RNTI)
|
||||
{
|
||||
#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]);
|
||||
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]);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Bytewise operations
|
||||
*/
|
||||
//(a to a')
|
||||
nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_A);
|
||||
for (int i=0; i<polarParams->crcParityBits; i++) polarParams->nr_polar_APrime[i]=1;
|
||||
for (int i=0; i<polarParams->payloadBits; i++) polarParams->nr_polar_APrime[i+(polarParams->crcParityBits)]=polarParams->nr_polar_A[i];
|
||||
/*
|
||||
* Bytewise operations
|
||||
*/
|
||||
//(a to a')
|
||||
nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_A);
|
||||
for (int i=0; i<polarParams->crcParityBits; i++) polarParams->nr_polar_APrime[i]=1;
|
||||
for (int i=0; i<polarParams->payloadBits; i++) polarParams->nr_polar_APrime[i+(polarParams->crcParityBits)]=polarParams->nr_polar_A[i];
|
||||
#ifdef DEBUG_POLAR_ENCODER_DCI
|
||||
printf("[polar_encoder_dci] A: ");
|
||||
for (int i=0; i<polarParams->payloadBits; i++) printf("%d-", polarParams->nr_polar_A[i]);
|
||||
printf("\n");
|
||||
printf("[polar_encoder_dci] APrime: ");
|
||||
for (int i=0; i<polarParams->K; i++) printf("%d-", polarParams->nr_polar_APrime[i]);
|
||||
printf("\n");
|
||||
printf("[polar_encoder_dci] GP: ");
|
||||
for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->crc_generator_matrix[0][i]);
|
||||
printf("\n");
|
||||
printf("[polar_encoder_dci] A: ");
|
||||
for (int i=0; i<polarParams->payloadBits; i++) printf("%d-", polarParams->nr_polar_A[i]);
|
||||
printf("\n");
|
||||
printf("[polar_encoder_dci] APrime: ");
|
||||
for (int i=0; i<polarParams->K; i++) printf("%d-", polarParams->nr_polar_APrime[i]);
|
||||
printf("\n");
|
||||
printf("[polar_encoder_dci] GP: ");
|
||||
for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->crc_generator_matrix[0][i]);
|
||||
printf("\n");
|
||||
#endif
|
||||
//Calculate CRC.
|
||||
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_APrime,
|
||||
polarParams->crc_generator_matrix,
|
||||
polarParams->nr_polar_crc,
|
||||
polarParams->K,
|
||||
polarParams->crcParityBits);
|
||||
for (uint8_t i = 0; i < polarParams->crcParityBits; i++) polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
|
||||
//Calculate CRC.
|
||||
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_APrime,
|
||||
polarParams->crc_generator_matrix,
|
||||
polarParams->nr_polar_crc,
|
||||
polarParams->K,
|
||||
polarParams->crcParityBits);
|
||||
for (uint8_t i = 0; i < polarParams->crcParityBits; i++) polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
|
||||
#ifdef DEBUG_POLAR_ENCODER_DCI
|
||||
printf("[polar_encoder_dci] CRC: ");
|
||||
for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->nr_polar_crc[i]);
|
||||
printf("\n");
|
||||
printf("[polar_encoder_dci] CRC: ");
|
||||
for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->nr_polar_crc[i]);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
//Attach CRC to the Transport Block. (a to b)
|
||||
for (uint16_t i = 0; i < polarParams->payloadBits; i++)
|
||||
polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i];
|
||||
for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++)
|
||||
polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
|
||||
//Scrambling (b to c)
|
||||
for (int i=0; i<16; i++) {
|
||||
polarParams->nr_polar_B[polarParams->payloadBits+8+i] =
|
||||
( polarParams->nr_polar_B[polarParams->payloadBits+8+i] + ((n_RNTI>>(15-i))&1) ) % 2;
|
||||
}
|
||||
//Attach CRC to the Transport Block. (a to b)
|
||||
for (uint16_t i = 0; i < polarParams->payloadBits; i++)
|
||||
polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i];
|
||||
for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++)
|
||||
polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
|
||||
//Scrambling (b to c)
|
||||
for (int i=0; i<16; i++) {
|
||||
polarParams->nr_polar_B[polarParams->payloadBits+8+i] =
|
||||
( polarParams->nr_polar_B[polarParams->payloadBits+8+i] + ((n_RNTI>>(15-i))&1) ) % 2;
|
||||
}
|
||||
|
||||
/* //(a to a')
|
||||
/* //(a to a')
|
||||
nr_crc_bit2bit_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_aPrime);
|
||||
//Parity bits computation (p)
|
||||
polarParams->crcBit = crc24c(polarParams->nr_polar_aPrime, (polarParams->payloadBits+polarParams->crcParityBits));
|
||||
#ifdef DEBUG_POLAR_ENCODER_DCI
|
||||
#ifdef DEBUG_POLAR_ENCODER_DCI
|
||||
printf("[polar_encoder_dci] crc: 0x%08x\n", polarParams->crcBit);
|
||||
for (int i=0; i<32; i++)
|
||||
{
|
||||
printf("%d\n",((polarParams->crcBit)>>i)&1);
|
||||
printf("%d\n",((polarParams->crcBit)>>i)&1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
//(a to b)
|
||||
//
|
||||
// Bytewise operations
|
||||
//
|
||||
uint8_t arrayInd = ceil(polarParams->payloadBits / 8.0);
|
||||
for (int i=0; i<arrayInd-1; i++){
|
||||
for (int j=0; j<8; j++) {
|
||||
polarParams->nr_polar_B[j+(i*8)] = ((polarParams->nr_polar_aPrime[3+i]>>(7-j)) & 1);
|
||||
}
|
||||
for (int j=0; j<8; j++) {
|
||||
polarParams->nr_polar_B[j+(i*8)] = ((polarParams->nr_polar_aPrime[3+i]>>(7-j)) & 1);
|
||||
}
|
||||
}
|
||||
for (int i=0; i<((polarParams->payloadBits)%8); i++) {
|
||||
polarParams->nr_polar_B[i+(arrayInd-1)*8] = ((polarParams->nr_polar_aPrime[3+(arrayInd-1)]>>(7-i)) & 1);
|
||||
polarParams->nr_polar_B[i+(arrayInd-1)*8] = ((polarParams->nr_polar_aPrime[3+(arrayInd-1)]>>(7-i)) & 1);
|
||||
}
|
||||
for (int i=0; i<8; i++) {
|
||||
polarParams->nr_polar_B[polarParams->payloadBits+i] = ((polarParams->crcBit)>>(31-i))&1;
|
||||
polarParams->nr_polar_B[polarParams->payloadBits+i] = ((polarParams->crcBit)>>(31-i))&1;
|
||||
}
|
||||
//Scrambling (b to c)
|
||||
for (int i=0; i<16; i++) {
|
||||
polarParams->nr_polar_B[polarParams->payloadBits+8+i] =
|
||||
( (((polarParams->crcBit)>>(23-i))&1) + ((n_RNTI>>(15-i))&1) ) % 2;
|
||||
polarParams->nr_polar_B[polarParams->payloadBits+8+i] =
|
||||
( (((polarParams->crcBit)>>(23-i))&1) + ((n_RNTI>>(15-i))&1) ) % 2;
|
||||
}*/
|
||||
#ifdef DEBUG_POLAR_ENCODER_DCI
|
||||
printf("[polar_encoder_dci] B: ");
|
||||
for (int i = 0; i < polarParams->K; i++) printf("%d-", polarParams->nr_polar_B[i]);
|
||||
printf("\n");
|
||||
printf("[polar_encoder_dci] B: ");
|
||||
for (int i = 0; i < polarParams->K; i++) printf("%d-", polarParams->nr_polar_B[i]);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
//Interleaving (c to c')
|
||||
nr_polar_interleaver(polarParams->nr_polar_B,
|
||||
polarParams->nr_polar_CPrime,
|
||||
polarParams->interleaving_pattern,
|
||||
polarParams->K);
|
||||
//Interleaving (c to c')
|
||||
nr_polar_interleaver(polarParams->nr_polar_B,
|
||||
polarParams->nr_polar_CPrime,
|
||||
polarParams->interleaving_pattern,
|
||||
polarParams->K);
|
||||
|
||||
//Bit insertion (c' to u)
|
||||
nr_polar_bit_insertion(polarParams->nr_polar_CPrime,
|
||||
polarParams->nr_polar_U,
|
||||
polarParams->N,
|
||||
polarParams->K,
|
||||
polarParams->Q_I_N,
|
||||
polarParams->Q_PC_N,
|
||||
polarParams->n_pc);
|
||||
//Bit insertion (c' to u)
|
||||
nr_polar_bit_insertion(polarParams->nr_polar_CPrime,
|
||||
polarParams->nr_polar_U,
|
||||
polarParams->N,
|
||||
polarParams->K,
|
||||
polarParams->Q_I_N,
|
||||
polarParams->Q_PC_N,
|
||||
polarParams->n_pc);
|
||||
|
||||
//Encoding (u to d)
|
||||
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_U,
|
||||
polarParams->G_N,
|
||||
polarParams->nr_polar_D,
|
||||
polarParams->N,
|
||||
polarParams->N);
|
||||
for (uint16_t i = 0; i < polarParams->N; i++)
|
||||
polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
|
||||
//Encoding (u to d)
|
||||
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_U,
|
||||
polarParams->G_N,
|
||||
polarParams->nr_polar_D,
|
||||
polarParams->N,
|
||||
polarParams->N);
|
||||
for (uint16_t i = 0; i < polarParams->N; i++)
|
||||
polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
|
||||
|
||||
//Rate matching
|
||||
//Sub-block interleaving (d to y) and Bit selection (y to e)
|
||||
nr_polar_interleaver(polarParams->nr_polar_D,
|
||||
polarParams->nr_polar_E,
|
||||
polarParams->rate_matching_pattern,
|
||||
polarParams->encoderLength);
|
||||
//Rate matching
|
||||
//Sub-block interleaving (d to y) and Bit selection (y to e)
|
||||
nr_polar_interleaver(polarParams->nr_polar_D,
|
||||
polarParams->nr_polar_E,
|
||||
polarParams->rate_matching_pattern,
|
||||
polarParams->encoderLength);
|
||||
|
||||
/*
|
||||
* Return bits.
|
||||
*/
|
||||
nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
|
||||
/*
|
||||
* Return bits.
|
||||
*/
|
||||
nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
|
||||
#ifdef DEBUG_POLAR_ENCODER_DCI
|
||||
printf("[polar_encoder_dci] E: ");
|
||||
for (int i = 0; i < polarParams->encoderLength; i++) printf("%d-", polarParams->nr_polar_E[i]);
|
||||
uint8_t outputInd = ceil(polarParams->encoderLength / 32.0);
|
||||
printf("\n[polar_encoder_dci] out: ");
|
||||
for (int i = 0; i < outputInd; i++) {
|
||||
printf("[%d]->0x%08x\t", i, out[i]);
|
||||
}
|
||||
printf("[polar_encoder_dci] E: ");
|
||||
for (int i = 0; i < polarParams->encoderLength; i++) printf("%d-", polarParams->nr_polar_E[i]);
|
||||
uint8_t outputInd = ceil(polarParams->encoderLength / 32.0);
|
||||
printf("\n[polar_encoder_dci] out: ");
|
||||
for (int i = 0; i < outputInd; i++) {
|
||||
printf("[%d]->0x%08x\t", i, out[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void polar_encoder_timing(uint32_t *in,
|
||||
uint32_t *out,
|
||||
t_nrPolar_paramsPtr polarParams,
|
||||
double cpuFreqGHz,
|
||||
FILE* logFile)
|
||||
uint32_t *out,
|
||||
t_nrPolar_paramsPtr polarParams,
|
||||
double cpuFreqGHz,
|
||||
FILE* logFile)
|
||||
{
|
||||
//Initiate timing.
|
||||
time_stats_t timeEncoderCRCByte, timeEncoderCRCBit, timeEncoderInterleaver, timeEncoderBitInsertion, timeEncoder1, timeEncoder2, timeEncoderRateMatching, timeEncoderByte2Bit;
|
||||
reset_meas(&timeEncoderCRCByte); reset_meas(&timeEncoderCRCBit); reset_meas(&timeEncoderInterleaver); reset_meas(&timeEncoderBitInsertion); reset_meas(&timeEncoder1); reset_meas(&timeEncoder2); reset_meas(&timeEncoderRateMatching); reset_meas(&timeEncoderByte2Bit);
|
||||
uint16_t n_RNTI=0x0000;
|
||||
//Initiate timing.
|
||||
time_stats_t timeEncoderCRCByte, timeEncoderCRCBit, timeEncoderInterleaver, timeEncoderBitInsertion, timeEncoder1, timeEncoder2, timeEncoderRateMatching, timeEncoderByte2Bit;
|
||||
reset_meas(&timeEncoderCRCByte); reset_meas(&timeEncoderCRCBit); reset_meas(&timeEncoderInterleaver); reset_meas(&timeEncoderBitInsertion); reset_meas(&timeEncoder1); reset_meas(&timeEncoder2); reset_meas(&timeEncoderRateMatching); reset_meas(&timeEncoderByte2Bit);
|
||||
uint16_t n_RNTI=0x0000;
|
||||
|
||||
start_meas(&timeEncoderCRCByte);
|
||||
nr_crc_bit2bit_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_aPrime); //(a to a')
|
||||
polarParams->crcBit = crc24c(polarParams->nr_polar_aPrime, (polarParams->payloadBits+polarParams->crcParityBits)); //Parity bits computation (p)
|
||||
uint8_t arrayInd = ceil(polarParams->payloadBits / 8.0); //(a to b)
|
||||
for (int i=0; i<arrayInd-1; i++)
|
||||
for (int j=0; j<8; j++)
|
||||
polarParams->nr_polar_B[j+(i*8)] = ((polarParams->nr_polar_aPrime[3+i]>>(7-j)) & 1);
|
||||
for (int i=0; i<((polarParams->payloadBits)%8); i++) polarParams->nr_polar_B[i+(arrayInd-1)*8] = ((polarParams->nr_polar_aPrime[3+(arrayInd-1)]>>(7-i)) & 1);
|
||||
for (int i=0; i<8; i++) polarParams->nr_polar_B[polarParams->payloadBits+i] = ((polarParams->crcBit)>>(31-i))&1;
|
||||
for (int i=0; i<16; i++) polarParams->nr_polar_B[polarParams->payloadBits+8+i] = ( (((polarParams->crcBit)>>(23-i))&1) + ((n_RNTI>>(15-i))&1) ) % 2; //Scrambling (b to c)
|
||||
stop_meas(&timeEncoderCRCByte);
|
||||
start_meas(&timeEncoderCRCByte);
|
||||
nr_crc_bit2bit_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_aPrime); //(a to a')
|
||||
polarParams->crcBit = crc24c(polarParams->nr_polar_aPrime, (polarParams->payloadBits+polarParams->crcParityBits)); //Parity bits computation (p)
|
||||
uint8_t arrayInd = ceil(polarParams->payloadBits / 8.0); //(a to b)
|
||||
for (int i=0; i<arrayInd-1; i++)
|
||||
for (int j=0; j<8; j++)
|
||||
polarParams->nr_polar_B[j+(i*8)] = ((polarParams->nr_polar_aPrime[3+i]>>(7-j)) & 1);
|
||||
for (int i=0; i<((polarParams->payloadBits)%8); i++) polarParams->nr_polar_B[i+(arrayInd-1)*8] = ((polarParams->nr_polar_aPrime[3+(arrayInd-1)]>>(7-i)) & 1);
|
||||
for (int i=0; i<8; i++) polarParams->nr_polar_B[polarParams->payloadBits+i] = ((polarParams->crcBit)>>(31-i))&1;
|
||||
for (int i=0; i<16; i++) polarParams->nr_polar_B[polarParams->payloadBits+8+i] = ( (((polarParams->crcBit)>>(23-i))&1) + ((n_RNTI>>(15-i))&1) ) % 2; //Scrambling (b to c)
|
||||
stop_meas(&timeEncoderCRCByte);
|
||||
|
||||
|
||||
start_meas(&timeEncoderCRCBit);
|
||||
nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_A);
|
||||
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_A, polarParams->crc_generator_matrix, polarParams->nr_polar_crc, polarParams->payloadBits, polarParams->crcParityBits); //Calculate CRC.
|
||||
for (uint8_t i = 0; i < polarParams->crcParityBits; i++) polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
|
||||
for (uint16_t i = 0; i < polarParams->payloadBits; i++) polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i]; //Attach CRC to the Transport Block. (a to b)
|
||||
for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++) polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
|
||||
stop_meas(&timeEncoderCRCBit);
|
||||
start_meas(&timeEncoderCRCBit);
|
||||
nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_A);
|
||||
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_A, polarParams->crc_generator_matrix, polarParams->nr_polar_crc, polarParams->payloadBits, polarParams->crcParityBits); //Calculate CRC.
|
||||
for (uint8_t i = 0; i < polarParams->crcParityBits; i++) polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
|
||||
for (uint16_t i = 0; i < polarParams->payloadBits; i++) polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i]; //Attach CRC to the Transport Block. (a to b)
|
||||
for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++) polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
|
||||
stop_meas(&timeEncoderCRCBit);
|
||||
|
||||
|
||||
start_meas(&timeEncoderInterleaver); //Interleaving (c to c')
|
||||
nr_polar_interleaver(polarParams->nr_polar_B, polarParams->nr_polar_CPrime, polarParams->interleaving_pattern, polarParams->K);
|
||||
stop_meas(&timeEncoderInterleaver);
|
||||
start_meas(&timeEncoderInterleaver); //Interleaving (c to c')
|
||||
nr_polar_interleaver(polarParams->nr_polar_B, polarParams->nr_polar_CPrime, polarParams->interleaving_pattern, polarParams->K);
|
||||
stop_meas(&timeEncoderInterleaver);
|
||||
|
||||
|
||||
start_meas(&timeEncoderBitInsertion); //Bit insertion (c' to u)
|
||||
nr_polar_bit_insertion(polarParams->nr_polar_CPrime, polarParams->nr_polar_U, polarParams->N, polarParams->K, polarParams->Q_I_N, polarParams->Q_PC_N, polarParams->n_pc);
|
||||
stop_meas(&timeEncoderBitInsertion);
|
||||
start_meas(&timeEncoderBitInsertion); //Bit insertion (c' to u)
|
||||
nr_polar_bit_insertion(polarParams->nr_polar_CPrime, polarParams->nr_polar_U, polarParams->N, polarParams->K, polarParams->Q_I_N, polarParams->Q_PC_N, polarParams->n_pc);
|
||||
stop_meas(&timeEncoderBitInsertion);
|
||||
|
||||
|
||||
start_meas(&timeEncoder1); //Encoding (u to d)
|
||||
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_U, polarParams->G_N, polarParams->nr_polar_D, polarParams->N, polarParams->N);
|
||||
stop_meas(&timeEncoder1);
|
||||
start_meas(&timeEncoder1); //Encoding (u to d)
|
||||
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_U, polarParams->G_N, polarParams->nr_polar_D, polarParams->N, polarParams->N);
|
||||
stop_meas(&timeEncoder1);
|
||||
|
||||
|
||||
start_meas(&timeEncoder2);
|
||||
for (uint16_t i = 0; i < polarParams->N; i++) polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
|
||||
stop_meas(&timeEncoder2);
|
||||
start_meas(&timeEncoder2);
|
||||
for (uint16_t i = 0; i < polarParams->N; i++) polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
|
||||
stop_meas(&timeEncoder2);
|
||||
|
||||
|
||||
start_meas(&timeEncoderRateMatching);//Rate matching //Sub-block interleaving (d to y) and Bit selection (y to e)
|
||||
nr_polar_interleaver(polarParams->nr_polar_D, polarParams->nr_polar_E, polarParams->rate_matching_pattern, polarParams->encoderLength);
|
||||
stop_meas(&timeEncoderRateMatching);
|
||||
start_meas(&timeEncoderRateMatching);//Rate matching //Sub-block interleaving (d to y) and Bit selection (y to e)
|
||||
nr_polar_interleaver(polarParams->nr_polar_D, polarParams->nr_polar_E, polarParams->rate_matching_pattern, polarParams->encoderLength);
|
||||
stop_meas(&timeEncoderRateMatching);
|
||||
|
||||
|
||||
start_meas(&timeEncoderByte2Bit); //Return bits.
|
||||
nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
|
||||
stop_meas(&timeEncoderByte2Bit);
|
||||
start_meas(&timeEncoderByte2Bit); //Return bits.
|
||||
nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
|
||||
stop_meas(&timeEncoderByte2Bit);
|
||||
|
||||
fprintf(logFile,",%f,%f,%f,%f,%f,%f,%f,%f\n",
|
||||
(timeEncoderCRCByte.diff_now/(cpuFreqGHz*1000.0)),
|
||||
(timeEncoderCRCBit.diff_now/(cpuFreqGHz*1000.0)),
|
||||
(timeEncoderInterleaver.diff_now/(cpuFreqGHz*1000.0)),
|
||||
(timeEncoderBitInsertion.diff_now/(cpuFreqGHz*1000.0)),
|
||||
(timeEncoder1.diff_now/(cpuFreqGHz*1000.0)),
|
||||
(timeEncoder2.diff_now/(cpuFreqGHz*1000.0)),
|
||||
(timeEncoderRateMatching.diff_now/(cpuFreqGHz*1000.0)),
|
||||
(timeEncoderByte2Bit.diff_now/(cpuFreqGHz*1000.0)));
|
||||
}
|
||||
|
||||
|
||||
void build_polar_tables(t_nrPolar_paramsPtr polarParams) {
|
||||
|
||||
|
||||
// build table b -> c'
|
||||
|
||||
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);
|
||||
|
||||
int bit_i;
|
||||
for (int byte=0;byte<8;byte++) {
|
||||
for (int val=0;val<256;val++) {
|
||||
for (int i=0;i<8;i++) {
|
||||
bit_i=(val>>i)&1;
|
||||
polarParams->cprime_tab[byte][val] |= (bit_i<<polarParams->interleaving_pattern[(8*byte)+i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AssertFatal(polarParams->N==512,"N = %d, not done yet\n",polarParams->N);
|
||||
|
||||
// build G bit vectors for information bit positions and convert the bit as bytes tables in nr_polar_kronecker_power_matrices.c to 64 bit packed vectors.
|
||||
// keep only rows of G which correspond to information/crc bits
|
||||
for (int i=0;i<polarParams->K;i++) {
|
||||
memset((void*)polarParams->G_N_tab[i],0,(polarParams->N/64)*sizeof(uint64_t));
|
||||
for (int j=0;j<polarParams->N;j++)
|
||||
polarParams->G_N_tab[i][j/64] |= polarParams->G_N[polarParams->Q_I_N[i]][j]<<(j&63);
|
||||
}
|
||||
}
|
||||
|
||||
void polar_encoder_fast(void *in,
|
||||
void *out,
|
||||
int bitlen,
|
||||
void *crcmask,
|
||||
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);
|
||||
|
||||
uint64_t A,B,Cprime;
|
||||
uint64_t D[8] __attribute__((aligned(32)));
|
||||
|
||||
// append crc
|
||||
B = A | (crc24c(A,bitlen)<<bitlen);
|
||||
uint8_t *Bbyte = (uint8_t*)&B;
|
||||
// for each byte of B, lookup in corresponding table for 64-bit word corresponding to tha byte and its position
|
||||
Cprime = polarParams->cprime_tab[0][Bbyte[0]] |
|
||||
polarParams->cprime_tab[1][Bbyte[1]] |
|
||||
polarParams->cprime_tab[2][Bbyte[2]] |
|
||||
polarParams->cprime_tab[3][Bbyte[3]] |
|
||||
polarParams->cprime_tab[4][Bbyte[4]] |
|
||||
polarParams->cprime_tab[5][Bbyte[5]] |
|
||||
polarParams->cprime_tab[6][Bbyte[6]] |
|
||||
polarParams->cprime_tab[7][Bbyte[7]];
|
||||
|
||||
|
||||
// now do Gu product (here using 64-bit XORs, we can also do with SIMD after)
|
||||
// here we're reading out the bits LSB -> MSB, is this correct w.r.t. 3GPP ?
|
||||
|
||||
uint64_t Cprime_i = -(Cprime & 1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11
|
||||
D[0] = Cprime_i & polarParams->G_N_tab[0][0];
|
||||
D[1] = Cprime_i & polarParams->G_N_tab[0][1];
|
||||
D[2] = Cprime_i & polarParams->G_N_tab[0][2];
|
||||
D[3] = Cprime_i & polarParams->G_N_tab[0][3];
|
||||
D[4] = Cprime_i & polarParams->G_N_tab[0][4];
|
||||
D[5] = Cprime_i & polarParams->G_N_tab[0][5];
|
||||
D[6] = Cprime_i & polarParams->G_N_tab[0][6];
|
||||
D[7] = Cprime_i & polarParams->G_N_tab[0][7];
|
||||
for (int i=1;i<bitlen;i++) {
|
||||
|
||||
Cprime_i = -((Cprime>>i)&1);
|
||||
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]);
|
||||
}
|
||||
|
||||
// Rate matching on the 8 64-bit D bit-strings should be performed more or less like
|
||||
// The interleaving on the single 64-bit input in the first step. We just need 64 lookup tables I guess, and they will have large entries
|
||||
|
||||
fprintf(logFile,",%f,%f,%f,%f,%f,%f,%f,%f\n",
|
||||
(timeEncoderCRCByte.diff_now/(cpuFreqGHz*1000.0)),
|
||||
(timeEncoderCRCBit.diff_now/(cpuFreqGHz*1000.0)),
|
||||
(timeEncoderInterleaver.diff_now/(cpuFreqGHz*1000.0)),
|
||||
(timeEncoderBitInsertion.diff_now/(cpuFreqGHz*1000.0)),
|
||||
(timeEncoder1.diff_now/(cpuFreqGHz*1000.0)),
|
||||
(timeEncoder2.diff_now/(cpuFreqGHz*1000.0)),
|
||||
(timeEncoderRateMatching.diff_now/(cpuFreqGHz*1000.0)),
|
||||
(timeEncoderByte2Bit.diff_now/(cpuFreqGHz*1000.0)));
|
||||
}
|
||||
|
||||
@@ -33,15 +33,15 @@
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||
|
||||
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)
|
||||
uint8_t *output,
|
||||
uint16_t N,
|
||||
uint16_t K,
|
||||
int16_t *Q_I_N,
|
||||
int16_t *Q_PC_N,
|
||||
uint8_t n_PC)
|
||||
{
|
||||
uint16_t k=0;
|
||||
uint8_t flag;
|
||||
uint16_t k=0;
|
||||
uint8_t flag;
|
||||
|
||||
if (n_PC>0) {
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user