Reformat all polar code

Commands used:

    clang-format -i openair1/PHY/CODING/TESTBENCH/polartest.c
    clang-format -i openair1/PHY/CODING/nr_polar_init.c
    clang-format -i openair1/PHY/CODING/nrPolar_tools/*
This commit is contained in:
Robert Schmidt
2024-11-07 09:43:19 +01:00
parent 28234893f7
commit 16535f3de4
18 changed files with 1041 additions and 926 deletions
+206 -191
View File
@@ -12,161 +12,162 @@
#include "PHY/CODING/coding_defs.h"
#include "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 (&currentTime);
if (logFlag) {
time(&currentTime);
#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(&currentTime));
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
+64 -47
View File
@@ -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
}