Reformat all polar code

Commands used:

    clang-format -i openair1/PHY/CODING/TESTBENCH/polartest.c
    clang-format -i openair1/PHY/CODING/nr_polar_init.c
    clang-format -i openair1/PHY/CODING/nrPolar_tools/*
This commit is contained in:
Robert Schmidt
2024-11-07 09:43:19 +01:00
parent 28234893f7
commit 16535f3de4
18 changed files with 1041 additions and 926 deletions
+206 -191
View File
@@ -12,161 +12,162 @@
#include "PHY/CODING/coding_defs.h" #include "PHY/CODING/coding_defs.h"
#include "SIMULATION/TOOLS/sim.h" #include "SIMULATION/TOOLS/sim.h"
#include "common/config/config_userapi.h" #include "common/config/config_userapi.h"
//#include "common/utils/LOG/log.h" // #include "common/utils/LOG/log.h"
#include "coding_unitary_defs.h" #include "coding_unitary_defs.h"
//#define DEBUG_DCI_POLAR_PARAMS // #define DEBUG_DCI_POLAR_PARAMS
//#define DEBUG_POLAR_TIMING // #define DEBUG_POLAR_TIMING
//#define DEBUG_POLARTEST // #define DEBUG_POLARTEST
configmodule_interface_t *uniqCfg = NULL; configmodule_interface_t *uniqCfg = NULL;
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
//Default simulation values (Aim for iterations = 1000000.) // Default simulation values (Aim for iterations = 1000000.)
int decoder_int16=0; int decoder_int16 = 0;
int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, 2=UCI int itr, iterations = 1000, arguments, polarMessageType = 0; // 0=PBCH, 1=DCI, 2=UCI
double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB double SNRstart = -20.0, SNRstop = 0.0, SNRinc = 0.5; // dB
double SNR, SNR_lin; double SNR, SNR_lin;
int16_t nBitError = 0; // -1 = Decoding failed (All list entries have failed the CRC checks). int16_t nBitError = 0; // -1 = Decoding failed (All list entries have failed the CRC checks).
uint32_t decoderState=0, blockErrorState=0; //0 = Success, -1 = Decoding failed, 1 = Block Error. uint32_t decoderState = 0, blockErrorState = 0; // 0 = Success, -1 = Decoding failed, 1 = Block Error.
uint16_t testLength = NR_POLAR_PBCH_PAYLOAD_BITS, coderLength = NR_POLAR_PBCH_E; uint16_t testLength = NR_POLAR_PBCH_PAYLOAD_BITS, coderLength = NR_POLAR_PBCH_E;
uint16_t blockErrorCumulative=0, bitErrorCumulative=0; uint16_t blockErrorCumulative = 0, bitErrorCumulative = 0;
uint8_t aggregation_level = 8, decoderListSize = 8, logFlag = 0; uint8_t aggregation_level = 8, decoderListSize = 8, logFlag = 0;
uint16_t rnti=0; uint16_t rnti = 0;
if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == 0) { if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == 0) {
exit_fun("[POLARTEST] Error, configuration module init failed\n"); exit_fun("[POLARTEST] Error, configuration module init failed\n");
} }
logInit(); logInit();
while ((arguments = getopt (argc, argv, "--:O:s:d:f:m:i:l:a:p:hqgFL:k:")) != -1) { while ((arguments = getopt(argc, argv, "--:O:s:d:f:m:i:l:a:p:hqgFL:k:")) != -1) {
/* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */ /* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */
/* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */ /* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */
if (arguments == 1 || arguments == '-' || arguments == 'O') if (arguments == 1 || arguments == '-' || arguments == 'O')
continue; continue;
printf("handling optarg %c\n",arguments); printf("handling optarg %c\n", arguments);
switch (arguments) { switch (arguments) {
case 's': case 's':
SNRstart = atof(optarg); SNRstart = atof(optarg);
SNRstop = SNRstart + 2; SNRstop = SNRstart + 2;
break; break;
case 'd': case 'd':
SNRinc = atof(optarg); SNRinc = atof(optarg);
break; break;
case 'f': case 'f':
SNRstop = atof(optarg); SNRstop = atof(optarg);
break; break;
case 'm': case 'm':
polarMessageType = atoi(optarg); polarMessageType = atoi(optarg);
if (polarMessageType!=0 && polarMessageType!=1 && polarMessageType!=2) if (polarMessageType != 0 && polarMessageType != 1 && polarMessageType != 2)
printf("Illegal polar message type %d (should be 0,1 or 2)\n", polarMessageType); printf("Illegal polar message type %d (should be 0,1 or 2)\n", polarMessageType);
break; break;
case 'i': case 'i':
iterations = atoi(optarg); iterations = atoi(optarg);
break; break;
case 'l': case 'l':
decoderListSize = (uint8_t) atoi(optarg); decoderListSize = (uint8_t)atoi(optarg);
break; break;
case 'q': case 'q':
decoder_int16 = 1; decoder_int16 = 1;
break; break;
case 'g': case 'g':
iterations = 1; iterations = 1;
SNRstart = -6.0; SNRstart = -6.0;
SNRstop = -6.0; SNRstop = -6.0;
decoder_int16 = 1; decoder_int16 = 1;
break; break;
case 'F': case 'F':
logFlag = 1; logFlag = 1;
break; break;
case 'L': case 'L':
aggregation_level=atoi(optarg); aggregation_level = atoi(optarg);
if (aggregation_level != 1 && aggregation_level != 2 && aggregation_level != 4 && aggregation_level != 8 if (aggregation_level != 1 && aggregation_level != 2 && aggregation_level != 4 && aggregation_level != 8
&& aggregation_level != 16) { && aggregation_level != 16) {
printf("Illegal aggregation level %d \n", aggregation_level); printf("Illegal aggregation level %d \n", aggregation_level);
exit(-1);
}
break;
case 'k':
testLength = atoi(optarg);
if (testLength < 12 || testLength > 127) {
printf("Illegal packet bitlength %d \n", testLength);
exit(-1);
}
break;
case 'h':
printf(
"./polartest\nOptions\n-h Print this help\n-s SNRstart (dB)\n-d SNRinc (dB)\n-f SNRstop (dB)\n-m [0=PBCH|1=DCI|2=UCI]\n"
"-i Number of iterations\n-l decoderListSize\n-q Flag for optimized coders usage\n-F Flag for test results logging\n"
"-L aggregation level (for DCI)\n-k packet_length (bits) for DCI/UCI\n");
exit(-1); exit(-1);
} break;
break;
case 'k': default:
testLength=atoi(optarg); perror("[polartest.c] Problem at argument parsing with getopt");
if (testLength < 12 || testLength > 127) { exit(-1);
printf("Illegal packet bitlength %d \n",testLength); break;
exit(-1);
}
break;
case 'h':
printf(
"./polartest\nOptions\n-h Print this help\n-s SNRstart (dB)\n-d SNRinc (dB)\n-f SNRstop (dB)\n-m [0=PBCH|1=DCI|2=UCI]\n"
"-i Number of iterations\n-l decoderListSize\n-q Flag for optimized coders usage\n-F Flag for test results logging\n"
"-L aggregation level (for DCI)\n-k packet_length (bits) for DCI/UCI\n");
exit(-1);
break;
default:
perror("[polartest.c] Problem at argument parsing with getopt");
exit(-1);
break;
} }
} }
//Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.) // Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.)
time_stats_t timeEncoder,timeDecoder; time_stats_t timeEncoder, timeDecoder;
cpu_meas_enabled = 1; cpu_meas_enabled = 1;
reset_meas(&timeEncoder); reset_meas(&timeEncoder);
reset_meas(&timeDecoder); reset_meas(&timeDecoder);
randominit(0); randominit(0);
crcTableInit(); crcTableInit();
if (polarMessageType == 0) { //PBCH if (polarMessageType == 0) { // PBCH
aggregation_level = NR_POLAR_PBCH_AGGREGATION_LEVEL; aggregation_level = NR_POLAR_PBCH_AGGREGATION_LEVEL;
} else if (polarMessageType == 1) { //DCI } else if (polarMessageType == 1) { // DCI
coderLength = 108*aggregation_level; coderLength = 108 * aggregation_level;
} else if (polarMessageType == 2) { //UCI } else if (polarMessageType == 2) { // UCI
//pucch2 parameters, 1 symbol, aggregation_level = NPRB // pucch2 parameters, 1 symbol, aggregation_level = NPRB
AssertFatal(aggregation_level>2,"For UCI formats, aggregation (N_RB) should be > 2\n"); AssertFatal(aggregation_level > 2, "For UCI formats, aggregation (N_RB) should be > 2\n");
coderLength = 16*aggregation_level; coderLength = 16 * aggregation_level;
} }
//Logging // Logging
time_t currentTime; time_t currentTime;
char fileName[512], currentTimeInfo[25]; char fileName[512], currentTimeInfo[25];
char folderName[] = "."; char folderName[] = ".";
FILE *logFile = NULL; FILE *logFile = NULL;
if (logFlag){ if (logFlag) {
time (&currentTime); time(&currentTime);
#ifdef DEBUG_POLAR_TIMING #ifdef DEBUG_POLAR_TIMING
sprintf(fileName,"%s/TIMING_ListSize_%d_Payload_%d_Itr_%d", folderName, decoderListSize, testLength, iterations); sprintf(fileName, "%s/TIMING_ListSize_%d_Payload_%d_Itr_%d", folderName, decoderListSize, testLength, iterations);
#else #else
sprintf(fileName,"%s/_ListSize_%d_Payload_%d_Itr_%d", folderName, decoderListSize, testLength, iterations); sprintf(fileName, "%s/_ListSize_%d_Payload_%d_Itr_%d", folderName, decoderListSize, testLength, iterations);
#endif #endif
strftime(currentTimeInfo, 25, "_%Y-%m-%d-%H-%M-%S.csv", localtime(&currentTime)); strftime(currentTimeInfo, 25, "_%Y-%m-%d-%H-%M-%S.csv", localtime(&currentTime));
strcat(fileName,currentTimeInfo); strcat(fileName, currentTimeInfo);
//Create "~/Desktop/polartestResults" folder if it doesn't already exist. // Create "~/Desktop/polartestResults" folder if it doesn't already exist.
/*struct stat folder = {0}; /*struct stat folder = {0};
if (stat(folderName, &folder) == -1) mkdir(folderName, S_IRWXU | S_IRWXG | S_IRWXO);*/ if (stat(folderName, &folder) == -1) mkdir(folderName, S_IRWXU | S_IRWXG | S_IRWXO);*/
logFile = fopen(fileName, "w"); logFile = fopen(fileName, "w");
if (logFile==NULL) { if (logFile == NULL) {
fprintf(stderr,"[polartest.c] Problem creating file %s with fopen\n",fileName); fprintf(stderr, "[polartest.c] Problem creating file %s with fopen\n", fileName);
exit(-1); exit(-1);
} }
#ifdef DEBUG_POLAR_TIMING #ifdef DEBUG_POLAR_TIMING
fprintf(logFile,",timeEncoderCRCByte[us],timeEncoderCRCBit[us],timeEncoderInterleaver[us],timeEncoderBitInsertion[us],timeEncoder1[us],timeEncoder2[us],timeEncoderRateMatching[us],timeEncoderByte2Bit[us]\n"); fprintf(logFile,
",timeEncoderCRCByte[us],timeEncoderCRCBit[us],timeEncoderInterleaver[us],timeEncoderBitInsertion[us],timeEncoder1[us],"
"timeEncoder2[us],timeEncoderRateMatching[us],timeEncoderByte2Bit[us]\n");
#else #else
fprintf(logFile,",SNR,nBitError,blockErrorState,t_encoder[us],t_decoder[us]\n"); fprintf(logFile, ",SNR,nBitError,blockErrorState,t_encoder[us],t_decoder[us]\n");
#endif #endif
} }
@@ -177,54 +178,55 @@ int main(int argc, char *argv[])
// satisfies uint64_t array length // satisfies uint64_t array length
const uint8_t realArrayLength = ((testArrayLength + 1) / 2) * 2; const uint8_t realArrayLength = ((testArrayLength + 1) / 2) * 2;
printf("testArrayLength %d realArrayLength %d\n", testArrayLength, realArrayLength); printf("testArrayLength %d realArrayLength %d\n", testArrayLength, realArrayLength);
uint32_t testInput[realArrayLength]; //generate randomly uint32_t testInput[realArrayLength]; // generate randomly
uint32_t encoderOutput[coderArrayLength]; uint32_t encoderOutput[coderArrayLength];
uint32_t estimatedOutput[realArrayLength]; //decoder output uint32_t estimatedOutput[realArrayLength]; // decoder output
memset(testInput,0,sizeof(uint32_t) * realArrayLength); // does not reset all memset(testInput, 0, sizeof(uint32_t) * realArrayLength); // does not reset all
memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength); memset(encoderOutput, 0, sizeof(uint32_t) * coderArrayLength);
memset(estimatedOutput,0,sizeof(uint32_t) * realArrayLength); memset(estimatedOutput, 0, sizeof(uint32_t) * realArrayLength);
uint8_t encoderOutputByte[coderLength]; uint8_t encoderOutputByte[coderLength];
double modulatedInput[coderLength]; //channel input double modulatedInput[coderLength]; // channel input
double channelOutput[coderLength]; //add noise double channelOutput[coderLength]; // add noise
int16_t channelOutput_int16[coderLength]; int16_t channelOutput_int16[coderLength];
t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level); t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level);
#ifdef DEBUG_DCI_POLAR_PARAMS #ifdef DEBUG_DCI_POLAR_PARAMS
uint32_t dci_pdu[4]; uint32_t dci_pdu[4];
memset(dci_pdu,0,sizeof(uint32_t)*4); memset(dci_pdu, 0, sizeof(uint32_t) * 4);
dci_pdu[0]=0x01189400; dci_pdu[0] = 0x01189400;
printf("dci_pdu: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", dci_pdu[0], dci_pdu[1], dci_pdu[2], dci_pdu[3]); printf("dci_pdu: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", dci_pdu[0], dci_pdu[1], dci_pdu[2], dci_pdu[3]);
uint16_t size=41; uint16_t size = 41;
rnti=3; rnti = 3;
aggregation_level=8; aggregation_level = 8;
uint32_t encoder_output[54]; uint32_t encoder_output[54];
memset(encoder_output,0,sizeof(uint32_t)*54); memset(encoder_output, 0, sizeof(uint32_t) * 54);
t_nrPolar_params *currentPtrDCI=nr_polar_params(1, size, aggregation_level); t_nrPolar_params *currentPtrDCI = nr_polar_params(1, size, aggregation_level);
polar_encoder_dci(dci_pdu, encoder_output, currentPtrDCI, rnti); polar_encoder_dci(dci_pdu, encoder_output, currentPtrDCI, rnti);
for (int i=0; i<54; i++) for (int i = 0; i < 54; i++)
printf("encoder_output: [%2d]->0x%08x \n", i, encoder_output[i]); printf("encoder_output: [%2d]->0x%08x \n", i, encoder_output[i]);
uint8_t *encoder_outputByte = malloc(sizeof(uint8_t) * currentPtrDCI->encoderLength); uint8_t *encoder_outputByte = malloc(sizeof(uint8_t) * currentPtrDCI->encoderLength);
double *modulated_input = malloc (sizeof(double) * currentPtrDCI->encoderLength); double *modulated_input = malloc(sizeof(double) * currentPtrDCI->encoderLength);
double *channel_output = malloc (sizeof(double) * currentPtrDCI->encoderLength); double *channel_output = malloc(sizeof(double) * currentPtrDCI->encoderLength);
uint32_t dci_est[4]; uint32_t dci_est[4];
memset(dci_est,0,sizeof(dci_est)); memset(dci_est, 0, sizeof(dci_est));
nr_bit2byte_uint32_8(encoder_output, currentPtrDCI->encoderLength, encoder_outputByte); nr_bit2byte_uint32_8(encoder_output, currentPtrDCI->encoderLength, encoder_outputByte);
printf("[polartest] encoder_outputByte: "); printf("[polartest] encoder_outputByte: ");
for (int i = 0; i < currentPtrDCI->encoderLength; i++) printf("%d-", encoder_outputByte[i]); printf("\n"); for (int i = 0; i < currentPtrDCI->encoderLength; i++)
printf("%d-", encoder_outputByte[i]);
printf("\n");
SNR_lin = pow(10, 0/10); //SNR = 0 dB SNR_lin = pow(10, 0 / 10); // SNR = 0 dB
for(int i=0; i<currentPtrDCI->encoderLength; i++) { for (int i = 0; i < currentPtrDCI->encoderLength; i++) {
if (encoder_outputByte[i] == 0) if (encoder_outputByte[i] == 0)
modulated_input[i]=1/sqrt(2); modulated_input[i] = 1 / sqrt(2);
else else
modulated_input[i]=(-1)/sqrt(2); modulated_input[i] = (-1) / sqrt(2);
channel_output[i] = modulated_input[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin))); channel_output[i] = modulated_input[i] + (gaussdouble(0.0, 1.0) * (1 / sqrt(2 * SNR_lin)));
} }
decoderState = polar_decoder_dci(channel_output, dci_est, NR_POLAR_DECODER_LISTSIZE, rnti, decoderState = polar_decoder_dci(channel_output, dci_est, NR_POLAR_DECODER_LISTSIZE, rnti, 1, size, aggregation_level);
1, size, aggregation_level);
printf("dci_est: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", dci_est[0], dci_est[1], dci_est[2], dci_est[3]); printf("dci_est: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", dci_est[0], dci_est[1], dci_est[2], dci_est[3]);
free(encoder_outputByte); free(encoder_outputByte);
free(channel_output); free(channel_output);
@@ -235,56 +237,56 @@ int main(int argc, char *argv[])
#endif #endif
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) { for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
printf("SNR %f\n",SNR); printf("SNR %f\n", SNR);
SNR_lin = pow(10, SNR/10); SNR_lin = pow(10, SNR / 10);
for (itr = 1; itr <= iterations; itr++) { for (itr = 1; itr <= iterations; itr++) {
//Generate random values for all the bits of "testInput", not just as much as "currentPtr->payloadBits". // Generate random values for all the bits of "testInput", not just as much as "currentPtr->payloadBits".
for (int i = 0; i < testArrayLength; i++) { for (int i = 0; i < testArrayLength; i++) {
for (int j = 0; j < (sizeof(testInput[0])*8)-1; j++) { for (int j = 0; j < (sizeof(testInput[0]) * 8) - 1; j++) {
testInput[i] |= ( ((uint32_t) (rand()%2)) &1); testInput[i] |= (((uint32_t)(rand() % 2)) & 1);
testInput[i]<<=1; testInput[i] <<= 1;
} }
testInput[i] |= ( ((uint32_t) (rand()%2)) &1); testInput[i] |= (((uint32_t)(rand() % 2)) & 1);
} }
#ifdef DEBUG_POLARTEST #ifdef DEBUG_POLARTEST
//testInput[0] = 0x360f8a5c; // testInput[0] = 0x360f8a5c;
printf("testInput: [0]->0x%08x\n", testInput[0]); printf("testInput: [0]->0x%08x\n", testInput[0]);
#endif #endif
int len_mod64=currentPtr->payloadBits&63; int len_mod64 = currentPtr->payloadBits & 63;
((uint64_t *)testInput)[currentPtr->payloadBits/64]&=((((uint64_t)1)<<len_mod64)-1); ((uint64_t *)testInput)[currentPtr->payloadBits / 64] &= ((((uint64_t)1) << len_mod64) - 1);
start_meas(&timeEncoder); start_meas(&timeEncoder);
if (decoder_int16==1) { if (decoder_int16 == 1) {
polar_encoder_fast((uint64_t *)testInput, encoderOutput, 0, 0, polarMessageType, testLength, aggregation_level); polar_encoder_fast((uint64_t *)testInput, encoderOutput, 0, 0, polarMessageType, testLength, aggregation_level);
//polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0,0,currentPtr); // polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0,0,currentPtr);
} else { //0 --> PBCH, 1 --> DCI, -1 --> UCI } else { // 0 --> PBCH, 1 --> DCI, -1 --> UCI
if (polarMessageType == 0) if (polarMessageType == 0)
polar_encoder(testInput, encoderOutput, polarMessageType, testLength, aggregation_level); polar_encoder(testInput, encoderOutput, polarMessageType, testLength, aggregation_level);
else if (polarMessageType == 1) else if (polarMessageType == 1)
polar_encoder_dci(testInput, encoderOutput, rnti, polarMessageType, testLength, aggregation_level); polar_encoder_dci(testInput, encoderOutput, rnti, polarMessageType, testLength, aggregation_level);
} }
stop_meas(&timeEncoder); stop_meas(&timeEncoder);
#ifdef DEBUG_POLARTEST #ifdef DEBUG_POLARTEST
printf("encoderOutput: [0]->0x%08x\n", encoderOutput[0]); printf("encoderOutput: [0]->0x%08x\n", encoderOutput[0]);
//for (int i=1;i<coderArrayLength;i++) printf("encoderOutput: [i]->0x%08x\n", i, encoderOutput[1]); // for (int i=1;i<coderArrayLength;i++) printf("encoderOutput: [i]->0x%08x\n", i, encoderOutput[1]);
#endif #endif
//Bit-to-byte: // Bit-to-byte:
nr_bit2byte_uint32_8(encoderOutput, coderLength, encoderOutputByte); nr_bit2byte_uint32_8(encoderOutput, coderLength, encoderOutputByte);
//BPSK modulation // BPSK modulation
for(int i=0; i<coderLength; i++) { for (int i = 0; i < coderLength; i++) {
if (encoderOutputByte[i] == 0) if (encoderOutputByte[i] == 0)
modulatedInput[i]=1/sqrt(2); modulatedInput[i] = 1 / sqrt(2);
else else
modulatedInput[i]=(-1)/sqrt(2); modulatedInput[i] = (-1) / sqrt(2);
channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin))); channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0, 1.0) * (1 / sqrt(2 * SNR_lin)));
if (decoder_int16==1) { if (decoder_int16 == 1) {
if (channelOutput[i] > 15) if (channelOutput[i] > 15)
channelOutput_int16[i] = 127; channelOutput_int16[i] = 127;
else if (channelOutput[i] < -16) else if (channelOutput[i] < -16)
@@ -306,7 +308,7 @@ int main(int argc, char *argv[])
} else { // 0 --> PBCH, 1 --> DCI, -1 --> UCI } else { // 0 --> PBCH, 1 --> DCI, -1 --> UCI
if (polarMessageType == 0) { if (polarMessageType == 0) {
decoderState = decoderState =
polar_decoder(channelOutput, estimatedOutput, decoderListSize, polarMessageType, testLength, aggregation_level); polar_decoder(channelOutput, estimatedOutput, decoderListSize, polarMessageType, testLength, aggregation_level);
} else if (polarMessageType == 1) { } else if (polarMessageType == 1) {
decoderState = polar_decoder_dci(channelOutput, decoderState = polar_decoder_dci(channelOutput,
estimatedOutput, estimatedOutput,
@@ -318,70 +320,83 @@ int main(int argc, char *argv[])
} }
} }
stop_meas(&timeDecoder); stop_meas(&timeDecoder);
#ifdef DEBUG_POLARTEST #ifdef DEBUG_POLARTEST
printf("estimatedOutput: [0]->0x%08x\n", estimatedOutput[0]); printf("estimatedOutput: [0]->0x%08x\n", estimatedOutput[0]);
#endif #endif
//calculate errors // calculate errors
if (decoderState!=0) { if (decoderState != 0) {
blockErrorState=-1; blockErrorState = -1;
nBitError=-1; nBitError = -1;
} else { } else {
for (int i = 0; i < (testArrayLength-1); i++) { for (int i = 0; i < (testArrayLength - 1); i++) {
for (int j = 0; j < 32; j++) { for (int j = 0; j < 32; j++) {
if ( ((estimatedOutput[i]>>j) & 1) != ((testInput[i]>>j) & 1) ) if (((estimatedOutput[i] >> j) & 1) != ((testInput[i] >> j) & 1))
nBitError++; nBitError++;
} }
} }
for (int j = 0; j < testLength - ((testArrayLength-1) * 32); j++) for (int j = 0; j < testLength - ((testArrayLength - 1) * 32); j++)
if ( ((estimatedOutput[(testArrayLength-1)]>>j) & 1) != ((testInput[(testArrayLength-1)]>>j) & 1) ) if (((estimatedOutput[(testArrayLength - 1)] >> j) & 1) != ((testInput[(testArrayLength - 1)] >> j) & 1))
nBitError++; nBitError++;
} }
if (nBitError>0) blockErrorState=1; if (nBitError > 0)
blockErrorState = 1;
#ifdef DEBUG_POLARTEST #ifdef DEBUG_POLARTEST
for (int i = 0; i < testArrayLength; i++) for (int i = 0; i < testArrayLength; i++)
printf("[polartest/decoderState=%u] testInput[%d]=0x%08x, estimatedOutput[%d]=0x%08x\n", printf("[polartest/decoderState=%u] testInput[%d]=0x%08x, estimatedOutput[%d]=0x%08x\n",
decoderState, decoderState,
i, i,
testInput[i], testInput[i],
i, i,
estimatedOutput[i]); estimatedOutput[i]);
#endif #endif
//Iteration times are in microseconds. // Iteration times are in microseconds.
if (logFlag) fprintf(logFile,",%f,%d,%u,%f,%f\n", SNR, nBitError, blockErrorState, (timeEncoder.diff/(get_cpu_freq_GHz()*1000.0)), (timeDecoder.diff/(get_cpu_freq_GHz()*1000.0))); if (logFlag)
fprintf(logFile,
",%f,%d,%u,%f,%f\n",
SNR,
nBitError,
blockErrorState,
(timeEncoder.diff / (get_cpu_freq_GHz() * 1000.0)),
(timeDecoder.diff / (get_cpu_freq_GHz() * 1000.0)));
if (nBitError<0) { if (nBitError < 0) {
blockErrorCumulative++; blockErrorCumulative++;
bitErrorCumulative+=testLength; bitErrorCumulative += testLength;
} else { } else {
blockErrorCumulative+=blockErrorState; blockErrorCumulative += blockErrorState;
bitErrorCumulative+=nBitError; bitErrorCumulative += nBitError;
} }
decoderState=0; decoderState = 0;
nBitError=0; nBitError = 0;
blockErrorState=0; blockErrorState = 0;
memset(testInput,0,sizeof(uint32_t) * realArrayLength); memset(testInput, 0, sizeof(uint32_t) * realArrayLength);
memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength); memset(encoderOutput, 0, sizeof(uint32_t) * coderArrayLength);
memset(estimatedOutput,0,sizeof(uint32_t) * realArrayLength); memset(estimatedOutput, 0, sizeof(uint32_t) * realArrayLength);
} }
//Calculate error statistics for the SNR. // Calculate error statistics for the SNR.
printf("[ListSize=%d] SNR=%+8.3f, BLER=%9.6f, BER=%12.9f, t_Encoder=%9.3fus, t_Decoder=%9.3fus\n", printf("[ListSize=%d] SNR=%+8.3f, BLER=%9.6f, BER=%12.9f, t_Encoder=%9.3fus, t_Decoder=%9.3fus\n",
decoderListSize, SNR, ((double)blockErrorCumulative/iterations), decoderListSize,
((double)bitErrorCumulative / (iterations*testLength)), SNR,
(double)timeEncoder.diff/timeEncoder.trials/(get_cpu_freq_GHz()*1000.0),(double)timeDecoder.diff/timeDecoder.trials/(get_cpu_freq_GHz()*1000.0)); ((double)blockErrorCumulative / iterations),
((double)bitErrorCumulative / (iterations * testLength)),
(double)timeEncoder.diff / timeEncoder.trials / (get_cpu_freq_GHz() * 1000.0),
(double)timeDecoder.diff / timeDecoder.trials / (get_cpu_freq_GHz() * 1000.0));
if (blockErrorCumulative==0 && bitErrorCumulative==0) break; if (blockErrorCumulative == 0 && bitErrorCumulative == 0)
break;
blockErrorCumulative = 0; blockErrorCumulative = 0;
bitErrorCumulative = 0; bitErrorCumulative = 0;
} }
print_meas(&timeEncoder,"polar_encoder",NULL,NULL); print_meas(&timeEncoder, "polar_encoder", NULL, NULL);
print_meas(&timeDecoder,"polar_decoder",NULL,NULL); print_meas(&timeDecoder, "polar_decoder", NULL, NULL);
if (logFlag) fclose(logFile); if (logFlag)
fclose(logFile);
return (0); return (0);
} }
@@ -28,11 +28,12 @@
* \email turker.yilmaz@eurecom.fr * \email turker.yilmaz@eurecom.fr
* \note * \note
* \warning * \warning
*/ */
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_bit2byte_uint32_8(uint32_t *in, uint16_t arraySize, uint8_t *out) { void nr_bit2byte_uint32_8(uint32_t *in, uint16_t arraySize, uint8_t *out)
{
const uint arrayInd = ceil(arraySize / 32.0); const uint arrayInd = ceil(arraySize / 32.0);
for (int i = 0; i < (arrayInd - 1); i++) { for (int i = 0; i < (arrayInd - 1); i++) {
for (int j = 0; j < 32; j++) { for (int j = 0; j < 32; j++) {
@@ -44,7 +45,8 @@ void nr_bit2byte_uint32_8(uint32_t *in, uint16_t arraySize, uint8_t *out) {
out[j + ((arrayInd - 1) * 32)] = (in[(arrayInd - 1)] >> j) & 1; out[j + ((arrayInd - 1) * 32)] = (in[(arrayInd - 1)] >> j) & 1;
} }
void nr_byte2bit_uint8_32(uint8_t *in, uint16_t arraySize, uint32_t *out) { void nr_byte2bit_uint8_32(uint8_t *in, uint16_t arraySize, uint32_t *out)
{
const uint arrayInd = ceil(arraySize / 32.0); const uint arrayInd = ceil(arraySize / 32.0);
for (int i = 0; i < arrayInd; i++) { for (int i = 0; i < arrayInd; i++) {
out[i] = 0; out[i] = 0;
@@ -29,7 +29,8 @@ const uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits)
uint8_t crcPolynomialSize = 24; uint8_t crcPolynomialSize = 24;
uint8_t temp1[crcPolynomialSize], temp2[crcPolynomialSize]; uint8_t temp1[crcPolynomialSize], temp2[crcPolynomialSize];
uint8_t **crc_generator_matrix = malloc(payloadSizeBits*sizeof(uint8_t *) + payloadSizeBits*crcPolynomialSize*sizeof(uint8_t)); uint8_t **crc_generator_matrix =
malloc(payloadSizeBits * sizeof(uint8_t *) + payloadSizeBits * crcPolynomialSize * sizeof(uint8_t));
if (crc_generator_matrix) if (crc_generator_matrix)
for (int i = 0; i < payloadSizeBits; i++) for (int i = 0; i < payloadSizeBits; i++)
crc_generator_matrix[i] = ((uint8_t *)&crc_generator_matrix[payloadSizeBits]) + i * crcPolynomialSize; crc_generator_matrix[i] = ((uint8_t *)&crc_generator_matrix[payloadSizeBits]) + i * crcPolynomialSize;
@@ -38,7 +39,8 @@ const uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits)
crc_generator_matrix[payloadSizeBits - 1][i] = crcPolynomialPattern[i + 1]; crc_generator_matrix[payloadSizeBits - 1][i] = crcPolynomialPattern[i + 1];
for (int i = payloadSizeBits - 2; i >= 0; i--) { for (int i = payloadSizeBits - 2; i >= 0; i--) {
for (int j = 0; j < crcPolynomialSize-1; j++) temp1[j]=crc_generator_matrix[i+1][j+1]; for (int j = 0; j < crcPolynomialSize - 1; j++)
temp1[j] = crc_generator_matrix[i + 1][j + 1];
temp1[crcPolynomialSize - 1] = 0; temp1[crcPolynomialSize - 1] = 0;
@@ -46,10 +48,10 @@ const uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits)
temp2[j] = crc_generator_matrix[i + 1][0] * crcPolynomialPattern[j + 1]; temp2[j] = crc_generator_matrix[i + 1][0] * crcPolynomialPattern[j + 1];
for (int j = 0; j < crcPolynomialSize; j++) { for (int j = 0; j < crcPolynomialSize; j++) {
if(temp1[j]+temp2[j] == 1) if (temp1[j] + temp2[j] == 1)
crc_generator_matrix[i][j]=1; crc_generator_matrix[i][j] = 1;
else else
crc_generator_matrix[i][j]=0; crc_generator_matrix[i][j] = 0;
} }
} }
return (const uint8_t **)crc_generator_matrix; return (const uint8_t **)crc_generator_matrix;
@@ -20,31 +20,31 @@
*/ */
/*! \file PHY/CODING/nrPolar_tools/nr_polar_dci_defs.h /*! \file PHY/CODING/nrPolar_tools/nr_polar_dci_defs.h
* \brief Defines the constant variables for polar coding of the DCI from 38-212, V15.1.1 2018-04. * \brief Defines the constant variables for polar coding of the DCI from 38-212, V15.1.1 2018-04.
* \author * \author
* \date 2018 * \date 2018
* \version 0.1 * \version 0.1
* \company Eurecom * \company Eurecom
* \email: * \email:
* \note * \note
* \warning * \warning
*/ */
#ifndef __NR_POLAR_DCI_DEFS__H__ #ifndef __NR_POLAR_DCI_DEFS__H__
#define __NR_POLAR_DCI_DEFS__H__ #define __NR_POLAR_DCI_DEFS__H__
#define NR_POLAR_DCI_MESSAGE_TYPE 1 //int8_t #define NR_POLAR_DCI_MESSAGE_TYPE 1 // int8_t
#define NR_POLAR_DCI_CRC_PARITY_BITS 24 #define NR_POLAR_DCI_CRC_PARITY_BITS 24
#define NR_POLAR_DCI_CRC_ERROR_CORRECTION_BITS 3 #define NR_POLAR_DCI_CRC_ERROR_CORRECTION_BITS 3
//Sec. 7.3.3: Channel Coding // Sec. 7.3.3: Channel Coding
#define NR_POLAR_DCI_N_MAX 9 //uint8_t #define NR_POLAR_DCI_N_MAX 9 // uint8_t
#define NR_POLAR_DCI_I_IL 1 //uint8_t #define NR_POLAR_DCI_I_IL 1 // uint8_t
#define NR_POLAR_DCI_I_SEG 0 //uint8_t #define NR_POLAR_DCI_I_SEG 0 // uint8_t
#define NR_POLAR_DCI_N_PC 0 //uint8_t #define NR_POLAR_DCI_N_PC 0 // uint8_t
#define NR_POLAR_DCI_N_PC_WM 0 //uint8_t #define NR_POLAR_DCI_N_PC_WM 0 // uint8_t
//Sec. 7.3.4: Rate Matching // Sec. 7.3.4: Rate Matching
#define NR_POLAR_DCI_I_BIL 0 //uint8_t #define NR_POLAR_DCI_I_BIL 0 // uint8_t
#endif #endif
@@ -39,17 +39,17 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "assertions.h" #include "assertions.h"
//#define POLAR_CODING_DEBUG // #define POLAR_CODING_DEBUG
static inline void updateCrcChecksum2(int xlen, static inline void updateCrcChecksum2(int xlen,
int ylen, int ylen,
uint8_t crcChecksum[xlen][ylen], uint8_t crcChecksum[xlen][ylen],
int gxlen, int gxlen,
int gylen, int gylen,
uint8_t crcGen[gxlen][gylen], uint8_t crcGen[gxlen][gylen],
uint8_t listSize, uint8_t listSize,
uint32_t i2, uint32_t i2,
uint8_t len) uint8_t len)
{ {
for (uint i = 0; i < listSize; i++) { for (uint i = 0; i < listSize; i++) {
for (uint j = 0; j < len; j++) { for (uint j = 0; j < len; j++) {
@@ -63,67 +63,71 @@ int8_t polar_decoder(double *input,
uint8_t listSize, uint8_t listSize,
int8_t messageType, int8_t messageType,
uint16_t messageLength, uint16_t messageLength,
uint8_t aggregation_level uint8_t aggregation_level)
)
{ {
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level); t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
//Assumes no a priori knowledge. // Assumes no a priori knowledge.
uint8_t bit[polarParams->N][polarParams->n + 1][2 * listSize]; uint8_t bit[polarParams->N][polarParams->n + 1][2 * listSize];
memset(bit, 0, sizeof bit); memset(bit, 0, sizeof bit);
uint8_t bitUpdated[polarParams->N][polarParams->n+1]; //0=False, 1=True uint8_t bitUpdated[polarParams->N][polarParams->n + 1]; // 0=False, 1=True
memset(bitUpdated,0,sizeof bitUpdated); memset(bitUpdated, 0, sizeof bitUpdated);
uint8_t llrUpdated[polarParams->N][polarParams->n+1]; //0=False, 1=True uint8_t llrUpdated[polarParams->N][polarParams->n + 1]; // 0=False, 1=True
memset(llrUpdated,0,sizeof llrUpdated); memset(llrUpdated, 0, sizeof llrUpdated);
double llr[polarParams->N][polarParams->n + 1][2 * listSize]; double llr[polarParams->N][polarParams->n + 1][2 * listSize];
uint8_t crcChecksum[polarParams->crcParityBits][2*listSize]; uint8_t crcChecksum[polarParams->crcParityBits][2 * listSize];
memset(crcChecksum,0,sizeof crcChecksum); memset(crcChecksum, 0, sizeof crcChecksum);
double pathMetric[2*listSize]; double pathMetric[2 * listSize];
uint8_t crcState[2*listSize]; //0=False, 1=True uint8_t crcState[2 * listSize]; // 0=False, 1=True
for (int i=0; i<(2*listSize); i++) { for (int i = 0; i < (2 * listSize); i++) {
pathMetric[i] = 0; pathMetric[i] = 0;
crcState[i]=1; crcState[i] = 1;
} }
for (int i=0; i<polarParams->N; i++) { for (int i = 0; i < polarParams->N; i++) {
llrUpdated[i][polarParams->n]=1; llrUpdated[i][polarParams->n] = 1;
bitUpdated[i][0] = (polarParams->information_bit_pattern[i] + 1) % 2; bitUpdated[i][0] = (polarParams->information_bit_pattern[i] + 1) % 2;
} }
uint8_t extended_crc_generator_matrix[polarParams->K][polarParams->crcParityBits]; //G_P3 uint8_t extended_crc_generator_matrix[polarParams->K][polarParams->crcParityBits]; // G_P3
uint8_t tempECGM[polarParams->K][polarParams->crcParityBits]; //G_P2 uint8_t tempECGM[polarParams->K][polarParams->crcParityBits]; // G_P2
for (int i=0; i<polarParams->payloadBits; i++) { for (int i = 0; i < polarParams->payloadBits; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) { for (int j = 0; j < polarParams->crcParityBits; j++) {
tempECGM[i][j]=polarParams->crc_generator_matrix[i][j]; tempECGM[i][j] = polarParams->crc_generator_matrix[i][j];
} }
} }
for (int i=polarParams->payloadBits; i<polarParams->K; i++) { for (int i = polarParams->payloadBits; i < polarParams->K; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) { for (int j = 0; j < polarParams->crcParityBits; j++) {
tempECGM[i][j] = (i - polarParams->payloadBits) == j; tempECGM[i][j] = (i - polarParams->payloadBits) == j;
} }
} }
for (int i=0; i<polarParams->K; i++) { for (int i = 0; i < polarParams->K; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) { for (int j = 0; j < polarParams->crcParityBits; j++) {
extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j]; extended_crc_generator_matrix[i][j] = tempECGM[polarParams->interleaving_pattern[i]][j];
} }
} }
//The index of the last 1-valued bit that appears in each column. // The index of the last 1-valued bit that appears in each column.
AssertFatal(polarParams->crcParityBits > 0, "UB for VLA. crcParityBits negative\n"); AssertFatal(polarParams->crcParityBits > 0, "UB for VLA. crcParityBits negative\n");
uint16_t last1ind[polarParams->crcParityBits]; uint16_t last1ind[polarParams->crcParityBits];
for (int j=0; j<polarParams->crcParityBits; j++) { for (int j = 0; j < polarParams->crcParityBits; j++) {
for (int i=0; i<polarParams->K; i++) { for (int i = 0; i < polarParams->K; i++) {
if (extended_crc_generator_matrix[i][j] == 1) if (extended_crc_generator_matrix[i][j] == 1)
last1ind[j] = i; last1ind[j] = i;
} }
} }
double d_tilde[polarParams->N]; double d_tilde[polarParams->N];
nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); nr_polar_rate_matching(input,
d_tilde,
polarParams->rate_matching_pattern,
polarParams->K,
polarParams->N,
polarParams->encoderLength);
for (int j = 0; j < polarParams->N; j++) for (int j = 0; j < polarParams->N; j++)
llr[j][polarParams->n][0] = d_tilde[j]; llr[j][polarParams->n][0] = d_tilde[j];
@@ -131,18 +135,18 @@ int8_t polar_decoder(double *input,
/* /*
* SCL polar decoder. * SCL polar decoder.
*/ */
uint32_t nonFrozenBit=0; uint32_t nonFrozenBit = 0;
uint currentListSize = 1; uint currentListSize = 1;
uint decoderIterationCheck = 0; uint decoderIterationCheck = 0;
int checkCrcBits = -1; int checkCrcBits = -1;
uint8_t listIndex[2*listSize], copyIndex; uint8_t listIndex[2 * listSize], copyIndex;
for (uint currentBit = 0; currentBit < polarParams->N; currentBit++) { for (uint currentBit = 0; currentBit < polarParams->N; currentBit++) {
updateLLR(currentListSize, currentBit, 0, polarParams->N, polarParams->n + 1, 2 * listSize, llr, llrUpdated, bit, bitUpdated); updateLLR(currentListSize, currentBit, 0, polarParams->N, polarParams->n + 1, 2 * listSize, llr, llrUpdated, bit, bitUpdated);
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. if (polarParams->information_bit_pattern[currentBit] == 0) { // Frozen bit.
updatePathMetric(pathMetric, currentListSize, 0, currentBit, polarParams->N, polarParams->n + 1, 2 * listSize, llr); updatePathMetric(pathMetric, currentListSize, 0, currentBit, polarParams->N, polarParams->n + 1, 2 * listSize, llr);
} else { //Information or CRC bit. } else { // Information or CRC bit.
updatePathMetric2(pathMetric, currentListSize, currentBit, polarParams->N, polarParams->n + 1, 2 * listSize, llr); updatePathMetric2(pathMetric, currentListSize, currentBit, polarParams->N, polarParams->n + 1, 2 * listSize, llr);
for (int i = 0; i < currentListSize; i++) { for (int i = 0; i < currentListSize; i++) {
@@ -198,30 +202,30 @@ int8_t polar_decoder(double *input,
break; break;
} }
//First, backup the best "listSize" number of entries. // First, backup the best "listSize" number of entries.
for (int k=(listSize-1); k>0; k--) { for (int k = (listSize - 1); k > 0; k--) {
for (int i=0; i<polarParams->N; i++) { for (int i = 0; i < polarParams->N; i++) {
for (int j=0; j<(polarParams->n+1); j++) { for (int j = 0; j < (polarParams->n + 1); j++) {
bit[i][j][listIndex[(2 * listSize - 1) - k]] = bit[i][j][listIndex[k]]; bit[i][j][listIndex[(2 * listSize - 1) - k]] = bit[i][j][listIndex[k]];
llr[i][j][listIndex[(2 * listSize - 1) - k]] = llr[i][j][listIndex[k]]; llr[i][j][listIndex[(2 * listSize - 1) - k]] = llr[i][j][listIndex[k]];
} }
} }
} }
for (int k=(listSize-1); k>0; k--) { for (int k = (listSize - 1); k > 0; k--) {
for (int i = 0; i < polarParams->crcParityBits; i++) { for (int i = 0; i < polarParams->crcParityBits; i++) {
crcChecksum[i][listIndex[(2*listSize-1)-k]] = crcChecksum[i][listIndex[k]]; crcChecksum[i][listIndex[(2 * listSize - 1) - k]] = crcChecksum[i][listIndex[k]];
} }
} }
for (int k = (listSize - 1); k > 0; k--) for (int k = (listSize - 1); k > 0; k--)
crcState[listIndex[(2 * listSize - 1) - k]] = crcState[listIndex[k]]; crcState[listIndex[(2 * listSize - 1) - k]] = crcState[listIndex[k]];
//Copy the best "listSize" number of entries to the first indices. // Copy the best "listSize" number of entries to the first indices.
for (int k = 0; k < listSize; k++) { for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) { if (k > listIndex[k]) {
copyIndex = listIndex[(2*listSize-1)-k]; copyIndex = listIndex[(2 * listSize - 1) - k];
} else { //Use the backup. } else { // Use the backup.
copyIndex = listIndex[k]; copyIndex = listIndex[k];
} }
@@ -235,40 +239,40 @@ int8_t polar_decoder(double *input,
for (int k = 0; k < listSize; k++) { for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) { if (k > listIndex[k]) {
copyIndex = listIndex[(2*listSize-1)-k]; copyIndex = listIndex[(2 * listSize - 1) - k];
} else { //Use the backup. } else { // Use the backup.
copyIndex = listIndex[k]; copyIndex = listIndex[k];
} }
for (int i = 0; i < polarParams->crcParityBits; i++) { for (int i = 0; i < polarParams->crcParityBits; i++) {
crcChecksum[i][k]=crcChecksum[i][copyIndex]; crcChecksum[i][k] = crcChecksum[i][copyIndex];
} }
} }
for (int k = 0; k < listSize; k++) { for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) { if (k > listIndex[k]) {
copyIndex = listIndex[(2*listSize-1)-k]; copyIndex = listIndex[(2 * listSize - 1) - k];
} else { //Use the backup. } else { // Use the backup.
copyIndex = listIndex[k]; copyIndex = listIndex[k];
} }
crcState[k]=crcState[copyIndex]; crcState[k] = crcState[copyIndex];
} }
currentListSize = listSize; currentListSize = listSize;
} }
for (int i=0; i<polarParams->crcParityBits; i++) { for (int i = 0; i < polarParams->crcParityBits; i++) {
if (last1ind[i]==nonFrozenBit) { if (last1ind[i] == nonFrozenBit) {
checkCrcBits=i; checkCrcBits = i;
break; break;
} }
} }
if ( checkCrcBits > (-1) ) { if (checkCrcBits > (-1)) {
for (uint i = 0; i < currentListSize; i++) { for (uint i = 0; i < currentListSize; i++) {
if (crcChecksum[checkCrcBits][i]==1) { if (crcChecksum[checkCrcBits][i] == 1) {
crcState[i]=0; //0=False, 1=True crcState[i] = 0; // 0=False, 1=True
} }
} }
} }
@@ -276,15 +280,15 @@ int8_t polar_decoder(double *input,
for (uint i = 0; i < currentListSize; i++) for (uint i = 0; i < currentListSize; i++)
decoderIterationCheck += crcState[i]; decoderIterationCheck += crcState[i];
if (decoderIterationCheck==0) { if (decoderIterationCheck == 0) {
//perror("[SCL polar decoder] All list entries have failed the CRC checks."); // perror("[SCL polar decoder] All list entries have failed the CRC checks.");
polarReturn(polarParams); polarReturn(polarParams);
return -1; return -1;
} }
nonFrozenBit++; nonFrozenBit++;
decoderIterationCheck=0; decoderIterationCheck = 0;
checkCrcBits=-1; checkCrcBits = -1;
} }
} }
@@ -294,19 +298,19 @@ int8_t polar_decoder(double *input,
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize); nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
uint8_t nr_polar_A[polarParams->payloadBits]; uint8_t nr_polar_A[polarParams->payloadBits];
for (uint i = 0; i < fmin(listSize, (pow(2, polarParams->crcCorrectionBits))); i++) { for (uint i = 0; i < fmin(listSize, (pow(2, polarParams->crcCorrectionBits))); i++) {
if ( crcState[listIndex[i]] == 1 ) { if (crcState[listIndex[i]] == 1) {
uint8_t nr_polar_U[polarParams->N]; uint8_t nr_polar_U[polarParams->N];
for (int j = 0; j < polarParams->N; j++) for (int j = 0; j < polarParams->N; j++)
nr_polar_U[j] = bit[j][0][listIndex[i]]; nr_polar_U[j] = bit[j][0][listIndex[i]];
//Extract the information bits (û to ĉ) // Extract the information bits (û to ĉ)
uint8_t nr_polar_CPrime[polarParams->N]; uint8_t nr_polar_CPrime[polarParams->N];
nr_polar_info_bit_extraction(nr_polar_U, nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N); nr_polar_info_bit_extraction(nr_polar_U, nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N);
//Deinterleaving (ĉ to b) // Deinterleaving (ĉ to b)
uint8_t nr_polar_B[polarParams->K]; uint8_t nr_polar_B[polarParams->K];
nr_polar_deinterleaver(nr_polar_CPrime, nr_polar_B, polarParams->interleaving_pattern, polarParams->K); nr_polar_deinterleaver(nr_polar_CPrime, nr_polar_B, polarParams->interleaving_pattern, polarParams->K);
//Remove the CRC (â) // Remove the CRC (â)
memcpy(nr_polar_A, nr_polar_B, polarParams->payloadBits); memcpy(nr_polar_A, nr_polar_B, polarParams->payloadBits);
break; break;
@@ -328,123 +332,137 @@ int8_t polar_decoder_dci(double *input,
uint16_t n_RNTI, uint16_t n_RNTI,
int8_t messageType, int8_t messageType,
uint16_t messageLength, uint16_t messageLength,
uint8_t aggregation_level ) { uint8_t aggregation_level)
{
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level); t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
uint8_t bit[polarParams->N][polarParams->n+1][2*listSize]; uint8_t bit[polarParams->N][polarParams->n + 1][2 * listSize];
memset(bit,0,sizeof bit); memset(bit, 0, sizeof bit);
uint8_t bitUpdated[polarParams->N][polarParams->n+1]; //0=False, 1=True uint8_t bitUpdated[polarParams->N][polarParams->n + 1]; // 0=False, 1=True
memset(bitUpdated,0,sizeof bitUpdated); memset(bitUpdated, 0, sizeof bitUpdated);
uint8_t llrUpdated[polarParams->N][polarParams->n+1]; //0=False, 1=True uint8_t llrUpdated[polarParams->N][polarParams->n + 1]; // 0=False, 1=True
memset(llrUpdated,0,sizeof llrUpdated); memset(llrUpdated, 0, sizeof llrUpdated);
double llr[polarParams->N][polarParams->n+1][2*listSize]; double llr[polarParams->N][polarParams->n + 1][2 * listSize];
uint8_t crcChecksum[polarParams->crcParityBits][2*listSize]; uint8_t crcChecksum[polarParams->crcParityBits][2 * listSize];
memset(crcChecksum,0,sizeof crcChecksum); memset(crcChecksum, 0, sizeof crcChecksum);
double pathMetric[2*listSize]; double pathMetric[2 * listSize];
uint8_t crcState[2*listSize]; //0=False, 1=True uint8_t crcState[2 * listSize]; // 0=False, 1=True
uint8_t extended_crc_scrambling_pattern[polarParams->crcParityBits]; uint8_t extended_crc_scrambling_pattern[polarParams->crcParityBits];
for (int i=0; i<(2*listSize); i++) { for (int i = 0; i < (2 * listSize); i++) {
pathMetric[i] = 0; pathMetric[i] = 0;
crcState[i]=1; crcState[i] = 1;
} }
for (int i=0; i<polarParams->N; i++) { for (int i = 0; i < polarParams->N; i++) {
llrUpdated[i][polarParams->n]=1; llrUpdated[i][polarParams->n] = 1;
bitUpdated[i][0] = (polarParams->information_bit_pattern[i] + 1) % 2; bitUpdated[i][0] = (polarParams->information_bit_pattern[i] + 1) % 2;
} }
uint8_t extended_crc_generator_matrix[polarParams->K][polarParams->crcParityBits]; //G_P3: K-by-P uint8_t extended_crc_generator_matrix[polarParams->K][polarParams->crcParityBits]; // G_P3: K-by-P
uint8_t tempECGM[polarParams->K][polarParams->crcParityBits]; //G_P2: K-by-P uint8_t tempECGM[polarParams->K][polarParams->crcParityBits]; // G_P2: K-by-P
for (int i=0; i<polarParams->payloadBits; i++) { for (int i = 0; i < polarParams->payloadBits; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) { for (int j = 0; j < polarParams->crcParityBits; j++) {
tempECGM[i][j]=polarParams->crc_generator_matrix[i+polarParams->crcParityBits][j]; tempECGM[i][j] = polarParams->crc_generator_matrix[i + polarParams->crcParityBits][j];
} }
} }
for (int i=polarParams->payloadBits; i<polarParams->K; i++) { for (int i = polarParams->payloadBits; i < polarParams->K; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) { for (int j = 0; j < polarParams->crcParityBits; j++) {
tempECGM[i][j] = (i - polarParams->payloadBits) == j; tempECGM[i][j] = (i - polarParams->payloadBits) == j;
} }
} }
for (int i=0; i<polarParams->K; i++) { for (int i = 0; i < polarParams->K; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) { for (int j = 0; j < polarParams->crcParityBits; j++) {
extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j]; extended_crc_generator_matrix[i][j] = tempECGM[polarParams->interleaving_pattern[i]][j];
} }
} }
//The index of the last 1-valued bit that appears in each column. // The index of the last 1-valued bit that appears in each column.
uint16_t last1ind[polarParams->crcParityBits]; uint16_t last1ind[polarParams->crcParityBits];
for (int j=0; j<polarParams->crcParityBits; j++) { for (int j = 0; j < polarParams->crcParityBits; j++) {
for (int i=0; i<polarParams->K; i++) { for (int i = 0; i < polarParams->K; i++) {
if (extended_crc_generator_matrix[i][j]==1) last1ind[j]=i; if (extended_crc_generator_matrix[i][j] == 1)
last1ind[j] = i;
} }
} }
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
extended_crc_scrambling_pattern[i] = 0; extended_crc_scrambling_pattern[i] = 0;
for (int i=8; i<polarParams->crcParityBits; i++) { for (int i = 8; i < polarParams->crcParityBits; i++) {
extended_crc_scrambling_pattern[i]=(n_RNTI>>(23-i))&1; extended_crc_scrambling_pattern[i] = (n_RNTI >> (23 - i)) & 1;
} }
double d_tilde[polarParams->N]; double d_tilde[polarParams->N];
nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); nr_polar_rate_matching(input,
d_tilde,
polarParams->rate_matching_pattern,
polarParams->K,
polarParams->N,
polarParams->encoderLength);
for (int j = 0; j < polarParams->N; j++) for (int j = 0; j < polarParams->N; j++)
llr[j][polarParams->n][0]=d_tilde[j]; llr[j][polarParams->n][0] = d_tilde[j];
/* /*
* SCL polar decoder. * SCL polar decoder.
*/ */
for (int i=0; i<polarParams->crcParityBits; i++) { for (int i = 0; i < polarParams->crcParityBits; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) for (int j = 0; j < polarParams->crcParityBits; j++)
crcChecksum[i][0]=crcChecksum[i][0]+polarParams->crc_generator_matrix[j][i]; crcChecksum[i][0] = crcChecksum[i][0] + polarParams->crc_generator_matrix[j][i];
crcChecksum[i][0]=(crcChecksum[i][0]%2); crcChecksum[i][0] = (crcChecksum[i][0] % 2);
} }
uint32_t nonFrozenBit=0; uint32_t nonFrozenBit = 0;
uint currentListSize = 1; uint currentListSize = 1;
uint decoderIterationCheck = 0; uint decoderIterationCheck = 0;
int checkCrcBits = -1; int checkCrcBits = -1;
uint8_t listIndex[2*listSize], copyIndex; uint8_t listIndex[2 * listSize], copyIndex;
for (uint currentBit = 0; currentBit < polarParams->N; currentBit++) { for (uint currentBit = 0; currentBit < polarParams->N; currentBit++) {
updateLLR(currentListSize, currentBit, 0, polarParams->N, polarParams->n+1, 2*listSize, llr, llrUpdated, bit, bitUpdated); updateLLR(currentListSize, currentBit, 0, polarParams->N, polarParams->n + 1, 2 * listSize, llr, llrUpdated, bit, bitUpdated);
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. if (polarParams->information_bit_pattern[currentBit] == 0) { // Frozen bit.
updatePathMetric(pathMetric, currentListSize, 0, currentBit,polarParams->N, polarParams->n+1, 2*listSize, llr); updatePathMetric(pathMetric, currentListSize, 0, currentBit, polarParams->N, polarParams->n + 1, 2 * listSize, llr);
} else { //Information or CRC bit. } else { // Information or CRC bit.
updatePathMetric2(pathMetric, currentListSize, currentBit, polarParams->N, polarParams->n+1, 2*listSize, llr); updatePathMetric2(pathMetric, currentListSize, currentBit, polarParams->N, polarParams->n + 1, 2 * listSize, llr);
for (int i = 0; i < currentListSize; i++) { for (int i = 0; i < currentListSize; i++) {
for (int j = 0; j < polarParams->N; j++) { for (int j = 0; j < polarParams->N; j++) {
for (int k = 0; k < (polarParams->n+1); k++) { for (int k = 0; k < (polarParams->n + 1); k++) {
bit[j][k][i+currentListSize]=bit[j][k][i]; bit[j][k][i + currentListSize] = bit[j][k][i];
llr[j][k][i+currentListSize]=llr[j][k][i]; llr[j][k][i + currentListSize] = llr[j][k][i];
} }
} }
} }
for (int i = 0; i < currentListSize; i++) { for (int i = 0; i < currentListSize; i++) {
bit[currentBit][0][i]=0; bit[currentBit][0][i] = 0;
crcState[i+currentListSize]=crcState[i]; crcState[i + currentListSize] = crcState[i];
} }
for (int i = currentListSize; i < 2*currentListSize; i++) bit[currentBit][0][i]=1; for (int i = currentListSize; i < 2 * currentListSize; i++)
bit[currentBit][0][i] = 1;
bitUpdated[currentBit][0]=1; bitUpdated[currentBit][0] = 1;
updateCrcChecksum2(polarParams->crcParityBits, 2*listSize, crcChecksum, updateCrcChecksum2(polarParams->crcParityBits,
polarParams->K, polarParams->crcParityBits, extended_crc_generator_matrix, 2 * listSize,
currentListSize, nonFrozenBit, polarParams->crcParityBits); crcChecksum,
currentListSize*=2; polarParams->K,
polarParams->crcParityBits,
extended_crc_generator_matrix,
currentListSize,
nonFrozenBit,
polarParams->crcParityBits);
currentListSize *= 2;
//Keep only the best "listSize" number of entries. // Keep only the best "listSize" number of entries.
if (currentListSize > listSize) { if (currentListSize > listSize) {
for (uint i = 0; i < 2 * listSize; i++) for (uint i = 0; i < 2 * listSize; i++)
listIndex[i] = i; listIndex[i] = i;
@@ -456,7 +474,7 @@ int8_t polar_decoder_dci(double *input,
int swaps = 0; int swaps = 0;
for (uint j = listSize; j < (2 * listSize - i) - 1; j++) { for (uint j = listSize; j < (2 * listSize - i) - 1; j++) {
if (listIndex[j+1] > listIndex[j]) { if (listIndex[j + 1] > listIndex[j]) {
int tempInd = listIndex[j]; int tempInd = listIndex[j];
listIndex[j] = listIndex[j + 1]; listIndex[j] = listIndex[j + 1];
listIndex[j + 1] = tempInd; listIndex[j + 1] = tempInd;
@@ -468,30 +486,30 @@ int8_t polar_decoder_dci(double *input,
break; break;
} }
//First, backup the best "listSize" number of entries. // First, backup the best "listSize" number of entries.
for (int k=(listSize-1); k>0; k--) { for (int k = (listSize - 1); k > 0; k--) {
for (int i=0; i<polarParams->N; i++) { for (int i = 0; i < polarParams->N; i++) {
for (int j=0; j<(polarParams->n+1); j++) { for (int j = 0; j < (polarParams->n + 1); j++) {
bit[i][j][listIndex[(2*listSize-1)-k]]=bit[i][j][listIndex[k]]; bit[i][j][listIndex[(2 * listSize - 1) - k]] = bit[i][j][listIndex[k]];
llr[i][j][listIndex[(2*listSize-1)-k]]=llr[i][j][listIndex[k]]; llr[i][j][listIndex[(2 * listSize - 1) - k]] = llr[i][j][listIndex[k]];
} }
} }
} }
for (int k=(listSize-1); k>0; k--) { for (int k = (listSize - 1); k > 0; k--) {
for (int i = 0; i < polarParams->crcParityBits; i++) { for (int i = 0; i < polarParams->crcParityBits; i++) {
crcChecksum[i][listIndex[(2*listSize-1)-k]] = crcChecksum[i][listIndex[k]]; crcChecksum[i][listIndex[(2 * listSize - 1) - k]] = crcChecksum[i][listIndex[k]];
} }
} }
for (int k = (listSize - 1); k > 0; k--) for (int k = (listSize - 1); k > 0; k--)
crcState[listIndex[(2 * listSize - 1) - k]] = crcState[listIndex[k]]; crcState[listIndex[(2 * listSize - 1) - k]] = crcState[listIndex[k]];
//Copy the best "listSize" number of entries to the first indices. // Copy the best "listSize" number of entries to the first indices.
for (int k = 0; k < listSize; k++) { for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) { if (k > listIndex[k]) {
copyIndex = listIndex[(2*listSize-1)-k]; copyIndex = listIndex[(2 * listSize - 1) - k];
} else { //Use the backup. } else { // Use the backup.
copyIndex = listIndex[k]; copyIndex = listIndex[k];
} }
@@ -505,40 +523,40 @@ int8_t polar_decoder_dci(double *input,
for (int k = 0; k < listSize; k++) { for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) { if (k > listIndex[k]) {
copyIndex = listIndex[(2*listSize-1)-k]; copyIndex = listIndex[(2 * listSize - 1) - k];
} else { //Use the backup. } else { // Use the backup.
copyIndex = listIndex[k]; copyIndex = listIndex[k];
} }
for (int i = 0; i < polarParams->crcParityBits; i++) { for (int i = 0; i < polarParams->crcParityBits; i++) {
crcChecksum[i][k]=crcChecksum[i][copyIndex]; crcChecksum[i][k] = crcChecksum[i][copyIndex];
} }
} }
for (int k = 0; k < listSize; k++) { for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) { if (k > listIndex[k]) {
copyIndex = listIndex[(2*listSize-1)-k]; copyIndex = listIndex[(2 * listSize - 1) - k];
} else { //Use the backup. } else { // Use the backup.
copyIndex = listIndex[k]; copyIndex = listIndex[k];
} }
crcState[k]=crcState[copyIndex]; crcState[k] = crcState[copyIndex];
} }
currentListSize = listSize; currentListSize = listSize;
} }
for (int i=0; i<polarParams->crcParityBits; i++) { for (int i = 0; i < polarParams->crcParityBits; i++) {
if (last1ind[i]==nonFrozenBit) { if (last1ind[i] == nonFrozenBit) {
checkCrcBits=i; checkCrcBits = i;
break; break;
} }
} }
if ( checkCrcBits > (-1) ) { if (checkCrcBits > (-1)) {
for (uint i = 0; i < currentListSize; i++) { for (uint i = 0; i < currentListSize; i++) {
if (crcChecksum[checkCrcBits][i]!=extended_crc_scrambling_pattern[checkCrcBits]) { if (crcChecksum[checkCrcBits][i] != extended_crc_scrambling_pattern[checkCrcBits]) {
crcState[i]=0; //0=False, 1=True crcState[i] = 0; // 0=False, 1=True
} }
} }
} }
@@ -546,15 +564,15 @@ int8_t polar_decoder_dci(double *input,
for (uint i = 0; i < currentListSize; i++) for (uint i = 0; i < currentListSize; i++)
decoderIterationCheck += crcState[i]; decoderIterationCheck += crcState[i];
if (decoderIterationCheck==0) { if (decoderIterationCheck == 0) {
//perror("[SCL polar decoder] All list entries have failed the CRC checks."); // perror("[SCL polar decoder] All list entries have failed the CRC checks.");
polarReturn(polarParams); polarReturn(polarParams);
return -1; return -1;
} }
nonFrozenBit++; nonFrozenBit++;
decoderIterationCheck=0; decoderIterationCheck = 0;
checkCrcBits=-1; checkCrcBits = -1;
} }
} }
@@ -565,19 +583,19 @@ int8_t polar_decoder_dci(double *input,
uint8_t nr_polar_A[polarParams->payloadBits]; uint8_t nr_polar_A[polarParams->payloadBits];
for (uint i = 0; i < fmin(listSize, (pow(2, polarParams->crcCorrectionBits))); i++) { for (uint i = 0; i < fmin(listSize, (pow(2, polarParams->crcCorrectionBits))); i++) {
if ( crcState[listIndex[i]] == 1 ) { if (crcState[listIndex[i]] == 1) {
uint8_t nr_polar_U[polarParams->N]; uint8_t nr_polar_U[polarParams->N];
for (int j = 0; j < polarParams->N; j++) for (int j = 0; j < polarParams->N; j++)
nr_polar_U[j] = bit[j][0][listIndex[i]]; nr_polar_U[j] = bit[j][0][listIndex[i]];
//Extract the information bits (û to ĉ) // Extract the information bits (û to ĉ)
uint8_t nr_polar_CPrime[polarParams->N]; uint8_t nr_polar_CPrime[polarParams->N];
nr_polar_info_bit_extraction(nr_polar_U, nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N); nr_polar_info_bit_extraction(nr_polar_U, nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N);
//Deinterleaving (ĉ to b) // Deinterleaving (ĉ to b)
uint8_t nr_polar_B[polarParams->K]; uint8_t nr_polar_B[polarParams->K];
nr_polar_deinterleaver(nr_polar_CPrime, nr_polar_B, polarParams->interleaving_pattern, polarParams->K); nr_polar_deinterleaver(nr_polar_CPrime, nr_polar_B, polarParams->interleaving_pattern, polarParams->K);
//Remove the CRC (â) // Remove the CRC (â)
memcpy(nr_polar_A, nr_polar_B, polarParams->payloadBits); memcpy(nr_polar_A, nr_polar_B, polarParams->payloadBits);
break; break;
} }
@@ -740,55 +758,61 @@ uint32_t polar_decoder_int16(int16_t *input,
printf("\n"); printf("\n");
#endif #endif
int len=polarParams->payloadBits; int len = polarParams->payloadBits;
//int len_mod64=len&63; // int len_mod64=len&63;
int crclen = polarParams->crcParityBits; int crclen = polarParams->crcParityBits;
uint64_t rxcrc=B[0]&((1<<crclen)-1); uint64_t rxcrc = B[0] & ((1 << crclen) - 1);
uint32_t crc = 0; uint32_t crc = 0;
uint64_t Ar = 0; uint64_t Ar = 0;
AssertFatal(len<65,"A must be less than 65 bits\n"); AssertFatal(len < 65, "A must be less than 65 bits\n");
// appending 24 ones before a0 for DCI as stated in 38.212 7.3.2 // appending 24 ones before a0 for DCI as stated in 38.212 7.3.2
uint8_t offset = 0; uint8_t offset = 0;
if (ones_flag) if (ones_flag)
offset = 3; offset = 3;
if (len<=32) { if (len <= 32) {
Ar = (uint32_t)(B[0]>>crclen); Ar = (uint32_t)(B[0] >> crclen);
uint8_t A32_flip[4+offset]; uint8_t A32_flip[4 + offset];
if (ones_flag) { if (ones_flag) {
A32_flip[0] = 0xff; A32_flip[0] = 0xff;
A32_flip[1] = 0xff; A32_flip[1] = 0xff;
A32_flip[2] = 0xff; A32_flip[2] = 0xff;
} }
uint32_t Aprime= (uint32_t)(Ar<<(32-len)); uint32_t Aprime = (uint32_t)(Ar << (32 - len));
A32_flip[0+offset]=((uint8_t *)&Aprime)[3]; A32_flip[0 + offset] = ((uint8_t *)&Aprime)[3];
A32_flip[1+offset]=((uint8_t *)&Aprime)[2]; A32_flip[1 + offset] = ((uint8_t *)&Aprime)[2];
A32_flip[2+offset]=((uint8_t *)&Aprime)[1]; A32_flip[2 + offset] = ((uint8_t *)&Aprime)[1];
A32_flip[3+offset]=((uint8_t *)&Aprime)[0]; A32_flip[3 + offset] = ((uint8_t *)&Aprime)[0];
if (crclen == 24) crc = (uint64_t)((crc24c(A32_flip,8*offset+len)>>8)&0xffffff); if (crclen == 24)
else if (crclen == 11) crc = (uint64_t)((crc11(A32_flip,8*offset+len)>>21)&0x7ff); crc = (uint64_t)((crc24c(A32_flip, 8 * offset + len) >> 8) & 0xffffff);
else if (crclen == 6) crc = (uint64_t)((crc6(A32_flip,8*offset+len)>>26)&0x3f); else if (crclen == 11)
} else if (len<=64) { crc = (uint64_t)((crc11(A32_flip, 8 * offset + len) >> 21) & 0x7ff);
else if (crclen == 6)
crc = (uint64_t)((crc6(A32_flip, 8 * offset + len) >> 26) & 0x3f);
} else if (len <= 64) {
Ar = (B[0] >> crclen) | (B[1] << (64 - crclen)); Ar = (B[0] >> crclen) | (B[1] << (64 - crclen));
uint8_t A64_flip[8+offset]; uint8_t A64_flip[8 + offset];
if (ones_flag) { if (ones_flag) {
A64_flip[0] = 0xff; A64_flip[0] = 0xff;
A64_flip[1] = 0xff; A64_flip[1] = 0xff;
A64_flip[2] = 0xff; A64_flip[2] = 0xff;
} }
uint64_t Aprime= (uint64_t)(Ar<<(64-len)); uint64_t Aprime = (uint64_t)(Ar << (64 - len));
A64_flip[0+offset]=((uint8_t *)&Aprime)[7]; A64_flip[0 + offset] = ((uint8_t *)&Aprime)[7];
A64_flip[1+offset]=((uint8_t *)&Aprime)[6]; A64_flip[1 + offset] = ((uint8_t *)&Aprime)[6];
A64_flip[2+offset]=((uint8_t *)&Aprime)[5]; A64_flip[2 + offset] = ((uint8_t *)&Aprime)[5];
A64_flip[3+offset]=((uint8_t *)&Aprime)[4]; A64_flip[3 + offset] = ((uint8_t *)&Aprime)[4];
A64_flip[4+offset]=((uint8_t *)&Aprime)[3]; A64_flip[4 + offset] = ((uint8_t *)&Aprime)[3];
A64_flip[5+offset]=((uint8_t *)&Aprime)[2]; A64_flip[5 + offset] = ((uint8_t *)&Aprime)[2];
A64_flip[6+offset]=((uint8_t *)&Aprime)[1]; A64_flip[6 + offset] = ((uint8_t *)&Aprime)[1];
A64_flip[7+offset]=((uint8_t *)&Aprime)[0]; A64_flip[7 + offset] = ((uint8_t *)&Aprime)[0];
if (crclen==24) crc = (uint64_t)(crc24c(A64_flip,8*offset+len)>>8)&0xffffff; if (crclen == 24)
else if (crclen==11) crc = (uint64_t)(crc11(A64_flip,8*offset+len)>>21)&0x7ff; crc = (uint64_t)(crc24c(A64_flip, 8 * offset + len) >> 8) & 0xffffff;
else if (crclen==6) crc = (uint64_t)(crc6(A64_flip,8*offset+len)>>26)&0x3f; else if (crclen == 11)
crc = (uint64_t)(crc11(A64_flip, 8 * offset + len) >> 21) & 0x7ff;
else if (crclen == 6)
crc = (uint64_t)(crc6(A64_flip, 8 * offset + len) >> 26) & 0x3f;
} }
#ifdef POLAR_CODING_DEBUG #ifdef POLAR_CODING_DEBUG
@@ -815,7 +839,7 @@ uint32_t polar_decoder_int16(int16_t *input,
Cprime[0], Cprime[0],
crc, crc,
rxcrc, rxcrc,
crc^rxcrc, crc ^ rxcrc,
polarParams->payloadBits); polarParams->payloadBits);
#endif #endif
@@ -28,22 +28,22 @@
* \email turker.yilmaz@eurecom.fr * \email turker.yilmaz@eurecom.fr
* \note * \note
* \warning * \warning
*/ */
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "PHY/sse_intrin.h" #include "PHY/sse_intrin.h"
#include "PHY/impl_defs_top.h" #include "PHY/impl_defs_top.h"
//#define DEBUG_NEW_IMPL 1 // #define DEBUG_NEW_IMPL 1
static inline void updateBit(uint8_t listSize, static inline void updateBit(uint8_t listSize,
uint16_t row, uint16_t row,
uint16_t col, uint16_t col,
uint16_t xlen, uint16_t xlen,
uint8_t ylen, uint8_t ylen,
int zlen, int zlen,
uint8_t bit[xlen][ylen][zlen], uint8_t bit[xlen][ylen][zlen],
uint8_t bitU[xlen][ylen]) uint8_t bitU[xlen][ylen])
{ {
const uint offset = (xlen / (pow(2, (ylen - col)))); const uint offset = (xlen / (pow(2, (ylen - col))));
@@ -64,18 +64,12 @@ static inline void updateBit(uint8_t listSize,
bitU[row][col] = 1; bitU[row][col] = 1;
} }
static inline void computeLLR(uint16_t row, static inline void
uint16_t col, computeLLR(uint16_t row, uint16_t col, uint8_t i, uint16_t offset, int xlen, int ylen, int zlen, double llr[xlen][ylen][zlen])
uint8_t i,
uint16_t offset,
int xlen,
int ylen,
int zlen,
double llr[xlen][ylen][zlen])
{ {
double a = llr[row][col + 1][i]; double a = llr[row][col + 1][i];
double b = llr[row + offset][col + 1][i]; double b = llr[row + offset][col + 1][i];
llr[row][col][i] = log((exp(a + b) + 1) / (exp(a) + exp(b))); //eq. (8a) llr[row][col][i] = log((exp(a + b) + 1) / (exp(a) + exp(b))); // eq. (8a)
} }
void updateLLR(uint8_t listSize, void updateLLR(uint8_t listSize,
@@ -113,14 +107,13 @@ void updateLLR(uint8_t listSize,
} }
void updatePathMetric(double *pathMetric, void updatePathMetric(double *pathMetric,
uint8_t listSize, uint8_t listSize,
uint8_t bitValue, uint8_t bitValue,
uint16_t row, uint16_t row,
int xlen, int xlen,
int ylen, int ylen,
int zlen, int zlen,
double llr[xlen][ylen][zlen] double llr[xlen][ylen][zlen])
)
{ {
const int multiplier = (2 * bitValue) - 1; const int multiplier = (2 * bitValue) - 1;
for (uint i = 0; i < listSize; i++) for (uint i = 0; i < listSize; i++)
@@ -128,12 +121,12 @@ void updatePathMetric(double *pathMetric,
} }
void updatePathMetric2(double *pathMetric, void updatePathMetric2(double *pathMetric,
uint8_t listSize, uint8_t listSize,
uint16_t row, uint16_t row,
int xlen, int xlen,
int ylen, int ylen,
int zlen, int zlen,
double llr[xlen][ylen][zlen]) double llr[xlen][ylen][zlen])
{ {
double tempPM[listSize]; double tempPM[listSize];
memcpy(tempPM, pathMetric, (sizeof(double) * listSize)); memcpy(tempPM, pathMetric, (sizeof(double) * listSize));
@@ -172,7 +165,7 @@ static inline decoder_node_t *new_decoder_node(simde__m256i **buffer,
.alpha = tree_sz, .alpha = tree_sz,
.beta = tree_sz + leaf_sz * sizeof(int16_t), .beta = tree_sz + leaf_sz * sizeof(int16_t),
.betaInit = false}; .betaInit = false};
return(node); return (node);
} }
static inline decoder_node_t *add_nodes(decoder_tree_t *tree, static inline decoder_node_t *add_nodes(decoder_tree_t *tree,
@@ -181,7 +174,7 @@ static inline decoder_node_t *add_nodes(decoder_tree_t *tree,
const uint8_t *information_bit_pattern, const uint8_t *information_bit_pattern,
simde__m256i **buffer) simde__m256i **buffer)
{ {
if (level==0) { if (level == 0) {
#ifdef DEBUG_NEW_IMPL #ifdef DEBUG_NEW_IMPL
printf("leaf %d (%s)\n", first_leaf_index, information_bit_pattern[first_leaf_index] == 1 ? "information or crc" : "frozen"); printf("leaf %d (%s)\n", first_leaf_index, information_bit_pattern[first_leaf_index] == 1 ? "information or crc" : "frozen");
#endif #endif
@@ -203,7 +196,7 @@ static inline decoder_node_t *add_nodes(decoder_tree_t *tree,
decoder_node_t *new_node = new_decoder_node(buffer, level, first_leaf_index, false, false); decoder_node_t *new_node = new_decoder_node(buffer, level, first_leaf_index, false, false);
new_node->left = add_nodes(tree, level - 1, first_leaf_index, information_bit_pattern, buffer); new_node->left = add_nodes(tree, level - 1, first_leaf_index, information_bit_pattern, buffer);
new_node->right = add_nodes(tree, level - 1, first_leaf_index + (Nv / 2), information_bit_pattern, buffer); new_node->right = add_nodes(tree, level - 1, first_leaf_index + (Nv / 2), information_bit_pattern, buffer);
return(new_node); return (new_node);
} }
void build_decoder_tree(t_nrPolar_params *pp) void build_decoder_tree(t_nrPolar_params *pp)
@@ -225,7 +218,12 @@ static inline void applyFtoleft(const t_nrPolar_params *pp, decoder_node_t *node
int8_t *betal = treeBeta(node->left); int8_t *betal = treeBeta(node->left);
#ifdef DEBUG_NEW_IMPL #ifdef DEBUG_NEW_IMPL
printf("applyFtoleft %d, Nv %d (level %d,node->left (leaf %d, AF %d))\n",node->first_leaf_index,node->Nv,node->level,node->left->leaf,node->left->all_frozen); printf("applyFtoleft %d, Nv %d (level %d,node->left (leaf %d, AF %d))\n",
node->first_leaf_index,
node->Nv,
node->level,
node->left->leaf,
node->left->all_frozen);
for (int i = 0; i < node->Nv; i++) for (int i = 0; i < node->Nv; i++)
printf("i%d (frozen %d): alpha_v[i] = %d\n", i, 1 - pp->information_bit_pattern[node->first_leaf_index + i], alpha_v[i]); printf("i%d (frozen %d): alpha_v[i] = %d\n", i, 1 - pp->information_bit_pattern[node->first_leaf_index + i], alpha_v[i]);
@@ -238,7 +236,7 @@ static inline void applyFtoleft(const t_nrPolar_params *pp, decoder_node_t *node
int avx2len = sz / 16; int avx2len = sz / 16;
// printf("avx2len %d\n",avx2len); // printf("avx2len %d\n",avx2len);
for (int i=0;i<avx2len;i++) { for (int i = 0; i < avx2len; i++) {
simde__m256i a256 = ((simde__m256i *)alpha_v)[i]; simde__m256i a256 = ((simde__m256i *)alpha_v)[i];
simde__m256i b256 = ((simde__m256i *)alpha_v)[i + avx2len]; simde__m256i b256 = ((simde__m256i *)alpha_v)[i + avx2len];
simde__m256i absa256 = simde_mm256_abs_epi16(a256); simde__m256i absa256 = simde_mm256_abs_epi16(a256);
@@ -246,22 +244,20 @@ static inline void applyFtoleft(const t_nrPolar_params *pp, decoder_node_t *node
simde__m256i minabs256 = simde_mm256_min_epi16(absa256, absb256); simde__m256i minabs256 = simde_mm256_min_epi16(absa256, absb256);
((simde__m256i *)alpha_l)[i] = simde_mm256_sign_epi16(minabs256, simde_mm256_sign_epi16(a256, b256)); ((simde__m256i *)alpha_l)[i] = simde_mm256_sign_epi16(minabs256, simde_mm256_sign_epi16(a256, b256));
} }
} } else if (avx2mod == 8) {
else if (avx2mod == 8) {
simde__m128i a128 = *((simde__m128i *)alpha_v); simde__m128i a128 = *((simde__m128i *)alpha_v);
simde__m128i b128 = ((simde__m128i *)alpha_v)[1]; simde__m128i b128 = ((simde__m128i *)alpha_v)[1];
simde__m128i absa128 = simde_mm_abs_epi16(a128); simde__m128i absa128 = simde_mm_abs_epi16(a128);
simde__m128i absb128 = simde_mm_abs_epi16(b128); simde__m128i absb128 = simde_mm_abs_epi16(b128);
simde__m128i minabs128 = simde_mm_min_epi16(absa128, absb128); simde__m128i minabs128 = simde_mm_min_epi16(absa128, absb128);
*((simde__m128i*)alpha_l) =simde_mm_sign_epi16(minabs128,simde_mm_sign_epi16(a128,b128)); *((simde__m128i *)alpha_l) = simde_mm_sign_epi16(minabs128, simde_mm_sign_epi16(a128, b128));
} } else if (avx2mod == 4) {
else if (avx2mod == 4) {
simde__m64 a64 = *((simde__m64 *)alpha_v); simde__m64 a64 = *((simde__m64 *)alpha_v);
simde__m64 b64 = ((simde__m64 *)alpha_v)[1]; simde__m64 b64 = ((simde__m64 *)alpha_v)[1];
simde__m64 absa64 = simde_mm_abs_pi16(a64); simde__m64 absa64 = simde_mm_abs_pi16(a64);
simde__m64 absb64 = simde_mm_abs_pi16(b64); simde__m64 absb64 = simde_mm_abs_pi16(b64);
simde__m64 minabs64 = simde_mm_min_pi16(absa64, absb64); simde__m64 minabs64 = simde_mm_min_pi16(absa64, absb64);
*((simde__m64*)alpha_l) =simde_mm_sign_pi16(minabs64,simde_mm_sign_pi16(a64,b64)); *((simde__m64 *)alpha_l) = simde_mm_sign_pi16(minabs64, simde_mm_sign_pi16(a64, b64));
} else { // equivalent scalar code to above, activated only on non x86/ARM architectures } else { // equivalent scalar code to above, activated only on non x86/ARM architectures
for (int i = 0; i < sz; i++) { for (int i = 0; i < sz; i++) {
int16_t a = alpha_v[i]; int16_t a = alpha_v[i];
@@ -280,11 +276,11 @@ static inline void applyFtoleft(const t_nrPolar_params *pp, decoder_node_t *node
betal[0] = tmp * 2 - 1; betal[0] = tmp * 2 - 1;
node->left->betaInit = true; node->left->betaInit = true;
#ifdef DEBUG_NEW_IMPL #ifdef DEBUG_NEW_IMPL
printf("betal[0] %d (%p)\n",betal[0],&betal[0]); printf("betal[0] %d (%p)\n", betal[0], &betal[0]);
#endif #endif
output[node->first_leaf_index] = tmp; output[node->first_leaf_index] = tmp;
#ifdef DEBUG_NEW_IMPL #ifdef DEBUG_NEW_IMPL
printf("Setting bit %d to %d (LLR %d)\n",node->first_leaf_index,(betal[0]+1)>>1,alpha_l[0]); printf("Setting bit %d to %d (LLR %d)\n", node->first_leaf_index, (betal[0] + 1) >> 1, alpha_l[0]);
#endif #endif
} }
} }
@@ -298,7 +294,12 @@ static inline void applyGtoright(const t_nrPolar_params *pp, decoder_node_t *nod
int8_t *betar = treeBeta(node->right); int8_t *betar = treeBeta(node->right);
#ifdef DEBUG_NEW_IMPL #ifdef DEBUG_NEW_IMPL
printf("applyGtoright %d, Nv %d (level %d), (leaf %d, AF %d)\n",node->first_leaf_index,node->Nv,node->level,node->right->leaf,node->right->all_frozen); printf("applyGtoright %d, Nv %d (level %d), (leaf %d, AF %d)\n",
node->first_leaf_index,
node->Nv,
node->level,
node->right->leaf,
node->right->all_frozen);
#endif #endif
assert(node->level); assert(node->level);
const int sz = 1 << (node->level - 1); const int sz = 1 << (node->level - 1);
@@ -320,7 +321,8 @@ static inline void applyGtoright(const t_nrPolar_params *pp, decoder_node_t *nod
int avx2len = sz / 16; int avx2len = sz / 16;
for (int i = 0; i < avx2len; i++) { for (int i = 0; i < avx2len; i++) {
simde__m256i tmp = simde_mm256_sign_epi16(((simde__m256i *)alpha_v)[i], simde_mm256_cvtepi8_epi16(((simde__m128i *)betal)[i])); simde__m256i tmp =
simde_mm256_sign_epi16(((simde__m256i *)alpha_v)[i], simde_mm256_cvtepi8_epi16(((simde__m128i *)betal)[i]));
((simde__m256i *)alpha_r)[i] = simde_mm256_subs_epi16(((simde__m256i *)alpha_v)[i + avx2len], tmp); ((simde__m256i *)alpha_r)[i] = simde_mm256_subs_epi16(((simde__m256i *)alpha_v)[i + avx2len], tmp);
} }
} else if (avx2mod == 8) { } else if (avx2mod == 8) {
@@ -340,7 +342,7 @@ static inline void applyGtoright(const t_nrPolar_params *pp, decoder_node_t *nod
output[node->first_leaf_index + 1] = tmp; output[node->first_leaf_index + 1] = tmp;
#ifdef DEBUG_NEW_IMPL #ifdef DEBUG_NEW_IMPL
printf("Setting bit %d to %d (LLR %d)\n",node->first_leaf_index+1,(betar[0]+1)>>1,alpha_r[0]); printf("Setting bit %d to %d (LLR %d)\n", node->first_leaf_index + 1, (betar[0] + 1) >> 1, alpha_r[0]);
#endif #endif
} }
} }
@@ -354,7 +356,10 @@ static inline void computeBeta(decoder_node_t *node)
int8_t *betal = treeBeta(node->left); int8_t *betal = treeBeta(node->left);
int8_t *betar = treeBeta(node->right); int8_t *betar = treeBeta(node->right);
#ifdef DEBUG_NEW_IMPL #ifdef DEBUG_NEW_IMPL
printf("Computing beta @ level %d first_leaf_index %d (all_frozen %d)\n",node->level,node->first_leaf_index,node->left->all_frozen); printf("Computing beta @ level %d first_leaf_index %d (all_frozen %d)\n",
node->level,
node->first_leaf_index,
node->left->all_frozen);
#endif #endif
assert(node->level); assert(node->level);
const int sz = 1 << (node->level - 1); const int sz = 1 << (node->level - 1);
@@ -370,7 +375,7 @@ static inline void computeBeta(decoder_node_t *node)
int avx2mod = sz & 31; int avx2mod = sz & 31;
if (avx2mod == 0) { if (avx2mod == 0) {
int avx2len = sz / 16; int avx2len = sz / 16;
for (int i=0;i<avx2len;i++) { for (int i = 0; i < avx2len; i++) {
((simde__m256i *)betav)[i] = ((simde__m256i *)betav)[i] =
simde_mm256_xor_si256(simde_mm256_xor_si256(((simde__m256i *)betar)[i], ((simde__m256i *)betal)[i]), simde_mm256_xor_si256(simde_mm256_xor_si256(((simde__m256i *)betar)[i], ((simde__m256i *)betal)[i]),
*(simde__m256i *)all11); *(simde__m256i *)all11);
@@ -389,7 +394,8 @@ static inline void computeBeta(decoder_node_t *node)
node->betaInit = true; node->betaInit = true;
} }
void generic_polar_decoder_recursive(t_nrPolar_params *pp, decoder_node_t *node, uint8_t *nr_polar_U) { void generic_polar_decoder_recursive(t_nrPolar_params *pp, decoder_node_t *node, uint8_t *nr_polar_U)
{
// Apply F to left // Apply F to left
applyFtoleft(pp, node, nr_polar_U); applyFtoleft(pp, node, nr_polar_U);
int iter = pp->tree_linearization.iter++; int iter = pp->tree_linearization.iter++;
@@ -397,7 +403,7 @@ void generic_polar_decoder_recursive(t_nrPolar_params *pp, decoder_node_t *node,
pp->tree_linearization.op_list[iter].node = node; pp->tree_linearization.op_list[iter].node = node;
// if left is not a leaf recurse down to the left // if left is not a leaf recurse down to the left
if (node->left->leaf==0) if (node->left->leaf == 0)
generic_polar_decoder_recursive(pp, node->left, nr_polar_U); generic_polar_decoder_recursive(pp, node->left, nr_polar_U);
applyGtoright(pp, node, nr_polar_U); applyGtoright(pp, node, nr_polar_U);
@@ -28,7 +28,7 @@
* \email raymond.knopp@eurecom.fr, turker.yilmaz@eurecom.fr * \email raymond.knopp@eurecom.fr, turker.yilmaz@eurecom.fr
* \note * \note
* \warning * \warning
*/ */
#ifndef __NR_POLAR_DEFS__H__ #ifndef __NR_POLAR_DEFS__H__
#define __NR_POLAR_DEFS__H__ #define __NR_POLAR_DEFS__H__
@@ -43,17 +43,18 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "PHY/CODING/coding_defs.h" #include "PHY/CODING/coding_defs.h"
//#include "SIMULATION/TOOLS/sim.h" // #include "SIMULATION/TOOLS/sim.h"
#define NR_POLAR_DECODER_LISTSIZE 8 //uint8_t #define NR_POLAR_DECODER_LISTSIZE 8 // uint8_t
#define NR_POLAR_AGGREGATION_LEVEL_1_PRIME 149 //uint16_t #define NR_POLAR_AGGREGATION_LEVEL_1_PRIME 149 // uint16_t
#define NR_POLAR_AGGREGATION_LEVEL_2_PRIME 151 //uint16_t #define NR_POLAR_AGGREGATION_LEVEL_2_PRIME 151 // uint16_t
#define NR_POLAR_AGGREGATION_LEVEL_4_PRIME 157 //uint16_t #define NR_POLAR_AGGREGATION_LEVEL_4_PRIME 157 // uint16_t
#define NR_POLAR_AGGREGATION_LEVEL_8_PRIME 163 //uint16_t #define NR_POLAR_AGGREGATION_LEVEL_8_PRIME 163 // uint16_t
#define NR_POLAR_AGGREGATION_LEVEL_16_PRIME 167 //uint16_t #define NR_POLAR_AGGREGATION_LEVEL_16_PRIME 167 // uint16_t
static const uint8_t nr_polar_subblock_interleaver_pattern[32] = {0,1,2,4,3,5,6,7,8,16,9,17,10,18,11,19,12,20,13,21,14,22,15,23,24,25,26,28,27,29,30,31}; static const uint8_t nr_polar_subblock_interleaver_pattern[32] = {0, 1, 2, 4, 3, 5, 6, 7, 8, 16, 9, 17, 10, 18, 11, 19,
12, 20, 13, 21, 14, 22, 15, 23, 24, 25, 26, 28, 27, 29, 30, 31};
#define Nmax 1024 #define Nmax 1024
#define nmax 10 #define nmax 10
@@ -82,7 +83,7 @@ typedef struct decoder_tree_t_s {
} decoder_tree_t; } decoder_tree_t;
typedef struct nrPolar_params { typedef struct nrPolar_params {
//messageType: 0=PBCH, 1=DCI, -1=UCI // messageType: 0=PBCH, 1=DCI, -1=UCI
struct nrPolar_params *nextPtr __attribute__((aligned(16))); struct nrPolar_params *nextPtr __attribute__((aligned(16)));
bool busy; bool busy;
@@ -123,16 +124,12 @@ typedef struct nrPolar_params {
bool is_initialized; bool is_initialized;
struct { struct {
int op_code; int op_code;
decoder_node_t* node; decoder_node_t *node;
} op_list[600]; } op_list[600];
} tree_linearization; } tree_linearization;
} t_nrPolar_params; } t_nrPolar_params;
void polar_encoder(uint32_t *input, void polar_encoder(uint32_t *input, uint32_t *output, int8_t messageType, uint16_t messageLength, uint8_t aggregation_level);
uint32_t *output,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level);
void polar_encoder_dci(uint32_t *in, void polar_encoder_dci(uint32_t *in,
uint32_t *out, uint32_t *out,
@@ -190,7 +187,7 @@ void nr_polar_print_polarParams(void);
t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, uint8_t aggregation_level); t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, uint8_t aggregation_level);
uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level); uint16_t nr_polar_aggregation_prime(uint8_t aggregation_level);
const uint8_t **nr_polar_kronecker_power_matrices(uint8_t n); const uint8_t **nr_polar_kronecker_power_matrices(uint8_t n);
@@ -201,27 +198,13 @@ const uint16_t *nr_polar_sequence_pattern(uint8_t n);
* @param K Number of bits to encode (=payloadBits+crcParityBits) * @param K Number of bits to encode (=payloadBits+crcParityBits)
* @param E * @param E
* @param n_max */ * @param n_max */
uint32_t nr_polar_output_length(uint16_t K, uint32_t nr_polar_output_length(uint16_t K, uint16_t E, uint8_t n_max);
uint16_t E,
uint8_t n_max);
void nr_polar_rate_matching_pattern(uint16_t *rmp, void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P_i_, uint16_t K, uint16_t N, uint16_t E);
uint16_t *J,
const uint8_t *P_i_,
uint16_t K,
uint16_t N,
uint16_t E);
void nr_polar_rate_matching(double *input, void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp, uint16_t K, uint16_t N, uint16_t E);
double *output,
uint16_t *rmp,
uint16_t K,
uint16_t N,
uint16_t E);
void nr_polar_interleaving_pattern(uint16_t K, void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_);
uint8_t I_IL,
uint16_t *PI_k_);
void nr_polar_info_bit_pattern(uint8_t *ibp, void nr_polar_info_bit_pattern(uint8_t *ibp,
uint8_t *pcbp, uint8_t *pcbp,
@@ -236,18 +219,11 @@ void nr_polar_info_bit_pattern(uint8_t *ibp,
const uint8_t n_PC, const uint8_t n_PC,
const uint8_t n_pc_wm); const uint8_t n_pc_wm);
void nr_polar_info_bit_extraction(uint8_t *input, void nr_polar_info_bit_extraction(uint8_t *input, uint8_t *output, uint8_t *pattern, uint16_t size);
uint8_t *output,
uint8_t *pattern,
uint16_t size);
void nr_bit2byte_uint32_8(uint32_t *in, void nr_bit2byte_uint32_8(uint32_t *in, uint16_t arraySize, uint8_t *out);
uint16_t arraySize,
uint8_t *out);
void nr_byte2bit_uint8_32(uint8_t *in, void nr_byte2bit_uint8_32(uint8_t *in, uint16_t arraySize, uint32_t *out);
uint16_t arraySize,
uint32_t *out);
const uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits); const uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits);
@@ -258,15 +234,9 @@ void nr_polar_generate_u(uint64_t *u,
uint16_t N, uint16_t N,
uint8_t n_pc); uint8_t n_pc);
void nr_polar_uxG(uint8_t const* u, size_t N, uint8_t* D); void nr_polar_uxG(uint8_t const *u, size_t N, uint8_t *D);
void nr_polar_bit_insertion(uint8_t *input, 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);
void nr_matrix_multiplication_uint8_1D_uint8_2D(const uint8_t *matrix1, void nr_matrix_multiplication_uint8_1D_uint8_2D(const uint8_t *matrix1,
const uint8_t **matrix2, const uint8_t **matrix2,
@@ -274,46 +244,39 @@ void nr_matrix_multiplication_uint8_1D_uint8_2D(const uint8_t *matrix1,
uint16_t row, uint16_t row,
uint16_t col); uint16_t col);
void nr_sort_asc_double_1D_array_ind(double *matrix, void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len);
uint8_t *ind,
uint8_t len);
void nr_free_double_2D_array(double **input, uint16_t xlen); void nr_free_double_2D_array(double **input, uint16_t xlen);
#ifndef __cplusplus #ifndef __cplusplus
void updateLLR(uint8_t listSize, void updateLLR(uint8_t listSize,
uint16_t row, uint16_t row,
uint16_t col, uint16_t col,
uint16_t xlen, uint16_t xlen,
uint8_t ylen, uint8_t ylen,
int zlen, int zlen,
double llr[xlen][ylen][zlen], double llr[xlen][ylen][zlen],
uint8_t llrU[xlen][ylen], uint8_t llrU[xlen][ylen],
uint8_t bit[xlen][ylen][zlen], uint8_t bit[xlen][ylen][zlen],
uint8_t bitU[xlen][ylen] uint8_t bitU[xlen][ylen]);
);
void updatePathMetric(double *pathMetric, void updatePathMetric(double *pathMetric,
uint8_t listSize, uint8_t listSize,
uint8_t bitValue, uint8_t bitValue,
uint16_t row, uint16_t row,
int xlen, int xlen,
int ylen, int ylen,
int zlen, int zlen,
double llr[xlen][ylen][zlen] double llr[xlen][ylen][zlen]);
);
void updatePathMetric2(double *pathMetric, void updatePathMetric2(double *pathMetric,
uint8_t listSize, uint8_t listSize,
uint16_t row, uint16_t row,
int xlen, int xlen,
int ylen, int ylen,
int zlen, int zlen,
double llr[xlen][ylen][zlen]); double llr[xlen][ylen][zlen]);
#endif #endif
//Also nr_polar_rate_matcher // Also nr_polar_rate_matcher
static inline void nr_polar_interleaver(uint8_t *input, static inline void nr_polar_interleaver(uint8_t *input, uint8_t *output, uint16_t *pattern, uint16_t size)
uint8_t *output,
uint16_t *pattern,
uint16_t size)
{ {
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
output[i] = input[pattern[i]]; output[i] = input[pattern[i]];
@@ -30,23 +30,20 @@
* \warning * \warning
*/ */
//#define DEBUG_POLAR_ENCODER // #define DEBUG_POLAR_ENCODER
//#define DEBUG_POLAR_ENCODER_DCI // #define DEBUG_POLAR_ENCODER_DCI
//#define DEBUG_POLAR_MATLAB // #define DEBUG_POLAR_MATLAB
//#define POLAR_CODING_DEBUG // #define POLAR_CODING_DEBUG
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "assertions.h" #include "assertions.h"
#include <stdint.h> #include <stdint.h>
//input [a_31 a_30 ... a_0] // input [a_31 a_30 ... a_0]
//output [f_31 f_30 ... f_0] [f_63 f_62 ... f_32] ... // output [f_31 f_30 ... f_0] [f_63 f_62 ... f_32] ...
void polar_encoder(uint32_t *in, void polar_encoder(uint32_t *in, uint32_t *out, int8_t messageType, uint16_t messageLength, uint8_t aggregation_level)
uint32_t *out, {
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level) {
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level); t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
uint8_t nr_polar_A[polarParams->payloadBits]; uint8_t nr_polar_A[polarParams->payloadBits];
nr_bit2byte_uint32_8(in, polarParams->payloadBits, nr_polar_A); nr_bit2byte_uint32_8(in, polarParams->payloadBits, nr_polar_A);
@@ -83,21 +80,21 @@ void polar_encoder(uint32_t *in,
printf("b[%d]=%d\n", i, nr_polar_B[i]); printf("b[%d]=%d\n", i, nr_polar_B[i]);
#endif #endif
//Interleaving (c to c') // Interleaving (c to c')
uint8_t nr_polar_CPrime[polarParams->K]; uint8_t nr_polar_CPrime[polarParams->K];
nr_polar_interleaver(nr_polar_B, nr_polar_CPrime, polarParams->interleaving_pattern, polarParams->K); nr_polar_interleaver(nr_polar_B, nr_polar_CPrime, polarParams->interleaving_pattern, polarParams->K);
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
uint64_t Cprime=0; uint64_t Cprime = 0;
for (int i = 0; i<polarParams->K; i++) { for (int i = 0; i < polarParams->K; i++) {
Cprime = Cprime | ((uint64_t)nr_polar_CPrime[i] << i); Cprime = Cprime | ((uint64_t)nr_polar_CPrime[i] << i);
if (nr_polar_CPrime[i] == 1) if (nr_polar_CPrime[i] == 1)
printf("pos %d : %lx\n", i, Cprime); printf("pos %d : %lx\n", i, Cprime);
} }
printf("polar_Cprime %lx\n",Cprime); printf("polar_Cprime %lx\n", Cprime);
#endif #endif
//Bit insertion (c' to u) // Bit insertion (c' to u)
uint8_t nr_polar_U[polarParams->N]; uint8_t nr_polar_U[polarParams->N];
nr_polar_bit_insertion(nr_polar_CPrime, nr_polar_bit_insertion(nr_polar_CPrime,
nr_polar_U, nr_polar_U,
@@ -119,11 +116,10 @@ void polar_encoder(uint32_t *in,
for (int i = 0; i < polarParams->N; i++) for (int i = 0; i < polarParams->N; i++)
D[i / 64] |= ((uint64_t)nr_polar_D[i]) << (i & 63); D[i / 64] |= ((uint64_t)nr_polar_D[i]) << (i & 63);
printf("D %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n", printf("D %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n", D[0], D[1], D[2], D[3], D[4], D[5], D[6], D[7]);
D[0],D[1],D[2],D[3],D[4],D[5],D[6],D[7]);
#endif #endif
//Rate matching // Rate matching
//Sub-block interleaving (d to y) and Bit selection (y to e) // Sub-block interleaving (d to y) and Bit selection (y to e)
uint8_t nr_polar_E[polarParams->encoderLength]; uint8_t nr_polar_E[polarParams->encoderLength];
nr_polar_interleaver(nr_polar_D, nr_polar_E, polarParams->rate_matching_pattern, polarParams->encoderLength); nr_polar_interleaver(nr_polar_D, nr_polar_E, polarParams->rate_matching_pattern, polarParams->encoderLength);
/* /*
@@ -145,7 +141,8 @@ void polar_encoder_dci(uint32_t *in,
uint16_t n_RNTI, uint16_t n_RNTI,
int8_t messageType, int8_t messageType,
uint16_t messageLength, uint16_t messageLength,
uint8_t aggregation_level) { uint8_t aggregation_level)
{
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level); t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
#ifdef DEBUG_POLAR_ENCODER_DCI #ifdef DEBUG_POLAR_ENCODER_DCI
@@ -176,10 +173,11 @@ void polar_encoder_dci(uint32_t *in,
printf("\n"); printf("\n");
printf("[polar_encoder_dci] GP: "); printf("[polar_encoder_dci] GP: ");
for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->crc_generator_matrix[0][i]); for (int i = 0; i < polarParams->crcParityBits; i++)
printf("%d-", polarParams->crc_generator_matrix[0][i]);
printf("\n"); printf("\n");
#endif #endif
//Calculate CRC. // Calculate CRC.
uint8_t nr_polar_crc[polarParams->crcParityBits]; uint8_t nr_polar_crc[polarParams->crcParityBits];
nr_matrix_multiplication_uint8_1D_uint8_2D(nr_polar_APrime, nr_matrix_multiplication_uint8_1D_uint8_2D(nr_polar_APrime,
polarParams->crc_generator_matrix, polarParams->crc_generator_matrix,
@@ -197,14 +195,14 @@ void polar_encoder_dci(uint32_t *in,
printf("\n"); printf("\n");
#endif #endif
uint8_t nr_polar_B[polarParams->payloadBits + 8 + 16]; uint8_t nr_polar_B[polarParams->payloadBits + 8 + 16];
//Attach CRC to the Transport Block. (a to b) // Attach CRC to the Transport Block. (a to b)
memcpy(nr_polar_B, nr_polar_A, polarParams->payloadBits); memcpy(nr_polar_B, nr_polar_A, polarParams->payloadBits);
for (uint i = polarParams->payloadBits; i < polarParams->K; i++) for (uint i = polarParams->payloadBits; i < polarParams->K; i++)
nr_polar_B[i] = nr_polar_crc[i - polarParams->payloadBits]; nr_polar_B[i] = nr_polar_crc[i - polarParams->payloadBits];
//Scrambling (b to c) // Scrambling (b to c)
for (int i=0; i<16; i++) for (int i = 0; i < 16; i++)
nr_polar_B[polarParams->payloadBits + 8 + i] = (nr_polar_B[polarParams->payloadBits + 8 + i] + ((n_RNTI >> (15 - i)) & 1)) % 2; nr_polar_B[polarParams->payloadBits + 8 + i] = (nr_polar_B[polarParams->payloadBits + 8 + i] + ((n_RNTI >> (15 - i)) & 1)) % 2;
#ifdef DEBUG_POLAR_ENCODER_DCI #ifdef DEBUG_POLAR_ENCODER_DCI
@@ -213,10 +211,10 @@ void polar_encoder_dci(uint32_t *in,
printf("%d-", nr_polar_B[i]); printf("%d-", nr_polar_B[i]);
printf("\n"); printf("\n");
#endif #endif
//Interleaving (c to c') // Interleaving (c to c')
uint8_t nr_polar_CPrime[polarParams->K]; uint8_t nr_polar_CPrime[polarParams->K];
nr_polar_interleaver(nr_polar_B, nr_polar_CPrime, polarParams->interleaving_pattern, polarParams->K); nr_polar_interleaver(nr_polar_B, nr_polar_CPrime, polarParams->interleaving_pattern, polarParams->K);
//Bit insertion (c' to u) // Bit insertion (c' to u)
uint8_t nr_polar_U[polarParams->N]; uint8_t nr_polar_U[polarParams->N];
nr_polar_bit_insertion(nr_polar_CPrime, nr_polar_bit_insertion(nr_polar_CPrime,
nr_polar_U, nr_polar_U,
@@ -225,14 +223,14 @@ void polar_encoder_dci(uint32_t *in,
polarParams->Q_I_N, polarParams->Q_I_N,
polarParams->Q_PC_N, polarParams->Q_PC_N,
polarParams->n_pc); polarParams->n_pc);
//Encoding (u to d) // Encoding (u to d)
uint8_t nr_polar_D[polarParams->N]; uint8_t nr_polar_D[polarParams->N];
nr_matrix_multiplication_uint8_1D_uint8_2D(nr_polar_U, polarParams->G_N, nr_polar_D, polarParams->N, polarParams->N); nr_matrix_multiplication_uint8_1D_uint8_2D(nr_polar_U, polarParams->G_N, nr_polar_D, polarParams->N, polarParams->N);
for (uint i = 0; i < polarParams->N; i++) for (uint i = 0; i < polarParams->N; i++)
nr_polar_D[i] %= 2; nr_polar_D[i] %= 2;
//Rate matching // Rate matching
//Sub-block interleaving (d to y) and Bit selection (y to e) // Sub-block interleaving (d to y) and Bit selection (y to e)
uint8_t nr_polar_E[polarParams->encoderLength]; uint8_t nr_polar_E[polarParams->encoderLength];
nr_polar_interleaver(nr_polar_D, nr_polar_E, polarParams->rate_matching_pattern, polarParams->encoderLength); nr_polar_interleaver(nr_polar_D, nr_polar_E, polarParams->rate_matching_pattern, polarParams->encoderLength);
/* /*
@@ -294,44 +292,50 @@ __attribute__((always_inline)) static inline void polar_rate_matching(const t_nr
{ {
// handle rate matching with a single 128 bit word using bit shuffling // handle rate matching with a single 128 bit word using bit shuffling
// can be done with SIMD intrisics if needed // can be done with SIMD intrisics if needed
if (polarParams->groupsize < 8) { if (polarParams->groupsize < 8) {
AssertFatal(polarParams->encoderLength<=512,"Need to handle groupsize(%d)<8 and N(%d)>512\n",polarParams->groupsize,polarParams->encoderLength); AssertFatal(polarParams->encoderLength <= 512,
uint128_t *out128=(uint128_t*)out; "Need to handle groupsize(%d)<8 and N(%d)>512\n",
uint128_t *in128=(uint128_t*)in; polarParams->groupsize,
for (int i=0;i<polarParams->encoderLength>>7;i++) polarParams->encoderLength);
uint128_t *out128 = (uint128_t *)out;
uint128_t *in128 = (uint128_t *)in;
for (int i = 0; i < polarParams->encoderLength >> 7; i++)
out128[i] = 0; out128[i] = 0;
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
uint128_t tmp1; uint128_t tmp1;
#endif #endif
for (int i=0; i<polarParams->encoderLength; i++) { for (int i = 0; i < polarParams->encoderLength; i++) {
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
printf("%d<-%u : %llx.%llx =>",i,polarParams->rate_matching_pattern[i],((uint64_t *)out)[1],((uint64_t *)out)[0]); printf("%d<-%u : %llx.%llx =>", i, polarParams->rate_matching_pattern[i], ((uint64_t *)out)[1], ((uint64_t *)out)[0]);
#endif #endif
uint8_t pi=polarParams->rate_matching_pattern[i]; uint8_t pi = polarParams->rate_matching_pattern[i];
uint8_t pi7=pi>>7; uint8_t pi7 = pi >> 7;
uint8_t pimod128=pi&127; uint8_t pimod128 = pi & 127;
uint8_t imod128=i&127; uint8_t imod128 = i & 127;
uint8_t i7=i>>7; uint8_t i7 = i >> 7;
uint128_t tmp0 = (in128[pi7] & (((uint128_t)1) << (pimod128))); uint128_t tmp0 = (in128[pi7] & (((uint128_t)1) << (pimod128)));
if (tmp0!=0) { if (tmp0 != 0) {
out128[i7] = out128[i7] | ((uint128_t)1)<<imod128; out128[i7] = out128[i7] | ((uint128_t)1) << imod128;
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
printf("%llx.%llx<->%llx.%llx => %llx.%llx\n", printf("%llx.%llx<->%llx.%llx => %llx.%llx\n",
((uint64_t *)&tmp0)[1],((uint64_t *)&tmp0)[0], ((uint64_t *)&tmp0)[1],
((uint64_t *)&tmp1)[1],((uint64_t *)&tmp1)[0], ((uint64_t *)&tmp0)[0],
((uint64_t *)out)[1],((uint64_t *)out)[0]); ((uint64_t *)&tmp1)[1],
((uint64_t *)&tmp1)[0],
((uint64_t *)out)[1],
((uint64_t *)out)[0]);
#endif #endif
} }
} }
} }
// These are based on LUTs for byte and short word groups // These are based on LUTs for byte and short word groups
else if (polarParams->groupsize == 8) else if (polarParams->groupsize == 8)
for (int i = 0; i < polarParams->encoderLength >> 3; i++) for (int i = 0; i < polarParams->encoderLength >> 3; i++)
((uint8_t *)out)[i] = ((uint8_t *)in)[polarParams->rm_tab[i]]; ((uint8_t *)out)[i] = ((uint8_t *)in)[polarParams->rm_tab[i]];
else // groupsize==16 else // groupsize==16
for (int i=0; i<polarParams->encoderLength>>4; i++) { for (int i = 0; i < polarParams->encoderLength >> 4; i++) {
((uint16_t *)out)[i] = ((uint16_t *)in)[polarParams->rm_tab[i]]; ((uint16_t *)out)[i] = ((uint16_t *)in)[polarParams->rm_tab[i]];
} }
@@ -340,19 +344,20 @@ __attribute__((always_inline)) static inline void polar_rate_matching(const t_nr
} }
} }
void build_polar_tables(t_nrPolar_params *polarParams) { void build_polar_tables(t_nrPolar_params *polarParams)
{
// build table b -> c' // build table b -> c'
AssertFatal(polarParams->K > 17, "K = %d < 18, is not possible\n",polarParams->K); AssertFatal(polarParams->K > 17, "K = %d < 18, is not possible\n", polarParams->K);
AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n", polarParams->K); AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n", polarParams->K);
const int numbytes = (polarParams->K+7)/8; const int numbytes = (polarParams->K + 7) / 8;
const int residue = polarParams->K&7; const int residue = polarParams->K & 7;
uint deinterleaving_pattern[polarParams->K]; uint deinterleaving_pattern[polarParams->K];
for (int i = 0; i < polarParams->K; i++) for (int i = 0; i < polarParams->K; i++)
deinterleaving_pattern[polarParams->interleaving_pattern[i]] = i; deinterleaving_pattern[polarParams->interleaving_pattern[i]] = i;
for (int byte=0; byte<numbytes; byte++) { for (int byte = 0; byte < numbytes; byte++) {
int numbits = byte<(polarParams->K>>3) ? 8 : residue; int numbits = byte < (polarParams->K >> 3) ? 8 : residue;
for (uint64_t val = 0; val < 256LU; val++) { for (uint64_t val = 0; val < 256LU; val++) {
// uint16_t * tmp=polarParams->deinterleaving_pattern+polarParams->K - 1 - 8 * byte; // uint16_t * tmp=polarParams->deinterleaving_pattern+polarParams->K - 1 - 8 * byte;
union { union {
@@ -360,10 +365,10 @@ void build_polar_tables(t_nrPolar_params *polarParams) {
uint64_t pieces[2]; uint64_t pieces[2];
} tab = {0}; } tab = {0};
uint *tmp = deinterleaving_pattern + polarParams->K - 8 * byte - 1; uint *tmp = deinterleaving_pattern + polarParams->K - 8 * byte - 1;
for (int i=0; i<numbits; i++) { for (int i = 0; i < numbits; i++) {
// flip bit endian of B bitstring // flip bit endian of B bitstring
const int ip = *tmp--; const int ip = *tmp--;
AssertFatal(ip<128,"ip = %d\n",ip); AssertFatal(ip < 128, "ip = %d\n", ip);
const uint128_t bit_i = (val >> i) & 1; const uint128_t bit_i = (val >> i) & 1;
tab.full |= bit_i << ip; tab.full |= bit_i << ip;
} }
@@ -372,50 +377,57 @@ void build_polar_tables(t_nrPolar_params *polarParams) {
} }
} }
AssertFatal(polarParams->N == 512 || polarParams->N == 256 || polarParams->N == 128 || polarParams->N == 64, "N = %d, not done yet\n", polarParams->N); AssertFatal(polarParams->N == 512 || polarParams->N == 256 || polarParams->N == 128 || polarParams->N == 64,
"N = %d, not done yet\n",
polarParams->N);
// rate matching table // rate matching table
int iplast=polarParams->rate_matching_pattern[0]; int iplast = polarParams->rate_matching_pattern[0];
int ccnt=0; int ccnt = 0;
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
int groupcnt=0; int groupcnt = 0;
int firstingroup_out=0; int firstingroup_out = 0;
int firstingroup_in=iplast; int firstingroup_in = iplast;
#endif #endif
int mingroupsize = 1024; int mingroupsize = 1024;
// compute minimum group size of rate-matching pattern // compute minimum group size of rate-matching pattern
for (int outpos=1; outpos<polarParams->encoderLength; outpos++) { for (int outpos = 1; outpos < polarParams->encoderLength; outpos++) {
int ip = polarParams->rate_matching_pattern[outpos]; int ip = polarParams->rate_matching_pattern[outpos];
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
printf("rm: outpos %d, inpos %d\n",outpos,ip); printf("rm: outpos %d, inpos %d\n", outpos, ip);
#endif #endif
if ((ip - iplast) == 1) if ((ip - iplast) == 1)
ccnt++; ccnt++;
else { else {
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
groupcnt++; groupcnt++;
printf("group %d (size %d): (%d:%d) => (%d:%d)\n",groupcnt,ccnt+1, printf("group %d (size %d): (%d:%d) => (%d:%d)\n",
firstingroup_in,firstingroup_in+ccnt, groupcnt,
firstingroup_out,firstingroup_out+ccnt); ccnt + 1,
firstingroup_in,
firstingroup_in + ccnt,
firstingroup_out,
firstingroup_out + ccnt);
#endif #endif
if ((ccnt + 1) < mingroupsize) if ((ccnt + 1) < mingroupsize)
mingroupsize = ccnt + 1; mingroupsize = ccnt + 1;
ccnt=0; ccnt = 0;
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
firstingroup_out=outpos; firstingroup_out = outpos;
firstingroup_in=ip; firstingroup_in = ip;
#endif #endif
} }
iplast=ip; iplast = ip;
} }
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
groupcnt++; groupcnt++;
#endif #endif
if ((ccnt+1)<mingroupsize) mingroupsize=ccnt+1; if ((ccnt + 1) < mingroupsize)
mingroupsize = ccnt + 1;
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
printf("group %d (size %d): (%d:%d) => (%d:%d)\n", printf("group %d (size %d): (%d:%d) => (%d:%d)\n",
groupcnt, groupcnt,
@@ -456,7 +468,6 @@ void build_polar_tables(t_nrPolar_params *polarParams) {
build_decoder_tree(polarParams); build_decoder_tree(polarParams);
} }
void polar_encoder_fast(uint64_t *A, void polar_encoder_fast(uint64_t *A,
void *out, void *out,
int32_t crcmask, int32_t crcmask,
@@ -482,27 +493,27 @@ void polar_encoder_fast(uint64_t *A,
#endif #endif
// AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K); // AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K); AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n", polarParams->K);
AssertFatal(polarParams->payloadBits < 65, "payload bits = %d > 64, is not supported yet\n",polarParams->payloadBits); AssertFatal(polarParams->payloadBits < 65, "payload bits = %d > 64, is not supported yet\n", polarParams->payloadBits);
int bitlen = polarParams->payloadBits; int bitlen = polarParams->payloadBits;
// append crc // append crc
AssertFatal(bitlen<129,"support for payloads <= 128 bits\n"); AssertFatal(bitlen < 129, "support for payloads <= 128 bits\n");
// AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n"); // AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n");
//int bitlen0=bitlen; // int bitlen0=bitlen;
#ifdef POLAR_CODING_DEBUG #ifdef POLAR_CODING_DEBUG
printf("\nTX\n"); printf("\nTX\n");
printf("a: "); printf("a: ");
for (int n = (bitlen + 63)/64 ; n >=0; n--) { for (int n = (bitlen + 63) / 64; n >= 0; n--) {
if (n % 4 == 0) if (n % 4 == 0)
printf(" "); printf(" ");
if (n < bitlen) if (n < bitlen)
printf("%lu", (A[n/64] >> (n%64)) & 1); printf("%lu", (A[n / 64] >> (n % 64)) & 1);
} }
printf("\n"); printf("\n");
#endif #endif
uint64_t tcrc=0; uint64_t tcrc = 0;
uint offset = 0; uint offset = 0;
// appending 24 ones before a0 for DCI as stated in 38.212 7.3.2 // appending 24 ones before a0 for DCI as stated in 38.212 7.3.2
@@ -513,76 +524,76 @@ void polar_encoder_fast(uint64_t *A,
//???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 //???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) // 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 down to 0, for PBCH/PDCCH we need to read in a_{A-1} down to a_{0}, A = length of bit string (e.g. 32 for PBCH) // CRC reads in each byte in bit positions 7 down to 0, for PBCH/PDCCH we need to read in a_{A-1} down to a_{0}, A = length of bit
if (bitlen<=32) { // string (e.g. 32 for PBCH)
uint8_t A32_flip[4+offset]; if (bitlen <= 32) {
uint8_t A32_flip[4 + offset];
if (ones_flag) { if (ones_flag) {
A32_flip[0] = 0xff; A32_flip[0] = 0xff;
A32_flip[1] = 0xff; A32_flip[1] = 0xff;
A32_flip[2] = 0xff; A32_flip[2] = 0xff;
} }
uint32_t Aprime= (uint32_t)(((uint32_t)*A)<<(32-bitlen)); uint32_t Aprime = (uint32_t)(((uint32_t)*A) << (32 - bitlen));
A32_flip[0+offset]=((uint8_t *)&Aprime)[3]; A32_flip[0 + offset] = ((uint8_t *)&Aprime)[3];
A32_flip[1+offset]=((uint8_t *)&Aprime)[2]; A32_flip[1 + offset] = ((uint8_t *)&Aprime)[2];
A32_flip[2+offset]=((uint8_t *)&Aprime)[1]; A32_flip[2 + offset] = ((uint8_t *)&Aprime)[1];
A32_flip[3+offset]=((uint8_t *)&Aprime)[0]; A32_flip[3 + offset] = ((uint8_t *)&Aprime)[0];
if (polarParams->crcParityBits == 24) if (polarParams->crcParityBits == 24)
tcrc = (uint64_t)(((crcmask^(crc24c(A32_flip,8*offset+bitlen)>>8)))&0xffffff); tcrc = (uint64_t)(((crcmask ^ (crc24c(A32_flip, 8 * offset + bitlen) >> 8))) & 0xffffff);
else if (polarParams->crcParityBits == 11) else if (polarParams->crcParityBits == 11)
tcrc = (uint64_t)(((crcmask^(crc11(A32_flip,bitlen)>>21)))&0x7ff); tcrc = (uint64_t)(((crcmask ^ (crc11(A32_flip, bitlen) >> 21))) & 0x7ff);
else if (polarParams->crcParityBits == 6) else if (polarParams->crcParityBits == 6)
tcrc = (uint64_t)(((crcmask^(crc6(A32_flip,bitlen)>>26)))&0x3f); tcrc = (uint64_t)(((crcmask ^ (crc6(A32_flip, bitlen) >> 26))) & 0x3f);
} else if (bitlen<=64) { } else if (bitlen <= 64) {
uint8_t A64_flip[8+offset]; uint8_t A64_flip[8 + offset];
if (ones_flag) { if (ones_flag) {
A64_flip[0] = 0xff; A64_flip[0] = 0xff;
A64_flip[1] = 0xff; A64_flip[1] = 0xff;
A64_flip[2] = 0xff; A64_flip[2] = 0xff;
} }
uint64_t Aprime= (uint64_t)(((uint64_t)*A)<<(64-bitlen)); uint64_t Aprime = (uint64_t)(((uint64_t)*A) << (64 - bitlen));
A64_flip[0+offset]=((uint8_t *)&Aprime)[7]; A64_flip[0 + offset] = ((uint8_t *)&Aprime)[7];
A64_flip[1+offset]=((uint8_t *)&Aprime)[6]; A64_flip[1 + offset] = ((uint8_t *)&Aprime)[6];
A64_flip[2+offset]=((uint8_t *)&Aprime)[5]; A64_flip[2 + offset] = ((uint8_t *)&Aprime)[5];
A64_flip[3+offset]=((uint8_t *)&Aprime)[4]; A64_flip[3 + offset] = ((uint8_t *)&Aprime)[4];
A64_flip[4+offset]=((uint8_t *)&Aprime)[3]; A64_flip[4 + offset] = ((uint8_t *)&Aprime)[3];
A64_flip[5+offset]=((uint8_t *)&Aprime)[2]; A64_flip[5 + offset] = ((uint8_t *)&Aprime)[2];
A64_flip[6+offset]=((uint8_t *)&Aprime)[1]; A64_flip[6 + offset] = ((uint8_t *)&Aprime)[1];
A64_flip[7+offset]=((uint8_t *)&Aprime)[0]; A64_flip[7 + offset] = ((uint8_t *)&Aprime)[0];
if (polarParams->crcParityBits == 24) if (polarParams->crcParityBits == 24)
tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,8*offset+bitlen)>>8)))&0xffffff; tcrc = (uint64_t)((crcmask ^ (crc24c(A64_flip, 8 * offset + bitlen) >> 8))) & 0xffffff;
else if (polarParams->crcParityBits == 11) else if (polarParams->crcParityBits == 11)
tcrc = (uint64_t)((crcmask^(crc11(A64_flip,bitlen)>>21)))&0x7ff; tcrc = (uint64_t)((crcmask ^ (crc11(A64_flip, bitlen) >> 21))) & 0x7ff;
} } else if (bitlen <= 128) {
else if (bitlen<=128) { uint8_t A128_flip[16 + offset];
uint8_t A128_flip[16+offset];
if (ones_flag) { if (ones_flag) {
A128_flip[0] = 0xff; A128_flip[0] = 0xff;
A128_flip[1] = 0xff; A128_flip[1] = 0xff;
A128_flip[2] = 0xff; A128_flip[2] = 0xff;
} }
uint128_t Aprime= (uint128_t)(((uint128_t)*A)<<(128-bitlen)); uint128_t Aprime = (uint128_t)(((uint128_t)*A) << (128 - bitlen));
for (int i=0; i<16 ; i++) for (int i = 0; i < 16; i++)
A128_flip[i+offset]=((uint8_t*)&Aprime)[15-i]; A128_flip[i + offset] = ((uint8_t *)&Aprime)[15 - i];
if (polarParams->crcParityBits == 24) if (polarParams->crcParityBits == 24)
tcrc = (uint64_t)((crcmask^(crc24c(A128_flip,8*offset+bitlen)>>8)))&0xffffff; tcrc = (uint64_t)((crcmask ^ (crc24c(A128_flip, 8 * offset + bitlen) >> 8))) & 0xffffff;
else if (polarParams->crcParityBits == 11) else if (polarParams->crcParityBits == 11)
tcrc = (uint64_t)((crcmask^(crc11(A128_flip,bitlen)>>21)))&0x7ff; tcrc = (uint64_t)((crcmask ^ (crc11(A128_flip, bitlen) >> 21))) & 0x7ff;
} }
// this is number of quadwords in the bit string // this is number of quadwords in the bit string
int quadwlen = (polarParams->K+63)/64; int quadwlen = (polarParams->K + 63) / 64;
// Create the B bit string as // Create the B bit string as
// 0, 0, ..., 0, a'_0, a'_1, ..., a'_A-1, p_0, p_1, ..., p_{N_parity-1} // 0, 0, ..., 0, a'_0, a'_1, ..., a'_A-1, p_0, p_1, ..., p_{N_parity-1}
//??? 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 //??? 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
uint64_t B[4]= {0}; uint64_t B[4] = {0};
B[0] = (A[0] << polarParams->crcParityBits) | tcrc; B[0] = (A[0] << polarParams->crcParityBits) | tcrc;
for (int n = 1; n < quadwlen; n++) for (int n = 1; n < quadwlen; n++)
if ((bitlen+63)/64 > n) if ((bitlen + 63) / 64 > n)
B[n] = (A[n] << polarParams->crcParityBits) | (A[n-1]>>(64-polarParams->crcParityBits)); B[n] = (A[n] << polarParams->crcParityBits) | (A[n - 1] >> (64 - polarParams->crcParityBits));
else else
B[n] = (A[n-1]>>(64-polarParams->crcParityBits)); B[n] = (A[n - 1] >> (64 - polarParams->crcParityBits));
#ifdef POLAR_CODING_DEBUG #ifdef POLAR_CODING_DEBUG
int bitlen_B = bitlen + polarParams->crcParityBits; int bitlen_B = bitlen + polarParams->crcParityBits;
@@ -602,17 +613,13 @@ void polar_encoder_fast(uint64_t *A,
// TS 38.212 - Section 5.3.1.1 Interleaving // TS 38.212 - Section 5.3.1.1 Interleaving
// For each byte of B, lookup in corresponding table for 64-bit word corresponding to that byte and its position // For each byte of B, lookup in corresponding table for 64-bit word corresponding to that byte and its position
uint64_t Cprime[4]= {0}; uint64_t Cprime[4] = {0};
uint8_t *Bbyte = (uint8_t *)B; uint8_t *Bbyte = (uint8_t *)B;
if (polarParams->K < 65) { if (polarParams->K < 65) {
Cprime[0] = polarParams->cprime_tab0[0][Bbyte[0]] | Cprime[0] = polarParams->cprime_tab0[0][Bbyte[0]] | polarParams->cprime_tab0[1][Bbyte[1]]
polarParams->cprime_tab0[1][Bbyte[1]] | | polarParams->cprime_tab0[2][Bbyte[2]] | polarParams->cprime_tab0[3][Bbyte[3]]
polarParams->cprime_tab0[2][Bbyte[2]] | | polarParams->cprime_tab0[4][Bbyte[4]] | polarParams->cprime_tab0[5][Bbyte[5]]
polarParams->cprime_tab0[3][Bbyte[3]] | | polarParams->cprime_tab0[6][Bbyte[6]] | polarParams->cprime_tab0[7][Bbyte[7]];
polarParams->cprime_tab0[4][Bbyte[4]] |
polarParams->cprime_tab0[5][Bbyte[5]] |
polarParams->cprime_tab0[6][Bbyte[6]] |
polarParams->cprime_tab0[7][Bbyte[7]];
} else if (polarParams->K < 129) { } else if (polarParams->K < 129) {
for (int i = 0; i < 1 + (polarParams->K / 8); i++) { for (int i = 0; i < 1 + (polarParams->K / 8); i++) {
Cprime[0] |= polarParams->cprime_tab0[i][Bbyte[i]]; Cprime[0] |= polarParams->cprime_tab0[i][Bbyte[i]];
@@ -622,7 +629,8 @@ void polar_encoder_fast(uint64_t *A,
#ifdef DEBUG_POLAR_MATLAB #ifdef DEBUG_POLAR_MATLAB
// Cprime = pbchCprime // Cprime = pbchCprime
for (int i = 0; i < quadwlen; i++) printf("[polar_encoder_fast]C'[%d]= 0x%llx\n", i, (unsigned long long)(Cprime[i])); for (int i = 0; i < quadwlen; i++)
printf("[polar_encoder_fast]C'[%d]= 0x%llx\n", i, (unsigned long long)(Cprime[i]));
#endif #endif
#ifdef POLAR_CODING_DEBUG #ifdef POLAR_CODING_DEBUG
@@ -677,8 +685,8 @@ void polar_encoder_fast(uint64_t *A,
fflush(stdout); fflush(stdout);
#endif #endif
memset((void*)out,0,polarParams->encoderLength>>3); memset((void *)out, 0, polarParams->encoderLength >> 3);
polar_rate_matching(polarParams,(void *)D, out); polar_rate_matching(polarParams, (void *)D, out);
#ifdef POLAR_CODING_DEBUG #ifdef POLAR_CODING_DEBUG
uint64_t *out64 = (uint64_t *)out; uint64_t *out64 = (uint64_t *)out;
@@ -28,11 +28,12 @@
* \email turker.yilmaz@eurecom.fr * \email turker.yilmaz@eurecom.fr
* \note * \note
* \warning * \warning
*/ */
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_){ void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_)
{
uint K_IL_max = 164; uint K_IL_max = 164;
uint8_t interleaving_pattern_table[164] = { uint8_t interleaving_pattern_table[164] = {
0, 2, 4, 7, 9, 14, 19, 20, 24, 25, 26, 28, 31, 34, 42, 45, 49, 50, 51, 53, 54, 56, 58, 59, 0, 2, 4, 7, 9, 14, 19, 20, 24, 25, 26, 28, 31, 34, 42, 45, 49, 50, 51, 53, 54, 56, 58, 59,
@@ -7,53 +7,48 @@
void nr_polar_kernal_operation(uint8_t *u, uint8_t *d, uint16_t N) void nr_polar_kernal_operation(uint8_t *u, uint8_t *d, uint16_t N)
{ {
// Martino's algorithm to avoid multiplication for the generating matrix of polar codes // Martino's algorithm to avoid multiplication for the generating matrix of polar codes
uint32_t i,j;
simde__m256i A,B,C,D,E,U,zerosOnly, OUT; uint32_t i, j;
simde__m256i inc;
uint32_t dTest[8];
uint32_t uArray[8];
uint32_t k;
uint32_t incArray[8];
//initialisation
for(k=0; k<8; k++)
incArray[k]=k;
inc=simde_mm256_loadu_si256((simde__m256i const*)incArray); // 0, 1, ..., 7 to increase
zerosOnly=simde_mm256_setzero_si256(); // for comparison
for(i=0; i<N; i+=8) simde__m256i A, B, C, D, E, U, zerosOnly, OUT;
{ simde__m256i inc;
B=simde_mm256_set1_epi32((int)i); // i, ..., i uint32_t dTest[8];
B=simde_mm256_add_epi32(B, inc); // i, i+1, ..., i+7 uint32_t uArray[8];
uint32_t k;
OUT=simde_mm256_setzero_si256(); // it will contain the result of all the XORs for the d(i)s uint32_t incArray[8];
for(j=0; j<N; j++)
{
A=simde_mm256_set1_epi32((int)(j)); //j, j, ..., j
A=simde_mm256_sub_epi32(A, B); //(j-i), (j-(i+1)), ... (j-(i+7))
U=simde_mm256_set1_epi32((int)u[j]);
simde_mm256_storeu_si256((simde__m256i*)uArray, U); //u(j) ... u(j) for the maskload
C=simde_mm256_and_si256(A, B); //(j-i)&i -> If zero, then XOR with the u(j) // initialisation
D=simde_mm256_cmpeq_epi32(C, zerosOnly); // compare with zero and use the result as mask for (k = 0; k < 8; k++)
incArray[k] = k;
E=simde_mm256_maskload_epi32((int const*)uArray, D); // load only some u(j)s for the XOR inc = simde_mm256_loadu_si256((simde__m256i const *)incArray); // 0, 1, ..., 7 to increase
OUT=simde_mm256_xor_si256(OUT, E); //32 bit x 8
} zerosOnly = simde_mm256_setzero_si256(); // for comparison
simde_mm256_storeu_si256((simde__m256i*)dTest, OUT);
for(k=0; k<8; k++) // Conversion from 32 bits to 8 bits for (i = 0; i < N; i += 8) {
{ B = simde_mm256_set1_epi32((int)i); // i, ..., i
d[i+k]=(uint8_t)dTest[k]; // With AVX512 there is an intrinsic to do it B = simde_mm256_add_epi32(B, inc); // i, i+1, ..., i+7
}
} OUT = simde_mm256_setzero_si256(); // it will contain the result of all the XORs for the d(i)s
for (j = 0; j < N; j++) {
A = simde_mm256_set1_epi32((int)(j)); // j, j, ..., j
A = simde_mm256_sub_epi32(A, B); //(j-i), (j-(i+1)), ... (j-(i+7))
U = simde_mm256_set1_epi32((int)u[j]);
simde_mm256_storeu_si256((simde__m256i *)uArray, U); // u(j) ... u(j) for the maskload
C = simde_mm256_and_si256(A, B); //(j-i)&i -> If zero, then XOR with the u(j)
D = simde_mm256_cmpeq_epi32(C, zerosOnly); // compare with zero and use the result as mask
E = simde_mm256_maskload_epi32((int const *)uArray, D); // load only some u(j)s for the XOR
OUT = simde_mm256_xor_si256(OUT, E); // 32 bit x 8
}
simde_mm256_storeu_si256((simde__m256i *)dTest, OUT);
for (k = 0; k < 8; k++) // Conversion from 32 bits to 8 bits
{
d[i + k] = (uint8_t)dTest[k]; // With AVX512 there is an intrinsic to do it
}
}
} }
@@ -28,7 +28,7 @@
* \email turker.yilmaz@eurecom.fr * \email turker.yilmaz@eurecom.fr
* \note * \note
* \warning * \warning
*/ */
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
@@ -47,7 +47,8 @@ void nr_matrix_multiplication_uint8_1D_uint8_2D(const uint8_t *matrix1,
} }
// Modified Bubble Sort. // Modified Bubble Sort.
void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len) { void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len)
{
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
int swaps = 0; int swaps = 0;
for (int j = 0; j < (len - i) - 1; j++) { for (int j = 0; j < (len - i) - 1; j++) {
@@ -28,46 +28,70 @@
* \email turker.yilmaz@eurecom.fr * \email turker.yilmaz@eurecom.fr
* \note * \note
* \warning * \warning
*/ */
#ifndef __NR_POLAR_PBCH_DEFS__H__ #ifndef __NR_POLAR_PBCH_DEFS__H__
#define __NR_POLAR_PBCH_DEFS__H__ #define __NR_POLAR_PBCH_DEFS__H__
#define NR_POLAR_PBCH_AGGREGATION_LEVEL 0 //uint8_t #define NR_POLAR_PBCH_AGGREGATION_LEVEL 0 // uint8_t
#define NR_POLAR_PBCH_MESSAGE_TYPE 0 //int8_t #define NR_POLAR_PBCH_MESSAGE_TYPE 0 // int8_t
#define NR_POLAR_PSBCH_MESSAGE_TYPE 3 //int8_t #define NR_POLAR_PSBCH_MESSAGE_TYPE 3 // int8_t
#define NR_POLAR_PBCH_PAYLOAD_BITS 32 //uint16_t #define NR_POLAR_PBCH_PAYLOAD_BITS 32 // uint16_t
#define NR_POLAR_PBCH_CRC_PARITY_BITS 24 #define NR_POLAR_PBCH_CRC_PARITY_BITS 24
#define NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS 3 #define NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS 3
//Assumed 3 by 3GPP when NR_POLAR_PBCH_L>8 to meet false alarm rate requirements. // Assumed 3 by 3GPP when NR_POLAR_PBCH_L>8 to meet false alarm rate requirements.
//Sec. 7.1.4: Channel Coding // Sec. 7.1.4: Channel Coding
#define NR_POLAR_PBCH_N_MAX 9 //uint8_t #define NR_POLAR_PBCH_N_MAX 9 // uint8_t
#define NR_POLAR_PBCH_I_IL 1 //uint8_t #define NR_POLAR_PBCH_I_IL 1 // uint8_t
#define NR_POLAR_PBCH_I_SEG 0 //uint8_t #define NR_POLAR_PBCH_I_SEG 0 // uint8_t
#define NR_POLAR_PBCH_N_PC 0 //uint8_t #define NR_POLAR_PBCH_N_PC 0 // uint8_t
#define NR_POLAR_PBCH_N_PC_WM 0 //uint8_t #define NR_POLAR_PBCH_N_PC_WM 0 // uint8_t
//#define NR_POLAR_PBCH_N 512 //uint16_t // #define NR_POLAR_PBCH_N 512 //uint16_t
//Sec. 7.1.5: Rate Matching // Sec. 7.1.5: Rate Matching
#define NR_POLAR_PBCH_I_BIL 0 //uint8_t #define NR_POLAR_PBCH_I_BIL 0 // uint8_t
#define NR_POLAR_PBCH_E 864 //uint16_t #define NR_POLAR_PBCH_E 864 // uint16_t
#define NR_POLAR_PBCH_E_DWORD 27 // NR_POLAR_PBCH_E/32 #define NR_POLAR_PBCH_E_DWORD 27 // NR_POLAR_PBCH_E/32
#define NR_POLAR_PSBCH_E 1792 //uint16_t #define NR_POLAR_PSBCH_E 1792 // uint16_t
#define NR_POLAR_PSBCH_E_DWORD 56 // NR_POLAR_PSBCH_E/32 #define NR_POLAR_PSBCH_E_DWORD 56 // NR_POLAR_PSBCH_E/32
/* /*
* TEST CODE * TEST CODE
*/ */
//#define DEBUG_POLAR // #define DEBUG_POLAR
// Usage in code: // Usage in code:
//#ifdef DEBUG_POLAR // #ifdef DEBUG_POLAR
//... //...
//#endif // #endif
//unsigned int testPayload0=0x00000000, testPayload1=0xffffffff; //payload1=~payload0; // unsigned int testPayload0=0x00000000, testPayload1=0xffffffff; //payload1=~payload0;
//unsigned int testPayload2=0xa5a5a5a5; //testPayload3=0xb3f02c82; // unsigned int testPayload2=0xa5a5a5a5; //testPayload3=0xb3f02c82;
//double testReceivedPayload3[NR_POLAR_PBCH_E] = {-1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1}; // double testReceivedPayload3[NR_POLAR_PBCH_E] = {-1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1,
// -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1,
// -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1,
// -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1,
// -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1,
// -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1,
// -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1,
// -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1,
// 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1,
// -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1,
// -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1,
// -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1,
// -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1,
// -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1,
// -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1,
// 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1,
// -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1,
// -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1,
// -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1,
// 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1,
// -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1,
// -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1,
// -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1,
// 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1,
// 1, -1, -1};
#endif #endif
@@ -89,8 +89,7 @@ void nr_polar_generate_u(uint64_t *u,
} }
} }
static static void encode_packed_byte(uint8_t *in_out)
void encode_packed_byte(uint8_t* in_out)
{ {
// *in_out ^= 0xAA & (*in_out << 1); // *in_out ^= 0xAA & (*in_out << 1);
// *in_out ^= 0xCC & (*in_out << 2); // *in_out ^= 0xCC & (*in_out << 2);
@@ -101,36 +100,33 @@ void encode_packed_byte(uint8_t* in_out)
*in_out ^= *in_out >> 4; *in_out ^= *in_out >> 4;
} }
static static void polar_encode_bits(uint8_t *in_out, size_t N)
void polar_encode_bits(uint8_t* in_out, size_t N)
{ {
size_t const num_bytes_per_block = N >> 3; size_t const num_bytes_per_block = N >> 3;
for(size_t i = 0; i < num_bytes_per_block; ++i){ for (size_t i = 0; i < num_bytes_per_block; ++i) {
encode_packed_byte(&in_out[i]); encode_packed_byte(&in_out[i]);
} }
} }
static static uint32_t log2_floor(uint32_t x)
uint32_t log2_floor(uint32_t x)
{ {
if(x == 0) if (x == 0)
return 0; return 0;
uint32_t clz = __builtin_clz(x); uint32_t clz = __builtin_clz(x);
return 31U - clz; return 31U - clz;
} }
static static void polar_encode_bytes(uint8_t *in_out, size_t N)
void polar_encode_bytes(uint8_t* in_out, size_t N)
{ {
size_t brnch_sz = 1; size_t brnch_sz = 1;
size_t n_brnch = N >> 4; size_t n_brnch = N >> 4;
size_t const blck_pwr = log2_floor(N); size_t const blck_pwr = log2_floor(N);
for (size_t stage = 3; stage < blck_pwr; ++stage) { for (size_t stage = 3; stage < blck_pwr; ++stage) {
for (size_t brnch = 0; brnch < n_brnch; ++brnch) { for (size_t brnch = 0; brnch < n_brnch; ++brnch) {
for(size_t byte = 0; byte < brnch_sz; ++byte){ for (size_t byte = 0; byte < brnch_sz; ++byte) {
size_t const dst = 2*brnch_sz*brnch + byte; size_t const dst = 2 * brnch_sz * brnch + byte;
in_out[dst] ^= in_out[dst + brnch_sz]; in_out[dst] ^= in_out[dst + brnch_sz];
} }
} }
n_brnch >>= 1; n_brnch >>= 1;
brnch_sz <<= 1; brnch_sz <<= 1;
@@ -139,12 +135,12 @@ void polar_encode_bytes(uint8_t* in_out, size_t N)
void nr_polar_uxG(uint8_t const *u, size_t N, uint8_t *D2) void nr_polar_uxG(uint8_t const *u, size_t N, uint8_t *D2)
{ {
assert(N > 7); assert(N > 7);
uint8_t tmp[N/8]; uint8_t tmp[N / 8];
for(int i = 0; i < N/8; ++i) for (int i = 0; i < N / 8; ++i)
tmp[i] = u[N/8 - 1 - i]; tmp[i] = u[N / 8 - 1 - i];
reverse_bits_u8(tmp, N/8, D2); reverse_bits_u8(tmp, N / 8, D2);
// Do the encoding/xor for the bottom 3 levels of the tree. // Do the encoding/xor for the bottom 3 levels of the tree.
// Thus, data remaining to encode, is in 2^3 type. // Thus, data remaining to encode, is in 2^3 type.
@@ -153,49 +149,40 @@ void nr_polar_uxG(uint8_t const *u, size_t N, uint8_t *D2)
polar_encode_bytes(D2, N); polar_encode_bytes(D2, N);
} }
void nr_polar_bit_insertion(uint8_t *input, 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)
{ {
int k = 0; int k = 0;
if (n_PC>0) { if (n_PC > 0) {
/* /*
* *
*/ */
} else { } else {
for (int n=0; n<=N-1; n++) { for (int n = 0; n <= N - 1; n++) {
output[n] = 0; output[n] = 0;
for (int m=0; m<=(K+n_PC)-1; m++) { for (int m = 0; m <= (K + n_PC) - 1; m++) {
if ( n == Q_I_N[m]) { if (n == Q_I_N[m]) {
output[n] = input[k]; output[n] = input[k];
k++; k++;
break; break;
} }
} }
} }
} }
} }
uint32_t nr_polar_output_length(uint16_t K, uint16_t E, uint8_t n_max)
uint32_t nr_polar_output_length(uint16_t K,
uint16_t E,
uint8_t n_max)
{ {
int n_1, n_2, n_min = 5; int n_1, n_2, n_min = 5;
double R_min=1.0/8; double R_min = 1.0 / 8;
if ( (E <= (9.0/8)*pow(2,ceil(log2(E))-1)) && (K/E < 9.0/16) ) { if ((E <= (9.0 / 8) * pow(2, ceil(log2(E)) - 1)) && (K / E < 9.0 / 16)) {
n_1 = ceil(log2(E))-1; n_1 = ceil(log2(E)) - 1;
} else { } else {
n_1 = ceil(log2(E)); n_1 = ceil(log2(E));
} }
n_2 = ceil(log2(K/R_min)); n_2 = ceil(log2(K / R_min));
int n = n_max; int n = n_max;
if (n > n_1) if (n > n_1)
@@ -206,9 +193,9 @@ uint32_t nr_polar_output_length(uint16_t K,
n = n_min; n = n_min;
/*printf("nr_polar_output_length: K %d, E %d, n %d (n_max %d,n_min %d, n_1 %d,n_2 %d)\n", /*printf("nr_polar_output_length: K %d, E %d, n %d (n_max %d,n_min %d, n_1 %d,n_2 %d)\n",
K,E,n,n_max,n_min,n_1,n_2); K,E,n,n_max,n_min,n_1,n_2);
exit(-1);*/ exit(-1);*/
return ((uint32_t) pow(2.0,n)); //=polar_code_output_length return ((uint32_t)pow(2.0, n)); //=polar_code_output_length
} }
void nr_polar_info_bit_pattern(uint8_t *ibp, void nr_polar_info_bit_pattern(uint8_t *ibp,
@@ -269,7 +256,7 @@ void nr_polar_info_bit_pattern(uint8_t *ibp,
const int end = Q_Ftmp_N[N]; const int end = Q_Ftmp_N[N];
int m; int m;
for (m = 0; m <= end; m++) { for (m = 0; m <= end; m++) {
AssertFatal(m < N+1, "Buffer boundary overflow"); AssertFatal(m < N + 1, "Buffer boundary overflow");
if (Q_0_Nminus1[n] == Q_Ftmp_N[m]) { if (Q_0_Nminus1[n] == Q_Ftmp_N[m]) {
break; break;
} }
@@ -309,7 +296,6 @@ void nr_polar_info_bit_pattern(uint8_t *ibp,
// Information and Parity Chack Bit Pattern // Information and Parity Chack Bit Pattern
for (int n = 0; n <= N - 1; n++) { for (int n = 0; n <= N - 1; n++) {
ibp[n] = 0; ibp[n] = 0;
for (int m = 0; m <= (K + n_PC) - 1; m++) { for (int m = 0; m <= (K + n_PC) - 1; m++) {
if (n == Q_I_N[m]) { if (n == Q_I_N[m]) {
@@ -328,11 +314,7 @@ void nr_polar_info_bit_pattern(uint8_t *ibp,
} }
} }
void nr_polar_info_bit_extraction(uint8_t *input, uint8_t *output, uint8_t *pattern, uint16_t size)
void nr_polar_info_bit_extraction(uint8_t *input,
uint8_t *output,
uint8_t *pattern,
uint16_t size)
{ {
uint16_t j = 0; uint16_t j = 0;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
@@ -343,13 +325,7 @@ void nr_polar_info_bit_extraction(uint8_t *input,
} }
} }
void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P_i_, uint16_t K, uint16_t N, uint16_t E)
void nr_polar_rate_matching_pattern(uint16_t *rmp,
uint16_t *J,
const uint8_t *P_i_,
uint16_t K,
uint16_t N,
uint16_t E)
{ {
uint16_t d[N]; uint16_t d[N];
for (int m = 0; m < N; m++) for (int m = 0; m < N; m++)
@@ -357,54 +333,49 @@ void nr_polar_rate_matching_pattern(uint16_t *rmp,
uint16_t y[N]; uint16_t y[N];
memset(y, 0, sizeof(y)); memset(y, 0, sizeof(y));
for (int m=0; m<=N-1; m++){ for (int m = 0; m <= N - 1; m++) {
int i = floor((32 * m) / N); int i = floor((32 * m) / N);
J[m] = (P_i_[i]*(N/32)) + (m%(N/32)); J[m] = (P_i_[i] * (N / 32)) + (m % (N / 32));
y[m] = d[J[m]]; y[m] = d[J[m]];
} }
if (E>=N) { //repetition if (E >= N) { // repetition
for (int k=0; k<=E-1; k++) { for (int k = 0; k <= E - 1; k++) {
int ind = (k % N); int ind = (k % N);
rmp[k]=y[ind]; rmp[k] = y[ind];
} }
} else { } else {
if ( (K/(double)E) <= (7.0/16) ) { //puncturing if ((K / (double)E) <= (7.0 / 16)) { // puncturing
for (int k=0; k<=E-1; k++) { for (int k = 0; k <= E - 1; k++) {
rmp[k]=y[k+N-E]; rmp[k] = y[k + N - E];
} }
} else { //shortening } else { // shortening
for (int k=0; k<=E-1; k++) { for (int k = 0; k <= E - 1; k++) {
rmp[k]=y[k]; rmp[k] = y[k];
} }
} }
} }
} }
void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp, uint16_t K, uint16_t N, uint16_t E)
void nr_polar_rate_matching(double *input,
double *output,
uint16_t *rmp,
uint16_t K,
uint16_t N,
uint16_t E)
{ {
if (E>=N) { //repetition if (E >= N) { // repetition
for (int i=0; i<=N-1; i++) output[i]=0; for (int i = 0; i <= N - 1; i++)
for (int i=0; i<=E-1; i++){ output[i] = 0;
output[rmp[i]]+=input[i]; for (int i = 0; i <= E - 1; i++) {
output[rmp[i]] += input[i];
} }
} else { } else {
if ( (K/(double)E) <= (7.0/16) ) { //puncturing if ((K / (double)E) <= (7.0 / 16)) { // puncturing
for (int i = 0; i <= N - 1; i++) for (int i = 0; i <= N - 1; i++)
output[i] = 0; output[i] = 0;
} else { //shortening } else { // shortening
for (int i = 0; i <= N - 1; i++) for (int i = 0; i <= N - 1; i++)
output[i] = INFINITY; output[i] = INFINITY;
} }
for (int i=0; i<=E-1; i++){ for (int i = 0; i <= E - 1; i++) {
output[rmp[i]]=input[i]; output[rmp[i]] = input[i];
} }
} }
} }
@@ -7,22 +7,21 @@
#define NR_POLAR_PUCCH_PAYLOAD_BITS 16 #define NR_POLAR_PUCCH_PAYLOAD_BITS 16
//Ref. 38-212 v15.0.1 // Ref. 38-212 v15.0.1
#define NR_POLAR_PUCCH_N_MAX 10 //uint8_t <------ #define NR_POLAR_PUCCH_N_MAX 10 // uint8_t <------
#define NR_POLAR_PUCCH_I_IL 1 //uint8_t <--- interleaving: if 0 no interleaving #define NR_POLAR_PUCCH_I_IL 1 // uint8_t <--- interleaving: if 0 no interleaving
#define NR_POLAR_PUCCH_N_PC 3 //uint8_t <-- or zero ?? #define NR_POLAR_PUCCH_N_PC 3 // uint8_t <-- or zero ??
#define NR_POLAR_PUCCH_N_PC_WM 0 //uint8_t #define NR_POLAR_PUCCH_N_PC_WM 0 // uint8_t
//#define NR_POLAR_PUCCH_N 512 //uint16_t // #define NR_POLAR_PUCCH_N 512 //uint16_t
//Ref. 38-212 v15.0.1, Section 7.1.5: Rate Matching
#define NR_POLAR_PUCCH_I_BIL 0 //uint8_t
#define NR_POLAR_PUCCH_E 864 //uint16_t
// Ref. 38-212 v15.0.1, Section 7.1.5: Rate Matching
#define NR_POLAR_PUCCH_I_BIL 0 // uint8_t
#define NR_POLAR_PUCCH_E 864 // uint16_t
/* /*
* TEST CODE * TEST CODE
*/ */
//unsigned int testPayload0=0x00000000, testPayload1=0xffffffff; //payload1=~payload0; // unsigned int testPayload0=0x00000000, testPayload1=0xffffffff; //payload1=~payload0;
//unsigned int testPayload2=0xa5a5a5a5, testPayload3=0xb3f02c82; // unsigned int testPayload2=0xa5a5a5a5, testPayload3=0xb3f02c82;
#endif #endif
@@ -22,7 +22,8 @@
#include <math.h> #include <math.h>
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P_i_, uint16_t K, uint16_t N, uint16_t E){ void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P_i_, uint16_t K, uint16_t N, uint16_t E)
{
int d[N]; int d[N];
int y[N]; int y[N];
@@ -53,8 +54,8 @@ void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P
} }
} }
void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp, uint16_t K, uint16_t N, uint16_t E)
void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp, uint16_t K, uint16_t N, uint16_t E){ {
if (E >= N) { // repetition if (E >= N) { // repetition
for (int i = 0; i <= N - 1; i++) for (int i = 0; i <= N - 1; i++)
output[i] = 0; output[i] = 0;
File diff suppressed because one or more lines are too long
@@ -20,32 +20,32 @@
*/ */
/*! \file PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h /*! \file PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h
* \brief Defines the constant variables for polar coding of the UCI from 38-212, V15.1.1 2018-04. * \brief Defines the constant variables for polar coding of the UCI from 38-212, V15.1.1 2018-04.
* \author * \author
* \date 2018 * \date 2018
* \version 0.1 * \version 0.1
* \company Eurecom * \company Eurecom
* \email: * \email:
* \note * \note
* \warning * \warning
*/ */
#ifndef __NR_POLAR_UCI_DEFS__H__ #ifndef __NR_POLAR_UCI_DEFS__H__
#define __NR_POLAR_UCI_DEFS__H__ #define __NR_POLAR_UCI_DEFS__H__
#define NR_POLAR_UCI_PUCCH_MESSAGE_TYPE 2 //int8_t #define NR_POLAR_UCI_PUCCH_MESSAGE_TYPE 2 // int8_t
#define NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS 3 #define NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS 3
#define NR_POLAR_PUCCH_PAYLOAD_BITS 32 #define NR_POLAR_PUCCH_PAYLOAD_BITS 32
#define NR_POLAR_PUCCH_E 32 #define NR_POLAR_PUCCH_E 32
//Ref. 38-212, Section 6.3.1.2.1 // Ref. 38-212, Section 6.3.1.2.1
#define NR_POLAR_PUCCH_CRC_PARITY_BITS_SHORT 6 #define NR_POLAR_PUCCH_CRC_PARITY_BITS_SHORT 6
#define NR_POLAR_PUCCH_CRC_PARITY_BITS_LONG 11 #define NR_POLAR_PUCCH_CRC_PARITY_BITS_LONG 11
#define NR_POLAR_PUCCH_I_SEG_LONG 1 #define NR_POLAR_PUCCH_I_SEG_LONG 1
#define NR_POLAR_PUCCH_I_SEG_SHORT 0 #define NR_POLAR_PUCCH_I_SEG_SHORT 0
//Ref. 38-212, Section 6.3.1.3.1 // Ref. 38-212, Section 6.3.1.3.1
#define NR_POLAR_PUCCH_N_MAX 10 #define NR_POLAR_PUCCH_N_MAX 10
#define NR_POLAR_PUCCH_I_IL 0 #define NR_POLAR_PUCCH_I_IL 0
#define NR_POLAR_PUCCH_N_PC_SHORT 3 #define NR_POLAR_PUCCH_N_PC_SHORT 3
@@ -53,9 +53,7 @@
#define NR_POLAR_PUCCH_N_PC_WM_LONG 0 #define NR_POLAR_PUCCH_N_PC_WM_LONG 0
#define NR_POLAR_PUCCH_N_PC_WM_SHORT 1 #define NR_POLAR_PUCCH_N_PC_WM_SHORT 1
//Ref. 38-212, Section 6.3.1.4.1 // Ref. 38-212, Section 6.3.1.4.1
#define NR_POLAR_PUCCH_I_BIL 1 #define NR_POLAR_PUCCH_I_BIL 1
#endif #endif
+64 -47
View File
@@ -34,15 +34,17 @@
#include "PHY/NR_TRANSPORT/nr_dci.h" #include "PHY/NR_TRANSPORT/nr_dci.h"
#include "nrPolar_tools/nr_polar_psbch_defs.h" #include "nrPolar_tools/nr_polar_psbch_defs.h"
#define PolarKey ((messageType<<24)|(messageLength<<8)|aggregation_level) #define PolarKey ((messageType << 24) | (messageLength << 8) | aggregation_level)
static t_nrPolar_params * PolarList=NULL; static t_nrPolar_params *PolarList = NULL;
pthread_mutex_t PolarListMutex=PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t PolarListMutex = PTHREAD_MUTEX_INITIALIZER;
static int intcmp(const void *p1,const void *p2) { static int intcmp(const void *p1, const void *p2)
return(*(int16_t *)p1 > *(int16_t *)p2); {
return (*(int16_t *)p1 > *(int16_t *)p2);
} }
static void nr_polar_delete_list(t_nrPolar_params * polarParams) { static void nr_polar_delete_list(t_nrPolar_params *polarParams)
{
if (!polarParams) if (!polarParams)
return; return;
if (polarParams->nextPtr) if (polarParams->nextPtr)
@@ -64,11 +66,12 @@ static void nr_polar_delete_list(t_nrPolar_params * polarParams) {
free(polarParams); free(polarParams);
} }
static void nr_polar_delete(void) { static void nr_polar_delete(void)
{
pthread_mutex_lock(&PolarListMutex); pthread_mutex_lock(&PolarListMutex);
nr_polar_delete_list(PolarList); nr_polar_delete_list(PolarList);
PolarList=NULL; PolarList = NULL;
pthread_mutex_unlock(&PolarListMutex); pthread_mutex_unlock(&PolarListMutex);
} }
t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, uint8_t aggregation_level) t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, uint8_t aggregation_level)
@@ -76,34 +79,35 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
// The lock is weak, because we never delete in the list, only at exit time // The lock is weak, because we never delete in the list, only at exit time
// therefore, returning t_nrPolar_params * from the list is safe for future usage // therefore, returning t_nrPolar_params * from the list is safe for future usage
pthread_mutex_lock(&PolarListMutex); pthread_mutex_lock(&PolarListMutex);
if(!PolarList) if (!PolarList)
atexit(nr_polar_delete); atexit(nr_polar_delete);
t_nrPolar_params *currentPtr = PolarList; t_nrPolar_params *currentPtr = PolarList;
//Parse the list. If the node is already created, return without initialization. // Parse the list. If the node is already created, return without initialization.
while (currentPtr != NULL) { while (currentPtr != NULL) {
//printf("currentPtr->idx %d, (%d,%d)\n",currentPtr->idx,currentPtr->payloadBits,currentPtr->encoderLength); // printf("currentPtr->idx %d, (%d,%d)\n",currentPtr->idx,currentPtr->payloadBits,currentPtr->encoderLength);
//LOG_D(PHY,"Looking for index %d\n",(messageType * messageLength * aggregation_prime)); // LOG_D(PHY,"Looking for index %d\n",(messageType * messageLength * aggregation_prime));
if (currentPtr->busy == false && currentPtr->idx == PolarKey ) { if (currentPtr->busy == false && currentPtr->idx == PolarKey) {
currentPtr->busy=true; currentPtr->busy = true;
pthread_mutex_unlock(&PolarListMutex); pthread_mutex_unlock(&PolarListMutex);
return currentPtr ; return currentPtr;
} } else
else
currentPtr = currentPtr->nextPtr; currentPtr = currentPtr->nextPtr;
} }
// printf("currentPtr %p (polarParams %p)\n",currentPtr,polarParams); // printf("currentPtr %p (polarParams %p)\n",currentPtr,polarParams);
//Else, initialize and add node to the end of the linked list. // Else, initialize and add node to the end of the linked list.
t_nrPolar_params *newPolarInitNode = malloc(sizeof(t_nrPolar_params)); t_nrPolar_params *newPolarInitNode = malloc(sizeof(t_nrPolar_params));
AssertFatal(newPolarInitNode, "[nr_polar_init] New t_nrPolar_params * could not be created"); AssertFatal(newPolarInitNode, "[nr_polar_init] New t_nrPolar_params * could not be created");
*newPolarInitNode = (t_nrPolar_params){.busy = true, .nextPtr = PolarList, .tree_linearization.is_initialized = false}; *newPolarInitNode = (t_nrPolar_params){.busy = true, .nextPtr = PolarList, .tree_linearization.is_initialized = false};
PolarList = newPolarInitNode; PolarList = newPolarInitNode;
pthread_mutex_unlock(&PolarListMutex); pthread_mutex_unlock(&PolarListMutex);
// LOG_D(PHY,"Setting new polarParams index %d, messageType %d, messageLength %d, aggregation_prime %d\n",(messageType * messageLength * aggregation_prime),messageType,messageLength,aggregation_prime); // LOG_D(PHY,"Setting new polarParams index %d, messageType %d, messageLength %d, aggregation_prime %d\n",(messageType *
// messageLength * aggregation_prime),messageType,messageLength,aggregation_prime);
newPolarInitNode->idx = PolarKey; newPolarInitNode->idx = PolarKey;
//printf("newPolarInitNode->idx %d, (%d,%d,%d:%d)\n",newPolarInitNode->idx,messageType,messageLength,aggregation_prime,aggregation_level); // printf("newPolarInitNode->idx %d,
// (%d,%d,%d:%d)\n",newPolarInitNode->idx,messageType,messageLength,aggregation_prime,aggregation_level);
if (messageType == NR_POLAR_PBCH_MESSAGE_TYPE) { if (messageType == NR_POLAR_PBCH_MESSAGE_TYPE) {
newPolarInitNode->n_max = NR_POLAR_PBCH_N_MAX; newPolarInitNode->n_max = NR_POLAR_PBCH_N_MAX;
@@ -117,7 +121,8 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
newPolarInitNode->encoderLength = NR_POLAR_PBCH_E; newPolarInitNode->encoderLength = NR_POLAR_PBCH_E;
newPolarInitNode->crcCorrectionBits = NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS; newPolarInitNode->crcCorrectionBits = NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits); // G_P newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits); // G_P
//printf("Initializing polar parameters for PBCH (K %d, E %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength); // printf("Initializing polar parameters for PBCH (K %d, E
// %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength);
} else if (messageType == NR_POLAR_DCI_MESSAGE_TYPE) { } else if (messageType == NR_POLAR_DCI_MESSAGE_TYPE) {
newPolarInitNode->n_max = NR_POLAR_DCI_N_MAX; newPolarInitNode->n_max = NR_POLAR_DCI_N_MAX;
@@ -130,11 +135,15 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
newPolarInitNode->payloadBits = messageLength; newPolarInitNode->payloadBits = messageLength;
newPolarInitNode->encoderLength = aggregation_level * 108; newPolarInitNode->encoderLength = aggregation_level * 108;
newPolarInitNode->crcCorrectionBits = NR_POLAR_DCI_CRC_ERROR_CORRECTION_BITS; newPolarInitNode->crcCorrectionBits = NR_POLAR_DCI_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits + newPolarInitNode->crcParityBits); // G_P newPolarInitNode->crc_generator_matrix =
//printf("Initializing polar parameters for DCI (K %d, E %d, L %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength,aggregation_level); crc24c_generator_matrix(newPolarInitNode->payloadBits + newPolarInitNode->crcParityBits); // G_P
// printf("Initializing polar parameters for DCI (K %d, E %d, L
// %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength,aggregation_level);
} else if (messageType == NR_POLAR_UCI_PUCCH_MESSAGE_TYPE) { } else if (messageType == NR_POLAR_UCI_PUCCH_MESSAGE_TYPE) {
AssertFatal(aggregation_level > 2, "Aggregation level (%d) for PUCCH 2 encoding is NPRB and should be > 2\n", aggregation_level); AssertFatal(aggregation_level > 2,
"Aggregation level (%d) for PUCCH 2 encoding is NPRB and should be > 2\n",
aggregation_level);
AssertFatal(messageLength > 11, "Message length %d is too short for polar encoding of UCI\n", messageLength); AssertFatal(messageLength > 11, "Message length %d is too short for polar encoding of UCI\n", messageLength);
// TS 38.212 - Section 6.3.1.2.1 UCI encoded by Polar code // TS 38.212 - Section 6.3.1.2.1 UCI encoded by Polar code
@@ -175,7 +184,7 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
newPolarInitNode->i_bil = NR_POLAR_PUCCH_I_BIL; newPolarInitNode->i_bil = NR_POLAR_PUCCH_I_BIL;
newPolarInitNode->payloadBits = messageLength; newPolarInitNode->payloadBits = messageLength;
newPolarInitNode->crcCorrectionBits = NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS; newPolarInitNode->crcCorrectionBits = NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS;
//LOG_D(PHY,"New polar node, encoderLength %d, aggregation_level %d\n",newPolarInitNode->encoderLength,aggregation_level); // LOG_D(PHY,"New polar node, encoderLength %d, aggregation_level %d\n",newPolarInitNode->encoderLength,aggregation_level);
} else if (messageType == SL_NR_POLAR_PSBCH_MESSAGE_TYPE) { // PSBCH } else if (messageType == SL_NR_POLAR_PSBCH_MESSAGE_TYPE) { // PSBCH
newPolarInitNode->n_max = SL_NR_POLAR_PSBCH_N_MAX; newPolarInitNode->n_max = SL_NR_POLAR_PSBCH_N_MAX;
newPolarInitNode->i_il = SL_NR_POLAR_PSBCH_I_IL; newPolarInitNode->i_il = SL_NR_POLAR_PSBCH_I_IL;
@@ -197,17 +206,13 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
} }
newPolarInitNode->K = newPolarInitNode->payloadBits + newPolarInitNode->crcParityBits; // Number of bits to encode. newPolarInitNode->K = newPolarInitNode->payloadBits + newPolarInitNode->crcParityBits; // Number of bits to encode.
newPolarInitNode->N = nr_polar_output_length(newPolarInitNode->K, newPolarInitNode->N = nr_polar_output_length(newPolarInitNode->K, newPolarInitNode->encoderLength, newPolarInitNode->n_max);
newPolarInitNode->encoderLength,
newPolarInitNode->n_max);
newPolarInitNode->n = log2(newPolarInitNode->N); newPolarInitNode->n = log2(newPolarInitNode->N);
newPolarInitNode->G_N = nr_polar_kronecker_power_matrices(newPolarInitNode->n); newPolarInitNode->G_N = nr_polar_kronecker_power_matrices(newPolarInitNode->n);
// polar_encoder vectors: // polar_encoder vectors:
newPolarInitNode->Q_0_Nminus1 = nr_polar_sequence_pattern(newPolarInitNode->n); newPolarInitNode->Q_0_Nminus1 = nr_polar_sequence_pattern(newPolarInitNode->n);
newPolarInitNode->interleaving_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->K); newPolarInitNode->interleaving_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->K);
nr_polar_interleaving_pattern(newPolarInitNode->K, nr_polar_interleaving_pattern(newPolarInitNode->K, newPolarInitNode->i_il, newPolarInitNode->interleaving_pattern);
newPolarInitNode->i_il,
newPolarInitNode->interleaving_pattern);
newPolarInitNode->rate_matching_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength); newPolarInitNode->rate_matching_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength);
uint16_t J[newPolarInitNode->N]; uint16_t J[newPolarInitNode->N];
@@ -224,8 +229,9 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
newPolarInitNode->information_bit_pattern = malloc(sizeof(uint8_t) * newPolarInitNode->N); newPolarInitNode->information_bit_pattern = malloc(sizeof(uint8_t) * newPolarInitNode->N);
newPolarInitNode->parity_check_bit_pattern = malloc(sizeof(uint8_t) * newPolarInitNode->N); newPolarInitNode->parity_check_bit_pattern = malloc(sizeof(uint8_t) * newPolarInitNode->N);
newPolarInitNode->Q_I_N = malloc(sizeof(int16_t) * (newPolarInitNode->K + newPolarInitNode->n_pc)); newPolarInitNode->Q_I_N = malloc(sizeof(int16_t) * (newPolarInitNode->K + newPolarInitNode->n_pc));
newPolarInitNode->Q_F_N = malloc( sizeof(int16_t) * (newPolarInitNode->N + 1)); // Last element shows the final array index assigned a value. newPolarInitNode->Q_F_N =
newPolarInitNode->Q_PC_N = malloc( sizeof(int16_t) * (newPolarInitNode->n_pc)); malloc(sizeof(int16_t) * (newPolarInitNode->N + 1)); // Last element shows the final array index assigned a value.
newPolarInitNode->Q_PC_N = malloc(sizeof(int16_t) * (newPolarInitNode->n_pc));
for (int i = 0; i <= newPolarInitNode->N; i++) for (int i = 0; i <= newPolarInitNode->N; i++)
newPolarInitNode->Q_F_N[i] = -1; // Empty array. newPolarInitNode->Q_F_N[i] = -1; // Empty array.
@@ -244,22 +250,26 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
newPolarInitNode->n_pc_wm); newPolarInitNode->n_pc_wm);
// sort the Q_I_N array in ascending order (first K positions) // sort the Q_I_N array in ascending order (first K positions)
qsort((void *)newPolarInitNode->Q_I_N,newPolarInitNode->K,sizeof(int16_t),intcmp); qsort((void *)newPolarInitNode->Q_I_N, newPolarInitNode->K, sizeof(int16_t), intcmp);
build_polar_tables(newPolarInitNode); build_polar_tables(newPolarInitNode);
return newPolarInitNode; return newPolarInitNode;
} }
void nr_polar_print_polarParams() { void nr_polar_print_polarParams()
{
uint8_t i = 0; uint8_t i = 0;
if (PolarList == NULL) { if (PolarList == NULL) {
printf("polarParams is empty.\n"); printf("polarParams is empty.\n");
} else { } else {
t_nrPolar_params * polarParams=PolarList; t_nrPolar_params *polarParams = PolarList;
while (polarParams != NULL) { while (polarParams != NULL) {
printf("polarParams[%d] = %d, %d, %d\n", i, printf("polarParams[%d] = %d, %d, %d\n",
polarParams->idx>>24, (polarParams->idx>>8)&0xFFFF, polarParams->idx&0xFF); i,
polarParams->idx >> 24,
(polarParams->idx >> 8) & 0xFFFF,
polarParams->idx & 0xFF);
polarParams = polarParams->nextPtr; polarParams = polarParams->nextPtr;
i++; i++;
} }
@@ -268,11 +278,18 @@ void nr_polar_print_polarParams() {
return; return;
} }
uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level) { uint16_t nr_polar_aggregation_prime(uint8_t aggregation_level)
if (aggregation_level == 0) return 0; {
else if (aggregation_level == 1) return NR_POLAR_AGGREGATION_LEVEL_1_PRIME; if (aggregation_level == 0)
else if (aggregation_level == 2) return NR_POLAR_AGGREGATION_LEVEL_2_PRIME; return 0;
else if (aggregation_level == 4) return NR_POLAR_AGGREGATION_LEVEL_4_PRIME; else if (aggregation_level == 1)
else if (aggregation_level == 8) return NR_POLAR_AGGREGATION_LEVEL_8_PRIME; return NR_POLAR_AGGREGATION_LEVEL_1_PRIME;
else return NR_POLAR_AGGREGATION_LEVEL_16_PRIME; //aggregation_level == 16 else if (aggregation_level == 2)
return NR_POLAR_AGGREGATION_LEVEL_2_PRIME;
else if (aggregation_level == 4)
return NR_POLAR_AGGREGATION_LEVEL_4_PRIME;
else if (aggregation_level == 8)
return NR_POLAR_AGGREGATION_LEVEL_8_PRIME;
else
return NR_POLAR_AGGREGATION_LEVEL_16_PRIME; // aggregation_level == 16
} }