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:
@@ -12,161 +12,162 @@
|
||||
#include "PHY/CODING/coding_defs.h"
|
||||
#include "SIMULATION/TOOLS/sim.h"
|
||||
#include "common/config/config_userapi.h"
|
||||
//#include "common/utils/LOG/log.h"
|
||||
// #include "common/utils/LOG/log.h"
|
||||
#include "coding_unitary_defs.h"
|
||||
//#define DEBUG_DCI_POLAR_PARAMS
|
||||
//#define DEBUG_POLAR_TIMING
|
||||
//#define DEBUG_POLARTEST
|
||||
// #define DEBUG_DCI_POLAR_PARAMS
|
||||
// #define DEBUG_POLAR_TIMING
|
||||
// #define DEBUG_POLARTEST
|
||||
|
||||
configmodule_interface_t *uniqCfg = NULL;
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
//Default simulation values (Aim for iterations = 1000000.)
|
||||
int decoder_int16=0;
|
||||
int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, 2=UCI
|
||||
double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB
|
||||
// Default simulation values (Aim for iterations = 1000000.)
|
||||
int decoder_int16 = 0;
|
||||
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 SNR, SNR_lin;
|
||||
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 blockErrorCumulative=0, bitErrorCumulative=0;
|
||||
uint16_t blockErrorCumulative = 0, bitErrorCumulative = 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) {
|
||||
exit_fun("[POLARTEST] Error, configuration module init failed\n");
|
||||
}
|
||||
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 */
|
||||
/* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */
|
||||
if (arguments == 1 || arguments == '-' || arguments == 'O')
|
||||
continue;
|
||||
|
||||
printf("handling optarg %c\n",arguments);
|
||||
printf("handling optarg %c\n", arguments);
|
||||
switch (arguments) {
|
||||
case 's':
|
||||
SNRstart = atof(optarg);
|
||||
SNRstop = SNRstart + 2;
|
||||
break;
|
||||
case 's':
|
||||
SNRstart = atof(optarg);
|
||||
SNRstop = SNRstart + 2;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
SNRinc = atof(optarg);
|
||||
break;
|
||||
case 'd':
|
||||
SNRinc = atof(optarg);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
SNRstop = atof(optarg);
|
||||
break;
|
||||
case 'f':
|
||||
SNRstop = atof(optarg);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
polarMessageType = atoi(optarg);
|
||||
if (polarMessageType!=0 && polarMessageType!=1 && polarMessageType!=2)
|
||||
printf("Illegal polar message type %d (should be 0,1 or 2)\n", polarMessageType);
|
||||
break;
|
||||
case 'm':
|
||||
polarMessageType = atoi(optarg);
|
||||
if (polarMessageType != 0 && polarMessageType != 1 && polarMessageType != 2)
|
||||
printf("Illegal polar message type %d (should be 0,1 or 2)\n", polarMessageType);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
iterations = atoi(optarg);
|
||||
break;
|
||||
case 'i':
|
||||
iterations = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
decoderListSize = (uint8_t) atoi(optarg);
|
||||
break;
|
||||
case 'l':
|
||||
decoderListSize = (uint8_t)atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
decoder_int16 = 1;
|
||||
break;
|
||||
case 'q':
|
||||
decoder_int16 = 1;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
iterations = 1;
|
||||
SNRstart = -6.0;
|
||||
SNRstop = -6.0;
|
||||
decoder_int16 = 1;
|
||||
break;
|
||||
case 'g':
|
||||
iterations = 1;
|
||||
SNRstart = -6.0;
|
||||
SNRstop = -6.0;
|
||||
decoder_int16 = 1;
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
logFlag = 1;
|
||||
break;
|
||||
case 'F':
|
||||
logFlag = 1;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
aggregation_level=atoi(optarg);
|
||||
if (aggregation_level != 1 && aggregation_level != 2 && aggregation_level != 4 && aggregation_level != 8
|
||||
&& aggregation_level != 16) {
|
||||
printf("Illegal aggregation level %d \n", aggregation_level);
|
||||
case 'L':
|
||||
aggregation_level = atoi(optarg);
|
||||
if (aggregation_level != 1 && aggregation_level != 2 && aggregation_level != 4 && aggregation_level != 8
|
||||
&& aggregation_level != 16) {
|
||||
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);
|
||||
}
|
||||
break;
|
||||
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);
|
||||
break;
|
||||
|
||||
default:
|
||||
perror("[polartest.c] Problem at argument parsing with getopt");
|
||||
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.)
|
||||
time_stats_t timeEncoder,timeDecoder;
|
||||
// Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.)
|
||||
time_stats_t timeEncoder, timeDecoder;
|
||||
cpu_meas_enabled = 1;
|
||||
reset_meas(&timeEncoder);
|
||||
reset_meas(&timeDecoder);
|
||||
randominit(0);
|
||||
crcTableInit();
|
||||
|
||||
if (polarMessageType == 0) { //PBCH
|
||||
if (polarMessageType == 0) { // PBCH
|
||||
aggregation_level = NR_POLAR_PBCH_AGGREGATION_LEVEL;
|
||||
} else if (polarMessageType == 1) { //DCI
|
||||
coderLength = 108*aggregation_level;
|
||||
} else if (polarMessageType == 2) { //UCI
|
||||
//pucch2 parameters, 1 symbol, aggregation_level = NPRB
|
||||
AssertFatal(aggregation_level>2,"For UCI formats, aggregation (N_RB) should be > 2\n");
|
||||
coderLength = 16*aggregation_level;
|
||||
} else if (polarMessageType == 1) { // DCI
|
||||
coderLength = 108 * aggregation_level;
|
||||
} else if (polarMessageType == 2) { // UCI
|
||||
// pucch2 parameters, 1 symbol, aggregation_level = NPRB
|
||||
AssertFatal(aggregation_level > 2, "For UCI formats, aggregation (N_RB) should be > 2\n");
|
||||
coderLength = 16 * aggregation_level;
|
||||
}
|
||||
|
||||
//Logging
|
||||
// Logging
|
||||
time_t currentTime;
|
||||
char fileName[512], currentTimeInfo[25];
|
||||
char folderName[] = ".";
|
||||
FILE *logFile = NULL;
|
||||
|
||||
if (logFlag){
|
||||
time (¤tTime);
|
||||
if (logFlag) {
|
||||
time(¤tTime);
|
||||
#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
|
||||
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
|
||||
strftime(currentTimeInfo, 25, "_%Y-%m-%d-%H-%M-%S.csv", localtime(¤tTime));
|
||||
strcat(fileName,currentTimeInfo);
|
||||
//Create "~/Desktop/polartestResults" folder if it doesn't already exist.
|
||||
strcat(fileName, currentTimeInfo);
|
||||
// Create "~/Desktop/polartestResults" folder if it doesn't already exist.
|
||||
/*struct stat folder = {0};
|
||||
if (stat(folderName, &folder) == -1) mkdir(folderName, S_IRWXU | S_IRWXG | S_IRWXO);*/
|
||||
logFile = fopen(fileName, "w");
|
||||
|
||||
if (logFile==NULL) {
|
||||
fprintf(stderr,"[polartest.c] Problem creating file %s with fopen\n",fileName);
|
||||
if (logFile == NULL) {
|
||||
fprintf(stderr, "[polartest.c] Problem creating file %s with fopen\n", fileName);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
#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
|
||||
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
|
||||
}
|
||||
|
||||
@@ -177,54 +178,55 @@ int main(int argc, char *argv[])
|
||||
// satisfies uint64_t array length
|
||||
const uint8_t realArrayLength = ((testArrayLength + 1) / 2) * 2;
|
||||
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 estimatedOutput[realArrayLength]; //decoder output
|
||||
memset(testInput,0,sizeof(uint32_t) * realArrayLength); // does not reset all
|
||||
memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength);
|
||||
memset(estimatedOutput,0,sizeof(uint32_t) * realArrayLength);
|
||||
uint32_t estimatedOutput[realArrayLength]; // decoder output
|
||||
memset(testInput, 0, sizeof(uint32_t) * realArrayLength); // does not reset all
|
||||
memset(encoderOutput, 0, sizeof(uint32_t) * coderArrayLength);
|
||||
memset(estimatedOutput, 0, sizeof(uint32_t) * realArrayLength);
|
||||
uint8_t encoderOutputByte[coderLength];
|
||||
double modulatedInput[coderLength]; //channel input
|
||||
double channelOutput[coderLength]; //add noise
|
||||
double modulatedInput[coderLength]; // channel input
|
||||
double channelOutput[coderLength]; // add noise
|
||||
int16_t channelOutput_int16[coderLength];
|
||||
|
||||
t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level);
|
||||
|
||||
#ifdef DEBUG_DCI_POLAR_PARAMS
|
||||
uint32_t dci_pdu[4];
|
||||
memset(dci_pdu,0,sizeof(uint32_t)*4);
|
||||
dci_pdu[0]=0x01189400;
|
||||
memset(dci_pdu, 0, sizeof(uint32_t) * 4);
|
||||
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]);
|
||||
uint16_t size=41;
|
||||
rnti=3;
|
||||
aggregation_level=8;
|
||||
uint16_t size = 41;
|
||||
rnti = 3;
|
||||
aggregation_level = 8;
|
||||
uint32_t encoder_output[54];
|
||||
memset(encoder_output,0,sizeof(uint32_t)*54);
|
||||
t_nrPolar_params *currentPtrDCI=nr_polar_params(1, size, aggregation_level);
|
||||
memset(encoder_output, 0, sizeof(uint32_t) * 54);
|
||||
t_nrPolar_params *currentPtrDCI = nr_polar_params(1, size, aggregation_level);
|
||||
|
||||
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]);
|
||||
|
||||
uint8_t *encoder_outputByte = malloc(sizeof(uint8_t) * currentPtrDCI->encoderLength);
|
||||
double *modulated_input = malloc (sizeof(double) * currentPtrDCI->encoderLength);
|
||||
double *channel_output = malloc (sizeof(double) * currentPtrDCI->encoderLength);
|
||||
double *modulated_input = malloc(sizeof(double) * currentPtrDCI->encoderLength);
|
||||
double *channel_output = malloc(sizeof(double) * currentPtrDCI->encoderLength);
|
||||
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);
|
||||
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
|
||||
for(int i=0; i<currentPtrDCI->encoderLength; i++) {
|
||||
SNR_lin = pow(10, 0 / 10); // SNR = 0 dB
|
||||
for (int i = 0; i < currentPtrDCI->encoderLength; i++) {
|
||||
if (encoder_outputByte[i] == 0)
|
||||
modulated_input[i]=1/sqrt(2);
|
||||
modulated_input[i] = 1 / sqrt(2);
|
||||
else
|
||||
modulated_input[i]=(-1)/sqrt(2);
|
||||
channel_output[i] = modulated_input[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin)));
|
||||
modulated_input[i] = (-1) / sqrt(2);
|
||||
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,
|
||||
1, size, aggregation_level);
|
||||
decoderState = polar_decoder_dci(channel_output, dci_est, NR_POLAR_DECODER_LISTSIZE, rnti, 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]);
|
||||
free(encoder_outputByte);
|
||||
free(channel_output);
|
||||
@@ -235,56 +237,56 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
|
||||
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
|
||||
printf("SNR %f\n",SNR);
|
||||
SNR_lin = pow(10, SNR/10);
|
||||
printf("SNR %f\n", SNR);
|
||||
SNR_lin = pow(10, SNR / 10);
|
||||
|
||||
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 j = 0; j < (sizeof(testInput[0])*8)-1; j++) {
|
||||
testInput[i] |= ( ((uint32_t) (rand()%2)) &1);
|
||||
testInput[i]<<=1;
|
||||
}
|
||||
testInput[i] |= ( ((uint32_t) (rand()%2)) &1);
|
||||
for (int j = 0; j < (sizeof(testInput[0]) * 8) - 1; j++) {
|
||||
testInput[i] |= (((uint32_t)(rand() % 2)) & 1);
|
||||
testInput[i] <<= 1;
|
||||
}
|
||||
testInput[i] |= (((uint32_t)(rand() % 2)) & 1);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_POLARTEST
|
||||
//testInput[0] = 0x360f8a5c;
|
||||
// testInput[0] = 0x360f8a5c;
|
||||
printf("testInput: [0]->0x%08x\n", testInput[0]);
|
||||
#endif
|
||||
int len_mod64=currentPtr->payloadBits&63;
|
||||
((uint64_t *)testInput)[currentPtr->payloadBits/64]&=((((uint64_t)1)<<len_mod64)-1);
|
||||
int len_mod64 = currentPtr->payloadBits & 63;
|
||||
((uint64_t *)testInput)[currentPtr->payloadBits / 64] &= ((((uint64_t)1) << len_mod64) - 1);
|
||||
|
||||
start_meas(&timeEncoder);
|
||||
if (decoder_int16==1) {
|
||||
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);
|
||||
} else { //0 --> PBCH, 1 --> DCI, -1 --> UCI
|
||||
if (polarMessageType == 0)
|
||||
polar_encoder(testInput, encoderOutput, polarMessageType, testLength, aggregation_level);
|
||||
else if (polarMessageType == 1)
|
||||
polar_encoder_dci(testInput, encoderOutput, rnti, polarMessageType, testLength, aggregation_level);
|
||||
if (decoder_int16 == 1) {
|
||||
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);
|
||||
} else { // 0 --> PBCH, 1 --> DCI, -1 --> UCI
|
||||
if (polarMessageType == 0)
|
||||
polar_encoder(testInput, encoderOutput, polarMessageType, testLength, aggregation_level);
|
||||
else if (polarMessageType == 1)
|
||||
polar_encoder_dci(testInput, encoderOutput, rnti, polarMessageType, testLength, aggregation_level);
|
||||
}
|
||||
stop_meas(&timeEncoder);
|
||||
|
||||
#ifdef DEBUG_POLARTEST
|
||||
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
|
||||
|
||||
//Bit-to-byte:
|
||||
// Bit-to-byte:
|
||||
nr_bit2byte_uint32_8(encoderOutput, coderLength, encoderOutputByte);
|
||||
|
||||
//BPSK modulation
|
||||
for(int i=0; i<coderLength; i++) {
|
||||
if (encoderOutputByte[i] == 0)
|
||||
modulatedInput[i]=1/sqrt(2);
|
||||
else
|
||||
modulatedInput[i]=(-1)/sqrt(2);
|
||||
// BPSK modulation
|
||||
for (int i = 0; i < coderLength; i++) {
|
||||
if (encoderOutputByte[i] == 0)
|
||||
modulatedInput[i] = 1 / sqrt(2);
|
||||
else
|
||||
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)
|
||||
channelOutput_int16[i] = 127;
|
||||
else if (channelOutput[i] < -16)
|
||||
@@ -306,7 +308,7 @@ int main(int argc, char *argv[])
|
||||
} else { // 0 --> PBCH, 1 --> DCI, -1 --> UCI
|
||||
if (polarMessageType == 0) {
|
||||
decoderState =
|
||||
polar_decoder(channelOutput, estimatedOutput, decoderListSize, polarMessageType, testLength, aggregation_level);
|
||||
polar_decoder(channelOutput, estimatedOutput, decoderListSize, polarMessageType, testLength, aggregation_level);
|
||||
} else if (polarMessageType == 1) {
|
||||
decoderState = polar_decoder_dci(channelOutput,
|
||||
estimatedOutput,
|
||||
@@ -318,70 +320,83 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
stop_meas(&timeDecoder);
|
||||
|
||||
|
||||
#ifdef DEBUG_POLARTEST
|
||||
printf("estimatedOutput: [0]->0x%08x\n", estimatedOutput[0]);
|
||||
#endif
|
||||
|
||||
//calculate errors
|
||||
if (decoderState!=0) {
|
||||
blockErrorState=-1;
|
||||
nBitError=-1;
|
||||
// calculate errors
|
||||
if (decoderState != 0) {
|
||||
blockErrorState = -1;
|
||||
nBitError = -1;
|
||||
} else {
|
||||
for (int i = 0; i < (testArrayLength-1); i++) {
|
||||
for (int j = 0; j < 32; j++) {
|
||||
if ( ((estimatedOutput[i]>>j) & 1) != ((testInput[i]>>j) & 1) )
|
||||
nBitError++;
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < testLength - ((testArrayLength-1) * 32); j++)
|
||||
if ( ((estimatedOutput[(testArrayLength-1)]>>j) & 1) != ((testInput[(testArrayLength-1)]>>j) & 1) )
|
||||
nBitError++;
|
||||
for (int i = 0; i < (testArrayLength - 1); i++) {
|
||||
for (int j = 0; j < 32; j++) {
|
||||
if (((estimatedOutput[i] >> j) & 1) != ((testInput[i] >> j) & 1))
|
||||
nBitError++;
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < testLength - ((testArrayLength - 1) * 32); j++)
|
||||
if (((estimatedOutput[(testArrayLength - 1)] >> j) & 1) != ((testInput[(testArrayLength - 1)] >> j) & 1))
|
||||
nBitError++;
|
||||
}
|
||||
if (nBitError>0) blockErrorState=1;
|
||||
if (nBitError > 0)
|
||||
blockErrorState = 1;
|
||||
#ifdef DEBUG_POLARTEST
|
||||
for (int i = 0; i < testArrayLength; i++)
|
||||
printf("[polartest/decoderState=%u] testInput[%d]=0x%08x, estimatedOutput[%d]=0x%08x\n",
|
||||
decoderState,
|
||||
i,
|
||||
testInput[i],
|
||||
i,
|
||||
estimatedOutput[i]);
|
||||
printf("[polartest/decoderState=%u] testInput[%d]=0x%08x, estimatedOutput[%d]=0x%08x\n",
|
||||
decoderState,
|
||||
i,
|
||||
testInput[i],
|
||||
i,
|
||||
estimatedOutput[i]);
|
||||
#endif
|
||||
|
||||
//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)));
|
||||
// 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 (nBitError<0) {
|
||||
if (nBitError < 0) {
|
||||
blockErrorCumulative++;
|
||||
bitErrorCumulative+=testLength;
|
||||
bitErrorCumulative += testLength;
|
||||
} else {
|
||||
blockErrorCumulative+=blockErrorState;
|
||||
bitErrorCumulative+=nBitError;
|
||||
blockErrorCumulative += blockErrorState;
|
||||
bitErrorCumulative += nBitError;
|
||||
}
|
||||
|
||||
decoderState=0;
|
||||
nBitError=0;
|
||||
blockErrorState=0;
|
||||
memset(testInput,0,sizeof(uint32_t) * realArrayLength);
|
||||
memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength);
|
||||
memset(estimatedOutput,0,sizeof(uint32_t) * realArrayLength);
|
||||
decoderState = 0;
|
||||
nBitError = 0;
|
||||
blockErrorState = 0;
|
||||
memset(testInput, 0, sizeof(uint32_t) * realArrayLength);
|
||||
memset(encoderOutput, 0, sizeof(uint32_t) * coderArrayLength);
|
||||
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",
|
||||
decoderListSize, SNR, ((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));
|
||||
decoderListSize,
|
||||
SNR,
|
||||
((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;
|
||||
bitErrorCumulative = 0;
|
||||
}
|
||||
|
||||
print_meas(&timeEncoder,"polar_encoder",NULL,NULL);
|
||||
print_meas(&timeDecoder,"polar_decoder",NULL,NULL);
|
||||
if (logFlag) fclose(logFile);
|
||||
print_meas(&timeEncoder, "polar_encoder", NULL, NULL);
|
||||
print_meas(&timeDecoder, "polar_decoder", NULL, NULL);
|
||||
if (logFlag)
|
||||
fclose(logFile);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -28,11 +28,12 @@
|
||||
* \email turker.yilmaz@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
*/
|
||||
|
||||
#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);
|
||||
for (int i = 0; i < (arrayInd - 1); i++) {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
for (int i = 0; i < arrayInd; i++) {
|
||||
out[i] = 0;
|
||||
|
||||
@@ -29,7 +29,8 @@ const uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits)
|
||||
uint8_t crcPolynomialSize = 24;
|
||||
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)
|
||||
for (int i = 0; i < payloadSizeBits; i++)
|
||||
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];
|
||||
|
||||
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;
|
||||
|
||||
@@ -46,10 +48,10 @@ const uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits)
|
||||
temp2[j] = crc_generator_matrix[i + 1][0] * crcPolynomialPattern[j + 1];
|
||||
|
||||
for (int j = 0; j < crcPolynomialSize; j++) {
|
||||
if(temp1[j]+temp2[j] == 1)
|
||||
crc_generator_matrix[i][j]=1;
|
||||
else
|
||||
crc_generator_matrix[i][j]=0;
|
||||
if (temp1[j] + temp2[j] == 1)
|
||||
crc_generator_matrix[i][j] = 1;
|
||||
else
|
||||
crc_generator_matrix[i][j] = 0;
|
||||
}
|
||||
}
|
||||
return (const uint8_t **)crc_generator_matrix;
|
||||
|
||||
@@ -20,31 +20,31 @@
|
||||
*/
|
||||
|
||||
/*! \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.
|
||||
* \author
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email:
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
* \brief Defines the constant variables for polar coding of the DCI from 38-212, V15.1.1 2018-04.
|
||||
* \author
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email:
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#ifndef __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_ERROR_CORRECTION_BITS 3
|
||||
|
||||
//Sec. 7.3.3: Channel Coding
|
||||
#define NR_POLAR_DCI_N_MAX 9 //uint8_t
|
||||
#define NR_POLAR_DCI_I_IL 1 //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_WM 0 //uint8_t
|
||||
// Sec. 7.3.3: Channel Coding
|
||||
#define NR_POLAR_DCI_N_MAX 9 // uint8_t
|
||||
#define NR_POLAR_DCI_I_IL 1 // 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_WM 0 // uint8_t
|
||||
|
||||
//Sec. 7.3.4: Rate Matching
|
||||
#define NR_POLAR_DCI_I_BIL 0 //uint8_t
|
||||
// Sec. 7.3.4: Rate Matching
|
||||
#define NR_POLAR_DCI_I_BIL 0 // uint8_t
|
||||
|
||||
#endif
|
||||
|
||||
@@ -39,17 +39,17 @@
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||
#include "assertions.h"
|
||||
|
||||
//#define POLAR_CODING_DEBUG
|
||||
// #define POLAR_CODING_DEBUG
|
||||
|
||||
static inline void updateCrcChecksum2(int xlen,
|
||||
int ylen,
|
||||
uint8_t crcChecksum[xlen][ylen],
|
||||
int gxlen,
|
||||
int gylen,
|
||||
uint8_t crcGen[gxlen][gylen],
|
||||
uint8_t listSize,
|
||||
uint32_t i2,
|
||||
uint8_t len)
|
||||
int ylen,
|
||||
uint8_t crcChecksum[xlen][ylen],
|
||||
int gxlen,
|
||||
int gylen,
|
||||
uint8_t crcGen[gxlen][gylen],
|
||||
uint8_t listSize,
|
||||
uint32_t i2,
|
||||
uint8_t len)
|
||||
{
|
||||
for (uint i = 0; i < listSize; i++) {
|
||||
for (uint j = 0; j < len; j++) {
|
||||
@@ -63,67 +63,71 @@ int8_t polar_decoder(double *input,
|
||||
uint8_t listSize,
|
||||
int8_t messageType,
|
||||
uint16_t messageLength,
|
||||
uint8_t aggregation_level
|
||||
)
|
||||
uint8_t 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];
|
||||
memset(bit, 0, sizeof bit);
|
||||
uint8_t bitUpdated[polarParams->N][polarParams->n+1]; //0=False, 1=True
|
||||
memset(bitUpdated,0,sizeof bitUpdated);
|
||||
uint8_t llrUpdated[polarParams->N][polarParams->n+1]; //0=False, 1=True
|
||||
memset(llrUpdated,0,sizeof llrUpdated);
|
||||
uint8_t bitUpdated[polarParams->N][polarParams->n + 1]; // 0=False, 1=True
|
||||
memset(bitUpdated, 0, sizeof bitUpdated);
|
||||
uint8_t llrUpdated[polarParams->N][polarParams->n + 1]; // 0=False, 1=True
|
||||
memset(llrUpdated, 0, sizeof llrUpdated);
|
||||
double llr[polarParams->N][polarParams->n + 1][2 * listSize];
|
||||
uint8_t crcChecksum[polarParams->crcParityBits][2*listSize];
|
||||
memset(crcChecksum,0,sizeof crcChecksum);
|
||||
double pathMetric[2*listSize];
|
||||
uint8_t crcState[2*listSize]; //0=False, 1=True
|
||||
uint8_t crcChecksum[polarParams->crcParityBits][2 * listSize];
|
||||
memset(crcChecksum, 0, sizeof crcChecksum);
|
||||
double pathMetric[2 * listSize];
|
||||
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;
|
||||
crcState[i]=1;
|
||||
crcState[i] = 1;
|
||||
}
|
||||
|
||||
for (int i=0; i<polarParams->N; i++) {
|
||||
llrUpdated[i][polarParams->n]=1;
|
||||
for (int i = 0; i < polarParams->N; i++) {
|
||||
llrUpdated[i][polarParams->n] = 1;
|
||||
bitUpdated[i][0] = (polarParams->information_bit_pattern[i] + 1) % 2;
|
||||
}
|
||||
|
||||
uint8_t extended_crc_generator_matrix[polarParams->K][polarParams->crcParityBits]; //G_P3
|
||||
uint8_t tempECGM[polarParams->K][polarParams->crcParityBits]; //G_P2
|
||||
uint8_t extended_crc_generator_matrix[polarParams->K][polarParams->crcParityBits]; // G_P3
|
||||
uint8_t tempECGM[polarParams->K][polarParams->crcParityBits]; // G_P2
|
||||
|
||||
for (int i=0; i<polarParams->payloadBits; i++) {
|
||||
for (int j=0; j<polarParams->crcParityBits; j++) {
|
||||
tempECGM[i][j]=polarParams->crc_generator_matrix[i][j];
|
||||
for (int i = 0; i < polarParams->payloadBits; i++) {
|
||||
for (int j = 0; j < polarParams->crcParityBits; j++) {
|
||||
tempECGM[i][j] = polarParams->crc_generator_matrix[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=polarParams->payloadBits; i<polarParams->K; i++) {
|
||||
for (int j=0; j<polarParams->crcParityBits; j++) {
|
||||
for (int i = polarParams->payloadBits; i < polarParams->K; i++) {
|
||||
for (int j = 0; j < polarParams->crcParityBits; j++) {
|
||||
tempECGM[i][j] = (i - polarParams->payloadBits) == j;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<polarParams->K; i++) {
|
||||
for (int j=0; j<polarParams->crcParityBits; j++) {
|
||||
extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j];
|
||||
for (int i = 0; i < polarParams->K; i++) {
|
||||
for (int j = 0; j < polarParams->crcParityBits; 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.
|
||||
AssertFatal(polarParams->crcParityBits > 0, "UB for VLA. crcParityBits negative\n");
|
||||
// The index of the last 1-valued bit that appears in each column.
|
||||
AssertFatal(polarParams->crcParityBits > 0, "UB for VLA. crcParityBits negative\n");
|
||||
uint16_t last1ind[polarParams->crcParityBits];
|
||||
|
||||
for (int j=0; j<polarParams->crcParityBits; j++) {
|
||||
for (int i=0; i<polarParams->K; i++) {
|
||||
for (int j = 0; j < polarParams->crcParityBits; j++) {
|
||||
for (int i = 0; i < polarParams->K; i++) {
|
||||
if (extended_crc_generator_matrix[i][j] == 1)
|
||||
last1ind[j] = i;
|
||||
}
|
||||
}
|
||||
|
||||
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++)
|
||||
llr[j][polarParams->n][0] = d_tilde[j];
|
||||
@@ -131,18 +135,18 @@ int8_t polar_decoder(double *input,
|
||||
/*
|
||||
* SCL polar decoder.
|
||||
*/
|
||||
uint32_t nonFrozenBit=0;
|
||||
uint32_t nonFrozenBit = 0;
|
||||
uint currentListSize = 1;
|
||||
uint decoderIterationCheck = 0;
|
||||
int checkCrcBits = -1;
|
||||
uint8_t listIndex[2*listSize], copyIndex;
|
||||
uint8_t listIndex[2 * listSize], copyIndex;
|
||||
|
||||
for (uint currentBit = 0; currentBit < polarParams->N; currentBit++) {
|
||||
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);
|
||||
} else { //Information or CRC bit.
|
||||
} else { // Information or CRC bit.
|
||||
updatePathMetric2(pathMetric, currentListSize, currentBit, polarParams->N, polarParams->n + 1, 2 * listSize, llr);
|
||||
|
||||
for (int i = 0; i < currentListSize; i++) {
|
||||
@@ -198,30 +202,30 @@ int8_t polar_decoder(double *input,
|
||||
break;
|
||||
}
|
||||
|
||||
//First, backup the best "listSize" number of entries.
|
||||
for (int k=(listSize-1); k>0; k--) {
|
||||
for (int i=0; i<polarParams->N; i++) {
|
||||
for (int j=0; j<(polarParams->n+1); j++) {
|
||||
// First, backup the best "listSize" number of entries.
|
||||
for (int k = (listSize - 1); k > 0; k--) {
|
||||
for (int i = 0; i < polarParams->N; i++) {
|
||||
for (int j = 0; j < (polarParams->n + 1); j++) {
|
||||
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]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int k=(listSize-1); k>0; k--) {
|
||||
for (int k = (listSize - 1); k > 0; k--) {
|
||||
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--)
|
||||
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++) {
|
||||
if (k > listIndex[k]) {
|
||||
copyIndex = listIndex[(2*listSize-1)-k];
|
||||
} else { //Use the backup.
|
||||
copyIndex = listIndex[(2 * listSize - 1) - k];
|
||||
} else { // Use the backup.
|
||||
copyIndex = listIndex[k];
|
||||
}
|
||||
|
||||
@@ -235,40 +239,40 @@ int8_t polar_decoder(double *input,
|
||||
|
||||
for (int k = 0; k < listSize; k++) {
|
||||
if (k > listIndex[k]) {
|
||||
copyIndex = listIndex[(2*listSize-1)-k];
|
||||
} else { //Use the backup.
|
||||
copyIndex = listIndex[(2 * listSize - 1) - k];
|
||||
} else { // Use the backup.
|
||||
copyIndex = listIndex[k];
|
||||
}
|
||||
|
||||
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++) {
|
||||
if (k > listIndex[k]) {
|
||||
copyIndex = listIndex[(2*listSize-1)-k];
|
||||
} else { //Use the backup.
|
||||
copyIndex = listIndex[(2 * listSize - 1) - k];
|
||||
} else { // Use the backup.
|
||||
copyIndex = listIndex[k];
|
||||
}
|
||||
|
||||
crcState[k]=crcState[copyIndex];
|
||||
crcState[k] = crcState[copyIndex];
|
||||
}
|
||||
|
||||
currentListSize = listSize;
|
||||
}
|
||||
|
||||
for (int i=0; i<polarParams->crcParityBits; i++) {
|
||||
if (last1ind[i]==nonFrozenBit) {
|
||||
checkCrcBits=i;
|
||||
for (int i = 0; i < polarParams->crcParityBits; i++) {
|
||||
if (last1ind[i] == nonFrozenBit) {
|
||||
checkCrcBits = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( checkCrcBits > (-1) ) {
|
||||
if (checkCrcBits > (-1)) {
|
||||
for (uint i = 0; i < currentListSize; i++) {
|
||||
if (crcChecksum[checkCrcBits][i]==1) {
|
||||
crcState[i]=0; //0=False, 1=True
|
||||
if (crcChecksum[checkCrcBits][i] == 1) {
|
||||
crcState[i] = 0; // 0=False, 1=True
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -276,15 +280,15 @@ int8_t polar_decoder(double *input,
|
||||
for (uint i = 0; i < currentListSize; i++)
|
||||
decoderIterationCheck += crcState[i];
|
||||
|
||||
if (decoderIterationCheck==0) {
|
||||
//perror("[SCL polar decoder] All list entries have failed the CRC checks.");
|
||||
if (decoderIterationCheck == 0) {
|
||||
// perror("[SCL polar decoder] All list entries have failed the CRC checks.");
|
||||
polarReturn(polarParams);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nonFrozenBit++;
|
||||
decoderIterationCheck=0;
|
||||
checkCrcBits=-1;
|
||||
decoderIterationCheck = 0;
|
||||
checkCrcBits = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,19 +298,19 @@ int8_t polar_decoder(double *input,
|
||||
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
|
||||
uint8_t nr_polar_A[polarParams->payloadBits];
|
||||
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];
|
||||
for (int j = 0; j < polarParams->N; j++)
|
||||
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];
|
||||
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];
|
||||
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);
|
||||
|
||||
break;
|
||||
@@ -328,123 +332,137 @@ int8_t polar_decoder_dci(double *input,
|
||||
uint16_t n_RNTI,
|
||||
int8_t messageType,
|
||||
uint16_t messageLength,
|
||||
uint8_t aggregation_level ) {
|
||||
uint8_t aggregation_level)
|
||||
{
|
||||
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
|
||||
|
||||
uint8_t bit[polarParams->N][polarParams->n+1][2*listSize];
|
||||
memset(bit,0,sizeof bit);
|
||||
uint8_t bitUpdated[polarParams->N][polarParams->n+1]; //0=False, 1=True
|
||||
memset(bitUpdated,0,sizeof bitUpdated);
|
||||
uint8_t llrUpdated[polarParams->N][polarParams->n+1]; //0=False, 1=True
|
||||
memset(llrUpdated,0,sizeof llrUpdated);
|
||||
double llr[polarParams->N][polarParams->n+1][2*listSize];
|
||||
uint8_t crcChecksum[polarParams->crcParityBits][2*listSize];
|
||||
memset(crcChecksum,0,sizeof crcChecksum);
|
||||
double pathMetric[2*listSize];
|
||||
uint8_t crcState[2*listSize]; //0=False, 1=True
|
||||
uint8_t bit[polarParams->N][polarParams->n + 1][2 * listSize];
|
||||
memset(bit, 0, sizeof bit);
|
||||
uint8_t bitUpdated[polarParams->N][polarParams->n + 1]; // 0=False, 1=True
|
||||
memset(bitUpdated, 0, sizeof bitUpdated);
|
||||
uint8_t llrUpdated[polarParams->N][polarParams->n + 1]; // 0=False, 1=True
|
||||
memset(llrUpdated, 0, sizeof llrUpdated);
|
||||
double llr[polarParams->N][polarParams->n + 1][2 * listSize];
|
||||
uint8_t crcChecksum[polarParams->crcParityBits][2 * listSize];
|
||||
memset(crcChecksum, 0, sizeof crcChecksum);
|
||||
double pathMetric[2 * listSize];
|
||||
uint8_t crcState[2 * listSize]; // 0=False, 1=True
|
||||
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;
|
||||
crcState[i]=1;
|
||||
crcState[i] = 1;
|
||||
}
|
||||
|
||||
for (int i=0; i<polarParams->N; i++) {
|
||||
llrUpdated[i][polarParams->n]=1;
|
||||
for (int i = 0; i < polarParams->N; i++) {
|
||||
llrUpdated[i][polarParams->n] = 1;
|
||||
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 tempECGM[polarParams->K][polarParams->crcParityBits]; //G_P2: 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
|
||||
|
||||
for (int i=0; i<polarParams->payloadBits; i++) {
|
||||
for (int j=0; j<polarParams->crcParityBits; j++) {
|
||||
tempECGM[i][j]=polarParams->crc_generator_matrix[i+polarParams->crcParityBits][j];
|
||||
for (int i = 0; i < polarParams->payloadBits; i++) {
|
||||
for (int j = 0; j < 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 j=0; j<polarParams->crcParityBits; j++) {
|
||||
for (int i = polarParams->payloadBits; i < polarParams->K; i++) {
|
||||
for (int j = 0; j < polarParams->crcParityBits; j++) {
|
||||
tempECGM[i][j] = (i - polarParams->payloadBits) == j;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<polarParams->K; i++) {
|
||||
for (int j=0; j<polarParams->crcParityBits; j++) {
|
||||
extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j];
|
||||
for (int i = 0; i < polarParams->K; i++) {
|
||||
for (int j = 0; j < polarParams->crcParityBits; 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];
|
||||
|
||||
for (int j=0; j<polarParams->crcParityBits; j++) {
|
||||
for (int i=0; i<polarParams->K; i++) {
|
||||
if (extended_crc_generator_matrix[i][j]==1) last1ind[j]=i;
|
||||
for (int j = 0; j < polarParams->crcParityBits; j++) {
|
||||
for (int i = 0; i < polarParams->K; i++) {
|
||||
if (extended_crc_generator_matrix[i][j] == 1)
|
||||
last1ind[j] = i;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
extended_crc_scrambling_pattern[i] = 0;
|
||||
|
||||
for (int i=8; i<polarParams->crcParityBits; i++) {
|
||||
extended_crc_scrambling_pattern[i]=(n_RNTI>>(23-i))&1;
|
||||
for (int i = 8; i < polarParams->crcParityBits; i++) {
|
||||
extended_crc_scrambling_pattern[i] = (n_RNTI >> (23 - i)) & 1;
|
||||
}
|
||||
|
||||
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++)
|
||||
llr[j][polarParams->n][0]=d_tilde[j];
|
||||
llr[j][polarParams->n][0] = d_tilde[j];
|
||||
|
||||
/*
|
||||
* SCL polar decoder.
|
||||
*/
|
||||
|
||||
for (int i=0; i<polarParams->crcParityBits; i++) {
|
||||
for (int j=0; j<polarParams->crcParityBits; j++)
|
||||
crcChecksum[i][0]=crcChecksum[i][0]+polarParams->crc_generator_matrix[j][i];
|
||||
for (int i = 0; i < polarParams->crcParityBits; i++) {
|
||||
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]%2);
|
||||
crcChecksum[i][0] = (crcChecksum[i][0] % 2);
|
||||
}
|
||||
|
||||
uint32_t nonFrozenBit=0;
|
||||
uint32_t nonFrozenBit = 0;
|
||||
uint currentListSize = 1;
|
||||
uint decoderIterationCheck = 0;
|
||||
int checkCrcBits = -1;
|
||||
uint8_t listIndex[2*listSize], copyIndex;
|
||||
uint8_t listIndex[2 * listSize], copyIndex;
|
||||
|
||||
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.
|
||||
updatePathMetric(pathMetric, currentListSize, 0, currentBit,polarParams->N, polarParams->n+1, 2*listSize, llr);
|
||||
} else { //Information or CRC bit.
|
||||
updatePathMetric2(pathMetric, currentListSize, currentBit, polarParams->N, polarParams->n+1, 2*listSize, llr);
|
||||
if (polarParams->information_bit_pattern[currentBit] == 0) { // Frozen bit.
|
||||
updatePathMetric(pathMetric, currentListSize, 0, currentBit, polarParams->N, polarParams->n + 1, 2 * listSize, llr);
|
||||
} else { // Information or CRC bit.
|
||||
updatePathMetric2(pathMetric, currentListSize, currentBit, polarParams->N, polarParams->n + 1, 2 * listSize, llr);
|
||||
|
||||
for (int i = 0; i < currentListSize; i++) {
|
||||
for (int j = 0; j < polarParams->N; j++) {
|
||||
for (int k = 0; k < (polarParams->n+1); k++) {
|
||||
bit[j][k][i+currentListSize]=bit[j][k][i];
|
||||
llr[j][k][i+currentListSize]=llr[j][k][i];
|
||||
for (int k = 0; k < (polarParams->n + 1); k++) {
|
||||
bit[j][k][i + currentListSize] = bit[j][k][i];
|
||||
llr[j][k][i + currentListSize] = llr[j][k][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < currentListSize; i++) {
|
||||
bit[currentBit][0][i]=0;
|
||||
crcState[i+currentListSize]=crcState[i];
|
||||
bit[currentBit][0][i] = 0;
|
||||
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;
|
||||
updateCrcChecksum2(polarParams->crcParityBits, 2*listSize, crcChecksum,
|
||||
polarParams->K, polarParams->crcParityBits, extended_crc_generator_matrix,
|
||||
currentListSize, nonFrozenBit, polarParams->crcParityBits);
|
||||
currentListSize*=2;
|
||||
bitUpdated[currentBit][0] = 1;
|
||||
updateCrcChecksum2(polarParams->crcParityBits,
|
||||
2 * listSize,
|
||||
crcChecksum,
|
||||
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) {
|
||||
for (uint i = 0; i < 2 * listSize; i++)
|
||||
listIndex[i] = i;
|
||||
@@ -456,7 +474,7 @@ int8_t polar_decoder_dci(double *input,
|
||||
int swaps = 0;
|
||||
|
||||
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];
|
||||
listIndex[j] = listIndex[j + 1];
|
||||
listIndex[j + 1] = tempInd;
|
||||
@@ -468,30 +486,30 @@ int8_t polar_decoder_dci(double *input,
|
||||
break;
|
||||
}
|
||||
|
||||
//First, backup the best "listSize" number of entries.
|
||||
for (int k=(listSize-1); k>0; k--) {
|
||||
for (int i=0; i<polarParams->N; i++) {
|
||||
for (int j=0; j<(polarParams->n+1); j++) {
|
||||
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]];
|
||||
// First, backup the best "listSize" number of entries.
|
||||
for (int k = (listSize - 1); k > 0; k--) {
|
||||
for (int i = 0; i < polarParams->N; i++) {
|
||||
for (int j = 0; j < (polarParams->n + 1); j++) {
|
||||
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]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int k=(listSize-1); k>0; k--) {
|
||||
for (int k = (listSize - 1); k > 0; k--) {
|
||||
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--)
|
||||
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++) {
|
||||
if (k > listIndex[k]) {
|
||||
copyIndex = listIndex[(2*listSize-1)-k];
|
||||
} else { //Use the backup.
|
||||
copyIndex = listIndex[(2 * listSize - 1) - k];
|
||||
} else { // Use the backup.
|
||||
copyIndex = listIndex[k];
|
||||
}
|
||||
|
||||
@@ -505,40 +523,40 @@ int8_t polar_decoder_dci(double *input,
|
||||
|
||||
for (int k = 0; k < listSize; k++) {
|
||||
if (k > listIndex[k]) {
|
||||
copyIndex = listIndex[(2*listSize-1)-k];
|
||||
} else { //Use the backup.
|
||||
copyIndex = listIndex[(2 * listSize - 1) - k];
|
||||
} else { // Use the backup.
|
||||
copyIndex = listIndex[k];
|
||||
}
|
||||
|
||||
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++) {
|
||||
if (k > listIndex[k]) {
|
||||
copyIndex = listIndex[(2*listSize-1)-k];
|
||||
} else { //Use the backup.
|
||||
copyIndex = listIndex[(2 * listSize - 1) - k];
|
||||
} else { // Use the backup.
|
||||
copyIndex = listIndex[k];
|
||||
}
|
||||
|
||||
crcState[k]=crcState[copyIndex];
|
||||
crcState[k] = crcState[copyIndex];
|
||||
}
|
||||
|
||||
currentListSize = listSize;
|
||||
}
|
||||
|
||||
for (int i=0; i<polarParams->crcParityBits; i++) {
|
||||
if (last1ind[i]==nonFrozenBit) {
|
||||
checkCrcBits=i;
|
||||
for (int i = 0; i < polarParams->crcParityBits; i++) {
|
||||
if (last1ind[i] == nonFrozenBit) {
|
||||
checkCrcBits = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( checkCrcBits > (-1) ) {
|
||||
if (checkCrcBits > (-1)) {
|
||||
for (uint i = 0; i < currentListSize; i++) {
|
||||
if (crcChecksum[checkCrcBits][i]!=extended_crc_scrambling_pattern[checkCrcBits]) {
|
||||
crcState[i]=0; //0=False, 1=True
|
||||
if (crcChecksum[checkCrcBits][i] != extended_crc_scrambling_pattern[checkCrcBits]) {
|
||||
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++)
|
||||
decoderIterationCheck += crcState[i];
|
||||
|
||||
if (decoderIterationCheck==0) {
|
||||
//perror("[SCL polar decoder] All list entries have failed the CRC checks.");
|
||||
if (decoderIterationCheck == 0) {
|
||||
// perror("[SCL polar decoder] All list entries have failed the CRC checks.");
|
||||
polarReturn(polarParams);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nonFrozenBit++;
|
||||
decoderIterationCheck=0;
|
||||
checkCrcBits=-1;
|
||||
decoderIterationCheck = 0;
|
||||
checkCrcBits = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -565,19 +583,19 @@ int8_t polar_decoder_dci(double *input,
|
||||
uint8_t nr_polar_A[polarParams->payloadBits];
|
||||
|
||||
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];
|
||||
for (int j = 0; j < polarParams->N; j++)
|
||||
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];
|
||||
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];
|
||||
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);
|
||||
break;
|
||||
}
|
||||
@@ -740,55 +758,61 @@ uint32_t polar_decoder_int16(int16_t *input,
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
int len=polarParams->payloadBits;
|
||||
//int len_mod64=len&63;
|
||||
int len = polarParams->payloadBits;
|
||||
// int len_mod64=len&63;
|
||||
int crclen = polarParams->crcParityBits;
|
||||
uint64_t rxcrc=B[0]&((1<<crclen)-1);
|
||||
uint64_t rxcrc = B[0] & ((1 << crclen) - 1);
|
||||
uint32_t crc = 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
|
||||
uint8_t offset = 0;
|
||||
if (ones_flag)
|
||||
offset = 3;
|
||||
|
||||
if (len<=32) {
|
||||
Ar = (uint32_t)(B[0]>>crclen);
|
||||
uint8_t A32_flip[4+offset];
|
||||
if (len <= 32) {
|
||||
Ar = (uint32_t)(B[0] >> crclen);
|
||||
uint8_t A32_flip[4 + offset];
|
||||
if (ones_flag) {
|
||||
A32_flip[0] = 0xff;
|
||||
A32_flip[1] = 0xff;
|
||||
A32_flip[2] = 0xff;
|
||||
}
|
||||
uint32_t Aprime= (uint32_t)(Ar<<(32-len));
|
||||
A32_flip[0+offset]=((uint8_t *)&Aprime)[3];
|
||||
A32_flip[1+offset]=((uint8_t *)&Aprime)[2];
|
||||
A32_flip[2+offset]=((uint8_t *)&Aprime)[1];
|
||||
A32_flip[3+offset]=((uint8_t *)&Aprime)[0];
|
||||
if (crclen == 24) crc = (uint64_t)((crc24c(A32_flip,8*offset+len)>>8)&0xffffff);
|
||||
else if (crclen == 11) 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) {
|
||||
uint32_t Aprime = (uint32_t)(Ar << (32 - len));
|
||||
A32_flip[0 + offset] = ((uint8_t *)&Aprime)[3];
|
||||
A32_flip[1 + offset] = ((uint8_t *)&Aprime)[2];
|
||||
A32_flip[2 + offset] = ((uint8_t *)&Aprime)[1];
|
||||
A32_flip[3 + offset] = ((uint8_t *)&Aprime)[0];
|
||||
if (crclen == 24)
|
||||
crc = (uint64_t)((crc24c(A32_flip, 8 * offset + len) >> 8) & 0xffffff);
|
||||
else if (crclen == 11)
|
||||
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));
|
||||
uint8_t A64_flip[8+offset];
|
||||
uint8_t A64_flip[8 + offset];
|
||||
if (ones_flag) {
|
||||
A64_flip[0] = 0xff;
|
||||
A64_flip[1] = 0xff;
|
||||
A64_flip[2] = 0xff;
|
||||
}
|
||||
uint64_t Aprime= (uint64_t)(Ar<<(64-len));
|
||||
A64_flip[0+offset]=((uint8_t *)&Aprime)[7];
|
||||
A64_flip[1+offset]=((uint8_t *)&Aprime)[6];
|
||||
A64_flip[2+offset]=((uint8_t *)&Aprime)[5];
|
||||
A64_flip[3+offset]=((uint8_t *)&Aprime)[4];
|
||||
A64_flip[4+offset]=((uint8_t *)&Aprime)[3];
|
||||
A64_flip[5+offset]=((uint8_t *)&Aprime)[2];
|
||||
A64_flip[6+offset]=((uint8_t *)&Aprime)[1];
|
||||
A64_flip[7+offset]=((uint8_t *)&Aprime)[0];
|
||||
if (crclen==24) crc = (uint64_t)(crc24c(A64_flip,8*offset+len)>>8)&0xffffff;
|
||||
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;
|
||||
uint64_t Aprime = (uint64_t)(Ar << (64 - len));
|
||||
A64_flip[0 + offset] = ((uint8_t *)&Aprime)[7];
|
||||
A64_flip[1 + offset] = ((uint8_t *)&Aprime)[6];
|
||||
A64_flip[2 + offset] = ((uint8_t *)&Aprime)[5];
|
||||
A64_flip[3 + offset] = ((uint8_t *)&Aprime)[4];
|
||||
A64_flip[4 + offset] = ((uint8_t *)&Aprime)[3];
|
||||
A64_flip[5 + offset] = ((uint8_t *)&Aprime)[2];
|
||||
A64_flip[6 + offset] = ((uint8_t *)&Aprime)[1];
|
||||
A64_flip[7 + offset] = ((uint8_t *)&Aprime)[0];
|
||||
if (crclen == 24)
|
||||
crc = (uint64_t)(crc24c(A64_flip, 8 * offset + len) >> 8) & 0xffffff;
|
||||
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
|
||||
@@ -815,7 +839,7 @@ uint32_t polar_decoder_int16(int16_t *input,
|
||||
Cprime[0],
|
||||
crc,
|
||||
rxcrc,
|
||||
crc^rxcrc,
|
||||
crc ^ rxcrc,
|
||||
polarParams->payloadBits);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -28,22 +28,22 @@
|
||||
* \email turker.yilmaz@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
*/
|
||||
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||
#include "PHY/sse_intrin.h"
|
||||
#include "PHY/impl_defs_top.h"
|
||||
|
||||
//#define DEBUG_NEW_IMPL 1
|
||||
// #define DEBUG_NEW_IMPL 1
|
||||
|
||||
static inline void updateBit(uint8_t listSize,
|
||||
uint16_t row,
|
||||
uint16_t col,
|
||||
uint16_t xlen,
|
||||
uint8_t ylen,
|
||||
int zlen,
|
||||
uint8_t bit[xlen][ylen][zlen],
|
||||
uint8_t bitU[xlen][ylen])
|
||||
uint16_t row,
|
||||
uint16_t col,
|
||||
uint16_t xlen,
|
||||
uint8_t ylen,
|
||||
int zlen,
|
||||
uint8_t bit[xlen][ylen][zlen],
|
||||
uint8_t bitU[xlen][ylen])
|
||||
{
|
||||
const uint offset = (xlen / (pow(2, (ylen - col))));
|
||||
|
||||
@@ -64,18 +64,12 @@ static inline void updateBit(uint8_t listSize,
|
||||
bitU[row][col] = 1;
|
||||
}
|
||||
|
||||
static inline void computeLLR(uint16_t row,
|
||||
uint16_t col,
|
||||
uint8_t i,
|
||||
uint16_t offset,
|
||||
int xlen,
|
||||
int ylen,
|
||||
int zlen,
|
||||
double llr[xlen][ylen][zlen])
|
||||
static inline void
|
||||
computeLLR(uint16_t row, uint16_t col, 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 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,
|
||||
@@ -113,14 +107,13 @@ void updateLLR(uint8_t listSize,
|
||||
}
|
||||
|
||||
void updatePathMetric(double *pathMetric,
|
||||
uint8_t listSize,
|
||||
uint8_t bitValue,
|
||||
uint16_t row,
|
||||
int xlen,
|
||||
int ylen,
|
||||
int zlen,
|
||||
double llr[xlen][ylen][zlen]
|
||||
)
|
||||
uint8_t listSize,
|
||||
uint8_t bitValue,
|
||||
uint16_t row,
|
||||
int xlen,
|
||||
int ylen,
|
||||
int zlen,
|
||||
double llr[xlen][ylen][zlen])
|
||||
{
|
||||
const int multiplier = (2 * bitValue) - 1;
|
||||
for (uint i = 0; i < listSize; i++)
|
||||
@@ -128,12 +121,12 @@ void updatePathMetric(double *pathMetric,
|
||||
}
|
||||
|
||||
void updatePathMetric2(double *pathMetric,
|
||||
uint8_t listSize,
|
||||
uint16_t row,
|
||||
int xlen,
|
||||
int ylen,
|
||||
int zlen,
|
||||
double llr[xlen][ylen][zlen])
|
||||
uint8_t listSize,
|
||||
uint16_t row,
|
||||
int xlen,
|
||||
int ylen,
|
||||
int zlen,
|
||||
double llr[xlen][ylen][zlen])
|
||||
{
|
||||
double tempPM[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,
|
||||
.beta = tree_sz + leaf_sz * sizeof(int16_t),
|
||||
.betaInit = false};
|
||||
return(node);
|
||||
return (node);
|
||||
}
|
||||
|
||||
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,
|
||||
simde__m256i **buffer)
|
||||
{
|
||||
if (level==0) {
|
||||
if (level == 0) {
|
||||
#ifdef DEBUG_NEW_IMPL
|
||||
printf("leaf %d (%s)\n", first_leaf_index, information_bit_pattern[first_leaf_index] == 1 ? "information or crc" : "frozen");
|
||||
#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);
|
||||
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);
|
||||
return(new_node);
|
||||
return (new_node);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
#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++)
|
||||
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;
|
||||
|
||||
// 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 b256 = ((simde__m256i *)alpha_v)[i + avx2len];
|
||||
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 *)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 b128 = ((simde__m128i *)alpha_v)[1];
|
||||
simde__m128i absa128 = simde_mm_abs_epi16(a128);
|
||||
simde__m128i absb128 = simde_mm_abs_epi16(b128);
|
||||
simde__m128i minabs128 = simde_mm_min_epi16(absa128, absb128);
|
||||
*((simde__m128i*)alpha_l) =simde_mm_sign_epi16(minabs128,simde_mm_sign_epi16(a128,b128));
|
||||
}
|
||||
else if (avx2mod == 4) {
|
||||
*((simde__m128i *)alpha_l) = simde_mm_sign_epi16(minabs128, simde_mm_sign_epi16(a128, b128));
|
||||
} else if (avx2mod == 4) {
|
||||
simde__m64 a64 = *((simde__m64 *)alpha_v);
|
||||
simde__m64 b64 = ((simde__m64 *)alpha_v)[1];
|
||||
simde__m64 absa64 = simde_mm_abs_pi16(a64);
|
||||
simde__m64 absb64 = simde_mm_abs_pi16(b64);
|
||||
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
|
||||
for (int i = 0; i < sz; 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;
|
||||
node->left->betaInit = true;
|
||||
#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
|
||||
output[node->first_leaf_index] = tmp;
|
||||
#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
|
||||
}
|
||||
}
|
||||
@@ -298,7 +294,12 @@ static inline void applyGtoright(const t_nrPolar_params *pp, decoder_node_t *nod
|
||||
int8_t *betar = treeBeta(node->right);
|
||||
|
||||
#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
|
||||
assert(node->level);
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
} 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;
|
||||
|
||||
#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
|
||||
}
|
||||
}
|
||||
@@ -354,7 +356,10 @@ static inline void computeBeta(decoder_node_t *node)
|
||||
int8_t *betal = treeBeta(node->left);
|
||||
int8_t *betar = treeBeta(node->right);
|
||||
#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
|
||||
assert(node->level);
|
||||
const int sz = 1 << (node->level - 1);
|
||||
@@ -370,7 +375,7 @@ static inline void computeBeta(decoder_node_t *node)
|
||||
int avx2mod = sz & 31;
|
||||
if (avx2mod == 0) {
|
||||
int avx2len = sz / 16;
|
||||
for (int i=0;i<avx2len;i++) {
|
||||
for (int i = 0; i < avx2len; i++) {
|
||||
((simde__m256i *)betav)[i] =
|
||||
simde_mm256_xor_si256(simde_mm256_xor_si256(((simde__m256i *)betar)[i], ((simde__m256i *)betal)[i]),
|
||||
*(simde__m256i *)all11);
|
||||
@@ -389,7 +394,8 @@ static inline void computeBeta(decoder_node_t *node)
|
||||
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
|
||||
applyFtoleft(pp, node, nr_polar_U);
|
||||
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;
|
||||
|
||||
// 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);
|
||||
|
||||
applyGtoright(pp, node, nr_polar_U);
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
* \email raymond.knopp@eurecom.fr, turker.yilmaz@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
*/
|
||||
|
||||
#ifndef __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_pbch_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_2_PRIME 151 //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_16_PRIME 167 //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_4_PRIME 157 // uint16_t
|
||||
#define NR_POLAR_AGGREGATION_LEVEL_8_PRIME 163 // 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 10
|
||||
@@ -82,7 +83,7 @@ typedef struct decoder_tree_t_s {
|
||||
} decoder_tree_t;
|
||||
|
||||
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)));
|
||||
bool busy;
|
||||
@@ -123,16 +124,12 @@ typedef struct nrPolar_params {
|
||||
bool is_initialized;
|
||||
struct {
|
||||
int op_code;
|
||||
decoder_node_t* node;
|
||||
decoder_node_t *node;
|
||||
} op_list[600];
|
||||
} tree_linearization;
|
||||
} t_nrPolar_params;
|
||||
|
||||
void polar_encoder(uint32_t *input,
|
||||
uint32_t *output,
|
||||
int8_t messageType,
|
||||
uint16_t messageLength,
|
||||
uint8_t aggregation_level);
|
||||
void polar_encoder(uint32_t *input, uint32_t *output, int8_t messageType, uint16_t messageLength, uint8_t aggregation_level);
|
||||
|
||||
void polar_encoder_dci(uint32_t *in,
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
@@ -201,27 +198,13 @@ const uint16_t *nr_polar_sequence_pattern(uint8_t n);
|
||||
* @param K Number of bits to encode (=payloadBits+crcParityBits)
|
||||
* @param E
|
||||
* @param n_max */
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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_);
|
||||
|
||||
void nr_polar_info_bit_pattern(uint8_t *ibp,
|
||||
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_wm);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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 uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits);
|
||||
|
||||
@@ -258,15 +234,9 @@ void nr_polar_generate_u(uint64_t *u,
|
||||
uint16_t N,
|
||||
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,
|
||||
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_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);
|
||||
|
||||
void nr_matrix_multiplication_uint8_1D_uint8_2D(const uint8_t *matrix1,
|
||||
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 col);
|
||||
|
||||
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);
|
||||
|
||||
void nr_free_double_2D_array(double **input, uint16_t xlen);
|
||||
|
||||
#ifndef __cplusplus
|
||||
void updateLLR(uint8_t listSize,
|
||||
uint16_t row,
|
||||
uint16_t col,
|
||||
uint16_t xlen,
|
||||
uint8_t ylen,
|
||||
int zlen,
|
||||
double llr[xlen][ylen][zlen],
|
||||
uint8_t llrU[xlen][ylen],
|
||||
uint8_t bit[xlen][ylen][zlen],
|
||||
uint8_t bitU[xlen][ylen]
|
||||
);
|
||||
uint16_t row,
|
||||
uint16_t col,
|
||||
uint16_t xlen,
|
||||
uint8_t ylen,
|
||||
int zlen,
|
||||
double llr[xlen][ylen][zlen],
|
||||
uint8_t llrU[xlen][ylen],
|
||||
uint8_t bit[xlen][ylen][zlen],
|
||||
uint8_t bitU[xlen][ylen]);
|
||||
void updatePathMetric(double *pathMetric,
|
||||
uint8_t listSize,
|
||||
uint8_t bitValue,
|
||||
uint16_t row,
|
||||
int xlen,
|
||||
int ylen,
|
||||
int zlen,
|
||||
double llr[xlen][ylen][zlen]
|
||||
);
|
||||
uint8_t listSize,
|
||||
uint8_t bitValue,
|
||||
uint16_t row,
|
||||
int xlen,
|
||||
int ylen,
|
||||
int zlen,
|
||||
double llr[xlen][ylen][zlen]);
|
||||
void updatePathMetric2(double *pathMetric,
|
||||
uint8_t listSize,
|
||||
uint16_t row,
|
||||
int xlen,
|
||||
int ylen,
|
||||
int zlen,
|
||||
double llr[xlen][ylen][zlen]);
|
||||
uint8_t listSize,
|
||||
uint16_t row,
|
||||
int xlen,
|
||||
int ylen,
|
||||
int zlen,
|
||||
double llr[xlen][ylen][zlen]);
|
||||
#endif
|
||||
//Also nr_polar_rate_matcher
|
||||
static inline void nr_polar_interleaver(uint8_t *input,
|
||||
uint8_t *output,
|
||||
uint16_t *pattern,
|
||||
uint16_t size)
|
||||
// Also nr_polar_rate_matcher
|
||||
static inline void nr_polar_interleaver(uint8_t *input, uint8_t *output, uint16_t *pattern, uint16_t size)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
output[i] = input[pattern[i]];
|
||||
|
||||
@@ -30,23 +30,20 @@
|
||||
* \warning
|
||||
*/
|
||||
|
||||
//#define DEBUG_POLAR_ENCODER
|
||||
//#define DEBUG_POLAR_ENCODER_DCI
|
||||
//#define DEBUG_POLAR_MATLAB
|
||||
//#define POLAR_CODING_DEBUG
|
||||
// #define DEBUG_POLAR_ENCODER
|
||||
// #define DEBUG_POLAR_ENCODER_DCI
|
||||
// #define DEBUG_POLAR_MATLAB
|
||||
// #define POLAR_CODING_DEBUG
|
||||
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||
#include "assertions.h"
|
||||
#include <stdint.h>
|
||||
|
||||
//input [a_31 a_30 ... a_0]
|
||||
//output [f_31 f_30 ... f_0] [f_63 f_62 ... f_32] ...
|
||||
// input [a_31 a_30 ... a_0]
|
||||
// output [f_31 f_30 ... f_0] [f_63 f_62 ... f_32] ...
|
||||
|
||||
void polar_encoder(uint32_t *in,
|
||||
uint32_t *out,
|
||||
int8_t messageType,
|
||||
uint16_t messageLength,
|
||||
uint8_t aggregation_level) {
|
||||
void polar_encoder(uint32_t *in, uint32_t *out, int8_t messageType, uint16_t messageLength, uint8_t aggregation_level)
|
||||
{
|
||||
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
|
||||
uint8_t nr_polar_A[polarParams->payloadBits];
|
||||
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]);
|
||||
#endif
|
||||
|
||||
//Interleaving (c to c')
|
||||
// Interleaving (c to c')
|
||||
uint8_t nr_polar_CPrime[polarParams->K];
|
||||
nr_polar_interleaver(nr_polar_B, nr_polar_CPrime, polarParams->interleaving_pattern, polarParams->K);
|
||||
#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);
|
||||
if (nr_polar_CPrime[i] == 1)
|
||||
printf("pos %d : %lx\n", i, Cprime);
|
||||
}
|
||||
|
||||
printf("polar_Cprime %lx\n",Cprime);
|
||||
printf("polar_Cprime %lx\n", Cprime);
|
||||
#endif
|
||||
//Bit insertion (c' to u)
|
||||
// Bit insertion (c' to u)
|
||||
uint8_t nr_polar_U[polarParams->N];
|
||||
nr_polar_bit_insertion(nr_polar_CPrime,
|
||||
nr_polar_U,
|
||||
@@ -119,11 +116,10 @@ void polar_encoder(uint32_t *in,
|
||||
for (int i = 0; i < polarParams->N; i++)
|
||||
D[i / 64] |= ((uint64_t)nr_polar_D[i]) << (i & 63);
|
||||
|
||||
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]);
|
||||
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]);
|
||||
#endif
|
||||
//Rate matching
|
||||
//Sub-block interleaving (d to y) and Bit selection (y to e)
|
||||
// Rate matching
|
||||
// Sub-block interleaving (d to y) and Bit selection (y to e)
|
||||
uint8_t nr_polar_E[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,
|
||||
int8_t messageType,
|
||||
uint16_t messageLength,
|
||||
uint8_t aggregation_level) {
|
||||
uint8_t aggregation_level)
|
||||
{
|
||||
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
|
||||
|
||||
#ifdef DEBUG_POLAR_ENCODER_DCI
|
||||
@@ -176,10 +173,11 @@ void polar_encoder_dci(uint32_t *in,
|
||||
printf("\n");
|
||||
|
||||
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");
|
||||
#endif
|
||||
//Calculate CRC.
|
||||
// Calculate CRC.
|
||||
uint8_t nr_polar_crc[polarParams->crcParityBits];
|
||||
nr_matrix_multiplication_uint8_1D_uint8_2D(nr_polar_APrime,
|
||||
polarParams->crc_generator_matrix,
|
||||
@@ -197,14 +195,14 @@ void polar_encoder_dci(uint32_t *in,
|
||||
printf("\n");
|
||||
#endif
|
||||
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);
|
||||
|
||||
for (uint i = polarParams->payloadBits; i < polarParams->K; i++)
|
||||
nr_polar_B[i] = nr_polar_crc[i - polarParams->payloadBits];
|
||||
|
||||
//Scrambling (b to c)
|
||||
for (int i=0; i<16; i++)
|
||||
// Scrambling (b to c)
|
||||
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;
|
||||
|
||||
#ifdef DEBUG_POLAR_ENCODER_DCI
|
||||
@@ -213,10 +211,10 @@ void polar_encoder_dci(uint32_t *in,
|
||||
printf("%d-", nr_polar_B[i]);
|
||||
printf("\n");
|
||||
#endif
|
||||
//Interleaving (c to c')
|
||||
// Interleaving (c to c')
|
||||
uint8_t nr_polar_CPrime[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];
|
||||
nr_polar_bit_insertion(nr_polar_CPrime,
|
||||
nr_polar_U,
|
||||
@@ -225,14 +223,14 @@ void polar_encoder_dci(uint32_t *in,
|
||||
polarParams->Q_I_N,
|
||||
polarParams->Q_PC_N,
|
||||
polarParams->n_pc);
|
||||
//Encoding (u to d)
|
||||
// Encoding (u to d)
|
||||
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);
|
||||
for (uint i = 0; i < polarParams->N; i++)
|
||||
nr_polar_D[i] %= 2;
|
||||
|
||||
//Rate matching
|
||||
//Sub-block interleaving (d to y) and Bit selection (y to e)
|
||||
// Rate matching
|
||||
// Sub-block interleaving (d to y) and Bit selection (y to e)
|
||||
uint8_t nr_polar_E[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
|
||||
// can be done with SIMD intrisics if needed
|
||||
if (polarParams->groupsize < 8) {
|
||||
AssertFatal(polarParams->encoderLength<=512,"Need to handle groupsize(%d)<8 and N(%d)>512\n",polarParams->groupsize,polarParams->encoderLength);
|
||||
uint128_t *out128=(uint128_t*)out;
|
||||
uint128_t *in128=(uint128_t*)in;
|
||||
for (int i=0;i<polarParams->encoderLength>>7;i++)
|
||||
if (polarParams->groupsize < 8) {
|
||||
AssertFatal(polarParams->encoderLength <= 512,
|
||||
"Need to handle groupsize(%d)<8 and N(%d)>512\n",
|
||||
polarParams->groupsize,
|
||||
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;
|
||||
#ifdef DEBUG_POLAR_ENCODER
|
||||
uint128_t tmp1;
|
||||
#endif
|
||||
for (int i=0; i<polarParams->encoderLength; i++) {
|
||||
for (int i = 0; i < polarParams->encoderLength; i++) {
|
||||
#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
|
||||
uint8_t pi=polarParams->rate_matching_pattern[i];
|
||||
uint8_t pi7=pi>>7;
|
||||
uint8_t pimod128=pi&127;
|
||||
uint8_t imod128=i&127;
|
||||
uint8_t i7=i>>7;
|
||||
uint8_t pi = polarParams->rate_matching_pattern[i];
|
||||
uint8_t pi7 = pi >> 7;
|
||||
uint8_t pimod128 = pi & 127;
|
||||
uint8_t imod128 = i & 127;
|
||||
uint8_t i7 = i >> 7;
|
||||
uint128_t tmp0 = (in128[pi7] & (((uint128_t)1) << (pimod128)));
|
||||
|
||||
if (tmp0!=0) {
|
||||
out128[i7] = out128[i7] | ((uint128_t)1)<<imod128;
|
||||
if (tmp0 != 0) {
|
||||
out128[i7] = out128[i7] | ((uint128_t)1) << imod128;
|
||||
#ifdef DEBUG_POLAR_ENCODER
|
||||
printf("%llx.%llx<->%llx.%llx => %llx.%llx\n",
|
||||
((uint64_t *)&tmp0)[1],((uint64_t *)&tmp0)[0],
|
||||
((uint64_t *)&tmp1)[1],((uint64_t *)&tmp1)[0],
|
||||
((uint64_t *)out)[1],((uint64_t *)out)[0]);
|
||||
((uint64_t *)&tmp0)[1],
|
||||
((uint64_t *)&tmp0)[0],
|
||||
((uint64_t *)&tmp1)[1],
|
||||
((uint64_t *)&tmp1)[0],
|
||||
((uint64_t *)out)[1],
|
||||
((uint64_t *)out)[0]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// These are based on LUTs for byte and short word groups
|
||||
else if (polarParams->groupsize == 8)
|
||||
for (int i = 0; i < polarParams->encoderLength >> 3; i++)
|
||||
((uint8_t *)out)[i] = ((uint8_t *)in)[polarParams->rm_tab[i]];
|
||||
else // 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]];
|
||||
}
|
||||
|
||||
@@ -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'
|
||||
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);
|
||||
const int numbytes = (polarParams->K+7)/8;
|
||||
const int residue = polarParams->K&7;
|
||||
const int numbytes = (polarParams->K + 7) / 8;
|
||||
const int residue = polarParams->K & 7;
|
||||
uint deinterleaving_pattern[polarParams->K];
|
||||
|
||||
for (int i = 0; i < polarParams->K; i++)
|
||||
deinterleaving_pattern[polarParams->interleaving_pattern[i]] = i;
|
||||
|
||||
for (int byte=0; byte<numbytes; byte++) {
|
||||
int numbits = byte<(polarParams->K>>3) ? 8 : residue;
|
||||
for (int byte = 0; byte < numbytes; byte++) {
|
||||
int numbits = byte < (polarParams->K >> 3) ? 8 : residue;
|
||||
for (uint64_t val = 0; val < 256LU; val++) {
|
||||
// uint16_t * tmp=polarParams->deinterleaving_pattern+polarParams->K - 1 - 8 * byte;
|
||||
union {
|
||||
@@ -360,10 +365,10 @@ void build_polar_tables(t_nrPolar_params *polarParams) {
|
||||
uint64_t pieces[2];
|
||||
} tab = {0};
|
||||
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
|
||||
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;
|
||||
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
|
||||
int iplast=polarParams->rate_matching_pattern[0];
|
||||
int ccnt=0;
|
||||
int iplast = polarParams->rate_matching_pattern[0];
|
||||
int ccnt = 0;
|
||||
#ifdef DEBUG_POLAR_ENCODER
|
||||
int groupcnt=0;
|
||||
int firstingroup_out=0;
|
||||
int firstingroup_in=iplast;
|
||||
int groupcnt = 0;
|
||||
int firstingroup_out = 0;
|
||||
int firstingroup_in = iplast;
|
||||
#endif
|
||||
int mingroupsize = 1024;
|
||||
|
||||
// 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];
|
||||
#ifdef DEBUG_POLAR_ENCODER
|
||||
printf("rm: outpos %d, inpos %d\n",outpos,ip);
|
||||
printf("rm: outpos %d, inpos %d\n", outpos, ip);
|
||||
#endif
|
||||
if ((ip - iplast) == 1)
|
||||
ccnt++;
|
||||
else {
|
||||
#ifdef DEBUG_POLAR_ENCODER
|
||||
groupcnt++;
|
||||
printf("group %d (size %d): (%d:%d) => (%d:%d)\n",groupcnt,ccnt+1,
|
||||
firstingroup_in,firstingroup_in+ccnt,
|
||||
firstingroup_out,firstingroup_out+ccnt);
|
||||
printf("group %d (size %d): (%d:%d) => (%d:%d)\n",
|
||||
groupcnt,
|
||||
ccnt + 1,
|
||||
firstingroup_in,
|
||||
firstingroup_in + ccnt,
|
||||
firstingroup_out,
|
||||
firstingroup_out + ccnt);
|
||||
#endif
|
||||
|
||||
if ((ccnt + 1) < mingroupsize)
|
||||
mingroupsize = ccnt + 1;
|
||||
|
||||
ccnt=0;
|
||||
ccnt = 0;
|
||||
#ifdef DEBUG_POLAR_ENCODER
|
||||
firstingroup_out=outpos;
|
||||
firstingroup_in=ip;
|
||||
firstingroup_out = outpos;
|
||||
firstingroup_in = ip;
|
||||
#endif
|
||||
}
|
||||
|
||||
iplast=ip;
|
||||
iplast = ip;
|
||||
}
|
||||
#ifdef DEBUG_POLAR_ENCODER
|
||||
groupcnt++;
|
||||
#endif
|
||||
if ((ccnt+1)<mingroupsize) mingroupsize=ccnt+1;
|
||||
if ((ccnt + 1) < mingroupsize)
|
||||
mingroupsize = ccnt + 1;
|
||||
#ifdef DEBUG_POLAR_ENCODER
|
||||
printf("group %d (size %d): (%d:%d) => (%d:%d)\n",
|
||||
groupcnt,
|
||||
@@ -456,7 +468,6 @@ void build_polar_tables(t_nrPolar_params *polarParams) {
|
||||
build_decoder_tree(polarParams);
|
||||
}
|
||||
|
||||
|
||||
void polar_encoder_fast(uint64_t *A,
|
||||
void *out,
|
||||
int32_t crcmask,
|
||||
@@ -482,27 +493,27 @@ void polar_encoder_fast(uint64_t *A,
|
||||
#endif
|
||||
|
||||
// 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->payloadBits < 65, "payload bits = %d > 64, is not supported yet\n",polarParams->payloadBits);
|
||||
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);
|
||||
int bitlen = polarParams->payloadBits;
|
||||
// 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");
|
||||
//int bitlen0=bitlen;
|
||||
// int bitlen0=bitlen;
|
||||
|
||||
#ifdef POLAR_CODING_DEBUG
|
||||
printf("\nTX\n");
|
||||
printf("a: ");
|
||||
for (int n = (bitlen + 63)/64 ; n >=0; n--) {
|
||||
if (n % 4 == 0)
|
||||
printf(" ");
|
||||
if (n < bitlen)
|
||||
printf("%lu", (A[n/64] >> (n%64)) & 1);
|
||||
for (int n = (bitlen + 63) / 64; n >= 0; n--) {
|
||||
if (n % 4 == 0)
|
||||
printf(" ");
|
||||
if (n < bitlen)
|
||||
printf("%lu", (A[n / 64] >> (n % 64)) & 1);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
uint64_t tcrc=0;
|
||||
uint64_t tcrc = 0;
|
||||
uint offset = 0;
|
||||
|
||||
// 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
|
||||
|
||||
// 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)
|
||||
if (bitlen<=32) {
|
||||
uint8_t A32_flip[4+offset];
|
||||
// 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)
|
||||
if (bitlen <= 32) {
|
||||
uint8_t A32_flip[4 + offset];
|
||||
if (ones_flag) {
|
||||
A32_flip[0] = 0xff;
|
||||
A32_flip[1] = 0xff;
|
||||
A32_flip[2] = 0xff;
|
||||
}
|
||||
uint32_t Aprime= (uint32_t)(((uint32_t)*A)<<(32-bitlen));
|
||||
A32_flip[0+offset]=((uint8_t *)&Aprime)[3];
|
||||
A32_flip[1+offset]=((uint8_t *)&Aprime)[2];
|
||||
A32_flip[2+offset]=((uint8_t *)&Aprime)[1];
|
||||
A32_flip[3+offset]=((uint8_t *)&Aprime)[0];
|
||||
if (polarParams->crcParityBits == 24)
|
||||
tcrc = (uint64_t)(((crcmask^(crc24c(A32_flip,8*offset+bitlen)>>8)))&0xffffff);
|
||||
uint32_t Aprime = (uint32_t)(((uint32_t)*A) << (32 - bitlen));
|
||||
A32_flip[0 + offset] = ((uint8_t *)&Aprime)[3];
|
||||
A32_flip[1 + offset] = ((uint8_t *)&Aprime)[2];
|
||||
A32_flip[2 + offset] = ((uint8_t *)&Aprime)[1];
|
||||
A32_flip[3 + offset] = ((uint8_t *)&Aprime)[0];
|
||||
if (polarParams->crcParityBits == 24)
|
||||
tcrc = (uint64_t)(((crcmask ^ (crc24c(A32_flip, 8 * offset + bitlen) >> 8))) & 0xffffff);
|
||||
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)
|
||||
tcrc = (uint64_t)(((crcmask^(crc6(A32_flip,bitlen)>>26)))&0x3f);
|
||||
} else if (bitlen<=64) {
|
||||
uint8_t A64_flip[8+offset];
|
||||
tcrc = (uint64_t)(((crcmask ^ (crc6(A32_flip, bitlen) >> 26))) & 0x3f);
|
||||
} else if (bitlen <= 64) {
|
||||
uint8_t A64_flip[8 + offset];
|
||||
if (ones_flag) {
|
||||
A64_flip[0] = 0xff;
|
||||
A64_flip[1] = 0xff;
|
||||
A64_flip[2] = 0xff;
|
||||
}
|
||||
uint64_t Aprime= (uint64_t)(((uint64_t)*A)<<(64-bitlen));
|
||||
A64_flip[0+offset]=((uint8_t *)&Aprime)[7];
|
||||
A64_flip[1+offset]=((uint8_t *)&Aprime)[6];
|
||||
A64_flip[2+offset]=((uint8_t *)&Aprime)[5];
|
||||
A64_flip[3+offset]=((uint8_t *)&Aprime)[4];
|
||||
A64_flip[4+offset]=((uint8_t *)&Aprime)[3];
|
||||
A64_flip[5+offset]=((uint8_t *)&Aprime)[2];
|
||||
A64_flip[6+offset]=((uint8_t *)&Aprime)[1];
|
||||
A64_flip[7+offset]=((uint8_t *)&Aprime)[0];
|
||||
uint64_t Aprime = (uint64_t)(((uint64_t)*A) << (64 - bitlen));
|
||||
A64_flip[0 + offset] = ((uint8_t *)&Aprime)[7];
|
||||
A64_flip[1 + offset] = ((uint8_t *)&Aprime)[6];
|
||||
A64_flip[2 + offset] = ((uint8_t *)&Aprime)[5];
|
||||
A64_flip[3 + offset] = ((uint8_t *)&Aprime)[4];
|
||||
A64_flip[4 + offset] = ((uint8_t *)&Aprime)[3];
|
||||
A64_flip[5 + offset] = ((uint8_t *)&Aprime)[2];
|
||||
A64_flip[6 + offset] = ((uint8_t *)&Aprime)[1];
|
||||
A64_flip[7 + offset] = ((uint8_t *)&Aprime)[0];
|
||||
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)
|
||||
tcrc = (uint64_t)((crcmask^(crc11(A64_flip,bitlen)>>21)))&0x7ff;
|
||||
}
|
||||
else if (bitlen<=128) {
|
||||
uint8_t A128_flip[16+offset];
|
||||
tcrc = (uint64_t)((crcmask ^ (crc11(A64_flip, bitlen) >> 21))) & 0x7ff;
|
||||
} else if (bitlen <= 128) {
|
||||
uint8_t A128_flip[16 + offset];
|
||||
if (ones_flag) {
|
||||
A128_flip[0] = 0xff;
|
||||
A128_flip[1] = 0xff;
|
||||
A128_flip[2] = 0xff;
|
||||
}
|
||||
uint128_t Aprime= (uint128_t)(((uint128_t)*A)<<(128-bitlen));
|
||||
for (int i=0; i<16 ; i++)
|
||||
A128_flip[i+offset]=((uint8_t*)&Aprime)[15-i];
|
||||
uint128_t Aprime = (uint128_t)(((uint128_t)*A) << (128 - bitlen));
|
||||
for (int i = 0; i < 16; i++)
|
||||
A128_flip[i + offset] = ((uint8_t *)&Aprime)[15 - i];
|
||||
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)
|
||||
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
|
||||
int quadwlen = (polarParams->K+63)/64;
|
||||
int quadwlen = (polarParams->K + 63) / 64;
|
||||
|
||||
// Create the B bit string as
|
||||
// 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
|
||||
uint64_t B[4]= {0};
|
||||
uint64_t B[4] = {0};
|
||||
B[0] = (A[0] << polarParams->crcParityBits) | tcrc;
|
||||
for (int n = 1; n < quadwlen; n++)
|
||||
if ((bitlen+63)/64 > n)
|
||||
B[n] = (A[n] << polarParams->crcParityBits) | (A[n-1]>>(64-polarParams->crcParityBits));
|
||||
if ((bitlen + 63) / 64 > n)
|
||||
B[n] = (A[n] << polarParams->crcParityBits) | (A[n - 1] >> (64 - polarParams->crcParityBits));
|
||||
else
|
||||
B[n] = (A[n-1]>>(64-polarParams->crcParityBits));
|
||||
B[n] = (A[n - 1] >> (64 - polarParams->crcParityBits));
|
||||
|
||||
#ifdef POLAR_CODING_DEBUG
|
||||
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
|
||||
// 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;
|
||||
if (polarParams->K < 65) {
|
||||
Cprime[0] = polarParams->cprime_tab0[0][Bbyte[0]] |
|
||||
polarParams->cprime_tab0[1][Bbyte[1]] |
|
||||
polarParams->cprime_tab0[2][Bbyte[2]] |
|
||||
polarParams->cprime_tab0[3][Bbyte[3]] |
|
||||
polarParams->cprime_tab0[4][Bbyte[4]] |
|
||||
polarParams->cprime_tab0[5][Bbyte[5]] |
|
||||
polarParams->cprime_tab0[6][Bbyte[6]] |
|
||||
polarParams->cprime_tab0[7][Bbyte[7]];
|
||||
Cprime[0] = polarParams->cprime_tab0[0][Bbyte[0]] | polarParams->cprime_tab0[1][Bbyte[1]]
|
||||
| polarParams->cprime_tab0[2][Bbyte[2]] | polarParams->cprime_tab0[3][Bbyte[3]]
|
||||
| polarParams->cprime_tab0[4][Bbyte[4]] | polarParams->cprime_tab0[5][Bbyte[5]]
|
||||
| polarParams->cprime_tab0[6][Bbyte[6]] | polarParams->cprime_tab0[7][Bbyte[7]];
|
||||
} else if (polarParams->K < 129) {
|
||||
for (int i = 0; i < 1 + (polarParams->K / 8); i++) {
|
||||
Cprime[0] |= polarParams->cprime_tab0[i][Bbyte[i]];
|
||||
@@ -622,7 +629,8 @@ void polar_encoder_fast(uint64_t *A,
|
||||
|
||||
#ifdef DEBUG_POLAR_MATLAB
|
||||
// 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
|
||||
|
||||
#ifdef POLAR_CODING_DEBUG
|
||||
@@ -677,8 +685,8 @@ void polar_encoder_fast(uint64_t *A,
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
memset((void*)out,0,polarParams->encoderLength>>3);
|
||||
polar_rate_matching(polarParams,(void *)D, out);
|
||||
memset((void *)out, 0, polarParams->encoderLength >> 3);
|
||||
polar_rate_matching(polarParams, (void *)D, out);
|
||||
|
||||
#ifdef POLAR_CODING_DEBUG
|
||||
uint64_t *out64 = (uint64_t *)out;
|
||||
|
||||
@@ -28,11 +28,12 @@
|
||||
* \email turker.yilmaz@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
*/
|
||||
|
||||
#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;
|
||||
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,
|
||||
|
||||
@@ -7,53 +7,48 @@
|
||||
|
||||
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
|
||||
|
||||
uint32_t i,j;
|
||||
// Martino's algorithm to avoid multiplication for the generating matrix of polar codes
|
||||
|
||||
simde__m256i A,B,C,D,E,U,zerosOnly, OUT;
|
||||
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
|
||||
uint32_t i, j;
|
||||
|
||||
for(i=0; i<N; i+=8)
|
||||
{
|
||||
B=simde_mm256_set1_epi32((int)i); // i, ..., i
|
||||
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
|
||||
simde__m256i A, B, C, D, E, U, zerosOnly, OUT;
|
||||
simde__m256i inc;
|
||||
uint32_t dTest[8];
|
||||
uint32_t uArray[8];
|
||||
uint32_t k;
|
||||
uint32_t incArray[8];
|
||||
|
||||
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
|
||||
// initialisation
|
||||
for (k = 0; k < 8; k++)
|
||||
incArray[k] = k;
|
||||
inc = simde_mm256_loadu_si256((simde__m256i const *)incArray); // 0, 1, ..., 7 to increase
|
||||
|
||||
}
|
||||
simde_mm256_storeu_si256((simde__m256i*)dTest, OUT);
|
||||
zerosOnly = simde_mm256_setzero_si256(); // for comparison
|
||||
|
||||
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
|
||||
}
|
||||
for (i = 0; i < N; i += 8) {
|
||||
B = simde_mm256_set1_epi32((int)i); // i, ..., i
|
||||
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
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
*/
|
||||
|
||||
#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.
|
||||
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++) {
|
||||
int swaps = 0;
|
||||
for (int j = 0; j < (len - i) - 1; j++) {
|
||||
|
||||
@@ -28,46 +28,70 @@
|
||||
* \email turker.yilmaz@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
*/
|
||||
|
||||
#ifndef __NR_POLAR_PBCH_DEFS__H__
|
||||
#define __NR_POLAR_PBCH_DEFS__H__
|
||||
|
||||
#define NR_POLAR_PBCH_AGGREGATION_LEVEL 0 //uint8_t
|
||||
#define NR_POLAR_PBCH_MESSAGE_TYPE 0 //int8_t
|
||||
#define NR_POLAR_PSBCH_MESSAGE_TYPE 3 //int8_t
|
||||
#define NR_POLAR_PBCH_PAYLOAD_BITS 32 //uint16_t
|
||||
#define NR_POLAR_PBCH_AGGREGATION_LEVEL 0 // uint8_t
|
||||
#define NR_POLAR_PBCH_MESSAGE_TYPE 0 // int8_t
|
||||
#define NR_POLAR_PSBCH_MESSAGE_TYPE 3 // int8_t
|
||||
#define NR_POLAR_PBCH_PAYLOAD_BITS 32 // uint16_t
|
||||
#define NR_POLAR_PBCH_CRC_PARITY_BITS 24
|
||||
#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
|
||||
#define NR_POLAR_PBCH_N_MAX 9 //uint8_t
|
||||
#define NR_POLAR_PBCH_I_IL 1 //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_WM 0 //uint8_t
|
||||
//#define NR_POLAR_PBCH_N 512 //uint16_t
|
||||
// Sec. 7.1.4: Channel Coding
|
||||
#define NR_POLAR_PBCH_N_MAX 9 // uint8_t
|
||||
#define NR_POLAR_PBCH_I_IL 1 // 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_WM 0 // uint8_t
|
||||
// #define NR_POLAR_PBCH_N 512 //uint16_t
|
||||
|
||||
//Sec. 7.1.5: Rate Matching
|
||||
#define NR_POLAR_PBCH_I_BIL 0 //uint8_t
|
||||
#define NR_POLAR_PBCH_E 864 //uint16_t
|
||||
// Sec. 7.1.5: Rate Matching
|
||||
#define NR_POLAR_PBCH_I_BIL 0 // uint8_t
|
||||
#define NR_POLAR_PBCH_E 864 // uint16_t
|
||||
#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
|
||||
|
||||
/*
|
||||
* TEST CODE
|
||||
*/
|
||||
//#define DEBUG_POLAR
|
||||
// Usage in code:
|
||||
//#ifdef DEBUG_POLAR
|
||||
// #define DEBUG_POLAR
|
||||
// Usage in code:
|
||||
// #ifdef DEBUG_POLAR
|
||||
//...
|
||||
//#endif
|
||||
// #endif
|
||||
|
||||
//unsigned int testPayload0=0x00000000, testPayload1=0xffffffff; //payload1=~payload0;
|
||||
//unsigned int testPayload2=0xa5a5a5a5; //testPayload3=0xb3f02c82;
|
||||
// unsigned int testPayload0=0x00000000, testPayload1=0xffffffff; //payload1=~payload0;
|
||||
// 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
|
||||
|
||||
@@ -89,8 +89,7 @@ void nr_polar_generate_u(uint64_t *u,
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void encode_packed_byte(uint8_t* in_out)
|
||||
static void encode_packed_byte(uint8_t *in_out)
|
||||
{
|
||||
// *in_out ^= 0xAA & (*in_out << 1);
|
||||
// *in_out ^= 0xCC & (*in_out << 2);
|
||||
@@ -101,36 +100,33 @@ void encode_packed_byte(uint8_t* in_out)
|
||||
*in_out ^= *in_out >> 4;
|
||||
}
|
||||
|
||||
static
|
||||
void polar_encode_bits(uint8_t* in_out, size_t N)
|
||||
static void polar_encode_bits(uint8_t *in_out, size_t N)
|
||||
{
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
uint32_t log2_floor(uint32_t x)
|
||||
static uint32_t log2_floor(uint32_t x)
|
||||
{
|
||||
if(x == 0)
|
||||
return 0;
|
||||
if (x == 0)
|
||||
return 0;
|
||||
uint32_t clz = __builtin_clz(x);
|
||||
return 31U - clz;
|
||||
}
|
||||
|
||||
static
|
||||
void polar_encode_bytes(uint8_t* in_out, size_t N)
|
||||
static void polar_encode_bytes(uint8_t *in_out, size_t N)
|
||||
{
|
||||
size_t brnch_sz = 1;
|
||||
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 brnch = 0; brnch < n_brnch; ++brnch) {
|
||||
for(size_t byte = 0; byte < brnch_sz; ++byte){
|
||||
size_t const dst = 2*brnch_sz*brnch + byte;
|
||||
in_out[dst] ^= in_out[dst + brnch_sz];
|
||||
}
|
||||
for (size_t byte = 0; byte < brnch_sz; ++byte) {
|
||||
size_t const dst = 2 * brnch_sz * brnch + byte;
|
||||
in_out[dst] ^= in_out[dst + brnch_sz];
|
||||
}
|
||||
}
|
||||
n_brnch >>= 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)
|
||||
{
|
||||
assert(N > 7);
|
||||
uint8_t tmp[N/8];
|
||||
for(int i = 0; i < N/8; ++i)
|
||||
tmp[i] = u[N/8 - 1 - i];
|
||||
assert(N > 7);
|
||||
uint8_t tmp[N / 8];
|
||||
for (int i = 0; i < N / 8; ++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.
|
||||
// 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);
|
||||
}
|
||||
|
||||
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)
|
||||
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)
|
||||
{
|
||||
int k = 0;
|
||||
|
||||
if (n_PC>0) {
|
||||
if (n_PC > 0) {
|
||||
/*
|
||||
*
|
||||
*/
|
||||
} else {
|
||||
for (int n=0; n<=N-1; n++) {
|
||||
for (int n = 0; n <= N - 1; n++) {
|
||||
output[n] = 0;
|
||||
for (int m=0; m<=(K+n_PC)-1; m++) {
|
||||
if ( n == Q_I_N[m]) {
|
||||
for (int m = 0; m <= (K + n_PC) - 1; m++) {
|
||||
if (n == Q_I_N[m]) {
|
||||
output[n] = input[k];
|
||||
k++;
|
||||
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;
|
||||
double R_min=1.0/8;
|
||||
|
||||
if ( (E <= (9.0/8)*pow(2,ceil(log2(E))-1)) && (K/E < 9.0/16) ) {
|
||||
n_1 = ceil(log2(E))-1;
|
||||
double R_min = 1.0 / 8;
|
||||
|
||||
if ((E <= (9.0 / 8) * pow(2, ceil(log2(E)) - 1)) && (K / E < 9.0 / 16)) {
|
||||
n_1 = ceil(log2(E)) - 1;
|
||||
} else {
|
||||
n_1 = ceil(log2(E));
|
||||
}
|
||||
|
||||
n_2 = ceil(log2(K/R_min));
|
||||
|
||||
n_2 = ceil(log2(K / R_min));
|
||||
|
||||
int n = n_max;
|
||||
if (n > n_1)
|
||||
@@ -206,9 +193,9 @@ uint32_t nr_polar_output_length(uint16_t K,
|
||||
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",
|
||||
K,E,n,n_max,n_min,n_1,n_2);
|
||||
exit(-1);*/
|
||||
return ((uint32_t) pow(2.0,n)); //=polar_code_output_length
|
||||
K,E,n,n_max,n_min,n_1,n_2);
|
||||
exit(-1);*/
|
||||
return ((uint32_t)pow(2.0, n)); //=polar_code_output_length
|
||||
}
|
||||
|
||||
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];
|
||||
int 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]) {
|
||||
break;
|
||||
}
|
||||
@@ -309,7 +296,6 @@ void nr_polar_info_bit_pattern(uint8_t *ibp,
|
||||
|
||||
// Information and Parity Chack Bit Pattern
|
||||
for (int n = 0; n <= N - 1; n++) {
|
||||
|
||||
ibp[n] = 0;
|
||||
for (int m = 0; m <= (K + n_PC) - 1; 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;
|
||||
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];
|
||||
for (int m = 0; m < N; m++)
|
||||
@@ -357,54 +333,49 @@ void nr_polar_rate_matching_pattern(uint16_t *rmp,
|
||||
uint16_t y[N];
|
||||
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);
|
||||
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]];
|
||||
}
|
||||
|
||||
if (E>=N) { //repetition
|
||||
for (int k=0; k<=E-1; k++) {
|
||||
if (E >= N) { // repetition
|
||||
for (int k = 0; k <= E - 1; k++) {
|
||||
int ind = (k % N);
|
||||
rmp[k]=y[ind];
|
||||
rmp[k] = y[ind];
|
||||
}
|
||||
} else {
|
||||
if ( (K/(double)E) <= (7.0/16) ) { //puncturing
|
||||
for (int k=0; k<=E-1; k++) {
|
||||
rmp[k]=y[k+N-E];
|
||||
if ((K / (double)E) <= (7.0 / 16)) { // puncturing
|
||||
for (int k = 0; k <= E - 1; k++) {
|
||||
rmp[k] = y[k + N - E];
|
||||
}
|
||||
} else { //shortening
|
||||
for (int k=0; k<=E-1; k++) {
|
||||
rmp[k]=y[k];
|
||||
} else { // shortening
|
||||
for (int k = 0; k <= E - 1; 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
|
||||
for (int i=0; i<=N-1; i++) output[i]=0;
|
||||
for (int i=0; i<=E-1; i++){
|
||||
output[rmp[i]]+=input[i];
|
||||
if (E >= N) { // repetition
|
||||
for (int i = 0; i <= N - 1; i++)
|
||||
output[i] = 0;
|
||||
for (int i = 0; i <= E - 1; i++) {
|
||||
output[rmp[i]] += input[i];
|
||||
}
|
||||
} 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++)
|
||||
output[i] = 0;
|
||||
} else { //shortening
|
||||
} else { // shortening
|
||||
for (int i = 0; i <= N - 1; i++)
|
||||
output[i] = INFINITY;
|
||||
}
|
||||
|
||||
for (int i=0; i<=E-1; i++){
|
||||
output[rmp[i]]=input[i];
|
||||
for (int i = 0; i <= E - 1; i++) {
|
||||
output[rmp[i]] = input[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,22 +7,21 @@
|
||||
|
||||
#define NR_POLAR_PUCCH_PAYLOAD_BITS 16
|
||||
|
||||
//Ref. 38-212 v15.0.1
|
||||
#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_N_PC 3 //uint8_t <-- or zero ??
|
||||
#define NR_POLAR_PUCCH_N_PC_WM 0 //uint8_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
|
||||
#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_N_PC 3 // uint8_t <-- or zero ??
|
||||
#define NR_POLAR_PUCCH_N_PC_WM 0 // uint8_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
|
||||
|
||||
/*
|
||||
* TEST CODE
|
||||
*/
|
||||
//unsigned int testPayload0=0x00000000, testPayload1=0xffffffff; //payload1=~payload0;
|
||||
//unsigned int testPayload2=0xa5a5a5a5, testPayload3=0xb3f02c82;
|
||||
// unsigned int testPayload0=0x00000000, testPayload1=0xffffffff; //payload1=~payload0;
|
||||
// unsigned int testPayload2=0xa5a5a5a5, testPayload3=0xb3f02c82;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
#include <math.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 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
|
||||
for (int i = 0; i <= N - 1; i++)
|
||||
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
|
||||
* \brief Defines the constant variables for polar coding of the UCI from 38-212, V15.1.1 2018-04.
|
||||
* \author
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email:
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
* \brief Defines the constant variables for polar coding of the UCI from 38-212, V15.1.1 2018-04.
|
||||
* \author
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email:
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#ifndef __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_PAYLOAD_BITS 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_LONG 11
|
||||
|
||||
#define NR_POLAR_PUCCH_I_SEG_LONG 1
|
||||
#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_I_IL 0
|
||||
#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_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
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,15 +34,17 @@
|
||||
#include "PHY/NR_TRANSPORT/nr_dci.h"
|
||||
#include "nrPolar_tools/nr_polar_psbch_defs.h"
|
||||
|
||||
#define PolarKey ((messageType<<24)|(messageLength<<8)|aggregation_level)
|
||||
static t_nrPolar_params * PolarList=NULL;
|
||||
pthread_mutex_t PolarListMutex=PTHREAD_MUTEX_INITIALIZER;
|
||||
#define PolarKey ((messageType << 24) | (messageLength << 8) | aggregation_level)
|
||||
static t_nrPolar_params *PolarList = NULL;
|
||||
pthread_mutex_t PolarListMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static int intcmp(const void *p1,const void *p2) {
|
||||
return(*(int16_t *)p1 > *(int16_t *)p2);
|
||||
static int intcmp(const void *p1, const void *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)
|
||||
return;
|
||||
if (polarParams->nextPtr)
|
||||
@@ -64,11 +66,12 @@ static void nr_polar_delete_list(t_nrPolar_params * polarParams) {
|
||||
free(polarParams);
|
||||
}
|
||||
|
||||
static void nr_polar_delete(void) {
|
||||
static void nr_polar_delete(void)
|
||||
{
|
||||
pthread_mutex_lock(&PolarListMutex);
|
||||
nr_polar_delete_list(PolarList);
|
||||
PolarList=NULL;
|
||||
pthread_mutex_unlock(&PolarListMutex);
|
||||
PolarList = NULL;
|
||||
pthread_mutex_unlock(&PolarListMutex);
|
||||
}
|
||||
|
||||
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
|
||||
// therefore, returning t_nrPolar_params * from the list is safe for future usage
|
||||
pthread_mutex_lock(&PolarListMutex);
|
||||
if(!PolarList)
|
||||
if (!PolarList)
|
||||
atexit(nr_polar_delete);
|
||||
|
||||
|
||||
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) {
|
||||
//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));
|
||||
if (currentPtr->busy == false && currentPtr->idx == PolarKey ) {
|
||||
currentPtr->busy=true;
|
||||
// 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));
|
||||
if (currentPtr->busy == false && currentPtr->idx == PolarKey) {
|
||||
currentPtr->busy = true;
|
||||
pthread_mutex_unlock(&PolarListMutex);
|
||||
return currentPtr ;
|
||||
}
|
||||
else
|
||||
return currentPtr;
|
||||
} else
|
||||
currentPtr = currentPtr->nextPtr;
|
||||
}
|
||||
|
||||
// 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));
|
||||
|
||||
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};
|
||||
PolarList = newPolarInitNode;
|
||||
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;
|
||||
//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) {
|
||||
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->crcCorrectionBits = NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS;
|
||||
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) {
|
||||
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->encoderLength = aggregation_level * 108;
|
||||
newPolarInitNode->crcCorrectionBits = NR_POLAR_DCI_CRC_ERROR_CORRECTION_BITS;
|
||||
newPolarInitNode->crc_generator_matrix = 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);
|
||||
newPolarInitNode->crc_generator_matrix =
|
||||
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) {
|
||||
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);
|
||||
|
||||
// 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->payloadBits = messageLength;
|
||||
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
|
||||
newPolarInitNode->n_max = SL_NR_POLAR_PSBCH_N_MAX;
|
||||
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->N = nr_polar_output_length(newPolarInitNode->K,
|
||||
newPolarInitNode->encoderLength,
|
||||
newPolarInitNode->n_max);
|
||||
newPolarInitNode->N = nr_polar_output_length(newPolarInitNode->K, newPolarInitNode->encoderLength, newPolarInitNode->n_max);
|
||||
newPolarInitNode->n = log2(newPolarInitNode->N);
|
||||
newPolarInitNode->G_N = nr_polar_kronecker_power_matrices(newPolarInitNode->n);
|
||||
// polar_encoder vectors:
|
||||
newPolarInitNode->Q_0_Nminus1 = nr_polar_sequence_pattern(newPolarInitNode->n);
|
||||
newPolarInitNode->interleaving_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->K);
|
||||
nr_polar_interleaving_pattern(newPolarInitNode->K,
|
||||
newPolarInitNode->i_il,
|
||||
newPolarInitNode->interleaving_pattern);
|
||||
nr_polar_interleaving_pattern(newPolarInitNode->K, newPolarInitNode->i_il, newPolarInitNode->interleaving_pattern);
|
||||
|
||||
newPolarInitNode->rate_matching_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength);
|
||||
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->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_F_N = 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));
|
||||
newPolarInitNode->Q_F_N =
|
||||
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++)
|
||||
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);
|
||||
|
||||
// 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);
|
||||
return newPolarInitNode;
|
||||
}
|
||||
|
||||
void nr_polar_print_polarParams() {
|
||||
void nr_polar_print_polarParams()
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
if (PolarList == NULL) {
|
||||
printf("polarParams is empty.\n");
|
||||
} else {
|
||||
t_nrPolar_params * polarParams=PolarList;
|
||||
t_nrPolar_params *polarParams = PolarList;
|
||||
while (polarParams != NULL) {
|
||||
printf("polarParams[%d] = %d, %d, %d\n", i,
|
||||
polarParams->idx>>24, (polarParams->idx>>8)&0xFFFF, polarParams->idx&0xFF);
|
||||
printf("polarParams[%d] = %d, %d, %d\n",
|
||||
i,
|
||||
polarParams->idx >> 24,
|
||||
(polarParams->idx >> 8) & 0xFFFF,
|
||||
polarParams->idx & 0xFF);
|
||||
polarParams = polarParams->nextPtr;
|
||||
i++;
|
||||
}
|
||||
@@ -268,11 +278,18 @@ void nr_polar_print_polarParams() {
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
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
|
||||
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;
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user