Commit 43ff9ccf authored by Florian Kaltenberger's avatar Florian Kaltenberger

Merge branch '403-memory-leak-in-polar_init' into 'develop-nr'

Resolve "memory leak in polar_init"

See merge request oai/openairinterface5g!518
parents d383cd52 9a46d487
...@@ -17,428 +17,414 @@ ...@@ -17,428 +17,414 @@
//#define DEBUG_CRC //#define DEBUG_CRC
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
//Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.)
//Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.) time_stats_t timeEncoder,timeDecoder;
time_stats_t timeEncoder,timeDecoder; opp_enabled=1;
opp_enabled=1; int decoder_int16=0;
int decoder_int16=0; cpu_freq_GHz = get_cpu_freq_GHz();
cpu_freq_GHz = get_cpu_freq_GHz(); reset_meas(&timeEncoder);
reset_meas(&timeEncoder); reset_meas(&timeDecoder);
reset_meas(&timeDecoder); randominit(0);
randominit(0); crcTableInit();
crcTableInit(); //Default simulation values (Aim for iterations = 1000000.)
int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI
//Default simulation values (Aim for iterations = 1000000.) double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB
int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI double SNR, SNR_lin;
double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB 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.
double SNR, SNR_lin; uint16_t testLength = 0, coderLength = 0, blockErrorCumulative=0, bitErrorCumulative=0;
int16_t nBitError = 0; // -1 = Decoding failed (All list entries have failed the CRC checks). double timeEncoderCumulative = 0, timeDecoderCumulative = 0;
uint32_t decoderState=0, blockErrorState=0; //0 = Success, -1 = Decoding failed, 1 = Block Error. uint8_t aggregation_level = 8, decoderListSize = 8, pathMetricAppr = 0;
uint16_t testLength = 0, coderLength = 0, blockErrorCumulative=0, bitErrorCumulative=0;
double timeEncoderCumulative = 0, timeDecoderCumulative = 0; while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:hqg")) != -1)
uint8_t aggregation_level = 8, decoderListSize = 8, pathMetricAppr = 0; switch (arguments) {
case 's':
while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:hqg")) != -1) SNRstart = atof(optarg);
switch (arguments) break;
{
case 's': case 'd':
SNRstart = atof(optarg); SNRinc = atof(optarg);
break; break;
case 'd': case 'f':
SNRinc = atof(optarg); SNRstop = atof(optarg);
break; break;
case 'f': case 'm':
SNRstop = atof(optarg); polarMessageType = atoi(optarg);
break; break;
case 'm': case 'i':
polarMessageType = atoi(optarg); iterations = atoi(optarg);
break; break;
case 'i': case 'l':
iterations = atoi(optarg); decoderListSize = (uint8_t) atoi(optarg);
break; break;
case 'l': case 'a':
decoderListSize = (uint8_t) atoi(optarg); pathMetricAppr = (uint8_t) atoi(optarg);
break; break;
case 'a': case 'q':
pathMetricAppr = (uint8_t) atoi(optarg); decoder_int16 = 1;
break; break;
case 'q': case 'g':
decoder_int16 = 1; iterations = 1;
break; SNRstart = -6.0;
SNRstop = -6.0;
case 'g': decoder_int16 = 1;
iterations = 1; break;
SNRstart = -6.0;
SNRstop = -6.0; case 'h':
decoder_int16 = 1; printf("./polartest -s SNRstart -d SNRinc -f SNRstop -m [0=PBCH|1=DCI|2=UCI] -i iterations -l decoderListSize -a pathMetricAppr\n");
break; exit(-1);
case 'h': default:
printf("./polartest -s SNRstart -d SNRinc -f SNRstop -m [0=PBCH|1=DCI|2=UCI] -i iterations -l decoderListSize -a pathMetricAppr\n"); perror("[polartest.c] Problem at argument parsing with getopt");
exit(-1); exit(-1);
}
default:
perror("[polartest.c] Problem at argument parsing with getopt"); if (polarMessageType == 0) { //PBCH
exit(-1); testLength = 64;//NR_POLAR_PBCH_PAYLOAD_BITS;
} coderLength = NR_POLAR_PBCH_E;
aggregation_level = NR_POLAR_PBCH_AGGREGATION_LEVEL;
if (polarMessageType == 0) { //PBCH } else if (polarMessageType == 1) { //DCI
testLength = 64;//NR_POLAR_PBCH_PAYLOAD_BITS; //testLength = nr_get_dci_size(params_rel15->dci_format, params_rel15->rnti_type, &fp->initial_bwp_dl, cfg);
coderLength = NR_POLAR_PBCH_E; testLength = 41; //20;
aggregation_level = NR_POLAR_PBCH_AGGREGATION_LEVEL; coderLength = 108*8; //to be changed by aggregate level function.
} else if (polarMessageType == 1) { //DCI } else if (polarMessageType == -1) { //UCI
//testLength = nr_get_dci_size(params_rel15->dci_format, params_rel15->rnti_type, &fp->initial_bwp_dl, cfg); //testLength = ;
testLength = 41; //20; //coderLength = ;
coderLength = 108*8; //to be changed by aggregate level function. }
} else if (polarMessageType == -1) { //UCI
//testLength = ; //Logging
//coderLength = ; time_t currentTime;
} time (&currentTime);
char fileName[512], currentTimeInfo[25];
char folderName[] = ".";
//Logging /*
time_t currentTime; folderName=getenv("HOME");
time (&currentTime); strcat(folderName,"/Desktop/polartestResults");
char fileName[512], currentTimeInfo[25]; */
char folderName[] = ".";
/*
folderName=getenv("HOME");
strcat(folderName,"/Desktop/polartestResults");
*/
#ifdef DEBUG_POLAR_TIMING
sprintf(fileName,"%s/TIMING_ListSize_%d_pmAppr_%d_Payload_%d_Itr_%d",folderName,decoderListSize,pathMetricAppr,testLength,iterations);
#else
sprintf(fileName,"%s/_ListSize_%d_pmAppr_%d_Payload_%d_Itr_%d",folderName,decoderListSize,pathMetricAppr,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.
/*
struct stat folder = {0};
if (stat(folderName, &folder) == -1) mkdir(folderName, S_IRWXU | S_IRWXG | S_IRWXO);
*/
FILE* logFile;
logFile = fopen(fileName, "w");
if (logFile==NULL) {
fprintf(stderr,"[polartest.c] Problem creating file %s with fopen\n",fileName);
exit(-1);
}
#ifdef DEBUG_POLAR_TIMING #ifdef DEBUG_POLAR_TIMING
fprintf(logFile,",timeEncoderCRCByte[us],timeEncoderCRCBit[us],timeEncoderInterleaver[us],timeEncoderBitInsertion[us],timeEncoder1[us],timeEncoder2[us],timeEncoderRateMatching[us],timeEncoderByte2Bit[us]\n"); sprintf(fileName,"%s/TIMING_ListSize_%d_pmAppr_%d_Payload_%d_Itr_%d",folderName,decoderListSize,pathMetricAppr,testLength,iterations);
#else #else
fprintf(logFile,",SNR,nBitError,blockErrorState,t_encoder[us],t_decoder[us]\n"); sprintf(fileName,"%s/_ListSize_%d_pmAppr_%d_Payload_%d_Itr_%d",folderName,decoderListSize,pathMetricAppr,testLength,iterations);
#endif #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.
/*
struct stat folder = {0};
if (stat(folderName, &folder) == -1) mkdir(folderName, S_IRWXU | S_IRWXG | S_IRWXO);
*/
FILE *logFile;
logFile = fopen(fileName, "w");
if (logFile==NULL) {
fprintf(stderr,"[polartest.c] Problem creating file %s with fopen\n",fileName);
exit(-1);
}
uint8_t testArrayLength = ceil(testLength / 32.0); #ifdef DEBUG_POLAR_TIMING
uint8_t coderArrayLength = ceil(coderLength / 32.0); fprintf(logFile,
",timeEncoderCRCByte[us],timeEncoderCRCBit[us],timeEncoderInterleaver[us],timeEncoderBitInsertion[us],timeEncoder1[us],timeEncoder2[us],timeEncoderRateMatching[us],timeEncoderByte2Bit[us]\n");
uint32_t testInput[testArrayLength]; //generate randomly #else
uint32_t encoderOutput[coderArrayLength]; fprintf(logFile,",SNR,nBitError,blockErrorState,t_encoder[us],t_decoder[us]\n");
uint32_t estimatedOutput[testArrayLength]; //decoder output #endif
memset(testInput,0,sizeof(uint32_t) * testArrayLength); uint8_t testArrayLength = ceil(testLength / 32.0);
memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength); uint8_t coderArrayLength = ceil(coderLength / 32.0);
memset(estimatedOutput,0,sizeof(uint32_t) * testArrayLength); uint32_t testInput[testArrayLength]; //generate randomly
uint32_t encoderOutput[coderArrayLength];
uint8_t encoderOutputByte[coderLength]; uint32_t estimatedOutput[testArrayLength]; //decoder output
double modulatedInput[coderLength]; //channel input memset(testInput,0,sizeof(uint32_t) * testArrayLength);
double channelOutput[coderLength]; //add noise memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength);
memset(estimatedOutput,0,sizeof(uint32_t) * testArrayLength);
int16_t channelOutput_int16[coderLength]; uint8_t encoderOutputByte[coderLength];
double modulatedInput[coderLength]; //channel input
t_nrPolar_paramsPtr nrPolar_params = NULL, currentPtr = NULL; double channelOutput[coderLength]; //add noise
nr_polar_init(&nrPolar_params, polarMessageType, testLength, aggregation_level); int16_t channelOutput_int16[coderLength];
currentPtr = nr_polar_params(nrPolar_params, polarMessageType, testLength, aggregation_level); t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level);
#ifdef DEBUG_DCI_POLAR_PARAMS #ifdef DEBUG_DCI_POLAR_PARAMS
uint32_t dci_pdu[4]; uint32_t dci_pdu[4];
memset(dci_pdu,0,sizeof(uint32_t)*4); memset(dci_pdu,0,sizeof(uint32_t)*4);
dci_pdu[0]=0x01189400; dci_pdu[0]=0x01189400;
printf("dci_pdu: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", 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]); dci_pdu[0], dci_pdu[1], dci_pdu[2], dci_pdu[3]);
uint32_t encoder_output[54]; uint32_t encoder_output[54];
memset(encoder_output,0,sizeof(uint32_t)*54); memset(encoder_output,0,sizeof(uint32_t)*54);
uint16_t size=41; uint16_t size=41;
uint16_t rnti=3; uint16_t rnti=3;
aggregation_level=8; aggregation_level=8;
nr_polar_init(&nrPolar_params, 1, size, aggregation_level); t_nrPolar_params *currentPtrDCI=nr_polar_params(1, size, aggregation_level);
t_nrPolar_paramsPtr currentPtrDCI=nr_polar_params(nrPolar_params, 1, size, aggregation_level); polar_encoder_dci(dci_pdu, encoder_output, currentPtrDCI, rnti);
polar_encoder_dci(dci_pdu, encoder_output, currentPtrDCI, rnti); for (int i=0; i<54; i++)
for (int i=0;i<54;i++) printf("encoder_output: [%2d]->0x%08x \n",i, encoder_output[i]);
printf("encoder_output: [%2d]->0x%08x \n",i, encoder_output[i]);
uint8_t *encoder_outputByte = malloc(sizeof(uint8_t) * currentPtrDCI->encoderLength);
uint8_t *encoder_outputByte = malloc(sizeof(uint8_t) * currentPtrDCI->encoderLength); double *channel_output = malloc (sizeof(double) * currentPtrDCI->encoderLength);
double *channel_output = malloc (sizeof(double) * currentPtrDCI->encoderLength); uint32_t dci_estimation[4];
uint32_t dci_estimation[4]; memset(dci_estimation,0,sizeof(uint32_t)*4);
memset(dci_estimation,0,sizeof(uint32_t)*4); printf("dci_estimation: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
printf("dci_estimation: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", dci_estimation[0], dci_estimation[1], dci_estimation[2], dci_estimation[3]);
dci_estimation[0], dci_estimation[1], dci_estimation[2], dci_estimation[3]); nr_bit2byte_uint32_8_t(encoder_output, currentPtrDCI->encoderLength, encoder_outputByte);
nr_bit2byte_uint32_8_t(encoder_output, currentPtrDCI->encoderLength, encoder_outputByte); printf("[polartest] encoder_outputByte: ");
printf("[polartest] encoder_outputByte: ");
for (int i = 0; i < currentPtrDCI->encoderLength; i++) printf("%d-", encoder_outputByte[i]); for (int i = 0; i < currentPtrDCI->encoderLength; i++) printf("%d-", encoder_outputByte[i]);
printf("\n");
for(int i=0; i<currentPtrDCI->encoderLength; i++) { printf("\n");
if (encoder_outputByte[i] == 0) {
channel_output[i]=1/sqrt(2); for(int i=0; i<currentPtrDCI->encoderLength; i++) {
} if (encoder_outputByte[i] == 0) {
else { channel_output[i]=1/sqrt(2);
channel_output[i]=(-1)/sqrt(2); } else {
} channel_output[i]=(-1)/sqrt(2);
} }
}
decoderState = polar_decoder_dci(channel_output,
dci_estimation, decoderState = polar_decoder_dci(channel_output,
currentPtrDCI, dci_estimation,
NR_POLAR_DECODER_LISTSIZE, currentPtrDCI,
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION, NR_POLAR_DECODER_LISTSIZE,
rnti); NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION,
printf("dci_estimation: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", rnti);
dci_estimation[0], dci_estimation[1], dci_estimation[2], dci_estimation[3]); printf("dci_estimation: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
free(encoder_outputByte); dci_estimation[0], dci_estimation[1], dci_estimation[2], dci_estimation[3]);
free(channel_output); free(encoder_outputByte);
return 0; free(channel_output);
return 0;
#endif #endif
#ifdef DEBUG_CRC #ifdef DEBUG_CRC
uint32_t crc; uint32_t crc;
unsigned int poly24c = 0xb2b11700; unsigned int poly24c = 0xb2b11700;
uint32_t testInputCRC[4]; uint32_t testInputCRC[4];
testInputCRC[0]=0x00291880; testInputCRC[0]=0x00291880;
//testInputCRC[0]=0x01189400; //testInputCRC[0]=0x01189400;
testInputCRC[1]=0x00000000; testInputCRC[1]=0x00000000;
testInputCRC[2]=0x00000000; testInputCRC[2]=0x00000000;
testInputCRC[3]=0x00000000; testInputCRC[3]=0x00000000;
uint32_t testInputcrc=0x01189400;
uint32_t testInputcrc=0x01189400; uint32_t testInputcrc2=0x00291880;
uint32_t testInputcrc2=0x00291880; uint8_t testInputCRC2[8];
nr_crc_bit2bit_uint32_8_t(testInputCRC, 32, testInputCRC2);
uint8_t testInputCRC2[8]; printf("testInputCRC2: [0]->%x \t [1]->%x \t [2]->%x \t [3]->%x\n"
nr_crc_bit2bit_uint32_8_t(testInputCRC, 32, testInputCRC2); " [4]->%x \t [5]->%x \t [6]->%x \t [7]->%x\n",
printf("testInputCRC2: [0]->%x \t [1]->%x \t [2]->%x \t [3]->%x\n" testInputCRC2[0], testInputCRC2[1], testInputCRC2[2], testInputCRC2[3],
" [4]->%x \t [5]->%x \t [6]->%x \t [7]->%x\n", testInputCRC2[4], testInputCRC2[5], testInputCRC2[6], testInputCRC2[7]);
testInputCRC2[0], testInputCRC2[1], testInputCRC2[2], testInputCRC2[3], unsigned int crc41 = crc24c(testInputCRC, 32);
testInputCRC2[4], testInputCRC2[5], testInputCRC2[6], testInputCRC2[7]); unsigned int crc65 = crc24c(testInputCRC, 56);
unsigned int crc41 = crc24c(testInputCRC, 32); printf("crc41: [0]->0x%08x\tcrc65: [0]->0x%08x\n",crc41, crc65);
unsigned int crc65 = crc24c(testInputCRC, 56);
printf("crc41: [0]->0x%08x\tcrc65: [0]->0x%08x\n",crc41, crc65); for (int i=0; i<32; i++) printf("crc41[%d]=%d\tcrc65[%d]=%d\n",i,(crc41>>i)&1,i,(crc65>>i)&1);
for (int i=0;i<32;i++) printf("crc41[%d]=%d\tcrc65[%d]=%d\n",i,(crc41>>i)&1,i,(crc65>>i)&1);
crc = crc24c(testInputCRC, testLength)>>8;
crc = crc24c(testInputCRC, testLength)>>8;
for (int i=0;i<24;i++) printf("[i]=%d\n",(crc>>i)&1); for (int i=0; i<24; i++) printf("[i]=%d\n",(crc>>i)&1);
printf("crc: [0]->0x%08x\n",crc);
//crcbit(testInputCRC, sizeof(test) - 1, poly24c)); printf("crc: [0]->0x%08x\n",crc);
//crcbit(testInputCRC, sizeof(test) - 1, poly24c));
testInputCRC[testLength>>3] = ((uint8_t*)&crc)[2]; testInputCRC[testLength>>3] = ((uint8_t *)&crc)[2];
testInputCRC[1+(testLength>>3)] = ((uint8_t*)&crc)[1]; testInputCRC[1+(testLength>>3)] = ((uint8_t *)&crc)[1];
testInputCRC[2+(testLength>>3)] = ((uint8_t*)&crc)[0]; testInputCRC[2+(testLength>>3)] = ((uint8_t *)&crc)[0];
printf("testInputCRC: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", printf("testInputCRC: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
testInputCRC[0], testInputCRC[1], testInputCRC[2], testInputCRC[3]); testInputCRC[0], testInputCRC[1], testInputCRC[2], testInputCRC[3]);
//uint32_t trial32 = 0xffffffff;
uint32_t trial32 = 0xf10fffff;
//uint32_t trial32 = 0xffffffff; uint8_t a[4];
uint32_t trial32 = 0xf10fffff; //memcpy(a, &trial32, sizeof(trial32));
uint8_t a[4]; *(uint32_t *)a = trial32;
//memcpy(a, &trial32, sizeof(trial32)); unsigned char trial[4];
*(uint32_t *)a = trial32; trial[0]=0xff;
unsigned char trial[4]; trial[1]=0xff;
trial[0]=0xff; trial[1]=0xff; trial[2]=0x0f; trial[3]=0xf1; trial[2]=0x0f;
uint32_t trialcrc = crc24c(trial, 32); trial[3]=0xf1;
uint32_t trialcrc32 = crc24c((uint8_t *)&trial32, 32); uint32_t trialcrc = crc24c(trial, 32);
//uint32_t trialcrc32 = crc24c(a, 32); uint32_t trialcrc32 = crc24c((uint8_t *)&trial32, 32);
printf("crcbit(trial = %x\n", crcbit(trial, 4, poly24c)); //uint32_t trialcrc32 = crc24c(a, 32);
printf("trialcrc = %x\n", trialcrc); printf("crcbit(trial = %x\n", crcbit(trial, 4, poly24c));
printf("trialcrc32 = %x\n", trialcrc32); printf("trialcrc = %x\n", trialcrc);
for (int i=0;i<32;i++) printf("trialcrc[%2d]=%d\ttrialcrc32[%2d]=%d\n",i,(trialcrc>>i)&1,i,(trialcrc32>>i)&1); printf("trialcrc32 = %x\n", trialcrc32);
for (int i=0; i<32; i++) printf("trialcrc[%2d]=%d\ttrialcrc32[%2d]=%d\n",i,(trialcrc>>i)&1,i,(trialcrc32>>i)&1);
//uint8_t nr_polar_A[32] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
uint8_t nr_polar_A[32] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,1}; //uint8_t nr_polar_A[32] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
uint8_t nr_polar_crc[24]; uint8_t nr_polar_A[32] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,1};
uint8_t **crc_generator_matrix = crc24c_generator_matrix(32); uint8_t nr_polar_crc[24];
nr_matrix_multiplication_uint8_1D_uint8_2D(nr_polar_A, uint8_t **crc_generator_matrix = crc24c_generator_matrix(32);
crc_generator_matrix, nr_matrix_multiplication_uint8_1D_uint8_2D(nr_polar_A,
nr_polar_crc, crc_generator_matrix,
32, nr_polar_crc,
24); 32,
for (uint8_t i = 0; i < 24; i++){ 24);
nr_polar_crc[i] = (nr_polar_crc[i] % 2);
printf("nr_polar_crc[%d]=%d\n",i,nr_polar_crc[i]); for (uint8_t i = 0; i < 24; i++) {
} nr_polar_crc[i] = (nr_polar_crc[i] % 2);
return 0; printf("nr_polar_crc[%d]=%d\n",i,nr_polar_crc[i]);
}
return 0;
#endif #endif
#ifdef DEBUG_POLAR_TIMING #ifdef DEBUG_POLAR_TIMING
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
SNR_lin = pow(10, SNR / 10);
for (itr = 1; itr <= iterations; itr++) {
for (int j=0; j<ceil(testLength / 32.0); j++) {
for(int i=0; i<32; i++) {
testInput[j] |= ( ((uint32_t) (rand()%2)) &1);
testInput[j]<<=1;
}
}
printf("testInput: [0]->0x%08x \n", testInput[0]);
polar_encoder_timing(testInput, encoderOutput, currentPtr, cpu_freq_GHz, logFile);
}
}
fclose(logFile);
free(testInput);
free(encoderOutput);
free(modulatedInput);
free(channelOutput);
free(estimatedOutput);
return (0);
#endif
// We assume no a priori knowledge available about the payload. for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
double aPrioriArray[currentPtr->payloadBits]; SNR_lin = pow(10, SNR / 10);
for (int i=0; i<currentPtr->payloadBits; i++) aPrioriArray[i] = NAN;
for (itr = 1; itr <= iterations; itr++) {
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) { for (int j=0; j<ceil(testLength / 32.0); j++) {
printf("SNR %f\n",SNR); for(int i=0; i<32; i++) {
SNR_lin = pow(10, SNR/10); testInput[j] |= ( ((uint32_t) (rand()%2)) &1);
for (itr = 1; itr <= iterations; itr++) { testInput[j]<<=1;
}
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); printf("testInput: [0]->0x%08x \n", testInput[0]);
testInput[i]<<=1; polar_encoder_timing(testInput, encoderOutput, currentPtr, cpu_freq_GHz, logFile);
} }
testInput[i] |= ( ((uint32_t) (rand()%2)) &1); }
}
fclose(logFile);
/*printf("testInput: [0]->0x%08x\n", testInput[0]); free(testInput);
for (int i=0; i<32; i++) free(encoderOutput);
printf("%d\n",(testInput[0]>>i)&1);*/ free(modulatedInput);
free(channelOutput);
free(estimatedOutput);
return (0);
int len_mod64=currentPtr->payloadBits&63; #endif
((uint64_t*)testInput)[currentPtr->payloadBits/64]&=((((uint64_t)1)<<len_mod64)-1); // We assume no a priori knowledge available about the payload.
double aPrioriArray[currentPtr->payloadBits];
start_meas(&timeEncoder);
if (decoder_int16==0) for (int i=0; i<currentPtr->payloadBits; i++) aPrioriArray[i] = NAN;
polar_encoder(testInput, encoderOutput, currentPtr);
else for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
polar_encoder_fast((uint64_t*)testInput, encoderOutput,0, currentPtr); printf("SNR %f\n",SNR);
//polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0, currentPtr); SNR_lin = pow(10, SNR/10);
stop_meas(&timeEncoder);
/*printf("encoderOutput: [0]->0x%08x\n", encoderOutput[0]); for (itr = 1; itr <= iterations; itr++) {
printf("encoderOutput: [1]->0x%08x\n", encoderOutput[1]);*/ for (int i = 0; i < testArrayLength; i++) {
for (int j = 0; j < (sizeof(testInput[0])*8)-1; j++) {
//Bit-to-byte: testInput[i] |= ( ((uint32_t) (rand()%2)) &1);
nr_bit2byte_uint32_8_t(encoderOutput, coderLength, encoderOutputByte); testInput[i]<<=1;
}
//BPSK modulation
for(int i=0; i<coderLength; i++) { testInput[i] |= ( ((uint32_t) (rand()%2)) &1);
if (encoderOutputByte[i] == 0) }
modulatedInput[i]=1/sqrt(2);
else /*printf("testInput: [0]->0x%08x\n", testInput[0]);
modulatedInput[i]=(-1)/sqrt(2); for (int i=0; i<32; i++)
printf("%d\n",(testInput[0]>>i)&1);*/
channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin))); 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) {
if (channelOutput[i] > 15) channelOutput_int16[i] = 127; if (decoder_int16==0)
else if (channelOutput[i] < -16) channelOutput_int16[i] = -128; polar_encoder(testInput, encoderOutput, currentPtr);
else channelOutput_int16[i] = (int16_t) (8*channelOutput[i]); else
} polar_encoder_fast((uint64_t *)testInput, encoderOutput,0, currentPtr);
//polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0, currentPtr);
} stop_meas(&timeEncoder);
/*printf("encoderOutput: [0]->0x%08x\n", encoderOutput[0]);
start_meas(&timeDecoder); printf("encoderOutput: [1]->0x%08x\n", encoderOutput[1]);*/
/*decoderState = polar_decoder(channelOutput, //Bit-to-byte:
estimatedOutput, nr_bit2byte_uint32_8_t(encoderOutput, coderLength, encoderOutputByte);
currentPtr,
NR_POLAR_DECODER_LISTSIZE, //BPSK modulation
aPrioriArray, for(int i=0; i<coderLength; i++) {
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION);*/ if (encoderOutputByte[i] == 0)
if (decoder_int16==0) modulatedInput[i]=1/sqrt(2);
decoderState = polar_decoder_aPriori(channelOutput, else
estimatedOutput, modulatedInput[i]=(-1)/sqrt(2);
currentPtr,
NR_POLAR_DECODER_LISTSIZE, channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin)));
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION,
aPrioriArray); if (decoder_int16==1) {
else if (channelOutput[i] > 15) channelOutput_int16[i] = 127;
decoderState = polar_decoder_int16(channelOutput_int16, else if (channelOutput[i] < -16) channelOutput_int16[i] = -128;
(uint64_t*)estimatedOutput, else channelOutput_int16[i] = (int16_t) (8*channelOutput[i]);
currentPtr); }
}
stop_meas(&timeDecoder); start_meas(&timeDecoder);
/*printf("testInput: [0]->0x%08x\n", testInput[0]);
printf("estimatedOutput: [0]->0x%08x\n", estimatedOutput[0]);*/ /*decoderState = polar_decoder(channelOutput,
estimatedOutput,
currentPtr,
//calculate errors NR_POLAR_DECODER_LISTSIZE,
if (decoderState!=0) { aPrioriArray,
blockErrorState=-1; NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION);*/
nBitError=-1; if (decoder_int16==0)
} else { decoderState = polar_decoder_aPriori(channelOutput,
for (int j = 0; j < currentPtr->payloadBits; j++) { estimatedOutput,
if (((estimatedOutput[0]>>j) & 1) != ((testInput[0]>>j) & 1)) nBitError++; currentPtr,
// printf("bit %d: %d => %d\n",j,(testInput[0]>>j)&1,(estimatedOutput[0]>>j)&1); NR_POLAR_DECODER_LISTSIZE,
} NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION,
aPrioriArray);
else
if (nBitError>0) { decoderState = polar_decoder_int16(channelOutput_int16,
blockErrorState=1; (uint64_t *)estimatedOutput,
// printf("Error: Input %x, Output %x\n",testInput[0],estimatedOutput[0]); currentPtr);
}
} stop_meas(&timeDecoder);
/*printf("testInput: [0]->0x%08x\n", testInput[0]);
//Iteration times are in microseconds. printf("estimatedOutput: [0]->0x%08x\n", estimatedOutput[0]);*/
timeEncoderCumulative+=(timeEncoder.diff/(cpu_freq_GHz*1000.0));
timeDecoderCumulative+=(timeDecoder.diff/(cpu_freq_GHz*1000.0)); //calculate errors
fprintf(logFile,",%f,%d,%d,%f,%f\n", SNR, nBitError, blockErrorState, if (decoderState!=0) {
(timeEncoder.diff/(cpu_freq_GHz*1000.0)), (timeDecoder.diff/(cpu_freq_GHz*1000.0))); blockErrorState=-1;
nBitError=-1;
if (nBitError<0) { } else {
blockErrorCumulative++; for (int j = 0; j < currentPtr->payloadBits; j++) {
bitErrorCumulative+=testLength; if (((estimatedOutput[0]>>j) & 1) != ((testInput[0]>>j) & 1)) nBitError++;
} else {
blockErrorCumulative+=blockErrorState; // printf("bit %d: %d => %d\n",j,(testInput[0]>>j)&1,(estimatedOutput[0]>>j)&1);
bitErrorCumulative+=nBitError; }
}
if (nBitError>0) {
decoderState=0; blockErrorState=1;
nBitError=0; // printf("Error: Input %x, Output %x\n",testInput[0],estimatedOutput[0]);
blockErrorState=0; }
}
}
//Calculate error statistics for the SNR. //Iteration times are in microseconds.
printf("[ListSize=%d, Appr=%d] SNR=%+8.3f, BLER=%9.6f, BER=%12.9f, t_Encoder=%9.3fus, t_Decoder=%9.3fus\n", timeEncoderCumulative+=(timeEncoder.diff/(cpu_freq_GHz*1000.0));
decoderListSize, pathMetricAppr, SNR, ((double)blockErrorCumulative/iterations), timeDecoderCumulative+=(timeDecoder.diff/(cpu_freq_GHz*1000.0));
((double)bitErrorCumulative / (iterations*testLength)), fprintf(logFile,",%f,%d,%d,%f,%f\n", SNR, nBitError, blockErrorState,
(double)timeEncoder.diff/timeEncoder.trials/(cpu_freq_GHz*1000.0),(double)timeDecoder.diff/timeDecoder.trials/(cpu_freq_GHz*1000.0)); (timeEncoder.diff/(cpu_freq_GHz*1000.0)), (timeDecoder.diff/(cpu_freq_GHz*1000.0)));
//(timeEncoderCumulative/iterations),timeDecoderCumulative/iterations);
if (nBitError<0) {
if (blockErrorCumulative==0 && bitErrorCumulative==0) blockErrorCumulative++;
break; bitErrorCumulative+=testLength;
} else {
blockErrorCumulative = 0; bitErrorCumulative = 0; blockErrorCumulative+=blockErrorState;
timeEncoderCumulative = 0; timeDecoderCumulative = 0; bitErrorCumulative+=nBitError;
} }
print_meas(&timeEncoder,"polar_encoder",NULL,NULL); decoderState=0;
print_meas(&timeDecoder,"polar_decoder",NULL,NULL); nBitError=0;
blockErrorState=0;
fclose(logFile); }
return (0);
//Calculate error statistics for the SNR.
printf("[ListSize=%d, Appr=%d] SNR=%+8.3f, BLER=%9.6f, BER=%12.9f, t_Encoder=%9.3fus, t_Decoder=%9.3fus\n",
decoderListSize, pathMetricAppr, SNR, ((double)blockErrorCumulative/iterations),
((double)bitErrorCumulative / (iterations*testLength)),
(double)timeEncoder.diff/timeEncoder.trials/(cpu_freq_GHz*1000.0),(double)timeDecoder.diff/timeDecoder.trials/(cpu_freq_GHz*1000.0));
//(timeEncoderCumulative/iterations),timeDecoderCumulative/iterations);
if (blockErrorCumulative==0 && bitErrorCumulative==0)
break;
blockErrorCumulative = 0;
bitErrorCumulative = 0;
timeEncoderCumulative = 0;
timeDecoderCumulative = 0;
}
print_meas(&timeEncoder,"polar_encoder",NULL,NULL);
print_meas(&timeDecoder,"polar_decoder",NULL,NULL);
fclose(logFile);
return (0);
} }
...@@ -40,1020 +40,1101 @@ ...@@ -40,1020 +40,1101 @@
#include "assertions.h" #include "assertions.h"
int8_t polar_decoder( int8_t polar_decoder(
double *input, double *input,
uint8_t *out, uint8_t *out,
t_nrPolar_paramsPtr polarParams, t_nrPolar_params *polarParams,
uint8_t listSize, uint8_t listSize,
uint8_t pathMetricAppr) uint8_t pathMetricAppr) {
{ //Assumes no a priori knowledge.
//Assumes no a priori knowledge. uint8_t ***bit = nr_alloc_uint8_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
uint8_t **bitUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
uint8_t ***bit = nr_alloc_uint8_3D_array(polarParams->N, (polarParams->n+1), 2*listSize); uint8_t **llrUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
uint8_t **bitUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True double ***llr = nr_alloc_double_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
uint8_t **llrUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True uint8_t **crcChecksum = nr_alloc_uint8_2D_array(polarParams->crcParityBits, 2*listSize);
double ***llr = nr_alloc_double_3D_array(polarParams->N, (polarParams->n+1), 2*listSize); double *pathMetric = malloc(sizeof(double)*(2*listSize));
uint8_t **crcChecksum = nr_alloc_uint8_2D_array(polarParams->crcParityBits, 2*listSize); uint8_t *crcState = malloc(sizeof(uint8_t)*(2*listSize)); //0=False, 1=True
double *pathMetric = malloc(sizeof(double)*(2*listSize));
uint8_t *crcState = malloc(sizeof(uint8_t)*(2*listSize)); //0=False, 1=True for (int i=0; i<(2*listSize); i++) {
pathMetric[i] = 0;
for (int i=0; i<(2*listSize); i++) { crcState[i]=1;
pathMetric[i] = 0; }
crcState[i]=1;
} for (int i=0; i<polarParams->N; i++) {
for (int i=0; i<polarParams->N; i++) { llrUpdated[i][polarParams->n]=1;
llrUpdated[i][polarParams->n]=1; bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2);
bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2); }
}
uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3
uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3 uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2
uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2
for (int i = 0; i < polarParams->K; i++){ for (int i = 0; i < polarParams->K; i++) {
extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t)); extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t)); tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
} }
for (int i=0; i<polarParams->payloadBits; i++) { for (int i=0; i<polarParams->payloadBits; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) { for (int j=0; j<polarParams->crcParityBits; j++) {
tempECGM[i][j]=polarParams->crc_generator_matrix[i][j]; tempECGM[i][j]=polarParams->crc_generator_matrix[i][j];
} }
} }
for (int i=polarParams->payloadBits; i<polarParams->K; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) { for (int i=polarParams->payloadBits; i<polarParams->K; i++) {
if( (i-polarParams->payloadBits) == j ){ for (int j=0; j<polarParams->crcParityBits; j++) {
tempECGM[i][j]=1; if( (i-polarParams->payloadBits) == j ) {
} else { tempECGM[i][j]=1;
tempECGM[i][j]=0; } else {
} tempECGM[i][j]=0;
} }
} }
}
for (int i=0; i<polarParams->K; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) { for (int i=0; i<polarParams->K; i++) {
extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j]; 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.
uint16_t last1ind[polarParams->crcParityBits]; //The index of the last 1-valued bit that appears in each column.
for (int j=0; j<polarParams->crcParityBits; j++) { uint16_t last1ind[polarParams->crcParityBits];
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;
}
double *d_tilde = malloc(sizeof(double) * polarParams->N); }
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]; double *d_tilde = malloc(sizeof(double) * polarParams->N);
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];
* SCL polar decoder.
*/ /*
* SCL polar decoder.
uint32_t nonFrozenBit=0; */
uint8_t currentListSize=1; uint32_t nonFrozenBit=0;
uint8_t decoderIterationCheck=0; uint8_t currentListSize=1;
int16_t checkCrcBits=-1; uint8_t decoderIterationCheck=0;
uint8_t listIndex[2*listSize], copyIndex; int16_t checkCrcBits=-1;
uint8_t listIndex[2*listSize], copyIndex;
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++){
updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr); for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++) {
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr);
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12
} else { //Information or CRC bit. if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr); updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12
} else { //Information or CRC bit.
for (int i = 0; i < currentListSize; i++) { updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr);
for (int j = 0; j < polarParams->N; j++) {
for (int k = 0; k < (polarParams->n+1); k++) { for (int i = 0; i < currentListSize; i++) {
bit[j][k][i+currentListSize]=bit[j][k][i]; for (int j = 0; j < polarParams->N; j++) {
llr[j][k][i+currentListSize]=llr[j][k][i];}}} for (int k = 0; k < (polarParams->n+1); k++) {
for (int i = 0; i < currentListSize; i++) { bit[j][k][i+currentListSize]=bit[j][k][i];
bit[currentBit][0][i]=0; llr[j][k][i+currentListSize]=llr[j][k][i];
crcState[i+currentListSize]=crcState[i]; }
} }
for (int i = currentListSize; i < 2*currentListSize; i++) bit[currentBit][0][i]=1; }
bitUpdated[currentBit][0]=1;
updateCrcChecksum2(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); for (int i = 0; i < currentListSize; i++) {
currentListSize*=2; bit[currentBit][0][i]=0;
crcState[i+currentListSize]=crcState[i];
//Keep only the best "listSize" number of entries. }
if (currentListSize > listSize) {
for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i; for (int i = currentListSize; i < 2*currentListSize; i++) bit[currentBit][0][i]=1;
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
bitUpdated[currentBit][0]=1;
//sort listIndex[listSize, ..., 2*listSize-1] in descending order. updateCrcChecksum2(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
uint8_t swaps, tempInd; currentListSize*=2;
for (uint8_t i = 0; i < listSize; i++) {
swaps = 0; //Keep only the best "listSize" number of entries.
for (uint8_t j = listSize; j < (2*listSize - i) - 1; j++) { if (currentListSize > listSize) {
if (listIndex[j+1] > listIndex[j]) { for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i;
tempInd = listIndex[j];
listIndex[j] = listIndex[j + 1]; nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
listIndex[j + 1] = tempInd; //sort listIndex[listSize, ..., 2*listSize-1] in descending order.
swaps++; uint8_t swaps, tempInd;
}
} for (uint8_t i = 0; i < listSize; i++) {
if (swaps == 0) swaps = 0;
break;
} for (uint8_t j = listSize; j < (2*listSize - i) - 1; j++) {
if (listIndex[j+1] > listIndex[j]) {
//First, backup the best "listSize" number of entries. tempInd = listIndex[j];
for (int k=(listSize-1); k>0; k--) { listIndex[j] = listIndex[j + 1];
for (int i=0; i<polarParams->N; i++) { listIndex[j + 1] = tempInd;
for (int j=0; j<(polarParams->n+1); j++) { swaps++;
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]]; }
}
} if (swaps == 0)
} break;
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]]; //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 k=(listSize-1); k>0; k--) crcState[listIndex[(2*listSize-1)-k]]=crcState[listIndex[k]]; for (int j=0; j<(polarParams->n+1); j++) {
bit[i][j][listIndex[(2*listSize-1)-k]]=bit[i][j][listIndex[k]];
//Copy the best "listSize" number of entries to the first indices. llr[i][j][listIndex[(2*listSize-1)-k]]=llr[i][j][listIndex[k]];
for (int k = 0; k < listSize; k++) { }
if (k > listIndex[k]) { }
copyIndex = listIndex[(2*listSize-1)-k]; }
} else { //Use the backup.
copyIndex = listIndex[k]; for (int k=(listSize-1); k>0; k--) {
} for (int i = 0; i < polarParams->crcParityBits; i++) {
for (int i = 0; i < polarParams->N; i++) { crcChecksum[i][listIndex[(2*listSize-1)-k]] = crcChecksum[i][listIndex[k]];
for (int j = 0; j < (polarParams->n + 1); j++) { }
bit[i][j][k] = bit[i][j][copyIndex]; }
llr[i][j][k] = llr[i][j][copyIndex];
} 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.
for (int k = 0; k < listSize; k++) { for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) { if (k > listIndex[k]) {
copyIndex = listIndex[(2*listSize-1)-k]; copyIndex = listIndex[(2*listSize-1)-k];
} else { //Use the backup. } else { //Use the backup.
copyIndex = listIndex[k]; copyIndex = listIndex[k];
} }
for (int i = 0; i < polarParams->crcParityBits; i++) {
crcChecksum[i][k]=crcChecksum[i][copyIndex]; for (int i = 0; i < polarParams->N; i++) {
} for (int j = 0; j < (polarParams->n + 1); j++) {
} bit[i][j][k] = bit[i][j][copyIndex];
for (int k = 0; k < listSize; k++) { llr[i][j][k] = llr[i][j][copyIndex];
if (k > listIndex[k]) { }
copyIndex = listIndex[(2*listSize-1)-k]; }
} else { //Use the backup. }
copyIndex = listIndex[k];
} for (int k = 0; k < listSize; k++) {
crcState[k]=crcState[copyIndex]; if (k > listIndex[k]) {
} copyIndex = listIndex[(2*listSize-1)-k];
currentListSize = listSize; } else { //Use the backup.
} copyIndex = listIndex[k];
}
for (int i=0; i<polarParams->crcParityBits; i++) { for (int i = 0; i < polarParams->crcParityBits; i++) {
if (last1ind[i]==nonFrozenBit) { crcChecksum[i][k]=crcChecksum[i][copyIndex];
checkCrcBits=i; }
break; }
}
} for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) {
if ( checkCrcBits > (-1) ) { copyIndex = listIndex[(2*listSize-1)-k];
for (uint8_t i = 0; i < currentListSize; i++) { } else { //Use the backup.
if (crcChecksum[checkCrcBits][i]==1) { copyIndex = listIndex[k];
crcState[i]=0; //0=False, 1=True }
}
} crcState[k]=crcState[copyIndex];
} }
for (uint8_t i = 0; i < currentListSize; i++) decoderIterationCheck+=crcState[i]; currentListSize = listSize;
if (decoderIterationCheck==0) { }
//perror("[SCL polar decoder] All list entries have failed the CRC checks.");
free(d_tilde); for (int i=0; i<polarParams->crcParityBits; i++) {
free(pathMetric); if (last1ind[i]==nonFrozenBit) {
free(crcState); checkCrcBits=i;
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1)); break;
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1)); }
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits); }
return(-1);
} if ( checkCrcBits > (-1) ) {
for (uint8_t i = 0; i < currentListSize; i++) {
nonFrozenBit++; if (crcChecksum[checkCrcBits][i]==1) {
decoderIterationCheck=0; crcState[i]=0; //0=False, 1=True
checkCrcBits=-1; }
} }
} }
for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i; for (uint8_t i = 0; i < currentListSize; i++) decoderIterationCheck+=crcState[i];
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
if (decoderIterationCheck==0) {
for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) { //perror("[SCL polar decoder] All list entries have failed the CRC checks.");
if ( crcState[listIndex[i]] == 1 ) { free(d_tilde);
for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_U[j]=bit[j][0][listIndex[i]]; free(pathMetric);
free(crcState);
//Extract the information bits (û to ĉ) nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
nr_polar_info_bit_extraction(polarParams->nr_polar_U, polarParams->nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N); nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
//Deinterleaving (ĉ to b) return(-1);
nr_polar_deinterleaver(polarParams->nr_polar_CPrime, polarParams->nr_polar_B, polarParams->interleaving_pattern, polarParams->K); }
nonFrozenBit++;
//Remove the CRC (â) decoderIterationCheck=0;
for (int j = 0; j < polarParams->payloadBits; j++) polarParams->nr_polar_A[j]=polarParams->nr_polar_B[j]; checkCrcBits=-1;
}
break; }
}
} for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i;
free(d_tilde); nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
free(pathMetric);
free(crcState); for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) {
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1)); if ( crcState[listIndex[i]] == 1 ) {
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1)); for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_U[j]=bit[j][0][listIndex[i]];
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
nr_free_uint8_2D_array(extended_crc_generator_matrix, polarParams->K); //Extract the information bits (û to ĉ)
nr_free_uint8_2D_array(tempECGM, polarParams->K); nr_polar_info_bit_extraction(polarParams->nr_polar_U, polarParams->nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N);
//Deinterleaving (ĉ to b)
/* nr_polar_deinterleaver(polarParams->nr_polar_CPrime, polarParams->nr_polar_B, polarParams->interleaving_pattern, polarParams->K);
* Return bits.
*/ //Remove the CRC (â)
//nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out); for (int j = 0; j < polarParams->payloadBits; j++) polarParams->nr_polar_A[j]=polarParams->nr_polar_B[j];
return(0);
break;
}
}
free(d_tilde);
free(pathMetric);
free(crcState);
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
nr_free_uint8_2D_array(extended_crc_generator_matrix, polarParams->K);
nr_free_uint8_2D_array(tempECGM, polarParams->K);
/*
* Return bits.
*/
//nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out);
return(0);
} }
int8_t polar_decoder_aPriori(double *input, int8_t polar_decoder_aPriori(double *input,
uint32_t *out, uint32_t *out,
t_nrPolar_paramsPtr polarParams, t_nrPolar_params *polarParams,
uint8_t listSize, uint8_t listSize,
uint8_t pathMetricAppr, uint8_t pathMetricAppr,
double *aPrioriPayload) double *aPrioriPayload) {
{
uint8_t ***bit = nr_alloc_uint8_3D_array(polarParams->N, (polarParams->n+1), 2*listSize); uint8_t ***bit = nr_alloc_uint8_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
uint8_t **bitUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True uint8_t **bitUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
uint8_t **llrUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True uint8_t **llrUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
double ***llr = nr_alloc_double_3D_array(polarParams->N, (polarParams->n+1), 2*listSize); double ***llr = nr_alloc_double_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
uint8_t **crcChecksum = nr_alloc_uint8_2D_array(polarParams->crcParityBits, 2*listSize); uint8_t **crcChecksum = nr_alloc_uint8_2D_array(polarParams->crcParityBits, 2*listSize);
double *pathMetric = malloc(sizeof(double)*(2*listSize)); double *pathMetric = malloc(sizeof(double)*(2*listSize));
uint8_t *crcState = malloc(sizeof(uint8_t)*(2*listSize)); //0=False, 1=True uint8_t *crcState = malloc(sizeof(uint8_t)*(2*listSize)); //0=False, 1=True
for (int i=0; i<(2*listSize); i++) { for (int i=0; i<(2*listSize); i++) {
pathMetric[i] = 0; pathMetric[i] = 0;
crcState[i]=1; crcState[i]=1;
} }
for (int i=0; i<polarParams->N; i++) {
llrUpdated[i][polarParams->n]=1; for (int i=0; i<polarParams->N; i++) {
bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2); llrUpdated[i][polarParams->n]=1;
} bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2);
}
uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3
uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2 uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3
for (int i = 0; i < polarParams->K; i++){ uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2
extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t)); for (int i = 0; i < polarParams->K; i++) {
} extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
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++) {
if( (i-polarParams->payloadBits) == j ){
tempECGM[i][j]=1;
} else {
tempECGM[i][j]=0;
}
}
}
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.
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;
}
}
double *d_tilde = malloc(sizeof(double) * polarParams->N);
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];
/*
* SCL polar decoder.
*/
uint32_t nonFrozenBit=0;
uint8_t currentListSize=1;
uint8_t decoderIterationCheck=0;
int16_t checkCrcBits=-1;
uint8_t listIndex[2*listSize], copyIndex;
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++){
updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr);
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12
} else { //Information or CRC bit.
if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) &&
(aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 0) ) {
//Information bit with known value of "0".
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr);
bitUpdated[currentBit][0]=1; //0=False, 1=True
} else if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) &&
(aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) {
//Information bit with known value of "1".
updatePathMetric(pathMetric, llr, currentListSize, 1, currentBit, pathMetricAppr);
for (uint8_t i=0; i<currentListSize; i++) bit[currentBit][0][i]=1;
bitUpdated[currentBit][0]=1;
updateCrcChecksum(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
} else {
updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr);
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 i = 0; i < currentListSize; i++) {
bit[currentBit][0][i]=0;
crcState[i+currentListSize]=crcState[i];
}
for (int i = currentListSize; i < 2*currentListSize; i++) bit[currentBit][0][i]=1;
bitUpdated[currentBit][0]=1;
updateCrcChecksum2(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
currentListSize*=2;
//Keep only the best "listSize" number of entries.
if (currentListSize > listSize) {
for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i;
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
//sort listIndex[listSize, ..., 2*listSize-1] in descending order.
uint8_t swaps, tempInd;
for (uint8_t i = 0; i < listSize; i++) {
swaps = 0;
for (uint8_t j = listSize; j < (2*listSize - i) - 1; j++) {
if (listIndex[j+1] > listIndex[j]) {
tempInd = listIndex[j];
listIndex[j] = listIndex[j + 1];
listIndex[j + 1] = tempInd;
swaps++;
}
}
if (swaps == 0)
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]];
}
}
}
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]];
}
}
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.
for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) {
copyIndex = listIndex[(2*listSize-1)-k];
} else { //Use the backup.
copyIndex = listIndex[k];
}
for (int i = 0; i < polarParams->N; i++) {
for (int j = 0; j < (polarParams->n + 1); j++) {
bit[i][j][k] = bit[i][j][copyIndex];
llr[i][j][k] = llr[i][j][copyIndex];
}
}
}
for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) {
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];
}
}
for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) {
copyIndex = listIndex[(2*listSize-1)-k];
} else { //Use the backup.
copyIndex = listIndex[k];
}
crcState[k]=crcState[copyIndex];
}
currentListSize = listSize;
}
}
for (int i=0; i<polarParams->crcParityBits; i++) {
if (last1ind[i]==nonFrozenBit) {
checkCrcBits=i;
break;
}
}
if ( checkCrcBits > (-1) ) {
for (uint8_t i = 0; i < currentListSize; i++) {
if (crcChecksum[checkCrcBits][i]==1) {
crcState[i]=0; //0=False, 1=True
}
}
}
for (uint8_t i = 0; i < currentListSize; i++) decoderIterationCheck+=crcState[i];
if (decoderIterationCheck==0) {
//perror("[SCL polar decoder] All list entries have failed the CRC checks.");
free(d_tilde);
free(pathMetric);
free(crcState);
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
return(-1);
}
nonFrozenBit++;
decoderIterationCheck=0;
checkCrcBits=-1;
}
}
for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i;
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) {
if ( crcState[listIndex[i]] == 1 ) {
for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_U[j]=bit[j][0][listIndex[i]];
//Extract the information bits (û to ĉ)
nr_polar_info_bit_extraction(polarParams->nr_polar_U, polarParams->nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N);
//Deinterleaving (ĉ to b)
nr_polar_deinterleaver(polarParams->nr_polar_CPrime, polarParams->nr_polar_B, polarParams->interleaving_pattern, polarParams->K);
//Remove the CRC (â)
for (int j = 0; j < polarParams->payloadBits; j++)
polarParams->nr_polar_A[j]=polarParams->nr_polar_B[j];
break;
}
}
free(d_tilde);
free(pathMetric);
free(crcState);
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
nr_free_uint8_2D_array(extended_crc_generator_matrix, polarParams->K);
nr_free_uint8_2D_array(tempECGM, polarParams->K);
/*
* Return bits.
*/
nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out);
return(0);
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++) {
if( (i-polarParams->payloadBits) == j ) {
tempECGM[i][j]=1;
} else {
tempECGM[i][j]=0;
}
}
}
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.
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;
}
}
double *d_tilde = malloc(sizeof(double) * polarParams->N);
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];
/*
* SCL polar decoder.
*/
uint32_t nonFrozenBit=0;
uint8_t currentListSize=1;
uint8_t decoderIterationCheck=0;
int16_t checkCrcBits=-1;
uint8_t listIndex[2*listSize], copyIndex;
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++) {
updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr);
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12
} else { //Information or CRC bit.
if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) &&
(aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 0) ) {
//Information bit with known value of "0".
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr);
bitUpdated[currentBit][0]=1; //0=False, 1=True
} else if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) &&
(aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) {
//Information bit with known value of "1".
updatePathMetric(pathMetric, llr, currentListSize, 1, currentBit, pathMetricAppr);
for (uint8_t i=0; i<currentListSize; i++) bit[currentBit][0][i]=1;
bitUpdated[currentBit][0]=1;
updateCrcChecksum(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
} else {
updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr);
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 i = 0; i < currentListSize; i++) {
bit[currentBit][0][i]=0;
crcState[i+currentListSize]=crcState[i];
}
for (int i = currentListSize; i < 2*currentListSize; i++) bit[currentBit][0][i]=1;
bitUpdated[currentBit][0]=1;
updateCrcChecksum2(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
currentListSize*=2;
//Keep only the best "listSize" number of entries.
if (currentListSize > listSize) {
for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i;
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
//sort listIndex[listSize, ..., 2*listSize-1] in descending order.
uint8_t swaps, tempInd;
for (uint8_t i = 0; i < listSize; i++) {
swaps = 0;
for (uint8_t j = listSize; j < (2*listSize - i) - 1; j++) {
if (listIndex[j+1] > listIndex[j]) {
tempInd = listIndex[j];
listIndex[j] = listIndex[j + 1];
listIndex[j + 1] = tempInd;
swaps++;
}
}
if (swaps == 0)
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]];
}
}
}
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]];
}
}
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.
for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) {
copyIndex = listIndex[(2*listSize-1)-k];
} else { //Use the backup.
copyIndex = listIndex[k];
}
for (int i = 0; i < polarParams->N; i++) {
for (int j = 0; j < (polarParams->n + 1); j++) {
bit[i][j][k] = bit[i][j][copyIndex];
llr[i][j][k] = llr[i][j][copyIndex];
}
}
}
for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) {
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];
}
}
for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) {
copyIndex = listIndex[(2*listSize-1)-k];
} else { //Use the backup.
copyIndex = listIndex[k];
}
crcState[k]=crcState[copyIndex];
}
currentListSize = listSize;
}
}
for (int i=0; i<polarParams->crcParityBits; i++) {
if (last1ind[i]==nonFrozenBit) {
checkCrcBits=i;
break;
}
}
if ( checkCrcBits > (-1) ) {
for (uint8_t i = 0; i < currentListSize; i++) {
if (crcChecksum[checkCrcBits][i]==1) {
crcState[i]=0; //0=False, 1=True
}
}
}
for (uint8_t i = 0; i < currentListSize; i++) decoderIterationCheck+=crcState[i];
if (decoderIterationCheck==0) {
//perror("[SCL polar decoder] All list entries have failed the CRC checks.");
free(d_tilde);
free(pathMetric);
free(crcState);
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
return(-1);
}
nonFrozenBit++;
decoderIterationCheck=0;
checkCrcBits=-1;
}
}
for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i;
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) {
if ( crcState[listIndex[i]] == 1 ) {
for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_U[j]=bit[j][0][listIndex[i]];
//Extract the information bits (û to ĉ)
nr_polar_info_bit_extraction(polarParams->nr_polar_U, polarParams->nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N);
//Deinterleaving (ĉ to b)
nr_polar_deinterleaver(polarParams->nr_polar_CPrime, polarParams->nr_polar_B, polarParams->interleaving_pattern, polarParams->K);
//Remove the CRC (â)
for (int j = 0; j < polarParams->payloadBits; j++)
polarParams->nr_polar_A[j]=polarParams->nr_polar_B[j];
break;
}
}
free(d_tilde);
free(pathMetric);
free(crcState);
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
nr_free_uint8_2D_array(extended_crc_generator_matrix, polarParams->K);
nr_free_uint8_2D_array(tempECGM, polarParams->K);
/*
* Return bits.
*/
nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out);
return(0);
} }
int8_t polar_decoder_aPriori_timing(double *input, int8_t polar_decoder_aPriori_timing(double *input,
uint32_t *out, uint32_t *out,
t_nrPolar_paramsPtr polarParams, t_nrPolar_params *polarParams,
uint8_t listSize, uint8_t listSize,
uint8_t pathMetricAppr, uint8_t pathMetricAppr,
double *aPrioriPayload, double *aPrioriPayload,
double cpuFreqGHz, double cpuFreqGHz,
FILE* logFile) FILE *logFile) {
{ uint8_t ***bit = nr_alloc_uint8_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
uint8_t **bitUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
uint8_t ***bit = nr_alloc_uint8_3D_array(polarParams->N, (polarParams->n+1), 2*listSize); uint8_t **llrUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
uint8_t **bitUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True double ***llr = nr_alloc_double_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
uint8_t **llrUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True uint8_t **crcChecksum = nr_alloc_uint8_2D_array(polarParams->crcParityBits, 2*listSize);
double ***llr = nr_alloc_double_3D_array(polarParams->N, (polarParams->n+1), 2*listSize); double *pathMetric = malloc(sizeof(double)*(2*listSize));
uint8_t **crcChecksum = nr_alloc_uint8_2D_array(polarParams->crcParityBits, 2*listSize); uint8_t *crcState = malloc(sizeof(uint8_t)*(2*listSize)); //0=False, 1=True
double *pathMetric = malloc(sizeof(double)*(2*listSize));
uint8_t *crcState = malloc(sizeof(uint8_t)*(2*listSize)); //0=False, 1=True for (int i=0; i<(2*listSize); i++) {
pathMetric[i] = 0;
for (int i=0; i<(2*listSize); i++) { crcState[i]=1;
pathMetric[i] = 0; }
crcState[i]=1;
} for (int i=0; i<polarParams->N; i++) {
for (int i=0; i<polarParams->N; i++) { llrUpdated[i][polarParams->n]=1;
llrUpdated[i][polarParams->n]=1; bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2);
bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2); }
}
uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3
uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3 uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2
uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2
for (int i = 0; i < polarParams->K; i++){ for (int i = 0; i < polarParams->K; i++) {
extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t)); extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t)); tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
} }
for (int i=0; i<polarParams->payloadBits; i++) { for (int i=0; i<polarParams->payloadBits; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) { for (int j=0; j<polarParams->crcParityBits; j++) {
tempECGM[i][j]=polarParams->crc_generator_matrix[i][j]; tempECGM[i][j]=polarParams->crc_generator_matrix[i][j];
} }
} }
for (int i=polarParams->payloadBits; i<polarParams->K; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) { for (int i=polarParams->payloadBits; i<polarParams->K; i++) {
if( (i-polarParams->payloadBits) == j ){ for (int j=0; j<polarParams->crcParityBits; j++) {
tempECGM[i][j]=1; if( (i-polarParams->payloadBits) == j ) {
} else { tempECGM[i][j]=1;
tempECGM[i][j]=0; } else {
} tempECGM[i][j]=0;
} }
} }
}
for (int i=0; i<polarParams->K; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) { for (int i=0; i<polarParams->K; i++) {
extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j]; 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.
uint16_t last1ind[polarParams->crcParityBits]; //The index of the last 1-valued bit that appears in each column.
for (int j=0; j<polarParams->crcParityBits; j++) { uint16_t last1ind[polarParams->crcParityBits];
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;
}
double *d_tilde = malloc(sizeof(double) * polarParams->N); }
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]; double *d_tilde = malloc(sizeof(double) * polarParams->N);
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];
* SCL polar decoder.
*/ /*
* SCL polar decoder.
uint32_t nonFrozenBit=0; */
uint8_t currentListSize=1; uint32_t nonFrozenBit=0;
uint8_t decoderIterationCheck=0; uint8_t currentListSize=1;
int16_t checkCrcBits=-1; uint8_t decoderIterationCheck=0;
uint8_t listIndex[2*listSize], copyIndex; int16_t checkCrcBits=-1;
uint8_t listIndex[2*listSize], copyIndex;
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++){
updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr); for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++) {
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr);
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12
} else { //Information or CRC bit. if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) && updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12
(aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 0) ) { } else { //Information or CRC bit.
//Information bit with known value of "0". if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) &&
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 0) ) {
bitUpdated[currentBit][0]=1; //0=False, 1=True //Information bit with known value of "0".
} else if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) && updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr);
(aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) { bitUpdated[currentBit][0]=1; //0=False, 1=True
//Information bit with known value of "1". } else if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) &&
updatePathMetric(pathMetric, llr, currentListSize, 1, currentBit, pathMetricAppr); (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) {
for (uint8_t i=0; i<currentListSize; i++) bit[currentBit][0][i]=1; //Information bit with known value of "1".
bitUpdated[currentBit][0]=1; updatePathMetric(pathMetric, llr, currentListSize, 1, currentBit, pathMetricAppr);
updateCrcChecksum(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
} else { for (uint8_t i=0; i<currentListSize; i++) bit[currentBit][0][i]=1;
updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr);
bitUpdated[currentBit][0]=1;
for (int i = 0; i < currentListSize; i++) { updateCrcChecksum(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
for (int j = 0; j < polarParams->N; j++) { } else {
for (int k = 0; k < (polarParams->n+1); k++) { updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr);
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++) {
for (int i = 0; i < currentListSize; i++) { for (int j = 0; j < polarParams->N; j++) {
bit[currentBit][0][i]=0; for (int k = 0; k < (polarParams->n+1); k++) {
crcState[i+currentListSize]=crcState[i]; bit[j][k][i+currentListSize]=bit[j][k][i];
} llr[j][k][i+currentListSize]=llr[j][k][i];
for (int i = currentListSize; i < 2*currentListSize; i++) bit[currentBit][0][i]=1; }
bitUpdated[currentBit][0]=1; }
updateCrcChecksum2(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); }
currentListSize*=2;
for (int i = 0; i < currentListSize; i++) {
//Keep only the best "listSize" number of entries. bit[currentBit][0][i]=0;
if (currentListSize > listSize) { crcState[i+currentListSize]=crcState[i];
for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i; }
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
for (int i = currentListSize; i < 2*currentListSize; i++) bit[currentBit][0][i]=1;
//sort listIndex[listSize, ..., 2*listSize-1] in descending order.
uint8_t swaps, tempInd; bitUpdated[currentBit][0]=1;
for (uint8_t i = 0; i < listSize; i++) { updateCrcChecksum2(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
swaps = 0; currentListSize*=2;
for (uint8_t j = listSize; j < (2*listSize - i) - 1; j++) {
if (listIndex[j+1] > listIndex[j]) { //Keep only the best "listSize" number of entries.
tempInd = listIndex[j]; if (currentListSize > listSize) {
listIndex[j] = listIndex[j + 1]; for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i;
listIndex[j + 1] = tempInd;
swaps++; nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
} //sort listIndex[listSize, ..., 2*listSize-1] in descending order.
} uint8_t swaps, tempInd;
if (swaps == 0)
break; for (uint8_t i = 0; i < listSize; i++) {
} swaps = 0;
//First, backup the best "listSize" number of entries. for (uint8_t j = listSize; j < (2*listSize - i) - 1; j++) {
for (int k=(listSize-1); k>0; k--) { if (listIndex[j+1] > listIndex[j]) {
for (int i=0; i<polarParams->N; i++) { tempInd = listIndex[j];
for (int j=0; j<(polarParams->n+1); j++) { listIndex[j] = listIndex[j + 1];
bit[i][j][listIndex[(2*listSize-1)-k]]=bit[i][j][listIndex[k]]; listIndex[j + 1] = tempInd;
llr[i][j][listIndex[(2*listSize-1)-k]]=llr[i][j][listIndex[k]]; swaps++;
} }
} }
}
for (int k=(listSize-1); k>0; k--) { if (swaps == 0)
for (int i = 0; i < polarParams->crcParityBits; i++) { break;
crcChecksum[i][listIndex[(2*listSize-1)-k]] = crcChecksum[i][listIndex[k]]; }
}
} //First, backup the best "listSize" number of entries.
for (int k=(listSize-1); k>0; k--) crcState[listIndex[(2*listSize-1)-k]]=crcState[listIndex[k]]; for (int k=(listSize-1); k>0; k--) {
for (int i=0; i<polarParams->N; i++) {
//Copy the best "listSize" number of entries to the first indices. for (int j=0; j<(polarParams->n+1); j++) {
for (int k = 0; k < listSize; k++) { bit[i][j][listIndex[(2*listSize-1)-k]]=bit[i][j][listIndex[k]];
if (k > listIndex[k]) { llr[i][j][listIndex[(2*listSize-1)-k]]=llr[i][j][listIndex[k]];
copyIndex = listIndex[(2*listSize-1)-k]; }
} else { //Use the backup. }
copyIndex = listIndex[k]; }
}
for (int i = 0; i < polarParams->N; i++) { for (int k=(listSize-1); k>0; k--) {
for (int j = 0; j < (polarParams->n + 1); j++) { for (int i = 0; i < polarParams->crcParityBits; i++) {
bit[i][j][k] = bit[i][j][copyIndex]; crcChecksum[i][listIndex[(2*listSize-1)-k]] = crcChecksum[i][listIndex[k]];
llr[i][j][k] = llr[i][j][copyIndex]; }
} }
}
} for (int k=(listSize-1); k>0; k--) crcState[listIndex[(2*listSize-1)-k]]=crcState[listIndex[k]];
for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) { //Copy the best "listSize" number of entries to the first indices.
copyIndex = listIndex[(2*listSize-1)-k]; for (int k = 0; k < listSize; k++) {
} else { //Use the backup. if (k > listIndex[k]) {
copyIndex = listIndex[k]; copyIndex = listIndex[(2*listSize-1)-k];
} } else { //Use the backup.
for (int i = 0; i < polarParams->crcParityBits; i++) { copyIndex = listIndex[k];
crcChecksum[i][k]=crcChecksum[i][copyIndex]; }
}
} for (int i = 0; i < polarParams->N; i++) {
for (int k = 0; k < listSize; k++) { for (int j = 0; j < (polarParams->n + 1); j++) {
if (k > listIndex[k]) { bit[i][j][k] = bit[i][j][copyIndex];
copyIndex = listIndex[(2*listSize-1)-k]; llr[i][j][k] = llr[i][j][copyIndex];
} else { //Use the backup. }
copyIndex = listIndex[k]; }
} }
crcState[k]=crcState[copyIndex];
} for (int k = 0; k < listSize; k++) {
currentListSize = listSize; if (k > listIndex[k]) {
} copyIndex = listIndex[(2*listSize-1)-k];
} } else { //Use the backup.
copyIndex = listIndex[k];
for (int i=0; i<polarParams->crcParityBits; i++) { }
if (last1ind[i]==nonFrozenBit) {
checkCrcBits=i; for (int i = 0; i < polarParams->crcParityBits; i++) {
break; crcChecksum[i][k]=crcChecksum[i][copyIndex];
} }
} }
if ( checkCrcBits > (-1) ) { for (int k = 0; k < listSize; k++) {
for (uint8_t i = 0; i < currentListSize; i++) { if (k > listIndex[k]) {
if (crcChecksum[checkCrcBits][i]==1) { copyIndex = listIndex[(2*listSize-1)-k];
crcState[i]=0; //0=False, 1=True } else { //Use the backup.
} copyIndex = listIndex[k];
} }
}
crcState[k]=crcState[copyIndex];
for (uint8_t i = 0; i < currentListSize; i++) decoderIterationCheck+=crcState[i]; }
if (decoderIterationCheck==0) {
//perror("[SCL polar decoder] All list entries have failed the CRC checks."); currentListSize = listSize;
free(d_tilde); }
free(pathMetric); }
free(crcState);
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1)); for (int i=0; i<polarParams->crcParityBits; i++) {
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1)); if (last1ind[i]==nonFrozenBit) {
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits); checkCrcBits=i;
return(-1); break;
} }
}
nonFrozenBit++;
decoderIterationCheck=0; if ( checkCrcBits > (-1) ) {
checkCrcBits=-1; for (uint8_t i = 0; i < currentListSize; i++) {
} if (crcChecksum[checkCrcBits][i]==1) {
} crcState[i]=0; //0=False, 1=True
}
for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i; }
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize); }
for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) { for (uint8_t i = 0; i < currentListSize; i++) decoderIterationCheck+=crcState[i];
if ( crcState[listIndex[i]] == 1 ) {
for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_U[j]=bit[j][0][listIndex[i]]; if (decoderIterationCheck==0) {
//perror("[SCL polar decoder] All list entries have failed the CRC checks.");
//Extract the information bits (û to ĉ) free(d_tilde);
nr_polar_info_bit_extraction(polarParams->nr_polar_U, polarParams->nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N); free(pathMetric);
free(crcState);
//Deinterleaving (ĉ to b) nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
nr_polar_deinterleaver(polarParams->nr_polar_CPrime, polarParams->nr_polar_B, polarParams->interleaving_pattern, polarParams->K); nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
//Remove the CRC (â) return(-1);
for (int j = 0; j < polarParams->payloadBits; j++) polarParams->nr_polar_A[j]=polarParams->nr_polar_B[j]; }
break; nonFrozenBit++;
} decoderIterationCheck=0;
} checkCrcBits=-1;
}
free(d_tilde); }
free(pathMetric);
free(crcState); for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i;
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1)); nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
nr_free_uint8_2D_array(extended_crc_generator_matrix, polarParams->K); for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) {
nr_free_uint8_2D_array(tempECGM, polarParams->K); if ( crcState[listIndex[i]] == 1 ) {
for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_U[j]=bit[j][0][listIndex[i]];
/*
* Return bits. //Extract the information bits (û to ĉ)
*/ nr_polar_info_bit_extraction(polarParams->nr_polar_U, polarParams->nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N);
nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out); //Deinterleaving (ĉ to b)
return(0); nr_polar_deinterleaver(polarParams->nr_polar_CPrime, polarParams->nr_polar_B, polarParams->interleaving_pattern, polarParams->K);
//Remove the CRC (â)
for (int j = 0; j < polarParams->payloadBits; j++) polarParams->nr_polar_A[j]=polarParams->nr_polar_B[j];
break;
}
}
free(d_tilde);
free(pathMetric);
free(crcState);
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
nr_free_uint8_2D_array(extended_crc_generator_matrix, polarParams->K);
nr_free_uint8_2D_array(tempECGM, polarParams->K);
/*
* Return bits.
*/
nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out);
return(0);
} }
int8_t polar_decoder_dci(double *input, int8_t polar_decoder_dci(double *input,
uint32_t *out, uint32_t *out,
t_nrPolar_paramsPtr polarParams, t_nrPolar_params *polarParams,
uint8_t listSize, uint8_t listSize,
uint8_t pathMetricAppr, uint8_t pathMetricAppr,
uint16_t n_RNTI) uint16_t n_RNTI) {
{ uint8_t ***bit = nr_alloc_uint8_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
uint8_t **bitUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
uint8_t ***bit = nr_alloc_uint8_3D_array(polarParams->N, (polarParams->n+1), 2*listSize); uint8_t **llrUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
uint8_t **bitUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True double ***llr = nr_alloc_double_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
uint8_t **llrUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True uint8_t **crcChecksum = nr_alloc_uint8_2D_array(polarParams->crcParityBits, 2*listSize);
double ***llr = nr_alloc_double_3D_array(polarParams->N, (polarParams->n+1), 2*listSize); double *pathMetric = malloc(sizeof(double)*(2*listSize));
uint8_t **crcChecksum = nr_alloc_uint8_2D_array(polarParams->crcParityBits, 2*listSize); uint8_t *crcState = malloc(sizeof(uint8_t)*(2*listSize)); //0=False, 1=True
double *pathMetric = malloc(sizeof(double)*(2*listSize)); uint8_t extended_crc_scrambling_pattern[polarParams->crcParityBits];
uint8_t *crcState = malloc(sizeof(uint8_t)*(2*listSize)); //0=False, 1=True
uint8_t extended_crc_scrambling_pattern[polarParams->crcParityBits]; for (int i=0; i<(2*listSize); i++) {
pathMetric[i] = 0;
for (int i=0; i<(2*listSize); i++) { crcState[i]=1;
pathMetric[i] = 0; }
crcState[i]=1;
} for (int i=0; i<polarParams->N; i++) {
for (int i=0; i<polarParams->N; i++) { llrUpdated[i][polarParams->n]=1;
llrUpdated[i][polarParams->n]=1; bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2);
bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2); }
}
uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3: K-by-P
uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3: K-by-P uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2: K-by-P
uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2: K-by-P
for (int i = 0; i < polarParams->K; i++){ for (int i = 0; i < polarParams->K; i++) {
extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t)); extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t)); tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
} }
for (int i=0; i<polarParams->payloadBits; i++) { for (int i=0; i<polarParams->payloadBits; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) { for (int j=0; j<polarParams->crcParityBits; j++) {
tempECGM[i][j]=polarParams->crc_generator_matrix[i+polarParams->crcParityBits][j]; tempECGM[i][j]=polarParams->crc_generator_matrix[i+polarParams->crcParityBits][j];
} }
} }
for (int i=polarParams->payloadBits; i<polarParams->K; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) { for (int i=polarParams->payloadBits; i<polarParams->K; i++) {
if( (i-polarParams->payloadBits) == j ){ for (int j=0; j<polarParams->crcParityBits; j++) {
tempECGM[i][j]=1; if( (i-polarParams->payloadBits) == j ) {
} else { tempECGM[i][j]=1;
tempECGM[i][j]=0; } else {
} tempECGM[i][j]=0;
} }
} }
}
for (int i=0; i<polarParams->K; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) { for (int i=0; i<polarParams->K; i++) {
extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j]; 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.
uint16_t last1ind[polarParams->crcParityBits]; //The index of the last 1-valued bit that appears in each column.
for (int j=0; j<polarParams->crcParityBits; j++) { uint16_t last1ind[polarParams->crcParityBits];
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=0; i<8; i++) extended_crc_scrambling_pattern[i]=0;
}
for (int i=8; i<polarParams->crcParityBits; i++) {
double *d_tilde = malloc(sizeof(double) * polarParams->N); extended_crc_scrambling_pattern[i]=(n_RNTI>>(23-i))&1;
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];
double *d_tilde = malloc(sizeof(double) * polarParams->N);
/* nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength);
* SCL polar decoder.
*/ for (int j = 0; j < polarParams->N; j++) llr[j][polarParams->n][0]=d_tilde[j];
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]; * SCL polar decoder.
crcChecksum[i][0]=(crcChecksum[i][0]%2); */
}
for (int i=0; i<polarParams->crcParityBits; i++) {
uint32_t nonFrozenBit=0; for (int j=0; j<polarParams->crcParityBits; j++) crcChecksum[i][0]=crcChecksum[i][0]+polarParams->crc_generator_matrix[j][i];
uint8_t currentListSize=1;
uint8_t decoderIterationCheck=0; crcChecksum[i][0]=(crcChecksum[i][0]%2);
int16_t checkCrcBits=-1; }
uint8_t listIndex[2*listSize], copyIndex;
uint32_t nonFrozenBit=0;
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++){ uint8_t currentListSize=1;
updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr); uint8_t decoderIterationCheck=0;
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. int16_t checkCrcBits=-1;
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12 uint8_t listIndex[2*listSize], copyIndex;
} else { //Information or CRC bit.
updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr); for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++) {
updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr);
for (int i = 0; i < currentListSize; i++) {
for (int j = 0; j < polarParams->N; j++) { if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
for (int k = 0; k < (polarParams->n+1); k++) { updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12
bit[j][k][i+currentListSize]=bit[j][k][i]; } else { //Information or CRC bit.
llr[j][k][i+currentListSize]=llr[j][k][i];}}} updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr);
for (int i = 0; i < currentListSize; i++) {
bit[currentBit][0][i]=0; for (int i = 0; i < currentListSize; i++) {
crcState[i+currentListSize]=crcState[i]; for (int j = 0; j < polarParams->N; j++) {
} for (int k = 0; k < (polarParams->n+1); k++) {
for (int i = currentListSize; i < 2*currentListSize; i++) bit[currentBit][0][i]=1; bit[j][k][i+currentListSize]=bit[j][k][i];
bitUpdated[currentBit][0]=1; llr[j][k][i+currentListSize]=llr[j][k][i];
updateCrcChecksum2(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); }
currentListSize*=2; }
}
//Keep only the best "listSize" number of entries.
if (currentListSize > listSize) { for (int i = 0; i < currentListSize; i++) {
for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i; bit[currentBit][0][i]=0;
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize); crcState[i+currentListSize]=crcState[i];
}
//sort listIndex[listSize, ..., 2*listSize-1] in descending order.
uint8_t swaps, tempInd; for (int i = currentListSize; i < 2*currentListSize; i++) bit[currentBit][0][i]=1;
for (uint8_t i = 0; i < listSize; i++) {
swaps = 0; bitUpdated[currentBit][0]=1;
for (uint8_t j = listSize; j < (2*listSize - i) - 1; j++) { updateCrcChecksum2(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
if (listIndex[j+1] > listIndex[j]) { currentListSize*=2;
tempInd = listIndex[j];
listIndex[j] = listIndex[j + 1]; //Keep only the best "listSize" number of entries.
listIndex[j + 1] = tempInd; if (currentListSize > listSize) {
swaps++; for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i;
}
} nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
if (swaps == 0) //sort listIndex[listSize, ..., 2*listSize-1] in descending order.
break; uint8_t swaps, tempInd;
}
for (uint8_t i = 0; i < listSize; i++) {
//First, backup the best "listSize" number of entries. swaps = 0;
for (int k=(listSize-1); k>0; k--) {
for (int i=0; i<polarParams->N; i++) { for (uint8_t j = listSize; j < (2*listSize - i) - 1; j++) {
for (int j=0; j<(polarParams->n+1); j++) { if (listIndex[j+1] > listIndex[j]) {
bit[i][j][listIndex[(2*listSize-1)-k]]=bit[i][j][listIndex[k]]; tempInd = listIndex[j];
llr[i][j][listIndex[(2*listSize-1)-k]]=llr[i][j][listIndex[k]]; listIndex[j] = listIndex[j + 1];
} listIndex[j + 1] = tempInd;
} swaps++;
} }
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]]; if (swaps == 0)
} break;
} }
for (int k=(listSize-1); k>0; k--) crcState[listIndex[(2*listSize-1)-k]]=crcState[listIndex[k]];
//First, backup the best "listSize" number of entries.
//Copy the best "listSize" number of entries to the first indices. for (int k=(listSize-1); k>0; k--) {
for (int k = 0; k < listSize; k++) { for (int i=0; i<polarParams->N; i++) {
if (k > listIndex[k]) { for (int j=0; j<(polarParams->n+1); j++) {
copyIndex = listIndex[(2*listSize-1)-k]; bit[i][j][listIndex[(2*listSize-1)-k]]=bit[i][j][listIndex[k]];
} else { //Use the backup. llr[i][j][listIndex[(2*listSize-1)-k]]=llr[i][j][listIndex[k]];
copyIndex = listIndex[k]; }
} }
for (int i = 0; i < polarParams->N; i++) { }
for (int j = 0; j < (polarParams->n + 1); j++) {
bit[i][j][k] = bit[i][j][copyIndex]; for (int k=(listSize-1); k>0; k--) {
llr[i][j][k] = llr[i][j][copyIndex]; for (int i = 0; i < polarParams->crcParityBits; i++) {
} crcChecksum[i][listIndex[(2*listSize-1)-k]] = crcChecksum[i][listIndex[k]];
} }
} }
for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) { for (int k=(listSize-1); k>0; k--) crcState[listIndex[(2*listSize-1)-k]]=crcState[listIndex[k]];
copyIndex = listIndex[(2*listSize-1)-k];
} else { //Use the backup. //Copy the best "listSize" number of entries to the first indices.
copyIndex = listIndex[k]; for (int k = 0; k < listSize; k++) {
} if (k > listIndex[k]) {
for (int i = 0; i < polarParams->crcParityBits; i++) { copyIndex = listIndex[(2*listSize-1)-k];
crcChecksum[i][k]=crcChecksum[i][copyIndex]; } else { //Use the backup.
} copyIndex = listIndex[k];
} }
for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) { for (int i = 0; i < polarParams->N; i++) {
copyIndex = listIndex[(2*listSize-1)-k]; for (int j = 0; j < (polarParams->n + 1); j++) {
} else { //Use the backup. bit[i][j][k] = bit[i][j][copyIndex];
copyIndex = listIndex[k]; llr[i][j][k] = llr[i][j][copyIndex];
} }
crcState[k]=crcState[copyIndex]; }
} }
currentListSize = listSize;
} for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) {
for (int i=0; i<polarParams->crcParityBits; i++) { copyIndex = listIndex[(2*listSize-1)-k];
if (last1ind[i]==nonFrozenBit) { } else { //Use the backup.
checkCrcBits=i; copyIndex = listIndex[k];
break; }
}
} for (int i = 0; i < polarParams->crcParityBits; i++) {
crcChecksum[i][k]=crcChecksum[i][copyIndex];
if ( checkCrcBits > (-1) ) { }
for (uint8_t i = 0; i < currentListSize; i++) { }
if (crcChecksum[checkCrcBits][i]!=extended_crc_scrambling_pattern[checkCrcBits]) {
crcState[i]=0; //0=False, 1=True for (int k = 0; k < listSize; k++) {
} if (k > listIndex[k]) {
} copyIndex = listIndex[(2*listSize-1)-k];
} } else { //Use the backup.
copyIndex = listIndex[k];
for (uint8_t i = 0; i < currentListSize; i++) decoderIterationCheck+=crcState[i]; }
if (decoderIterationCheck==0) {
//perror("[SCL polar decoder] All list entries have failed the CRC checks."); crcState[k]=crcState[copyIndex];
free(d_tilde); }
free(pathMetric);
free(crcState); currentListSize = listSize;
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1)); }
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits); for (int i=0; i<polarParams->crcParityBits; i++) {
return(-1); if (last1ind[i]==nonFrozenBit) {
} checkCrcBits=i;
break;
nonFrozenBit++; }
decoderIterationCheck=0; }
checkCrcBits=-1;
} if ( checkCrcBits > (-1) ) {
} for (uint8_t i = 0; i < currentListSize; i++) {
if (crcChecksum[checkCrcBits][i]!=extended_crc_scrambling_pattern[checkCrcBits]) {
for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i; crcState[i]=0; //0=False, 1=True
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize); }
}
for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) { }
if ( crcState[listIndex[i]] == 1 ) {
for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_U[j]=bit[j][0][listIndex[i]]; for (uint8_t i = 0; i < currentListSize; i++) decoderIterationCheck+=crcState[i];
//Extract the information bits (û to ĉ) if (decoderIterationCheck==0) {
nr_polar_info_bit_extraction(polarParams->nr_polar_U, polarParams->nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N); //perror("[SCL polar decoder] All list entries have failed the CRC checks.");
free(d_tilde);
//Deinterleaving (ĉ to b) free(pathMetric);
nr_polar_deinterleaver(polarParams->nr_polar_CPrime, polarParams->nr_polar_B, polarParams->interleaving_pattern, polarParams->K); free(crcState);
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
//Remove the CRC (â) nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
for (int j = 0; j < polarParams->payloadBits; j++) polarParams->nr_polar_A[j]=polarParams->nr_polar_B[j]; nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
return(-1);
break; }
}
} nonFrozenBit++;
decoderIterationCheck=0;
free(d_tilde); checkCrcBits=-1;
free(pathMetric); }
free(crcState); }
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1)); for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i;
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
nr_free_uint8_2D_array(extended_crc_generator_matrix, polarParams->K); nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
nr_free_uint8_2D_array(tempECGM, polarParams->K);
for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) {
/* if ( crcState[listIndex[i]] == 1 ) {
* Return bits. for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_U[j]=bit[j][0][listIndex[i]];
*/
nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out); //Extract the information bits (û to ĉ)
return(0); nr_polar_info_bit_extraction(polarParams->nr_polar_U, polarParams->nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N);
//Deinterleaving (ĉ to b)
nr_polar_deinterleaver(polarParams->nr_polar_CPrime, polarParams->nr_polar_B, polarParams->interleaving_pattern, polarParams->K);
//Remove the CRC (â)
for (int j = 0; j < polarParams->payloadBits; j++) polarParams->nr_polar_A[j]=polarParams->nr_polar_B[j];
break;
}
}
free(d_tilde);
free(pathMetric);
free(crcState);
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
nr_free_uint8_2D_array(extended_crc_generator_matrix, polarParams->K);
nr_free_uint8_2D_array(tempECGM, polarParams->K);
/*
* Return bits.
*/
nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out);
return(0);
} }
void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) { void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) {
AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K); AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K); AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K);
int bit_i,ip,ipmod64; int bit_i,ip,ipmod64;
int numbytes = polarParams->K>>3; int numbytes = polarParams->K>>3;
int residue = polarParams->K&7; int residue = polarParams->K&7;
int numbits; int numbits;
if (residue>0) numbytes++; if (residue>0) numbytes++;
for (int byte=0;byte<numbytes;byte++) {
for (int byte=0; byte<numbytes; byte++) {
if (byte<(polarParams->K>>3)) numbits=8; if (byte<(polarParams->K>>3)) numbits=8;
else numbits=residue; else numbits=residue;
for (int i=0;i<numbits;i++) {
for (int i=0; i<numbits; i++) {
// flip bit endian for B // flip bit endian for B
ip=polarParams->K - 1 - polarParams->interleaving_pattern[(8*byte)+i]; ip=polarParams->K - 1 - polarParams->interleaving_pattern[(8*byte)+i];
#if 0 #if 0
...@@ -1061,107 +1142,97 @@ void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) { ...@@ -1061,107 +1142,97 @@ void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) {
#endif #endif
ipmod64 = ip&63; ipmod64 = ip&63;
AssertFatal(ip<128,"ip = %d\n",ip); AssertFatal(ip<128,"ip = %d\n",ip);
for (int val=0;val<256;val++) {
bit_i=(val>>i)&1; for (int val=0; val<256; val++) {
if (ip<64) polarParams->B_tab0[byte][val] |= (((uint64_t)bit_i)<<ipmod64); bit_i=(val>>i)&1;
else polarParams->B_tab1[byte][val] |= (((uint64_t)bit_i)<<ipmod64);
if (ip<64) polarParams->B_tab0[byte][val] |= (((uint64_t)bit_i)<<ipmod64);
else polarParams->B_tab1[byte][val] |= (((uint64_t)bit_i)<<ipmod64);
} }
} }
} }
} }
uint32_t polar_decoder_int16(int16_t *input, uint32_t polar_decoder_int16(int16_t *input,
uint64_t *out, uint64_t *out,
t_nrPolar_params *polarParams) const t_nrPolar_params *polarParams) {
{
int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N);
nr_polar_rate_matching_int16(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); nr_polar_rate_matching_int16(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength);
for (int i=0;i<polarParams->N;i++) {
for (int i=0; i<polarParams->N; i++) {
if (d_tilde[i]<-128) d_tilde[i]=-128; if (d_tilde[i]<-128) d_tilde[i]=-128;
else if (d_tilde[i]>127) d_tilde[i]=128; else if (d_tilde[i]>127) d_tilde[i]=128;
} }
memcpy((void*)&polarParams->tree.root->alpha[0],(void*)&d_tilde[0],sizeof(int16_t)*polarParams->N); memcpy((void *)&polarParams->tree.root->alpha[0],(void *)&d_tilde[0],sizeof(int16_t)*polarParams->N);
generic_polar_decoder(polarParams,polarParams->tree.root); generic_polar_decoder(polarParams,polarParams->tree.root);
//Extract the information bits (û to ĉ) //Extract the information bits (û to ĉ)
uint64_t Cprime[4]={0,0,0,0}; uint64_t Cprime[4]= {0,0,0,0};
uint64_t B[4]={0,0,0,0}; uint64_t B[4]= {0,0,0,0};
for (int i=0;i<polarParams->K;i++) Cprime[i>>6] = Cprime[i>>6] | ((uint64_t)polarParams->nr_polar_U[polarParams->Q_I_N[i]])<<(i&63);
for (int i=0; i<polarParams->K; i++) Cprime[i>>6] = Cprime[i>>6] | ((uint64_t)polarParams->nr_polar_U[polarParams->Q_I_N[i]])<<(i&63);
//Deinterleaving (ĉ to b) //Deinterleaving (ĉ to b)
uint8_t *Cprimebyte = (uint8_t*)Cprime; uint8_t *Cprimebyte = (uint8_t *)Cprime;
if (polarParams->K<65) { if (polarParams->K<65) {
B[0] = polarParams->B_tab0[0][Cprimebyte[0]] | B[0] = polarParams->B_tab0[0][Cprimebyte[0]] |
polarParams->B_tab0[1][Cprimebyte[1]] | polarParams->B_tab0[1][Cprimebyte[1]] |
polarParams->B_tab0[2][Cprimebyte[2]] | polarParams->B_tab0[2][Cprimebyte[2]] |
polarParams->B_tab0[3][Cprimebyte[3]] | polarParams->B_tab0[3][Cprimebyte[3]] |
polarParams->B_tab0[4][Cprimebyte[4]] | polarParams->B_tab0[4][Cprimebyte[4]] |
polarParams->B_tab0[5][Cprimebyte[5]] | polarParams->B_tab0[5][Cprimebyte[5]] |
polarParams->B_tab0[6][Cprimebyte[6]] | polarParams->B_tab0[6][Cprimebyte[6]] |
polarParams->B_tab0[7][Cprimebyte[7]]; polarParams->B_tab0[7][Cprimebyte[7]];
} } else if (polarParams->K<129) {
else if (polarParams->K<129) {
int len = polarParams->K/8; int len = polarParams->K/8;
if ((polarParams->K&7) > 0) len++; if ((polarParams->K&7) > 0) len++;
for (int k=0;k<len;k++) {
for (int k=0; k<len; k++) {
B[0] |= polarParams->B_tab0[k][Cprimebyte[k]]; B[0] |= polarParams->B_tab0[k][Cprimebyte[k]];
B[1] |= polarParams->B_tab1[k][Cprimebyte[k]]; B[1] |= polarParams->B_tab1[k][Cprimebyte[k]];
} }
} }
int len=polarParams->payloadBits; int len=polarParams->payloadBits;
//int len_mod64=len&63; //int len_mod64=len&63;
int crclen = polarParams->crcParityBits; int crclen = polarParams->crcParityBits;
uint64_t rxcrc=B[0]&((1<<crclen)-1); uint64_t rxcrc=B[0]&((1<<crclen)-1);
uint32_t crc; uint32_t crc;
uint64_t Ar; uint64_t Ar;
AssertFatal(len<65,"A must be less than 65 bits\n"); AssertFatal(len<65,"A must be less than 65 bits\n");
if (len<=32) { if (len<=32) {
Ar = (uint32_t)(B[0]>>crclen); Ar = (uint32_t)(B[0]>>crclen);
uint8_t A32_flip[4]; uint8_t A32_flip[4];
uint32_t Aprime= (uint32_t)(Ar<<(32-len)); uint32_t Aprime= (uint32_t)(Ar<<(32-len));
A32_flip[0]=((uint8_t*)&Aprime)[3]; A32_flip[0]=((uint8_t *)&Aprime)[3];
A32_flip[1]=((uint8_t*)&Aprime)[2]; A32_flip[1]=((uint8_t *)&Aprime)[2];
A32_flip[2]=((uint8_t*)&Aprime)[1]; A32_flip[2]=((uint8_t *)&Aprime)[1];
A32_flip[3]=((uint8_t*)&Aprime)[0]; A32_flip[3]=((uint8_t *)&Aprime)[0];
crc = (uint64_t)(crc24c(A32_flip,len)>>8); crc = (uint64_t)(crc24c(A32_flip,len)>>8);
} } else if (len<=64) {
else if (len<=64) {
Ar = (B[0]>>crclen) | (B[1]<<(64-crclen));; Ar = (B[0]>>crclen) | (B[1]<<(64-crclen));;
uint8_t A64_flip[8]; uint8_t A64_flip[8];
uint64_t Aprime= (uint32_t)(Ar<<(64-len)); uint64_t Aprime= (uint32_t)(Ar<<(64-len));
A64_flip[0]=((uint8_t*)&Aprime)[7]; A64_flip[0]=((uint8_t *)&Aprime)[7];
A64_flip[1]=((uint8_t*)&Aprime)[6]; A64_flip[1]=((uint8_t *)&Aprime)[6];
A64_flip[2]=((uint8_t*)&Aprime)[5]; A64_flip[2]=((uint8_t *)&Aprime)[5];
A64_flip[3]=((uint8_t*)&Aprime)[4]; A64_flip[3]=((uint8_t *)&Aprime)[4];
A64_flip[4]=((uint8_t*)&Aprime)[3]; A64_flip[4]=((uint8_t *)&Aprime)[3];
A64_flip[5]=((uint8_t*)&Aprime)[2]; A64_flip[5]=((uint8_t *)&Aprime)[2];
A64_flip[6]=((uint8_t*)&Aprime)[1]; A64_flip[6]=((uint8_t *)&Aprime)[1];
A64_flip[7]=((uint8_t*)&Aprime)[0]; A64_flip[7]=((uint8_t *)&Aprime)[0];
crc = (uint64_t)(crc24c(A64_flip,len)>>8); crc = (uint64_t)(crc24c(A64_flip,len)>>8);
} }
#if 0 #if 0
printf("A %llx B %llx|%llx Cprime %llx|%llx (crc %x,rxcrc %llx %d)\n", printf("A %llx B %llx|%llx Cprime %llx|%llx (crc %x,rxcrc %llx %d)\n",
Ar, Ar,
B[1],B[0],Cprime[1],Cprime[0],crc, B[1],B[0],Cprime[1],Cprime[0],crc,
rxcrc,polarParams->payloadBits); rxcrc,polarParams->payloadBits);
#endif #endif
out[0]=Ar; out[0]=Ar;
return(crc^rxcrc); return(crc^rxcrc);
} }
...@@ -81,7 +81,7 @@ struct nrPolar_params { ...@@ -81,7 +81,7 @@ struct nrPolar_params {
//messageType: 0=PBCH, 1=DCI, -1=UCI //messageType: 0=PBCH, 1=DCI, -1=UCI
int idx; //idx = (messageType * messageLength * aggregation_prime); int idx; //idx = (messageType * messageLength * aggregation_prime);
struct nrPolar_params *nextPtr; struct nrPolar_params *nextPtr;
uint8_t n_max; uint8_t n_max;
uint8_t i_il; uint8_t i_il;
uint8_t i_seg; uint8_t i_seg;
...@@ -96,7 +96,7 @@ struct nrPolar_params { ...@@ -96,7 +96,7 @@ struct nrPolar_params {
uint16_t N; uint16_t N;
uint8_t n; uint8_t n;
uint32_t crcBit; uint32_t crcBit;
uint16_t *interleaving_pattern; uint16_t *interleaving_pattern;
uint16_t *deinterleaving_pattern; uint16_t *deinterleaving_pattern;
uint16_t *rate_matching_pattern; uint16_t *rate_matching_pattern;
...@@ -107,7 +107,7 @@ struct nrPolar_params { ...@@ -107,7 +107,7 @@ struct nrPolar_params {
uint8_t *information_bit_pattern; uint8_t *information_bit_pattern;
uint16_t *channel_interleaver_pattern; uint16_t *channel_interleaver_pattern;
uint32_t crc_polynomial; uint32_t crc_polynomial;
uint8_t **crc_generator_matrix; //G_P uint8_t **crc_generator_matrix; //G_P
uint8_t **G_N; uint8_t **G_N;
uint64_t **G_N_tab; uint64_t **G_N_tab;
...@@ -117,7 +117,7 @@ struct nrPolar_params { ...@@ -117,7 +117,7 @@ struct nrPolar_params {
uint64_t cprime_tab1[32][256]; uint64_t cprime_tab1[32][256];
uint64_t B_tab0[32][256]; uint64_t B_tab0[32][256];
uint64_t B_tab1[32][256]; uint64_t B_tab1[32][256];
uint32_t* crc256Table; uint32_t *crc256Table;
uint8_t **extended_crc_generator_matrix; uint8_t **extended_crc_generator_matrix;
//lowercase: bits, Uppercase: Bits stored in bytes //lowercase: bits, Uppercase: Bits stored in bytes
//polar_encoder vectors //polar_encoder vectors
...@@ -126,89 +126,82 @@ struct nrPolar_params { ...@@ -126,89 +126,82 @@ struct nrPolar_params {
uint8_t *nr_polar_APrime; uint8_t *nr_polar_APrime;
uint8_t *nr_polar_D; uint8_t *nr_polar_D;
uint8_t *nr_polar_E; uint8_t *nr_polar_E;
//Polar Coding vectors //Polar Coding vectors
uint8_t *nr_polar_A; uint8_t *nr_polar_A;
uint8_t *nr_polar_CPrime; uint8_t *nr_polar_CPrime;
uint8_t *nr_polar_B; uint8_t *nr_polar_B;
uint8_t *nr_polar_U; uint8_t *nr_polar_U;
decoder_tree_t tree; decoder_tree_t tree;
} __attribute__ ((__packed__)); } __attribute__ ((__packed__));
typedef struct nrPolar_params t_nrPolar_params; typedef struct nrPolar_params t_nrPolar_params;
typedef t_nrPolar_params *t_nrPolar_paramsPtr;
void polar_encoder(uint32_t *input, void polar_encoder(uint32_t *input,
uint32_t *output, uint32_t *output,
t_nrPolar_paramsPtr polarParams); t_nrPolar_params *polarParams);
void polar_encoder_dci(uint32_t *in, void polar_encoder_dci(uint32_t *in,
uint32_t *out, uint32_t *out,
t_nrPolar_paramsPtr polarParams, t_nrPolar_params *polarParams,
uint16_t n_RNTI); uint16_t n_RNTI);
void polar_encoder_fast(uint64_t *A, void polar_encoder_fast(uint64_t *A,
uint32_t *out, uint32_t *out,
int32_t crcmask, int32_t crcmask,
t_nrPolar_paramsPtr polarParams); t_nrPolar_params *polarParams);
int8_t polar_decoder(double *input, int8_t polar_decoder(double *input,
uint8_t *output, uint8_t *output,
t_nrPolar_paramsPtr polarParams, t_nrPolar_params *polarParams,
uint8_t listSize, uint8_t listSize,
uint8_t pathMetricAppr); uint8_t pathMetricAppr);
uint32_t polar_decoder_int16(int16_t *input, uint32_t polar_decoder_int16(int16_t *input,
uint64_t *out, uint64_t *out,
t_nrPolar_params *polarParams); const t_nrPolar_params *polarParams);
int8_t polar_decoder_aPriori(double *input, int8_t polar_decoder_aPriori(double *input,
uint32_t *output, uint32_t *output,
t_nrPolar_paramsPtr polarParams, t_nrPolar_params *polarParams,
uint8_t listSize, uint8_t listSize,
uint8_t pathMetricAppr, uint8_t pathMetricAppr,
double *aPrioriPayload); double *aPrioriPayload);
int8_t polar_decoder_aPriori_timing(double *input, int8_t polar_decoder_aPriori_timing(double *input,
uint32_t *output, uint32_t *output,
t_nrPolar_paramsPtr polarParams, t_nrPolar_params *polarParams,
uint8_t listSize, uint8_t listSize,
uint8_t pathMetricAppr, uint8_t pathMetricAppr,
double *aPrioriPayload, double *aPrioriPayload,
double cpuFreqGHz, double cpuFreqGHz,
FILE* logFile); FILE *logFile);
int8_t polar_decoder_dci(double *input, int8_t polar_decoder_dci(double *input,
uint32_t *out, uint32_t *out,
t_nrPolar_paramsPtr polarParams, t_nrPolar_params *polarParams,
uint8_t listSize, uint8_t listSize,
uint8_t pathMetricAppr, uint8_t pathMetricAppr,
uint16_t n_RNTI); uint16_t n_RNTI);
void generic_polar_decoder(t_nrPolar_params *, void generic_polar_decoder(t_nrPolar_params *,
decoder_node_t *); decoder_node_t *);
void build_decoder_tree(t_nrPolar_params *pp); void build_decoder_tree(t_nrPolar_params *pp);
void build_polar_tables(t_nrPolar_paramsPtr polarParams); void build_polar_tables(t_nrPolar_params *polarParams);
void init_polar_deinterleaver_table(t_nrPolar_params *polarParams); void init_polar_deinterleaver_table(t_nrPolar_params *polarParams);
void nr_polar_init(t_nrPolar_paramsPtr *polarParams, void nr_polar_print_polarParams(t_nrPolar_params *polarParams);
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level);
void nr_polar_print_polarParams(t_nrPolar_paramsPtr polarParams);
t_nrPolar_paramsPtr nr_polar_params (t_nrPolar_paramsPtr polarParams, t_nrPolar_params *nr_polar_params ( int8_t messageType,
int8_t messageType, uint16_t messageLength,
uint16_t messageLength, uint8_t aggregation_level);
uint8_t aggregation_level);
uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level); uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level);
uint8_t** nr_polar_kronecker_power_matrices(uint8_t n); uint8_t **nr_polar_kronecker_power_matrices(uint8_t n);
const uint16_t* nr_polar_sequence_pattern(uint8_t n); const uint16_t *nr_polar_sequence_pattern(uint8_t n);
/*!@fn uint32_t nr_polar_output_length(uint16_t K, uint16_t E, uint8_t n_max) /*!@fn uint32_t nr_polar_output_length(uint16_t K, uint16_t E, uint8_t n_max)
* @brief Computes... * @brief Computes...
...@@ -216,168 +209,168 @@ const uint16_t* nr_polar_sequence_pattern(uint8_t n); ...@@ -216,168 +209,168 @@ const uint16_t* nr_polar_sequence_pattern(uint8_t n);
* @param E * @param E
* @param n_max */ * @param n_max */
uint32_t nr_polar_output_length(uint16_t K, uint32_t nr_polar_output_length(uint16_t K,
uint16_t E, uint16_t E,
uint8_t n_max); uint8_t n_max);
void nr_polar_channel_interleaver_pattern(uint16_t *cip, void nr_polar_channel_interleaver_pattern(uint16_t *cip,
uint8_t I_BIL, uint8_t I_BIL,
uint16_t E); uint16_t E);
void nr_polar_rate_matching_pattern(uint16_t *rmp, void nr_polar_rate_matching_pattern(uint16_t *rmp,
uint16_t *J, uint16_t *J,
const uint8_t *P_i_, const uint8_t *P_i_,
uint16_t K, uint16_t K,
uint16_t N, uint16_t N,
uint16_t E); uint16_t E);
void nr_polar_rate_matching(double *input, void nr_polar_rate_matching(double *input,
double *output, double *output,
uint16_t *rmp, uint16_t *rmp,
uint16_t K, uint16_t K,
uint16_t N, uint16_t N,
uint16_t E); uint16_t E);
void nr_polar_rate_matching_int16(int16_t *input, void nr_polar_rate_matching_int16(int16_t *input,
int16_t *output, int16_t *output,
uint16_t *rmp, uint16_t *rmp,
uint16_t K, uint16_t K,
uint16_t N, uint16_t N,
uint16_t E); uint16_t E);
void nr_polar_interleaving_pattern(uint16_t K, void nr_polar_interleaving_pattern(uint16_t K,
uint8_t I_IL, uint8_t I_IL,
uint16_t *PI_k_); uint16_t *PI_k_);
void nr_polar_info_bit_pattern(uint8_t *ibp, void nr_polar_info_bit_pattern(uint8_t *ibp,
int16_t *Q_I_N, int16_t *Q_I_N,
int16_t *Q_F_N, int16_t *Q_F_N,
uint16_t *J, uint16_t *J,
const uint16_t *Q_0_Nminus1, const uint16_t *Q_0_Nminus1,
uint16_t K, uint16_t K,
uint16_t N, uint16_t N,
uint16_t E, uint16_t E,
uint8_t n_PC); uint8_t n_PC);
void nr_polar_info_bit_extraction(uint8_t *input, void nr_polar_info_bit_extraction(uint8_t *input,
uint8_t *output, uint8_t *output,
uint8_t *pattern, uint8_t *pattern,
uint16_t size); uint16_t size);
void nr_bit2byte_uint32_8_t(uint32_t *in, void nr_bit2byte_uint32_8_t(uint32_t *in,
uint16_t arraySize, uint16_t arraySize,
uint8_t *out); uint8_t *out);
void nr_byte2bit_uint8_32_t(uint8_t *in, void nr_byte2bit_uint8_32_t(uint8_t *in,
uint16_t arraySize, uint16_t arraySize,
uint32_t *out); uint32_t *out);
void nr_crc_bit2bit_uint32_8_t(uint32_t *in, void nr_crc_bit2bit_uint32_8_t(uint32_t *in,
uint16_t arraySize, uint16_t arraySize,
uint8_t *out); uint8_t *out);
void nr_polar_bit_insertion(uint8_t *input, void nr_polar_bit_insertion(uint8_t *input,
uint8_t *output, uint8_t *output,
uint16_t N, uint16_t N,
uint16_t K, uint16_t K,
int16_t *Q_I_N, int16_t *Q_I_N,
int16_t *Q_PC_N, int16_t *Q_PC_N,
uint8_t n_PC); uint8_t n_PC);
void nr_matrix_multiplication_uint8_1D_uint8_2D(uint8_t *matrix1, void nr_matrix_multiplication_uint8_1D_uint8_2D(uint8_t *matrix1,
uint8_t **matrix2, uint8_t **matrix2,
uint8_t *output, uint8_t *output,
uint16_t row, uint16_t row,
uint16_t col); uint16_t col);
uint8_t ***nr_alloc_uint8_3D_array(uint16_t xlen, uint8_t ***nr_alloc_uint8_3D_array(uint16_t xlen,
uint16_t ylen, uint16_t ylen,
uint16_t zlen); uint16_t zlen);
uint8_t **nr_alloc_uint8_2D_array(uint16_t xlen, uint8_t **nr_alloc_uint8_2D_array(uint16_t xlen,
uint16_t ylen); uint16_t ylen);
double ***nr_alloc_double_3D_array(uint16_t xlen, double ***nr_alloc_double_3D_array(uint16_t xlen,
uint16_t ylen, uint16_t ylen,
uint16_t zlen); uint16_t zlen);
double **nr_alloc_double_2D_array(uint16_t xlen, double **nr_alloc_double_2D_array(uint16_t xlen,
uint16_t ylen); uint16_t ylen);
void nr_free_double_3D_array(double ***input, void nr_free_double_3D_array(double ***input,
uint16_t xlen, uint16_t xlen,
uint16_t ylen); uint16_t ylen);
void nr_free_double_2D_array(double **input, void nr_free_double_2D_array(double **input,
uint16_t xlen); uint16_t xlen);
void nr_free_uint8_3D_array(uint8_t ***input, void nr_free_uint8_3D_array(uint8_t ***input,
uint16_t xlen, uint16_t xlen,
uint16_t ylen); uint16_t ylen);
void nr_free_uint8_2D_array(uint8_t **input, void nr_free_uint8_2D_array(uint8_t **input,
uint16_t xlen); uint16_t xlen);
void nr_sort_asc_double_1D_array_ind(double *matrix, void nr_sort_asc_double_1D_array_ind(double *matrix,
uint8_t *ind, uint8_t *ind,
uint8_t len); uint8_t len);
void nr_sort_asc_int16_1D_array_ind(int32_t *matrix, void nr_sort_asc_int16_1D_array_ind(int32_t *matrix,
int *ind, int *ind,
int len); int len);
void nr_free_double_2D_array(double **input, uint16_t xlen); void nr_free_double_2D_array(double **input, uint16_t xlen);
void updateLLR(double ***llr, void updateLLR(double ***llr,
uint8_t **llrU, uint8_t **llrU,
uint8_t ***bit, uint8_t ***bit,
uint8_t **bitU, uint8_t **bitU,
uint8_t listSize, uint8_t listSize,
uint16_t row, uint16_t row,
uint16_t col, uint16_t col,
uint16_t xlen, uint16_t xlen,
uint8_t ylen, uint8_t ylen,
uint8_t approximation); uint8_t approximation);
void updateBit(uint8_t ***bit, void updateBit(uint8_t ***bit,
uint8_t **bitU, uint8_t **bitU,
uint8_t listSize, uint8_t listSize,
uint16_t row, uint16_t row,
uint16_t col, uint16_t col,
uint16_t xlen, uint16_t xlen,
uint8_t ylen); uint8_t ylen);
void updatePathMetric(double *pathMetric, void updatePathMetric(double *pathMetric,
double ***llr, double ***llr,
uint8_t listSize, uint8_t listSize,
uint8_t bitValue, uint8_t bitValue,
uint16_t row, uint16_t row,
uint8_t approximation); uint8_t approximation);
void updatePathMetric2(double *pathMetric, void updatePathMetric2(double *pathMetric,
double ***llr, double ***llr,
uint8_t listSize, uint8_t listSize,
uint16_t row, uint16_t row,
uint8_t approximation); uint8_t approximation);
void computeLLR(double ***llr, void computeLLR(double ***llr,
uint16_t row, uint16_t row,
uint16_t col, uint16_t col,
uint8_t i, uint8_t i,
uint16_t offset, uint16_t offset,
uint8_t approximation); uint8_t approximation);
void updateCrcChecksum(uint8_t **crcChecksum, void updateCrcChecksum(uint8_t **crcChecksum,
uint8_t **crcGen, uint8_t **crcGen,
uint8_t listSize, uint8_t listSize,
uint32_t i2, uint32_t i2,
uint8_t len); uint8_t len);
void updateCrcChecksum2(uint8_t **crcChecksum, void updateCrcChecksum2(uint8_t **crcChecksum,
uint8_t **crcGen, uint8_t **crcGen,
uint8_t listSize, uint8_t listSize,
uint32_t i2, uint32_t i2,
uint8_t len); uint8_t len);
uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits); uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits);
...@@ -387,18 +380,16 @@ uint8_t **crc6_generator_matrix(uint16_t payloadSizeBits); ...@@ -387,18 +380,16 @@ uint8_t **crc6_generator_matrix(uint16_t payloadSizeBits);
//Also nr_polar_rate_matcher //Also nr_polar_rate_matcher
static inline void nr_polar_interleaver(uint8_t *input, static inline void nr_polar_interleaver(uint8_t *input,
uint8_t *output, uint8_t *output,
uint16_t *pattern, uint16_t *pattern,
uint16_t size) uint16_t size) {
{
for (int i=0; i<size; i++) output[i]=input[pattern[i]]; for (int i=0; i<size; i++) output[i]=input[pattern[i]];
} }
static inline void nr_polar_deinterleaver(uint8_t *input, static inline void nr_polar_deinterleaver(uint8_t *input,
uint8_t *output, uint8_t *output,
uint16_t *pattern, uint16_t *pattern,
uint16_t size) uint16_t size) {
{
for (int i=0; i<size; i++) { for (int i=0; i<size; i++) {
output[pattern[i]]=input[i]; output[pattern[i]]=input[i];
} }
......
...@@ -41,306 +41,326 @@ ...@@ -41,306 +41,326 @@
//output [f_31 f_30 ... f_0] [f_63 f_62 ... f_32] ... //output [f_31 f_30 ... f_0] [f_63 f_62 ... f_32] ...
void polar_encoder(uint32_t *in, void polar_encoder(uint32_t *in,
uint32_t *out, uint32_t *out,
t_nrPolar_paramsPtr polarParams) t_nrPolar_params *polarParams) {
{ if (polarParams->idx == 0) { //PBCH
if (polarParams->idx == 0){//PBCH
/* /*
uint64_t B = (((uint64_t)*in)&((((uint64_t)1)<<32)-1)) | (((uint64_t)crc24c((uint8_t*)in,polarParams->payloadBits)>>8)<<polarParams->payloadBits); uint64_t B = (((uint64_t)*in)&((((uint64_t)1)<<32)-1)) | (((uint64_t)crc24c((uint8_t*)in,polarParams->payloadBits)>>8)<<polarParams->payloadBits);
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
printf("polar_B %llx (crc %x)\n",B,crc24c((uint8_t*)in,polarParams->payloadBits)>>8); printf("polar_B %llx (crc %x)\n",B,crc24c((uint8_t*)in,polarParams->payloadBits)>>8);
#endif #endif
nr_bit2byte_uint32_8_t((uint32_t*)&B, polarParams->K, polarParams->nr_polar_B);*/ nr_bit2byte_uint32_8_t((uint32_t*)&B, polarParams->K, polarParams->nr_polar_B);*/
nr_bit2byte_uint32_8_t((uint32_t *)in, polarParams->payloadBits, polarParams->nr_polar_A);
nr_bit2byte_uint32_8_t((uint32_t*)in, polarParams->payloadBits, polarParams->nr_polar_A);
/* /*
* Bytewise operations * Bytewise operations
*/ */
//Calculate CRC. //Calculate CRC.
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_A,
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_A, polarParams->crc_generator_matrix,
polarParams->crc_generator_matrix, polarParams->nr_polar_crc,
polarParams->nr_polar_crc, polarParams->payloadBits,
polarParams->payloadBits, polarParams->crcParityBits);
polarParams->crcParityBits);
for (uint8_t i = 0; i < polarParams->crcParityBits; i++) for (uint8_t i = 0; i < polarParams->crcParityBits; i++)
polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2); polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
//Attach CRC to the Transport Block. (a to b)
//Attach CRC to the Transport Block. (a to b) for (uint16_t i = 0; i < polarParams->payloadBits; i++)
for (uint16_t i = 0; i < polarParams->payloadBits; i++) polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i];
polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i];
for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++) for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++)
polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)]; polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
uint64_t B2=0; uint64_t B2=0;
for (int i = 0;i<polarParams->K;i++) B2 = B2 | ((uint64_t)polarParams->nr_polar_B[i] << i);
for (int i = 0; i<polarParams->K; i++) B2 = B2 | ((uint64_t)polarParams->nr_polar_B[i] << i);
printf("polar_B %llx\n",B2); printf("polar_B %llx\n",B2);
#endif #endif
/* for (int j=0;j<polarParams->crcParityBits;j++) { /* for (int j=0;j<polarParams->crcParityBits;j++) {
for (int i=0;i<polarParams->payloadBits;i++) for (int i=0;i<polarParams->payloadBits;i++)
printf("%1d.%1d+",polarParams->crc_generator_matrix[i][j],polarParams->nr_polar_A[i]); printf("%1d.%1d+",polarParams->crc_generator_matrix[i][j],polarParams->nr_polar_A[i]);
printf(" => %d\n",polarParams->nr_polar_crc[j]); printf(" => %d\n",polarParams->nr_polar_crc[j]);
}*/ }*/
} else { //UCI } else { //UCI
} }
//Interleaving (c to c') //Interleaving (c to c')
nr_polar_interleaver(polarParams->nr_polar_B, nr_polar_interleaver(polarParams->nr_polar_B,
polarParams->nr_polar_CPrime, polarParams->nr_polar_CPrime,
polarParams->interleaving_pattern, polarParams->interleaving_pattern,
polarParams->K); polarParams->K);
#ifdef DEBUG_POLAR_ENCODER
#ifdef DEBUG_POLAR_ENCODER
uint64_t Cprime=0; uint64_t Cprime=0;
for (int i = 0;i<polarParams->K;i++) {
for (int i = 0; i<polarParams->K; i++) {
Cprime = Cprime | ((uint64_t)polarParams->nr_polar_CPrime[i] << i); Cprime = Cprime | ((uint64_t)polarParams->nr_polar_CPrime[i] << i);
if (polarParams->nr_polar_CPrime[i] == 1) printf("pos %d : %llx\n",i,Cprime); if (polarParams->nr_polar_CPrime[i] == 1) printf("pos %d : %llx\n",i,Cprime);
} }
printf("polar_Cprime %llx\n",Cprime); printf("polar_Cprime %llx\n",Cprime);
#endif #endif
//Bit insertion (c' to u) //Bit insertion (c' to u)
nr_polar_bit_insertion(polarParams->nr_polar_CPrime, nr_polar_bit_insertion(polarParams->nr_polar_CPrime,
polarParams->nr_polar_U, polarParams->nr_polar_U,
polarParams->N, polarParams->N,
polarParams->K, polarParams->K,
polarParams->Q_I_N, polarParams->Q_I_N,
polarParams->Q_PC_N, polarParams->Q_PC_N,
polarParams->n_pc); polarParams->n_pc);
//Encoding (u to d) //Encoding (u to d)
/* memset(polarParams->nr_polar_U,0,polarParams->N); /* memset(polarParams->nr_polar_U,0,polarParams->N);
polarParams->nr_polar_U[247]=1; polarParams->nr_polar_U[247]=1;
polarParams->nr_polar_U[253]=1;*/ polarParams->nr_polar_U[253]=1;*/
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_U, nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_U,
polarParams->G_N, polarParams->G_N,
polarParams->nr_polar_D, polarParams->nr_polar_D,
polarParams->N, polarParams->N,
polarParams->N); polarParams->N);
for (uint16_t i = 0; i < polarParams->N; i++) for (uint16_t i = 0; i < polarParams->N; i++)
polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2); polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
uint64_t D[8]; uint64_t D[8];
memset((void*)D,0,8*sizeof(int64_t)); memset((void *)D,0,8*sizeof(int64_t));
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
for (int i=0;i<polarParams->N;i++) D[i/64] |= ((uint64_t)polarParams->nr_polar_D[i])<<(i&63);
for (int i=0; i<polarParams->N; i++) D[i/64] |= ((uint64_t)polarParams->nr_polar_D[i])<<(i&63);
printf("D %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n", printf("D %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
D[0],D[1],D[2],D[3],D[4],D[5],D[6],D[7]); D[0],D[1],D[2],D[3],D[4],D[5],D[6],D[7]);
#endif #endif
//Rate matching //Rate matching
//Sub-block interleaving (d to y) and Bit selection (y to e) //Sub-block interleaving (d to y) and Bit selection (y to e)
nr_polar_interleaver(polarParams->nr_polar_D, nr_polar_interleaver(polarParams->nr_polar_D,
polarParams->nr_polar_E, polarParams->nr_polar_E,
polarParams->rate_matching_pattern, polarParams->rate_matching_pattern,
polarParams->encoderLength); polarParams->encoderLength);
/* /*
* Return bits. * Return bits.
*/ */
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
for (int i=0; i< polarParams->encoderLength;i++) printf("f[%d]=%d\n", i, polarParams->nr_polar_E[i]);
#endif
for (int i=0; i< polarParams->encoderLength; i++) printf("f[%d]=%d\n", i, polarParams->nr_polar_E[i]);
#endif
nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out); nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
} }
void polar_encoder_dci(uint32_t *in, void polar_encoder_dci(uint32_t *in,
uint32_t *out, uint32_t *out,
t_nrPolar_paramsPtr polarParams, t_nrPolar_params *polarParams,
uint16_t n_RNTI) uint16_t n_RNTI) {
{
#ifdef DEBUG_POLAR_ENCODER_DCI #ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] in: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", in[0], in[1], in[2], in[3]); printf("[polar_encoder_dci] in: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", in[0], in[1], in[2], in[3]);
#endif #endif
/* /*
* Bytewise operations * Bytewise operations
*/ */
//(a to a') //(a to a')
nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_A); nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_A);
for (int i=0; i<polarParams->crcParityBits; i++) polarParams->nr_polar_APrime[i]=1; for (int i=0; i<polarParams->crcParityBits; i++) polarParams->nr_polar_APrime[i]=1;
for (int i=0; i<polarParams->payloadBits; i++) polarParams->nr_polar_APrime[i+(polarParams->crcParityBits)]=polarParams->nr_polar_A[i]; for (int i=0; i<polarParams->payloadBits; i++) polarParams->nr_polar_APrime[i+(polarParams->crcParityBits)]=polarParams->nr_polar_A[i];
#ifdef DEBUG_POLAR_ENCODER_DCI #ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] A: "); printf("[polar_encoder_dci] A: ");
for (int i=0; i<polarParams->payloadBits; i++) printf("%d-", polarParams->nr_polar_A[i]); for (int i=0; i<polarParams->payloadBits; i++) printf("%d-", polarParams->nr_polar_A[i]);
printf("\n"); printf("\n");
printf("[polar_encoder_dci] APrime: "); printf("[polar_encoder_dci] APrime: ");
for (int i=0; i<polarParams->K; i++) printf("%d-", polarParams->nr_polar_APrime[i]); for (int i=0; i<polarParams->K; i++) printf("%d-", polarParams->nr_polar_APrime[i]);
printf("\n"); printf("\n");
printf("[polar_encoder_dci] GP: "); printf("[polar_encoder_dci] GP: ");
for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->crc_generator_matrix[0][i]); for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->crc_generator_matrix[0][i]);
printf("\n"); printf("\n");
#endif #endif
//Calculate CRC. //Calculate CRC.
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_APrime, nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_APrime,
polarParams->crc_generator_matrix, polarParams->crc_generator_matrix,
polarParams->nr_polar_crc, polarParams->nr_polar_crc,
polarParams->K, polarParams->K,
polarParams->crcParityBits); polarParams->crcParityBits);
for (uint8_t i = 0; i < polarParams->crcParityBits; i++) polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2); for (uint8_t i = 0; i < polarParams->crcParityBits; i++) polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
#ifdef DEBUG_POLAR_ENCODER_DCI #ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] CRC: "); printf("[polar_encoder_dci] CRC: ");
for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->nr_polar_crc[i]); for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->nr_polar_crc[i]);
printf("\n"); printf("\n");
#endif #endif
//Attach CRC to the Transport Block. (a to b) //Attach CRC to the Transport Block. (a to b)
for (uint16_t i = 0; i < polarParams->payloadBits; i++) for (uint16_t i = 0; i < polarParams->payloadBits; i++)
polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i]; polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i];
for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++) for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++)
polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)]; polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
//Scrambling (b to c) //Scrambling (b to c)
for (int i=0; i<16; i++) { for (int i=0; i<16; i++) {
polarParams->nr_polar_B[polarParams->payloadBits+8+i] = polarParams->nr_polar_B[polarParams->payloadBits+8+i] =
( polarParams->nr_polar_B[polarParams->payloadBits+8+i] + ((n_RNTI>>(15-i))&1) ) % 2; ( polarParams->nr_polar_B[polarParams->payloadBits+8+i] + ((n_RNTI>>(15-i))&1) ) % 2;
} }
/* //(a to a') /* //(a to a')
nr_crc_bit2bit_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_aPrime); nr_crc_bit2bit_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_aPrime);
//Parity bits computation (p) //Parity bits computation (p)
polarParams->crcBit = crc24c(polarParams->nr_polar_aPrime, (polarParams->payloadBits+polarParams->crcParityBits)); polarParams->crcBit = crc24c(polarParams->nr_polar_aPrime, (polarParams->payloadBits+polarParams->crcParityBits));
#ifdef DEBUG_POLAR_ENCODER_DCI #ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] crc: 0x%08x\n", polarParams->crcBit); printf("[polar_encoder_dci] crc: 0x%08x\n", polarParams->crcBit);
for (int i=0; i<32; i++) for (int i=0; i<32; i++)
{ {
printf("%d\n",((polarParams->crcBit)>>i)&1); printf("%d\n",((polarParams->crcBit)>>i)&1);
} }
#endif #endif
//(a to b) //(a to b)
// //
// Bytewise operations // Bytewise operations
// //
uint8_t arrayInd = ceil(polarParams->payloadBits / 8.0); uint8_t arrayInd = ceil(polarParams->payloadBits / 8.0);
for (int i=0; i<arrayInd-1; i++){ for (int i=0; i<arrayInd-1; i++){
for (int j=0; j<8; j++) { for (int j=0; j<8; j++) {
polarParams->nr_polar_B[j+(i*8)] = ((polarParams->nr_polar_aPrime[3+i]>>(7-j)) & 1); polarParams->nr_polar_B[j+(i*8)] = ((polarParams->nr_polar_aPrime[3+i]>>(7-j)) & 1);
} }
} }
for (int i=0; i<((polarParams->payloadBits)%8); i++) { for (int i=0; i<((polarParams->payloadBits)%8); i++) {
polarParams->nr_polar_B[i+(arrayInd-1)*8] = ((polarParams->nr_polar_aPrime[3+(arrayInd-1)]>>(7-i)) & 1); polarParams->nr_polar_B[i+(arrayInd-1)*8] = ((polarParams->nr_polar_aPrime[3+(arrayInd-1)]>>(7-i)) & 1);
} }
for (int i=0; i<8; i++) { for (int i=0; i<8; i++) {
polarParams->nr_polar_B[polarParams->payloadBits+i] = ((polarParams->crcBit)>>(31-i))&1; polarParams->nr_polar_B[polarParams->payloadBits+i] = ((polarParams->crcBit)>>(31-i))&1;
} }
//Scrambling (b to c) //Scrambling (b to c)
for (int i=0; i<16; i++) { for (int i=0; i<16; i++) {
polarParams->nr_polar_B[polarParams->payloadBits+8+i] = polarParams->nr_polar_B[polarParams->payloadBits+8+i] =
( (((polarParams->crcBit)>>(23-i))&1) + ((n_RNTI>>(15-i))&1) ) % 2; ( (((polarParams->crcBit)>>(23-i))&1) + ((n_RNTI>>(15-i))&1) ) % 2;
}*/ }*/
#ifdef DEBUG_POLAR_ENCODER_DCI #ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] B: "); printf("[polar_encoder_dci] B: ");
for (int i = 0; i < polarParams->K; i++) printf("%d-", polarParams->nr_polar_B[i]); for (int i = 0; i < polarParams->K; i++) printf("%d-", polarParams->nr_polar_B[i]);
printf("\n"); printf("\n");
#endif #endif
//Interleaving (c to c') //Interleaving (c to c')
nr_polar_interleaver(polarParams->nr_polar_B, nr_polar_interleaver(polarParams->nr_polar_B,
polarParams->nr_polar_CPrime, polarParams->nr_polar_CPrime,
polarParams->interleaving_pattern, polarParams->interleaving_pattern,
polarParams->K); polarParams->K);
//Bit insertion (c' to u) //Bit insertion (c' to u)
nr_polar_bit_insertion(polarParams->nr_polar_CPrime, nr_polar_bit_insertion(polarParams->nr_polar_CPrime,
polarParams->nr_polar_U, polarParams->nr_polar_U,
polarParams->N, polarParams->N,
polarParams->K, polarParams->K,
polarParams->Q_I_N, polarParams->Q_I_N,
polarParams->Q_PC_N, polarParams->Q_PC_N,
polarParams->n_pc); polarParams->n_pc);
//Encoding (u to d) //Encoding (u to d)
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_U, nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_U,
polarParams->G_N, polarParams->G_N,
polarParams->nr_polar_D, polarParams->nr_polar_D,
polarParams->N, polarParams->N,
polarParams->N); polarParams->N);
for (uint16_t i = 0; i < polarParams->N; i++) for (uint16_t i = 0; i < polarParams->N; i++)
polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2); polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
//Rate matching //Rate matching
//Sub-block interleaving (d to y) and Bit selection (y to e) //Sub-block interleaving (d to y) and Bit selection (y to e)
nr_polar_interleaver(polarParams->nr_polar_D, nr_polar_interleaver(polarParams->nr_polar_D,
polarParams->nr_polar_E, polarParams->nr_polar_E,
polarParams->rate_matching_pattern, polarParams->rate_matching_pattern,
polarParams->encoderLength); polarParams->encoderLength);
/* /*
* Return bits. * Return bits.
*/ */
nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out); nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
#ifdef DEBUG_POLAR_ENCODER_DCI #ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] E: "); printf("[polar_encoder_dci] E: ");
for (int i = 0; i < polarParams->encoderLength; i++) printf("%d-", polarParams->nr_polar_E[i]); for (int i = 0; i < polarParams->encoderLength; i++) printf("%d-", polarParams->nr_polar_E[i]);
uint8_t outputInd = ceil(polarParams->encoderLength / 32.0); uint8_t outputInd = ceil(polarParams->encoderLength / 32.0);
printf("\n[polar_encoder_dci] out: "); printf("\n[polar_encoder_dci] out: ");
for (int i = 0; i < outputInd; i++) { for (int i = 0; i < outputInd; i++) {
printf("[%d]->0x%08x\t", i, out[i]); printf("[%d]->0x%08x\t", i, out[i]);
} }
#endif #endif
} }
static inline void polar_rate_matching(t_nrPolar_paramsPtr polarParams,void *in,void *out) __attribute__((always_inline)); static inline void polar_rate_matching(t_nrPolar_params *polarParams,void *in,void *out) __attribute__((always_inline));
static inline void polar_rate_matching(t_nrPolar_paramsPtr polarParams,void *in,void *out) { static inline void polar_rate_matching(t_nrPolar_params *polarParams,void *in,void *out) {
if (polarParams->groupsize == 8)
if (polarParams->groupsize == 8) for (int i=0; i<polarParams->encoderLength>>3; i++) ((uint8_t *)out)[i] = ((uint8_t *)in)[polarParams->rm_tab[i]];
for (int i=0;i<polarParams->encoderLength>>3;i++) ((uint8_t*)out)[i] = ((uint8_t *)in)[polarParams->rm_tab[i]];
else else
for (int i=0;i<polarParams->encoderLength>>4;i++) { for (int i=0; i<polarParams->encoderLength>>4; i++) {
((uint16_t*)out)[i] = ((uint16_t *)in)[polarParams->rm_tab[i]]; ((uint16_t *)out)[i] = ((uint16_t *)in)[polarParams->rm_tab[i]];
} }
} }
void build_polar_tables(t_nrPolar_paramsPtr polarParams) { void build_polar_tables(t_nrPolar_params *polarParams) {
// build table b -> c' // build table b -> c'
AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K); AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
AssertFatal(polarParams->K < 129, "K = %d > 64, is not supported yet\n",polarParams->K); AssertFatal(polarParams->K < 129, "K = %d > 64, is not supported yet\n",polarParams->K);
int bit_i,ip; int bit_i,ip;
int numbytes = polarParams->K>>3; int numbytes = polarParams->K>>3;
int residue = polarParams->K&7; int residue = polarParams->K&7;
int numbits; int numbits;
if (residue>0) numbytes++; if (residue>0) numbytes++;
for (int byte=0;byte<numbytes;byte++) {
for (int byte=0; byte<numbytes; byte++) {
if (byte<(polarParams->K>>3)) numbits=8; if (byte<(polarParams->K>>3)) numbits=8;
else numbits=residue; else numbits=residue;
for (int val=0;val<256;val++) {
for (int val=0; val<256; val++) {
polarParams->cprime_tab0[byte][val] = 0; polarParams->cprime_tab0[byte][val] = 0;
polarParams->cprime_tab1[byte][val] = 0; polarParams->cprime_tab1[byte][val] = 0;
for (int i=0;i<numbits;i++) {
// flip bit endian of B bitstring for (int i=0; i<numbits; i++) {
ip=polarParams->deinterleaving_pattern[polarParams->K-1-((8*byte)+i)]; // flip bit endian of B bitstring
AssertFatal(ip<128,"ip = %d\n",ip); ip=polarParams->deinterleaving_pattern[polarParams->K-1-((8*byte)+i)];
bit_i=(val>>i)&1; AssertFatal(ip<128,"ip = %d\n",ip);
if (ip<64) polarParams->cprime_tab0[byte][val] |= (((uint64_t)bit_i)<<ip); bit_i=(val>>i)&1;
else polarParams->cprime_tab1[byte][val] |= (((uint64_t)bit_i)<<(ip&63));
if (ip<64) polarParams->cprime_tab0[byte][val] |= (((uint64_t)bit_i)<<ip);
else polarParams->cprime_tab1[byte][val] |= (((uint64_t)bit_i)<<(ip&63));
} }
} }
} }
AssertFatal(polarParams->N==512,"N = %d, not done yet\n",polarParams->N); AssertFatal(polarParams->N==512,"N = %d, not done yet\n",polarParams->N);
// build G bit vectors for information bit positions and convert the bit as bytes tables in nr_polar_kronecker_power_matrices.c to 64 bit packed vectors. // build G bit vectors for information bit positions and convert the bit as bytes tables in nr_polar_kronecker_power_matrices.c to 64 bit packed vectors.
// keep only rows of G which correspond to information/crc bits // keep only rows of G which correspond to information/crc bits
polarParams->G_N_tab = (uint64_t**)malloc(polarParams->K * sizeof(int64_t*)); polarParams->G_N_tab = (uint64_t **)malloc(polarParams->K * sizeof(int64_t *));
int k=0; int k=0;
for (int i=0;i<polarParams->N;i++) {
for (int i=0; i<polarParams->N; i++) {
if (polarParams->information_bit_pattern[i] > 0) { if (polarParams->information_bit_pattern[i] > 0) {
polarParams->G_N_tab[k] = (uint64_t*)memalign(32,(polarParams->N/64)*sizeof(uint64_t)); polarParams->G_N_tab[k] = (uint64_t *)memalign(32,(polarParams->N/64)*sizeof(uint64_t));
memset((void*)polarParams->G_N_tab[k],0,(polarParams->N/64)*sizeof(uint64_t)); memset((void *)polarParams->G_N_tab[k],0,(polarParams->N/64)*sizeof(uint64_t));
for (int j=0;j<polarParams->N;j++)
polarParams->G_N_tab[k][j/64] |= ((uint64_t)polarParams->G_N[i][j])<<(j&63); for (int j=0; j<polarParams->N; j++)
polarParams->G_N_tab[k][j/64] |= ((uint64_t)polarParams->G_N[i][j])<<(j&63);
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
printf("Bit %d Selecting row %d of G : ",k,i); printf("Bit %d Selecting row %d of G : ",k,i);
for (int j=0;j<polarParams->N;j+=4) printf("%1x",polarParams->G_N[i][j]+(polarParams->G_N[i][j+1]*2)+(polarParams->G_N[i][j+2]*4)+(polarParams->G_N[i][j+3]*8));
for (int j=0; j<polarParams->N; j+=4) printf("%1x",polarParams->G_N[i][j]+(polarParams->G_N[i][j+1]*2)+(polarParams->G_N[i][j+2]*4)+(polarParams->G_N[i][j+3]*8));
printf("\n"); printf("\n");
#endif #endif
k++; k++;
...@@ -354,56 +374,57 @@ void build_polar_tables(t_nrPolar_paramsPtr polarParams) { ...@@ -354,56 +374,57 @@ void build_polar_tables(t_nrPolar_paramsPtr polarParams) {
int firstingroup_out=0; int firstingroup_out=0;
int firstingroup_in=iplast; int firstingroup_in=iplast;
int mingroupsize = 1024; int mingroupsize = 1024;
// compute minimum group size of rate-matching pattern // compute minimum group size of rate-matching pattern
for (int outpos=1; outpos<polarParams->encoderLength; outpos++) { for (int outpos=1; outpos<polarParams->encoderLength; outpos++) {
ip=polarParams->rate_matching_pattern[outpos]; ip=polarParams->rate_matching_pattern[outpos];
if ((ip - iplast) == 1) ccnt++; if ((ip - iplast) == 1) ccnt++;
else { else {
groupcnt++; groupcnt++;
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
printf("group %d (size %d): (%d:%d) => (%d:%d)\n",groupcnt,ccnt+1, printf("group %d (size %d): (%d:%d) => (%d:%d)\n",groupcnt,ccnt+1,
firstingroup_in,firstingroup_in+ccnt, firstingroup_in,firstingroup_in+ccnt,
firstingroup_out,firstingroup_out+ccnt); firstingroup_out,firstingroup_out+ccnt);
#endif #endif
if ((ccnt+1)<mingroupsize) mingroupsize=ccnt+1; if ((ccnt+1)<mingroupsize) mingroupsize=ccnt+1;
ccnt=0; ccnt=0;
firstingroup_out=outpos; firstingroup_out=outpos;
firstingroup_in=ip; firstingroup_in=ip;
} }
iplast=ip; iplast=ip;
} }
AssertFatal(mingroupsize==8 || mingroupsize==16,"mingroupsize %d, needs to be handled\n",mingroupsize); AssertFatal(mingroupsize==8 || mingroupsize==16,"mingroupsize %d, needs to be handled\n",mingroupsize);
polarParams->groupsize=mingroupsize; polarParams->groupsize=mingroupsize;
int shift=3; int shift=3;
if (mingroupsize == 16) shift=4; if (mingroupsize == 16) shift=4;
polarParams->rm_tab=(int*)malloc(sizeof(int)*polarParams->encoderLength/mingroupsize);
polarParams->rm_tab=(int *)malloc(sizeof(int)*polarParams->encoderLength/mingroupsize);
// rerun again to create groups // rerun again to create groups
int tcnt=0; int tcnt=0;
for (int outpos=0;outpos<polarParams->encoderLength; outpos+=mingroupsize,tcnt++)
for (int outpos=0; outpos<polarParams->encoderLength; outpos+=mingroupsize,tcnt++)
polarParams->rm_tab[tcnt] = polarParams->rate_matching_pattern[outpos]>>shift; polarParams->rm_tab[tcnt] = polarParams->rate_matching_pattern[outpos]>>shift;
} }
void polar_encoder_fast(uint64_t *A, void polar_encoder_fast(uint64_t *A,
uint32_t *out, uint32_t *out,
int32_t crcmask, int32_t crcmask,
t_nrPolar_paramsPtr polarParams) { t_nrPolar_params *polarParams) {
AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K); AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K); AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K);
AssertFatal(polarParams->payloadBits < 65, "payload bits = %d > 64, is not supported yet\n",polarParams->payloadBits); AssertFatal(polarParams->payloadBits < 65, "payload bits = %d > 64, is not supported yet\n",polarParams->payloadBits);
uint64_t B[4]= {0,0,0,0},Cprime[4]= {0,0,0,0};
uint64_t B[4]={0,0,0,0},Cprime[4]={0,0,0,0};
int bitlen = polarParams->payloadBits; int bitlen = polarParams->payloadBits;
// append crc // append crc
AssertFatal(bitlen<129,"support for payloads <= 128 bits\n"); AssertFatal(bitlen<129,"support for payloads <= 128 bits\n");
AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n"); AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n");
//int bitlen0=bitlen; //int bitlen0=bitlen;
uint64_t tcrc=0; uint64_t tcrc=0;
// A bitstring should be stored as a_{N-1} a_{N-2} ... a_{N-A} 0 .... 0, where N=64,128,192,..., N is smallest multiple of 64 greater than or equal to A // A bitstring should be stored as 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
...@@ -413,41 +434,41 @@ void polar_encoder_fast(uint64_t *A, ...@@ -413,41 +434,41 @@ void polar_encoder_fast(uint64_t *A,
if (bitlen<=32) { if (bitlen<=32) {
uint8_t A32_flip[4]; uint8_t A32_flip[4];
uint32_t Aprime= (uint32_t)(((uint32_t)*A)<<(32-bitlen)); uint32_t Aprime= (uint32_t)(((uint32_t)*A)<<(32-bitlen));
A32_flip[0]=((uint8_t*)&Aprime)[3]; A32_flip[0]=((uint8_t *)&Aprime)[3];
A32_flip[1]=((uint8_t*)&Aprime)[2]; A32_flip[1]=((uint8_t *)&Aprime)[2];
A32_flip[2]=((uint8_t*)&Aprime)[1]; A32_flip[2]=((uint8_t *)&Aprime)[1];
A32_flip[3]=((uint8_t*)&Aprime)[0]; A32_flip[3]=((uint8_t *)&Aprime)[0];
tcrc = (uint64_t)((crcmask^(crc24c(A32_flip,bitlen)>>8))); tcrc = (uint64_t)((crcmask^(crc24c(A32_flip,bitlen)>>8)));
} } else if (bitlen<=64) {
else if (bitlen<=64) {
uint8_t A64_flip[8]; uint8_t A64_flip[8];
uint64_t Aprime= (uint32_t)(((uint64_t)*A)<<(64-bitlen)); uint64_t Aprime= (uint32_t)(((uint64_t)*A)<<(64-bitlen));
A64_flip[0]=((uint8_t*)&Aprime)[7]; A64_flip[0]=((uint8_t *)&Aprime)[7];
A64_flip[1]=((uint8_t*)&Aprime)[6]; A64_flip[1]=((uint8_t *)&Aprime)[6];
A64_flip[2]=((uint8_t*)&Aprime)[5]; A64_flip[2]=((uint8_t *)&Aprime)[5];
A64_flip[3]=((uint8_t*)&Aprime)[4]; A64_flip[3]=((uint8_t *)&Aprime)[4];
A64_flip[4]=((uint8_t*)&Aprime)[3]; A64_flip[4]=((uint8_t *)&Aprime)[3];
A64_flip[5]=((uint8_t*)&Aprime)[2]; A64_flip[5]=((uint8_t *)&Aprime)[2];
A64_flip[6]=((uint8_t*)&Aprime)[1]; A64_flip[6]=((uint8_t *)&Aprime)[1];
A64_flip[7]=((uint8_t*)&Aprime)[0]; A64_flip[7]=((uint8_t *)&Aprime)[0];
tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,bitlen)>>8))); tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,bitlen)>>8)));
} }
int n; int n;
// this is number of quadwords in the bit string // this is number of quadwords in the bit string
int quadwlen = (polarParams->K>>6); int quadwlen = (polarParams->K>>6);
if ((polarParams->K&63) > 0) quadwlen++; if ((polarParams->K&63) > 0) quadwlen++;
// Create the B bitstring as // Create the B bitstring as
// b_{N'-1} b_{N'-2} ... b_{N'-A} b_{N'-A-1} ... b_{N'-A-Nparity} = a_{N-1} a_{N-2} ... a_{N-A} p_{N_parity-1} ... p_0 // b_{N'-1} b_{N'-2} ... b_{N'-A} b_{N'-A-1} ... b_{N'-A-Nparity} = a_{N-1} a_{N-2} ... a_{N-A} p_{N_parity-1} ... p_0
for (n=0;n<quadwlen;n++) if (n==0) B[n] = (A[n] << polarParams->crcParityBits) | tcrc; for (n=0; n<quadwlen; n++) if (n==0) B[n] = (A[n] << polarParams->crcParityBits) | tcrc;
else B[n] = (A[n] << polarParams->crcParityBits) | (A[n-1]>>(64-polarParams->crcParityBits)); else B[n] = (A[n] << polarParams->crcParityBits) | (A[n-1]>>(64-polarParams->crcParityBits));
uint8_t *Bbyte = (uint8_t *)B;
uint8_t *Bbyte = (uint8_t*)B;
// for each byte of B, lookup in corresponding table for 64-bit word corresponding to that byte and its position // for each byte of B, lookup in corresponding table for 64-bit word corresponding to that byte and its position
if (polarParams->K<65) if (polarParams->K<65)
Cprime[0] = polarParams->cprime_tab0[0][Bbyte[0]] | Cprime[0] = polarParams->cprime_tab0[0][Bbyte[0]] |
polarParams->cprime_tab0[1][Bbyte[1]] | polarParams->cprime_tab0[1][Bbyte[1]] |
polarParams->cprime_tab0[2][Bbyte[2]] | polarParams->cprime_tab0[2][Bbyte[2]] |
...@@ -456,82 +477,81 @@ void polar_encoder_fast(uint64_t *A, ...@@ -456,82 +477,81 @@ void polar_encoder_fast(uint64_t *A,
polarParams->cprime_tab0[5][Bbyte[5]] | polarParams->cprime_tab0[5][Bbyte[5]] |
polarParams->cprime_tab0[6][Bbyte[6]] | polarParams->cprime_tab0[6][Bbyte[6]] |
polarParams->cprime_tab0[7][Bbyte[7]]; polarParams->cprime_tab0[7][Bbyte[7]];
else if (polarParams->K < 129) { else if (polarParams->K < 129) {
for (int i=0;i<1+(polarParams->K/8);i++) { for (int i=0; i<1+(polarParams->K/8); i++) {
Cprime[0] |= polarParams->cprime_tab0[i][Bbyte[i]]; Cprime[0] |= polarParams->cprime_tab0[i][Bbyte[i]];
Cprime[1] |= polarParams->cprime_tab1[i][Bbyte[i]]; Cprime[1] |= polarParams->cprime_tab1[i][Bbyte[i]];
} }
} }
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
if (polarParams->K<65)
if (polarParams->K<65)
printf("A %llx B %llx Cprime %llx (payload bits %d,crc %x)\n", printf("A %llx B %llx Cprime %llx (payload bits %d,crc %x)\n",
(unsigned long long)(A[0]&(((uint64_t)1<<bitlen)-1)), (unsigned long long)(A[0]&(((uint64_t)1<<bitlen)-1)),
(unsigned long long)(B[0]), (unsigned long long)(B[0]),
(unsigned long long)(Cprime[0]), (unsigned long long)(Cprime[0]),
polarParams->payloadBits, polarParams->payloadBits,
tcrc); tcrc);
else if (polarParams->K<129) { else if (polarParams->K<129) {
if (bitlen<64) if (bitlen<64)
printf("A %llx B %llx|%llx Cprime %llx|%llx (payload bits %d,crc %x)\n", printf("A %llx B %llx|%llx Cprime %llx|%llx (payload bits %d,crc %x)\n",
(unsigned long long)(A[0]&(((uint64_t)1<<bitlen)-1)), (unsigned long long)(A[0]&(((uint64_t)1<<bitlen)-1)),
(unsigned long long)(B[1]),(unsigned long long)(B[0]), (unsigned long long)(B[1]),(unsigned long long)(B[0]),
(unsigned long long)(Cprime[1]),(unsigned long long)(Cprime[0]), (unsigned long long)(Cprime[1]),(unsigned long long)(Cprime[0]),
polarParams->payloadBits, polarParams->payloadBits,
tcrc); tcrc);
else else
printf("A %llx|%llx B %llx|%llx Cprime %llx|%llx (payload bits %d,crc %x)\n", printf("A %llx|%llx B %llx|%llx Cprime %llx|%llx (payload bits %d,crc %x)\n",
(unsigned long long)(A[1]&(((uint64_t)1<<(bitlen-64))-1)),(unsigned long long)(A[0]), (unsigned long long)(A[1]&(((uint64_t)1<<(bitlen-64))-1)),(unsigned long long)(A[0]),
(unsigned long long)(B[1]),(unsigned long long)(B[0]), (unsigned long long)(B[1]),(unsigned long long)(B[0]),
(unsigned long long)(Cprime[1]),(unsigned long long)(Cprime[0]), (unsigned long long)(Cprime[1]),(unsigned long long)(Cprime[0]),
polarParams->payloadBits, polarParams->payloadBits,
crc24c((uint8_t*)A,bitlen)>>8); crc24c((uint8_t *)A,bitlen)>>8);
} }
#endif #endif
/* printf("Bbytes : %x.%x.%x.%x.%x.%x.%x.%x\n",Bbyte[0],Bbyte[1],Bbyte[2],Bbyte[3],Bbyte[4],Bbyte[5],Bbyte[6],Bbyte[7]); /* printf("Bbytes : %x.%x.%x.%x.%x.%x.%x.%x\n",Bbyte[0],Bbyte[1],Bbyte[2],Bbyte[3],Bbyte[4],Bbyte[5],Bbyte[6],Bbyte[7]);
printf("%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",polarParams->cprime_tab[0][Bbyte[0]] , printf("%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",polarParams->cprime_tab[0][Bbyte[0]] ,
polarParams->cprime_tab[1][Bbyte[1]] , polarParams->cprime_tab[1][Bbyte[1]] ,
polarParams->cprime_tab[2][Bbyte[2]] , polarParams->cprime_tab[2][Bbyte[2]] ,
polarParams->cprime_tab[3][Bbyte[3]] , polarParams->cprime_tab[3][Bbyte[3]] ,
polarParams->cprime_tab[4][Bbyte[4]] , polarParams->cprime_tab[4][Bbyte[4]] ,
polarParams->cprime_tab[5][Bbyte[5]] , polarParams->cprime_tab[5][Bbyte[5]] ,
polarParams->cprime_tab[6][Bbyte[6]] , polarParams->cprime_tab[6][Bbyte[6]] ,
polarParams->cprime_tab[7][Bbyte[7]]);*/ polarParams->cprime_tab[7][Bbyte[7]]);*/
// now do Gu product (here using 64-bit XORs, we can also do with SIMD after) // now do Gu product (here using 64-bit XORs, we can also do with SIMD after)
// here we're reading out the bits LSB -> MSB, is this correct w.r.t. 3GPP ? // here we're reading out the bits LSB -> MSB, is this correct w.r.t. 3GPP ?
uint64_t Cprime_i; uint64_t Cprime_i;
/* printf("%llx Cprime_0 (%llx) G %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",Cprime_i,Cprime &1, /* printf("%llx Cprime_0 (%llx) G %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",Cprime_i,Cprime &1,
polarParams->G_N_tab[0][0], polarParams->G_N_tab[0][0],
polarParams->G_N_tab[0][1], polarParams->G_N_tab[0][1],
polarParams->G_N_tab[0][2], polarParams->G_N_tab[0][2],
polarParams->G_N_tab[0][3], polarParams->G_N_tab[0][3],
polarParams->G_N_tab[0][4], polarParams->G_N_tab[0][4],
polarParams->G_N_tab[0][5], polarParams->G_N_tab[0][5],
polarParams->G_N_tab[0][6], polarParams->G_N_tab[0][6],
polarParams->G_N_tab[0][7]);*/ polarParams->G_N_tab[0][7]);*/
uint64_t D[8]={0,0,0,0,0,0,0,0}; uint64_t D[8]= {0,0,0,0,0,0,0,0};
int off=0; int off=0;
int len=polarParams->K; int len=polarParams->K;
for (int j=0;j<(1+(polarParams->K>>6));j++,off+=64,len-=64) {
for (int i=0;i<((len>63) ? 64 : len);i++) {
for (int j=0; j<(1+(polarParams->K>>6)); j++,off+=64,len-=64) {
for (int i=0; i<((len>63) ? 64 : len); i++) {
Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11 Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11
/* /*
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
printf("%llx Cprime_%d (%llx) G %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n", printf("%llx Cprime_%d (%llx) G %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
Cprime_i,off+i,(Cprime[j]>>i) &1, Cprime_i,off+i,(Cprime[j]>>i) &1,
polarParams->G_N_tab[off+i][0], polarParams->G_N_tab[off+i][0],
polarParams->G_N_tab[off+i][1], polarParams->G_N_tab[off+i][1],
polarParams->G_N_tab[off+i][2], polarParams->G_N_tab[off+i][2],
polarParams->G_N_tab[off+i][3], polarParams->G_N_tab[off+i][3],
polarParams->G_N_tab[off+i][4], polarParams->G_N_tab[off+i][4],
polarParams->G_N_tab[off+i][5], polarParams->G_N_tab[off+i][5],
polarParams->G_N_tab[off+i][6], polarParams->G_N_tab[off+i][6],
polarParams->G_N_tab[off+i][7]); polarParams->G_N_tab[off+i][7]);
#endif #endif
*/ */
uint64_t *Gi=polarParams->G_N_tab[off+i]; uint64_t *Gi=polarParams->G_N_tab[off+i];
D[0] ^= (Cprime_i & Gi[0]); D[0] ^= (Cprime_i & Gi[0]);
...@@ -544,18 +564,17 @@ void polar_encoder_fast(uint64_t *A, ...@@ -544,18 +564,17 @@ void polar_encoder_fast(uint64_t *A,
D[7] ^= (Cprime_i & Gi[7]); D[7] ^= (Cprime_i & Gi[7]);
} }
} }
#ifdef DEBUG_POLAR_ENCODER #ifdef DEBUG_POLAR_ENCODER
printf("D %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n", printf("D %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
D[0], D[0],
D[1], D[1],
D[2], D[2],
D[3], D[3],
D[4], D[4],
D[5], D[5],
D[6], D[6],
D[7]); D[7]);
#endif #endif
polar_rate_matching(polarParams,(void *)D,(void *)out);
polar_rate_matching(polarParams,(void*)D,(void*)out);
} }
...@@ -37,202 +37,175 @@ ...@@ -37,202 +37,175 @@
#include "PHY/NR_TRANSPORT/nr_dci.h" #include "PHY/NR_TRANSPORT/nr_dci.h"
static int intcmp(const void *p1,const void *p2) { static int intcmp(const void *p1,const void *p2) {
return(*(int16_t *)p1 > *(int16_t *)p2);
return(*(int16_t*)p1 > *(int16_t*)p2);
} }
void nr_polar_init(t_nrPolar_paramsPtr *polarParams, static void nr_polar_init(t_nrPolar_params * *polarParams,
int8_t messageType, int8_t messageType,
uint16_t messageLength, uint16_t messageLength,
uint8_t aggregation_level) uint8_t aggregation_level) {
{ t_nrPolar_params *currentPtr = *polarParams;
t_nrPolar_paramsPtr currentPtr = *polarParams; uint16_t aggregation_prime = nr_polar_aggregation_prime(aggregation_level);
uint16_t aggregation_prime = nr_polar_aggregation_prime(aggregation_level);
//Parse the list. If the node is already created, return without initialization.
//Parse the list. If the node is already created, return without initialization. while (currentPtr != NULL) {
while (currentPtr != NULL) { //printf("currentPtr->idx %d, (%d,%d)\n",currentPtr->idx,currentPtr->payloadBits,currentPtr->encoderLength);
//printf("currentPtr->idx %d, (%d,%d)\n",currentPtr->idx,currentPtr->payloadBits,currentPtr->encoderLength); if (currentPtr->idx == (messageType * messageLength * aggregation_prime)) return;
if (currentPtr->idx == (messageType * messageLength * aggregation_prime)) return; else currentPtr = currentPtr->nextPtr;
else currentPtr = currentPtr->nextPtr; }
}
// printf("currentPtr %p (polarParams %p)\n",currentPtr,polarParams);
// printf("currentPtr %p (polarParams %p)\n",currentPtr,polarParams); //Else, initialize and add node to the end of the linked list.
//Else, initialize and add node to the end of the linked list. t_nrPolar_params *newPolarInitNode = malloc(sizeof(t_nrPolar_params));
t_nrPolar_paramsPtr newPolarInitNode = malloc(sizeof(t_nrPolar_params));
if (newPolarInitNode != NULL) {
if (newPolarInitNode != NULL) { newPolarInitNode->idx = (messageType * messageLength * aggregation_prime);
newPolarInitNode->nextPtr = NULL;
newPolarInitNode->idx = (messageType * messageLength * aggregation_prime); //printf("newPolarInitNode->idx %d, (%d,%d,%d:%d)\n",newPolarInitNode->idx,messageType,messageLength,aggregation_prime,aggregation_level);
newPolarInitNode->nextPtr = NULL;
//printf("newPolarInitNode->idx %d, (%d,%d,%d:%d)\n",newPolarInitNode->idx,messageType,messageLength,aggregation_prime,aggregation_level); if (messageType == 0) { //PBCH
newPolarInitNode->n_max = NR_POLAR_PBCH_N_MAX;
if (messageType == 0) { //PBCH newPolarInitNode->i_il = NR_POLAR_PBCH_I_IL;
newPolarInitNode->n_max = NR_POLAR_PBCH_N_MAX; newPolarInitNode->i_seg = NR_POLAR_PBCH_I_SEG;
newPolarInitNode->i_il = NR_POLAR_PBCH_I_IL; newPolarInitNode->n_pc = NR_POLAR_PBCH_N_PC;
newPolarInitNode->i_seg = NR_POLAR_PBCH_I_SEG; newPolarInitNode->n_pc_wm = NR_POLAR_PBCH_N_PC_WM;
newPolarInitNode->n_pc = NR_POLAR_PBCH_N_PC; newPolarInitNode->i_bil = NR_POLAR_PBCH_I_BIL;
newPolarInitNode->n_pc_wm = NR_POLAR_PBCH_N_PC_WM; newPolarInitNode->crcParityBits = NR_POLAR_PBCH_CRC_PARITY_BITS;
newPolarInitNode->i_bil = NR_POLAR_PBCH_I_BIL; newPolarInitNode->payloadBits = NR_POLAR_PBCH_PAYLOAD_BITS;
newPolarInitNode->crcParityBits = NR_POLAR_PBCH_CRC_PARITY_BITS; newPolarInitNode->encoderLength = NR_POLAR_PBCH_E;
newPolarInitNode->payloadBits = NR_POLAR_PBCH_PAYLOAD_BITS; newPolarInitNode->crcCorrectionBits = NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->encoderLength = NR_POLAR_PBCH_E; newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits);//G_P
newPolarInitNode->crcCorrectionBits = NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS; //printf("Initializing polar parameters for PBCH (K %d, E %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength);
newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits);//G_P } else if (messageType == 1) { //DCI
//printf("Initializing polar parameters for PBCH (K %d, E %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength); newPolarInitNode->n_max = NR_POLAR_DCI_N_MAX;
} else if (messageType == 1) { //DCI newPolarInitNode->i_il = NR_POLAR_DCI_I_IL;
newPolarInitNode->n_max = NR_POLAR_DCI_N_MAX; newPolarInitNode->i_seg = NR_POLAR_DCI_I_SEG;
newPolarInitNode->i_il = NR_POLAR_DCI_I_IL; newPolarInitNode->n_pc = NR_POLAR_DCI_N_PC;
newPolarInitNode->i_seg = NR_POLAR_DCI_I_SEG; newPolarInitNode->n_pc_wm = NR_POLAR_DCI_N_PC_WM;
newPolarInitNode->n_pc = NR_POLAR_DCI_N_PC; newPolarInitNode->i_bil = NR_POLAR_DCI_I_BIL;
newPolarInitNode->n_pc_wm = NR_POLAR_DCI_N_PC_WM; newPolarInitNode->crcParityBits = NR_POLAR_DCI_CRC_PARITY_BITS;
newPolarInitNode->i_bil = NR_POLAR_DCI_I_BIL; newPolarInitNode->payloadBits = messageLength;
newPolarInitNode->crcParityBits = NR_POLAR_DCI_CRC_PARITY_BITS; newPolarInitNode->encoderLength = aggregation_level*108;
newPolarInitNode->payloadBits = messageLength; newPolarInitNode->crcCorrectionBits = NR_POLAR_DCI_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->encoderLength = aggregation_level*108; newPolarInitNode->crc_generator_matrix=crc24c_generator_matrix(newPolarInitNode->payloadBits+newPolarInitNode->crcParityBits);//G_P
newPolarInitNode->crcCorrectionBits = NR_POLAR_DCI_CRC_ERROR_CORRECTION_BITS; //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 } else if (messageType == -1) { //UCI
//printf("Initializing polar parameters for DCI (K %d, E %d, L %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength,aggregation_level); } else {
} else if (messageType == -1) { //UCI AssertFatal(1 == 0, "[nr_polar_init] Incorrect Message Type(%d)", messageType);
}
} else {
AssertFatal(1 == 0, "[nr_polar_init] Incorrect Message Type(%d)", messageType); 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 = log2(newPolarInitNode->N);
newPolarInitNode->K = newPolarInitNode->payloadBits + newPolarInitNode->crcParityBits; // Number of bits to encode. newPolarInitNode->G_N = nr_polar_kronecker_power_matrices(newPolarInitNode->n);
newPolarInitNode->N = nr_polar_output_length(newPolarInitNode->K, newPolarInitNode->encoderLength, newPolarInitNode->n_max); //polar_encoder vectors:
newPolarInitNode->n = log2(newPolarInitNode->N); newPolarInitNode->nr_polar_crc = malloc(sizeof(uint8_t) * newPolarInitNode->crcParityBits);
newPolarInitNode->G_N = nr_polar_kronecker_power_matrices(newPolarInitNode->n); newPolarInitNode->nr_polar_aPrime = malloc(sizeof(uint8_t) * ((ceil((newPolarInitNode->payloadBits)/32.0)*4)+3));
newPolarInitNode->nr_polar_APrime = malloc(sizeof(uint8_t) * newPolarInitNode->K);
//polar_encoder vectors: newPolarInitNode->nr_polar_D = malloc(sizeof(uint8_t) * newPolarInitNode->N);
newPolarInitNode->nr_polar_crc = malloc(sizeof(uint8_t) * newPolarInitNode->crcParityBits); newPolarInitNode->nr_polar_E = malloc(sizeof(uint8_t) * newPolarInitNode->encoderLength);
newPolarInitNode->nr_polar_aPrime = malloc(sizeof(uint8_t) * ((ceil((newPolarInitNode->payloadBits)/32.0)*4)+3)); //Polar Coding vectors
newPolarInitNode->nr_polar_APrime = malloc(sizeof(uint8_t) * newPolarInitNode->K); newPolarInitNode->nr_polar_U = malloc(sizeof(uint8_t) * newPolarInitNode->N); //Decoder: nr_polar_uHat
newPolarInitNode->nr_polar_D = malloc(sizeof(uint8_t) * newPolarInitNode->N); newPolarInitNode->nr_polar_CPrime = malloc(sizeof(uint8_t) * newPolarInitNode->K); //Decoder: nr_polar_cHat
newPolarInitNode->nr_polar_E = malloc(sizeof(uint8_t) * newPolarInitNode->encoderLength); newPolarInitNode->nr_polar_B = malloc(sizeof(uint8_t) * newPolarInitNode->K); //Decoder: nr_polar_bHat
newPolarInitNode->nr_polar_A = malloc(sizeof(uint8_t) * newPolarInitNode->payloadBits); //Decoder: nr_polar_aHat
//Polar Coding vectors newPolarInitNode->Q_0_Nminus1 = nr_polar_sequence_pattern(newPolarInitNode->n);
newPolarInitNode->nr_polar_U = malloc(sizeof(uint8_t) * newPolarInitNode->N); //Decoder: nr_polar_uHat newPolarInitNode->interleaving_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->K);
newPolarInitNode->nr_polar_CPrime = malloc(sizeof(uint8_t) * newPolarInitNode->K); //Decoder: nr_polar_cHat nr_polar_interleaving_pattern(newPolarInitNode->K,
newPolarInitNode->nr_polar_B = malloc(sizeof(uint8_t) * newPolarInitNode->K); //Decoder: nr_polar_bHat newPolarInitNode->i_il,
newPolarInitNode->nr_polar_A = malloc(sizeof(uint8_t) * newPolarInitNode->payloadBits); //Decoder: nr_polar_aHat newPolarInitNode->interleaving_pattern);
newPolarInitNode->deinterleaving_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->K);
for (int i=0; i<newPolarInitNode->K; i++)
newPolarInitNode->Q_0_Nminus1 = nr_polar_sequence_pattern(newPolarInitNode->n); newPolarInitNode->deinterleaving_pattern[newPolarInitNode->interleaving_pattern[i]] = i;
newPolarInitNode->interleaving_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->K); newPolarInitNode->rate_matching_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength);
nr_polar_interleaving_pattern(newPolarInitNode->K, uint16_t *J = malloc(sizeof(uint16_t) * newPolarInitNode->N);
newPolarInitNode->i_il, nr_polar_rate_matching_pattern(newPolarInitNode->rate_matching_pattern,
newPolarInitNode->interleaving_pattern); J,
nr_polar_subblock_interleaver_pattern,
newPolarInitNode->deinterleaving_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->K); newPolarInitNode->K,
for (int i=0;i<newPolarInitNode->K;i++) newPolarInitNode->N,
newPolarInitNode->deinterleaving_pattern[newPolarInitNode->interleaving_pattern[i]] = i; newPolarInitNode->encoderLength);
newPolarInitNode->information_bit_pattern = malloc(sizeof(uint8_t) * newPolarInitNode->N);
newPolarInitNode->rate_matching_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength); newPolarInitNode->Q_I_N = malloc(sizeof(int16_t) * (newPolarInitNode->K + newPolarInitNode->n_pc));
uint16_t *J = malloc(sizeof(uint16_t) * newPolarInitNode->N); newPolarInitNode->Q_F_N = malloc( sizeof(int16_t) * (newPolarInitNode->N + 1)); // Last element shows the final array index assigned a value.
nr_polar_rate_matching_pattern(newPolarInitNode->rate_matching_pattern, newPolarInitNode->Q_PC_N = malloc( sizeof(int16_t) * (newPolarInitNode->n_pc));
J,
nr_polar_subblock_interleaver_pattern, for (int i = 0; i <= newPolarInitNode->N; i++)
newPolarInitNode->K, newPolarInitNode->Q_F_N[i] = -1; // Empty array.
newPolarInitNode->N,
newPolarInitNode->encoderLength); nr_polar_info_bit_pattern(newPolarInitNode->information_bit_pattern,
newPolarInitNode->Q_I_N,
newPolarInitNode->information_bit_pattern = malloc(sizeof(uint8_t) * newPolarInitNode->N); newPolarInitNode->Q_F_N,
newPolarInitNode->Q_I_N = malloc(sizeof(int16_t) * (newPolarInitNode->K + newPolarInitNode->n_pc)); J,
newPolarInitNode->Q_F_N = malloc( sizeof(int16_t) * (newPolarInitNode->N + 1)); // Last element shows the final array index assigned a value. newPolarInitNode->Q_0_Nminus1,
newPolarInitNode->Q_PC_N = malloc( sizeof(int16_t) * (newPolarInitNode->n_pc)); newPolarInitNode->K,
for (int i = 0; i <= newPolarInitNode->N; i++) newPolarInitNode->N,
newPolarInitNode->Q_F_N[i] = -1; // Empty array. newPolarInitNode->encoderLength,
nr_polar_info_bit_pattern(newPolarInitNode->information_bit_pattern, newPolarInitNode->n_pc);
newPolarInitNode->Q_I_N, // sort the Q_I_N array in ascending order (first K positions)
newPolarInitNode->Q_F_N, qsort((void *)newPolarInitNode->Q_I_N,newPolarInitNode->K,sizeof(int16_t),intcmp);
J, newPolarInitNode->channel_interleaver_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength);
newPolarInitNode->Q_0_Nminus1, nr_polar_channel_interleaver_pattern(newPolarInitNode->channel_interleaver_pattern,
newPolarInitNode->K, newPolarInitNode->i_bil,
newPolarInitNode->N, newPolarInitNode->encoderLength);
newPolarInitNode->encoderLength, free(J);
newPolarInitNode->n_pc); build_decoder_tree(newPolarInitNode);
// sort the Q_I_N array in ascending order (first K positions) build_polar_tables(newPolarInitNode);
qsort((void*)newPolarInitNode->Q_I_N,newPolarInitNode->K,sizeof(int16_t),intcmp); init_polar_deinterleaver_table(newPolarInitNode);
//printf("decoder tree nodes %d\n",newPolarInitNode->tree.num_nodes);
newPolarInitNode->channel_interleaver_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength); } else {
nr_polar_channel_interleaver_pattern(newPolarInitNode->channel_interleaver_pattern, AssertFatal(1 == 0, "[nr_polar_init] New t_nrPolar_params * could not be created");
newPolarInitNode->i_bil, }
newPolarInitNode->encoderLength);
//Fixme: the list is not thread safe
free(J); //The defect is not critical: we always append (never delete items) and adding two times the same is fine
newPolarInitNode->nextPtr=*polarParams;
build_decoder_tree(newPolarInitNode); *polarParams=newPolarInitNode;
build_polar_tables(newPolarInitNode); return;
init_polar_deinterleaver_table(newPolarInitNode);
//printf("decoder tree nodes %d\n",newPolarInitNode->tree.num_nodes);
} else {
AssertFatal(1 == 0, "[nr_polar_init] New t_nrPolar_paramsPtr could not be created");
}
currentPtr = *polarParams;
//If polarParams is empty:
if (currentPtr == NULL)
{
*polarParams = newPolarInitNode;
//printf("Creating first polarParams entry index %d, %p\n",newPolarInitNode->idx,*polarParams);
return;
}
//Else, add node to the end of the linked list.
while (currentPtr->nextPtr != NULL) {
currentPtr = currentPtr->nextPtr;
}
currentPtr->nextPtr= newPolarInitNode;
printf("Adding new polarParams entry to list index %d,%p\n",
newPolarInitNode->idx,
currentPtr->nextPtr);
return;
} }
void nr_polar_print_polarParams(t_nrPolar_paramsPtr polarParams) void nr_polar_print_polarParams(t_nrPolar_params *polarParams) {
{ uint8_t i = 0;
uint8_t i = 0;
if (polarParams == NULL) { if (polarParams == NULL) {
printf("polarParams is empty.\n"); printf("polarParams is empty.\n");
} else { } else {
while (polarParams != NULL){ while (polarParams != NULL) {
printf("polarParams[%d] = %d\n", i, polarParams->idx); printf("polarParams[%d] = %d\n", i, polarParams->idx);
polarParams = polarParams->nextPtr; polarParams = polarParams->nextPtr;
i++; i++;
} }
} }
return;
return;
} }
t_nrPolar_paramsPtr nr_polar_params (t_nrPolar_paramsPtr polarParams, t_nrPolar_params *nr_polar_params ( int8_t messageType,
int8_t messageType, uint16_t messageLength,
uint16_t messageLength, uint8_t aggregation_level) {
uint8_t aggregation_level) static t_nrPolar_params *polarList = NULL;
{ nr_polar_init(&polarList, messageType,messageLength,aggregation_level);
t_nrPolar_paramsPtr currentPtr = NULL; t_nrPolar_params *polarParams=polarList;
const int tag=messageType * messageLength * nr_polar_aggregation_prime(aggregation_level);
while (polarParams != NULL) {
if (polarParams->idx == while (polarParams != NULL) {
(messageType * messageLength * (nr_polar_aggregation_prime(aggregation_level)) )) { if (polarParams->idx == tag)
currentPtr = polarParams; return polarParams;
break;
} else { polarParams = polarParams->nextPtr;
polarParams = polarParams->nextPtr; }
}
} AssertFatal(false,"Polar Init tables internal failure\n");
return currentPtr; return NULL;
} }
uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level) uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level) {
{ if (aggregation_level == 0) return 0;
if (aggregation_level == 0) return 0; else if (aggregation_level == 1) return NR_POLAR_AGGREGATION_LEVEL_1_PRIME;
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 == 2) return NR_POLAR_AGGREGATION_LEVEL_2_PRIME; else if (aggregation_level == 4) return NR_POLAR_AGGREGATION_LEVEL_4_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 if (aggregation_level == 8) return NR_POLAR_AGGREGATION_LEVEL_8_PRIME; else return NR_POLAR_AGGREGATION_LEVEL_16_PRIME; //aggregation_level == 16
else return NR_POLAR_AGGREGATION_LEVEL_16_PRIME; //aggregation_level == 16
} }
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#include "assertions.h" #include "assertions.h"
#include <math.h> #include <math.h>
#include "PHY/NR_REFSIG/nr_refsig.h" #include "PHY/NR_REFSIG/nr_refsig.h"
#include "PHY/LTE_REFSIG/lte_refsig.h" #include "PHY/LTE_REFSIG/lte_refsig.h"
#include "SCHED_NR/fapi_nr_l1.h" #include "SCHED_NR/fapi_nr_l1.h"
...@@ -41,104 +41,86 @@ extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn); ...@@ -41,104 +41,86 @@ extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn);
extern int32_t get_uldl_offset(int nr_bandP); extern int32_t get_uldl_offset(int nr_bandP);
int l1_north_init_gNB() { int l1_north_init_gNB() {
int i,j; int i,j;
if (RC.nb_nr_L1_inst > 0 && RC.nb_nr_L1_CC != NULL && RC.gNB != NULL) if (RC.nb_nr_L1_inst > 0 && RC.nb_nr_L1_CC != NULL && RC.gNB != NULL) {
{
AssertFatal(RC.nb_nr_L1_inst>0,"nb_nr_L1_inst=%d\n",RC.nb_nr_L1_inst); AssertFatal(RC.nb_nr_L1_inst>0,"nb_nr_L1_inst=%d\n",RC.nb_nr_L1_inst);
AssertFatal(RC.nb_nr_L1_CC!=NULL,"nb_nr_L1_CC is null\n"); AssertFatal(RC.nb_nr_L1_CC!=NULL,"nb_nr_L1_CC is null\n");
AssertFatal(RC.gNB!=NULL,"RC.gNB is null\n"); AssertFatal(RC.gNB!=NULL,"RC.gNB is null\n");
LOG_I(PHY,"%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst); LOG_I(PHY,"%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst);
for (i=0;i<RC.nb_nr_L1_inst;i++) { for (i=0; i<RC.nb_nr_L1_inst; i++) {
AssertFatal(RC.gNB[i]!=NULL,"RC.gNB[%d] is null\n",i); AssertFatal(RC.gNB[i]!=NULL,"RC.gNB[%d] is null\n",i);
AssertFatal(RC.nb_nr_L1_CC[i]>0,"RC.nb_nr_L1_CC[%d]=%d\n",i,RC.nb_nr_L1_CC[i]); AssertFatal(RC.nb_nr_L1_CC[i]>0,"RC.nb_nr_L1_CC[%d]=%d\n",i,RC.nb_nr_L1_CC[i]);
LOG_I(PHY,"%s() RC.nb_nr_L1_CC[%d]:%d\n", __FUNCTION__, i, RC.nb_nr_L1_CC[i]); LOG_I(PHY,"%s() RC.nb_nr_L1_CC[%d]:%d\n", __FUNCTION__, i, RC.nb_nr_L1_CC[i]);
for (j=0;j<RC.nb_nr_L1_CC[i];j++) { for (j=0; j<RC.nb_nr_L1_CC[i]; j++) {
AssertFatal(RC.gNB[i][j]!=NULL,"RC.gNB[%d][%d] is null\n",i,j); AssertFatal(RC.gNB[i][j]!=NULL,"RC.gNB[%d][%d] is null\n",i,j);
if ((RC.gNB[i][j]->if_inst = NR_IF_Module_init(i))<0) return(-1); if ((RC.gNB[i][j]->if_inst = NR_IF_Module_init(i))<0) return(-1);
LOG_I(PHY,"%s() RC.gNB[%d][%d] installing callbacks\n", __FUNCTION__, i, j); LOG_I(PHY,"%s() RC.gNB[%d][%d] installing callbacks\n", __FUNCTION__, i, j);
RC.gNB[i][j]->if_inst->NR_PHY_config_req = nr_phy_config_request; RC.gNB[i][j]->if_inst->NR_PHY_config_req = nr_phy_config_request;
RC.gNB[i][j]->if_inst->NR_Schedule_response = nr_schedule_response; RC.gNB[i][j]->if_inst->NR_Schedule_response = nr_schedule_response;
} }
} }
} } else {
else
{
LOG_I(PHY,"%s() Not installing PHY callbacks - RC.nb_nr_L1_inst:%d RC.nb_nr_L1_CC:%p RC.gNB:%p\n", __FUNCTION__, RC.nb_nr_L1_inst, RC.nb_nr_L1_CC, RC.gNB); LOG_I(PHY,"%s() Not installing PHY callbacks - RC.nb_nr_L1_inst:%d RC.nb_nr_L1_CC:%p RC.gNB:%p\n", __FUNCTION__, RC.nb_nr_L1_inst, RC.nb_nr_L1_CC, RC.gNB);
} }
return(0); return(0);
} }
int phy_init_nr_gNB(PHY_VARS_gNB *gNB, int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
unsigned char is_secondary_gNB, unsigned char is_secondary_gNB,
unsigned char abstraction_flag) unsigned char abstraction_flag) {
{
// shortcuts // shortcuts
NR_DL_FRAME_PARMS* const fp = &gNB->frame_parms; NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms;
nfapi_nr_config_request_t* cfg = &gNB->gNB_config; nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
NR_gNB_COMMON* const common_vars = &gNB->common_vars; NR_gNB_COMMON *const common_vars = &gNB->common_vars;
LTE_eNB_PUSCH** const pusch_vars = gNB->pusch_vars; LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars;
LTE_eNB_SRS* const srs_vars = gNB->srs_vars; LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
LTE_eNB_PRACH* const prach_vars = &gNB->prach_vars; LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;
int i, UE_id;
int i, UE_id;
LOG_I(PHY,"[gNB %d] %s() About to wait for gNB to be configured\n", gNB->Mod_id, __FUNCTION__); LOG_I(PHY,"[gNB %d] %s() About to wait for gNB to be configured\n", gNB->Mod_id, __FUNCTION__);
gNB->total_dlsch_bitrate = 0; gNB->total_dlsch_bitrate = 0;
gNB->total_transmitted_bits = 0; gNB->total_transmitted_bits = 0;
gNB->total_system_throughput = 0; gNB->total_system_throughput = 0;
gNB->check_for_MUMIMO_transmissions=0; gNB->check_for_MUMIMO_transmissions=0;
while(gNB->configured == 0) usleep(10000); while(gNB->configured == 0) usleep(10000);
init_dfts(); init_dfts();
/* /*
LOG_I(PHY,"[gNB %"PRIu8"] Initializing DL_FRAME_PARMS : N_RB_DL %"PRIu8", PHICH Resource %d, PHICH Duration %d nb_antennas_tx:%u nb_antennas_rx:%u PRACH[rootSequenceIndex:%u prach_Config_enabled:%u configIndex:%u highSpeed:%u zeroCorrelationZoneConfig:%u freqOffset:%u]\n", LOG_I(PHY,"[gNB %"PRIu8"] Initializing DL_FRAME_PARMS : N_RB_DL %"PRIu8", PHICH Resource %d, PHICH Duration %d nb_antennas_tx:%u nb_antennas_rx:%u PRACH[rootSequenceIndex:%u prach_Config_enabled:%u configIndex:%u highSpeed:%u zeroCorrelationZoneConfig:%u freqOffset:%u]\n",
gNB->Mod_id, gNB->Mod_id,
fp->N_RB_DL,fp->phich_config_common.phich_resource, fp->N_RB_DL,fp->phich_config_common.phich_resource,
fp->phich_config_common.phich_duration, fp->phich_config_common.phich_duration,
fp->nb_antennas_tx, fp->nb_antennas_rx, fp->nb_antennas_tx, fp->nb_antennas_rx,
fp->prach_config_common.rootSequenceIndex, fp->prach_config_common.rootSequenceIndex,
fp->prach_config_common.prach_Config_enabled, fp->prach_config_common.prach_Config_enabled,
fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
fp->prach_config_common.prach_ConfigInfo.highSpeedFlag, fp->prach_config_common.prach_ConfigInfo.highSpeedFlag,
fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset
);*/ );*/
LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_gNB][MOD %02"PRIu8"][]\n", gNB->Mod_id); LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_gNB][MOD %02"PRIu8"][]\n", gNB->Mod_id);
crcTableInit(); crcTableInit();
init_dfts(); init_dfts();
// PBCH DMRS gold sequences generation // PBCH DMRS gold sequences generation
nr_init_pbch_dmrs(gNB); nr_init_pbch_dmrs(gNB);
// Polar encoder init for PBCH // Polar encoder init for PBCH
nr_polar_init(&gNB->nrPolar_params,
NR_POLAR_PBCH_MESSAGE_TYPE,
NR_POLAR_PBCH_PAYLOAD_BITS,
NR_POLAR_PBCH_AGGREGATION_LEVEL);
//PDCCH DMRS init //PDCCH DMRS init
gNB->nr_gold_pdcch_dmrs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t**)); gNB->nr_gold_pdcch_dmrs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs; uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
AssertFatal(pdcch_dmrs!=NULL, "NR init: pdcch_dmrs malloc failed\n"); AssertFatal(pdcch_dmrs!=NULL, "NR init: pdcch_dmrs malloc failed\n");
for (int slot=0; slot<fp->slots_per_frame; slot++) { for (int slot=0; slot<fp->slots_per_frame; slot++) {
pdcch_dmrs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t*)); pdcch_dmrs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
AssertFatal(pdcch_dmrs[slot]!=NULL, "NR init: pdcch_dmrs for slot %d - malloc failed\n", slot); AssertFatal(pdcch_dmrs[slot]!=NULL, "NR init: pdcch_dmrs for slot %d - malloc failed\n", slot);
for (int symb=0; symb<fp->symbols_per_slot; symb++){
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
pdcch_dmrs[slot][symb] = (uint32_t *)malloc16(NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t)); pdcch_dmrs[slot][symb] = (uint32_t *)malloc16(NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
AssertFatal(pdcch_dmrs[slot][symb]!=NULL, "NR init: pdcch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb); AssertFatal(pdcch_dmrs[slot][symb]!=NULL, "NR init: pdcch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
} }
...@@ -146,127 +128,115 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, ...@@ -146,127 +128,115 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
nr_init_pdcch_dmrs(gNB, cfg->sch_config.physical_cell_id.value); nr_init_pdcch_dmrs(gNB, cfg->sch_config.physical_cell_id.value);
nr_init_pbch_interleaver(gNB->nr_pbch_interleaver); nr_init_pbch_interleaver(gNB->nr_pbch_interleaver);
//PDSCH DMRS init
gNB->nr_gold_pdsch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs;
for (int slot=0; slot<fp->slots_per_frame; slot++) {
//PDSCH DMRS init pdsch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t **));
gNB->nr_gold_pdsch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t***));
uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs;
for (int slot=0; slot<fp->slots_per_frame; slot++) {
pdsch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t**));
AssertFatal(pdsch_dmrs[slot]!=NULL, "NR init: pdsch_dmrs for slot %d - malloc failed\n", slot); AssertFatal(pdsch_dmrs[slot]!=NULL, "NR init: pdsch_dmrs for slot %d - malloc failed\n", slot);
for (int symb=0; symb<fp->symbols_per_slot; symb++){
pdsch_dmrs[slot][symb] = (uint32_t **)malloc16(NR_MAX_NB_CODEWORDS*sizeof(uint32_t*)); for (int symb=0; symb<fp->symbols_per_slot; symb++) {
pdsch_dmrs[slot][symb] = (uint32_t **)malloc16(NR_MAX_NB_CODEWORDS*sizeof(uint32_t *));
AssertFatal(pdsch_dmrs[slot][symb]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb); AssertFatal(pdsch_dmrs[slot][symb]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
for (int q=0; q<NR_MAX_NB_CODEWORDS; q++) { for (int q=0; q<NR_MAX_NB_CODEWORDS; q++) {
pdsch_dmrs[slot][symb][q] = (uint32_t*)malloc16(NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t)); pdsch_dmrs[slot][symb][q] = (uint32_t *)malloc16(NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
AssertFatal(pdsch_dmrs[slot][symb][q]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d codeword %d - malloc failed\n", slot, symb, q); AssertFatal(pdsch_dmrs[slot][symb][q]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d codeword %d - malloc failed\n", slot, symb, q);
} }
} }
} }
nr_init_pdsch_dmrs(gNB, cfg->sch_config.physical_cell_id.value); nr_init_pdsch_dmrs(gNB, cfg->sch_config.physical_cell_id.value);
/// Transport init necessary for NR synchro /// Transport init necessary for NR synchro
init_nr_transport(gNB); init_nr_transport(gNB);
/* /*
lte_gold(fp,gNB->lte_gold_table,fp->Nid_cell); lte_gold(fp,gNB->lte_gold_table,fp->Nid_cell);
generate_pcfich_reg_mapping(fp); generate_pcfich_reg_mapping(fp);
generate_phich_reg_mapping(fp);*/ generate_phich_reg_mapping(fp);*/
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
gNB->first_run_timing_advance[UE_id] = gNB->first_run_timing_advance[UE_id] =
1; ///This flag used to be static. With multiple gNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here. 1; ///This flag used to be static. With multiple gNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here.
// clear whole structure // clear whole structure
bzero( &gNB->UE_stats[UE_id], sizeof(LTE_eNB_UE_stats) ); bzero( &gNB->UE_stats[UE_id], sizeof(LTE_eNB_UE_stats) );
gNB->physicalConfigDedicated[UE_id] = NULL; gNB->physicalConfigDedicated[UE_id] = NULL;
} }
gNB->first_run_I0_measurements = 1; ///This flag used to be static. With multiple gNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here.
gNB->first_run_I0_measurements =
1; ///This flag used to be static. With multiple gNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here.
common_vars->rxdata = (int32_t **)NULL; common_vars->rxdata = (int32_t **)NULL;
common_vars->txdataF = (int32_t **)malloc16(15*sizeof(int32_t*)); common_vars->txdataF = (int32_t **)malloc16(15*sizeof(int32_t *));
common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t*)); common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t *));
for (i=0;i<15;i++){ for (i=0; i<15; i++) {
common_vars->txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t) ); common_vars->txdataF[i] = (int32_t *)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t) );
LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n", i,common_vars->txdataF[i],
i,common_vars->txdataF[i], fp->samples_per_frame_wCP*sizeof(int32_t));
fp->samples_per_frame_wCP*sizeof(int32_t));
} }
// Channel estimates for SRS // Channel estimates for SRS
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
srs_vars[UE_id].srs_ch_estimates = (int32_t **)malloc16( 64*sizeof(int32_t *) );
srs_vars[UE_id].srs_ch_estimates = (int32_t**)malloc16( 64*sizeof(int32_t*) ); srs_vars[UE_id].srs_ch_estimates_time = (int32_t **)malloc16( 64*sizeof(int32_t *) );
srs_vars[UE_id].srs_ch_estimates_time = (int32_t**)malloc16( 64*sizeof(int32_t*) );
for (i=0; i<64; i++) { for (i=0; i<64; i++) {
srs_vars[UE_id].srs_ch_estimates[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size ); srs_vars[UE_id].srs_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size );
srs_vars[UE_id].srs_ch_estimates_time[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 ); srs_vars[UE_id].srs_ch_estimates_time[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
} }
} //UE_id } //UE_id
/*generate_ul_ref_sigs_rx(); /*generate_ul_ref_sigs_rx();
init_ulsch_power_LUT();*/ init_ulsch_power_LUT();*/
// SRS // SRS
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
srs_vars[UE_id].srs = (int32_t*)malloc16_clear(2*fp->ofdm_symbol_size*sizeof(int32_t)); srs_vars[UE_id].srs = (int32_t *)malloc16_clear(2*fp->ofdm_symbol_size*sizeof(int32_t));
} }
// PRACH // PRACH
prach_vars->prachF = (int16_t*)malloc16_clear( 1024*2*sizeof(int16_t) ); prach_vars->prachF = (int16_t *)malloc16_clear( 1024*2*sizeof(int16_t) );
// assume maximum of 64 RX antennas for PRACH receiver // assume maximum of 64 RX antennas for PRACH receiver
prach_vars->prach_ifft[0] = (int32_t**)malloc16_clear(64*sizeof(int32_t*)); prach_vars->prach_ifft[0] = (int32_t **)malloc16_clear(64*sizeof(int32_t *));
for (i=0;i<64;i++) prach_vars->prach_ifft[0][i] = (int32_t*)malloc16_clear(1024*2*sizeof(int32_t));
for (i=0; i<64; i++) prach_vars->prach_ifft[0][i] = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t));
prach_vars->rxsigF[0] = (int16_t**)malloc16_clear(64*sizeof(int16_t*)); prach_vars->rxsigF[0] = (int16_t **)malloc16_clear(64*sizeof(int16_t *));
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
//FIXME //FIXME
pusch_vars[UE_id] = (LTE_eNB_PUSCH*)malloc16_clear( NUMBER_OF_UE_MAX*sizeof(LTE_eNB_PUSCH) ); pusch_vars[UE_id] = (LTE_eNB_PUSCH *)malloc16_clear( NUMBER_OF_UE_MAX*sizeof(LTE_eNB_PUSCH) );
pusch_vars[UE_id]->rxdataF_ext = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->rxdataF_ext = (int32_t**)malloc16( 2*sizeof(int32_t*) ); pusch_vars[UE_id]->rxdataF_ext2 = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->rxdataF_ext2 = (int32_t**)malloc16( 2*sizeof(int32_t*) ); pusch_vars[UE_id]->drs_ch_estimates = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->drs_ch_estimates = (int32_t**)malloc16( 2*sizeof(int32_t*) ); pusch_vars[UE_id]->drs_ch_estimates_time = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->drs_ch_estimates_time = (int32_t**)malloc16( 2*sizeof(int32_t*) ); pusch_vars[UE_id]->rxdataF_comp = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->rxdataF_comp = (int32_t**)malloc16( 2*sizeof(int32_t*) ); pusch_vars[UE_id]->ul_ch_mag = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->ul_ch_mag = (int32_t**)malloc16( 2*sizeof(int32_t*) ); pusch_vars[UE_id]->ul_ch_magb = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->ul_ch_magb = (int32_t**)malloc16( 2*sizeof(int32_t*) );
for (i=0; i<2; i++) { for (i=0; i<2; i++) {
// RK 2 times because of output format of FFT! // RK 2 times because of output format of FFT!
// FIXME We should get rid of this // FIXME We should get rid of this
pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->drs_ch_estimates[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); pusch_vars[UE_id]->drs_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->drs_ch_estimates_time[i] = (int32_t*)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size ); pusch_vars[UE_id]->drs_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t*)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 ); pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t*)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 ); pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
} }
pusch_vars[UE_id]->llr = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); pusch_vars[UE_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
} //UE_id } //UE_id
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++)
gNB->UE_stats_ptr[UE_id] = &gNB->UE_stats[UE_id]; gNB->UE_stats_ptr[UE_id] = &gNB->UE_stats[UE_id];
gNB->pdsch_config_dedicated->p_a = dB0; //defaul value until overwritten by RRCConnectionReconfiguration
gNB->pdsch_config_dedicated->p_a = dB0; //defaul value until overwritten by RRCConnectionReconfiguration
return (0); return (0);
} }
/* /*
void phy_config_request(PHY_Config_t *phy_config) { void phy_config_request(PHY_Config_t *phy_config) {
...@@ -277,7 +247,7 @@ void phy_config_request(PHY_Config_t *phy_config) { ...@@ -277,7 +247,7 @@ void phy_config_request(PHY_Config_t *phy_config) {
NR_DL_FRAME_PARMS *fp; NR_DL_FRAME_PARMS *fp;
PHICH_RESOURCE_t phich_resource_table[4]={oneSixth,half,one,two}; PHICH_RESOURCE_t phich_resource_table[4]={oneSixth,half,one,two};
int eutra_band = cfg->nfapi_config.rf_bands.rf_band[0]; int eutra_band = cfg->nfapi_config.rf_bands.rf_band[0];
int dl_Bandwidth = cfg->rf_config.dl_carrier_bandwidth.value; int dl_Bandwidth = cfg->rf_config.dl_carrier_bandwidth.value;
int ul_Bandwidth = cfg->rf_config.ul_carrier_bandwidth.value; int ul_Bandwidth = cfg->rf_config.ul_carrier_bandwidth.value;
int Nid_cell = cfg->sch_config.physical_cell_id.value; int Nid_cell = cfg->sch_config.physical_cell_id.value;
...@@ -286,7 +256,7 @@ void phy_config_request(PHY_Config_t *phy_config) { ...@@ -286,7 +256,7 @@ void phy_config_request(PHY_Config_t *phy_config) {
uint32_t dl_CarrierFreq = cfg->nfapi_config.earfcn.value; uint32_t dl_CarrierFreq = cfg->nfapi_config.earfcn.value;
LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,gNB_tx_antenna_ports %d,Ncp %d,DL freq %u)\n", LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,gNB_tx_antenna_ports %d,Ncp %d,DL freq %u)\n",
Mod_id, CC_id, eutra_band, dl_Bandwidth, ul_Bandwidth, Nid_cell, p_eNB,Ncp,dl_CarrierFreq ); Mod_id, CC_id, eutra_band, dl_Bandwidth, ul_Bandwidth, Nid_cell, p_eNB,Ncp,dl_CarrierFreq );
AssertFatal(RC.gNB != NULL, "PHY instance pointer doesn't exist\n"); AssertFatal(RC.gNB != NULL, "PHY instance pointer doesn't exist\n");
AssertFatal(RC.gNB[Mod_id] != NULL, "PHY instance %d doesn't exist\n",Mod_id); AssertFatal(RC.gNB[Mod_id] != NULL, "PHY instance %d doesn't exist\n",Mod_id);
...@@ -312,25 +282,23 @@ void phy_config_request(PHY_Config_t *phy_config) { ...@@ -312,25 +282,23 @@ void phy_config_request(PHY_Config_t *phy_config) {
}*/ }*/
void phy_free_nr_gNB(PHY_VARS_gNB *gNB) void phy_free_nr_gNB(PHY_VARS_gNB *gNB) {
{
//NR_DL_FRAME_PARMS* const fp = &gNB->frame_parms; //NR_DL_FRAME_PARMS* const fp = &gNB->frame_parms;
//nfapi_nr_config_request_t *cfg = &gNB->gNB_config; //nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
NR_gNB_COMMON* const common_vars = &gNB->common_vars; NR_gNB_COMMON *const common_vars = &gNB->common_vars;
LTE_eNB_PUSCH** const pusch_vars = gNB->pusch_vars; LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars;
LTE_eNB_SRS* const srs_vars = gNB->srs_vars; LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
LTE_eNB_PRACH* const prach_vars = &gNB->prach_vars; LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs; uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
int i, UE_id; int i, UE_id;
for (i = 0; i < 15; i++) { for (i = 0; i < 15; i++) {
free_and_zero(common_vars->txdataF[i]); free_and_zero(common_vars->txdataF[i]);
/* rxdataF[i] is not allocated -> don't free */ /* rxdataF[i] is not allocated -> don't free */
} }
free_and_zero(common_vars->txdataF); free_and_zero(common_vars->txdataF);
free_and_zero(common_vars->rxdataF); free_and_zero(common_vars->rxdataF);
// PDCCH DMRS sequences // PDCCH DMRS sequences
free_and_zero(pdcch_dmrs); free_and_zero(pdcch_dmrs);
...@@ -340,6 +308,7 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) ...@@ -340,6 +308,7 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_and_zero(srs_vars[UE_id].srs_ch_estimates[i]); free_and_zero(srs_vars[UE_id].srs_ch_estimates[i]);
free_and_zero(srs_vars[UE_id].srs_ch_estimates_time[i]); free_and_zero(srs_vars[UE_id].srs_ch_estimates_time[i]);
} }
free_and_zero(srs_vars[UE_id].srs_ch_estimates); free_and_zero(srs_vars[UE_id].srs_ch_estimates);
free_and_zero(srs_vars[UE_id].srs_ch_estimates_time); free_and_zero(srs_vars[UE_id].srs_ch_estimates_time);
} //UE_id } //UE_id
...@@ -351,8 +320,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) ...@@ -351,8 +320,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_and_zero(prach_vars->prachF); free_and_zero(prach_vars->prachF);
for (i = 0; i < 64; i++) free_and_zero(prach_vars->prach_ifft[0][i]); for (i = 0; i < 64; i++) free_and_zero(prach_vars->prach_ifft[0][i]);
free_and_zero(prach_vars->prach_ifft[0]);
free_and_zero(prach_vars->prach_ifft[0]);
free_and_zero(prach_vars->rxsigF[0]); free_and_zero(prach_vars->rxsigF[0]);
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
...@@ -365,6 +334,7 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) ...@@ -365,6 +334,7 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_and_zero(pusch_vars[UE_id]->ul_ch_mag[i]); free_and_zero(pusch_vars[UE_id]->ul_ch_mag[i]);
free_and_zero(pusch_vars[UE_id]->ul_ch_magb[i]); free_and_zero(pusch_vars[UE_id]->ul_ch_magb[i]);
} }
free_and_zero(pusch_vars[UE_id]->rxdataF_ext); free_and_zero(pusch_vars[UE_id]->rxdataF_ext);
free_and_zero(pusch_vars[UE_id]->rxdataF_ext2); free_and_zero(pusch_vars[UE_id]->rxdataF_ext2);
free_and_zero(pusch_vars[UE_id]->drs_ch_estimates); free_and_zero(pusch_vars[UE_id]->drs_ch_estimates);
...@@ -387,11 +357,9 @@ void install_schedule_handlers(IF_Module_t *if_inst) ...@@ -387,11 +357,9 @@ void install_schedule_handlers(IF_Module_t *if_inst)
/// this function is a temporary addition for NR configuration /// this function is a temporary addition for NR configuration
void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu,int Nid_cell) void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu,int Nid_cell) {
{
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
nfapi_nr_config_request_t *gNB_config = &gNB->gNB_config; nfapi_nr_config_request_t *gNB_config = &gNB->gNB_config;
//overwrite for new NR parameters //overwrite for new NR parameters
gNB_config->nfapi_config.rf_bands.rf_band[0] = 78; gNB_config->nfapi_config.rf_bands.rf_band[0] = 78;
gNB_config->nfapi_config.nrarfcn.value = 620000; gNB_config->nfapi_config.nrarfcn.value = 620000;
...@@ -404,31 +372,21 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu, ...@@ -404,31 +372,21 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu,
gNB_config->sch_config.n_ssb_crb.value = (N_RB_DL-20); gNB_config->sch_config.n_ssb_crb.value = (N_RB_DL-20);
gNB_config->sch_config.ssb_subcarrier_offset.value = 0; gNB_config->sch_config.ssb_subcarrier_offset.value = 0;
gNB_config->sch_config.physical_cell_id.value=Nid_cell; gNB_config->sch_config.physical_cell_id.value=Nid_cell;
gNB->mac_enabled = 1; gNB->mac_enabled = 1;
fp->dl_CarrierFreq = from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); fp->dl_CarrierFreq = from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
fp->ul_CarrierFreq = fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); fp->ul_CarrierFreq = fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
fp->threequarter_fs = 0; fp->threequarter_fs = 0;
nr_init_frame_parms(gNB_config, fp); nr_init_frame_parms(gNB_config, fp);
gNB->configured = 1; gNB->configured = 1;
LOG_I(PHY,"gNB configured\n"); LOG_I(PHY,"gNB configured\n");
} }
void nr_phy_config_request(NR_PHY_Config_t *phy_config) void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
{
uint8_t Mod_id = phy_config->Mod_id; uint8_t Mod_id = phy_config->Mod_id;
int CC_id = phy_config->CC_id; int CC_id = phy_config->CC_id;
NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id][CC_id]->frame_parms; NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id][CC_id]->frame_parms;
nfapi_nr_config_request_t *gNB_config = &RC.gNB[Mod_id][CC_id]->gNB_config; nfapi_nr_config_request_t *gNB_config = &RC.gNB[Mod_id][CC_id]->gNB_config;
gNB_config->nfapi_config.rf_bands.rf_band[0] = phy_config->cfg->nfapi_config.rf_bands.rf_band[0]; //22 gNB_config->nfapi_config.rf_bands.rf_band[0] = phy_config->cfg->nfapi_config.rf_bands.rf_band[0]; //22
gNB_config->nfapi_config.nrarfcn.value = phy_config->cfg->nfapi_config.nrarfcn.value; //6600 gNB_config->nfapi_config.nrarfcn.value = phy_config->cfg->nfapi_config.nrarfcn.value; //6600
gNB_config->subframe_config.numerology_index_mu.value = phy_config->cfg->subframe_config.numerology_index_mu.value;//1 gNB_config->subframe_config.numerology_index_mu.value = phy_config->cfg->subframe_config.numerology_index_mu.value;//1
...@@ -441,77 +399,69 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) ...@@ -441,77 +399,69 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config)
if (phy_config->cfg->subframe_config.duplex_mode.value == 0) { if (phy_config->cfg->subframe_config.duplex_mode.value == 0) {
gNB_config->subframe_config.duplex_mode.value = TDD; gNB_config->subframe_config.duplex_mode.value = TDD;
} } else {
else {
gNB_config->subframe_config.duplex_mode.value = FDD; gNB_config->subframe_config.duplex_mode.value = FDD;
} }
RC.gNB[Mod_id][CC_id]->mac_enabled = 1; RC.gNB[Mod_id][CC_id]->mac_enabled = 1;
fp->dl_CarrierFreq = from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); fp->dl_CarrierFreq = from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
fp->ul_CarrierFreq = fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); fp->ul_CarrierFreq = fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
fp->threequarter_fs = 0; fp->threequarter_fs = 0;
LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,DL freq %u)\n", LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,DL freq %u)\n",
Mod_id, Mod_id,
CC_id, CC_id,
gNB_config->nfapi_config.rf_bands.rf_band[0], gNB_config->nfapi_config.rf_bands.rf_band[0],
gNB_config->rf_config.dl_carrier_bandwidth.value, gNB_config->rf_config.dl_carrier_bandwidth.value,
gNB_config->rf_config.ul_carrier_bandwidth.value, gNB_config->rf_config.ul_carrier_bandwidth.value,
gNB_config->sch_config.physical_cell_id.value, gNB_config->sch_config.physical_cell_id.value,
fp->dl_CarrierFreq ); fp->dl_CarrierFreq );
nr_init_frame_parms(gNB_config, fp); nr_init_frame_parms(gNB_config, fp);
if (RC.gNB[Mod_id][CC_id]->configured == 1){ if (RC.gNB[Mod_id][CC_id]->configured == 1) {
LOG_E(PHY,"Already gNB already configured, do nothing\n"); LOG_E(PHY,"Already gNB already configured, do nothing\n");
return; return;
} }
RC.gNB[Mod_id][CC_id]->configured = 1; RC.gNB[Mod_id][CC_id]->configured = 1;
LOG_I(PHY,"gNB %d/%d configured\n",Mod_id,CC_id); LOG_I(PHY,"gNB %d/%d configured\n",Mod_id,CC_id);
} }
void init_nr_transport(PHY_VARS_gNB *gNB) { void init_nr_transport(PHY_VARS_gNB *gNB) {
int i; int i;
int j; int j;
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
nfapi_nr_config_request_t *cfg = &gNB->gNB_config; nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
LOG_I(PHY, "Initialise nr transport\n"); LOG_I(PHY, "Initialise nr transport\n");
for (i=0; i<NUMBER_OF_UE_MAX; i++) { for (i=0; i<NUMBER_OF_UE_MAX; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i); LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
for (j=0; j<2; j++) { for (j=0; j<2; j++) {
gNB->dlsch[i][j] = new_gNB_dlsch(1,16,NSOFT,0,fp,cfg); gNB->dlsch[i][j] = new_gNB_dlsch(1,16,NSOFT,0,fp,cfg);
if (!gNB->dlsch[i][j]) { if (!gNB->dlsch[i][j]) {
LOG_E(PHY,"Can't get gNB dlsch structures for UE %d \n", i); LOG_E(PHY,"Can't get gNB dlsch structures for UE %d \n", i);
exit(-1); exit(-1);
}/* else { }/* else {
gNB->dlsch[i][j]->rnti=0;
LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,gNB->dlsch[i][j], gNB->dlsch[i][j]->rnti); gNB->dlsch[i][j]->rnti=0;
LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,gNB->dlsch[i][j], gNB->dlsch[i][j]->rnti);
}*/ }*/
} }
//LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i); //LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
//gNB->ulsch[1+i] = new_gNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0); //gNB->ulsch[1+i] = new_gNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0);
/*if (!gNB->ulsch[1+i]) { /*if (!gNB->ulsch[1+i]) {
LOG_E(PHY,"Can't get gNB ulsch structures\n"); LOG_E(PHY,"Can't get gNB ulsch structures\n");
exit(-1); exit(-1);
}*/ }*/
// this is the transmission mode for the signalling channels // this is the transmission mode for the signalling channels
// this will be overwritten with the real transmission mode by the RRC once the UE is connected // this will be overwritten with the real transmission mode by the RRC once the UE is connected
//gNB->transmission_mode[i] = fp->nb_antenna_ports_gNB==1 ? 1 : 2; //gNB->transmission_mode[i] = fp->nb_antenna_ports_gNB==1 ? 1 : 2;
} }
// ULSCH for RA // ULSCH for RA
//gNB->ulsch[0] = new_gNB_ulsch(MAX_TURBO_ITERATIONS, fp->N_RB_UL, 0); //gNB->ulsch[0] = new_gNB_ulsch(MAX_TURBO_ITERATIONS, fp->N_RB_UL, 0);
/*if (!gNB->ulsch[0]) { /*if (!gNB->ulsch[0]) {
LOG_E(PHY,"Can't get gNB ulsch structures\n"); LOG_E(PHY,"Can't get gNB ulsch structures\n");
exit(-1); exit(-1);
...@@ -522,21 +472,14 @@ void init_nr_transport(PHY_VARS_gNB *gNB) { ...@@ -522,21 +472,14 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
LOG_D(PHY,"gNB %d.%d : RA %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_ra); LOG_D(PHY,"gNB %d.%d : RA %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_ra);
gNB->dlsch_MCH = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg); gNB->dlsch_MCH = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg);
LOG_D(PHY,"gNB %d.%d : MCH %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_MCH); LOG_D(PHY,"gNB %d.%d : MCH %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_MCH);
gNB->rx_total_gain_dB=130; gNB->rx_total_gain_dB=130;
for(i=0; i<NUMBER_OF_UE_MAX; i++) for(i=0; i<NUMBER_OF_UE_MAX; i++)
gNB->mu_mimo_mode[i].dl_pow_off = 2; gNB->mu_mimo_mode[i].dl_pow_off = 2;
gNB->check_for_total_transmissions = 0; gNB->check_for_total_transmissions = 0;
gNB->check_for_MUMIMO_transmissions = 0; gNB->check_for_MUMIMO_transmissions = 0;
gNB->FULL_MUMIMO_transmissions = 0; gNB->FULL_MUMIMO_transmissions = 0;
gNB->check_for_SUMIMO_transmissions = 0; gNB->check_for_SUMIMO_transmissions = 0;
//fp->pucch_config_common.deltaPUCCH_Shift = 1; //fp->pucch_config_common.deltaPUCCH_Shift = 1;
} }
...@@ -40,14 +40,13 @@ ...@@ -40,14 +40,13 @@
extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT]; extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format, uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
nfapi_nr_rnti_type_e rnti_type, nfapi_nr_rnti_type_e rnti_type,
uint16_t N_RB, uint16_t N_RB,
nfapi_nr_config_request_t* config) nfapi_nr_config_request_t *config) {
{
uint16_t size = 0; uint16_t size = 0;
switch(format) { switch(format) {
/*Only sizes for 0_0 and 1_0 are correct at the moment*/ /*Only sizes for 0_0 and 1_0 are correct at the moment*/
case NFAPI_NR_UL_DCI_FORMAT_0_0: case NFAPI_NR_UL_DCI_FORMAT_0_0:
/// fixed: Format identifier 1, Hop flag 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2 Time Domain assgnmt 4 --20 /// fixed: Format identifier 1, Hop flag 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2 Time Domain assgnmt 4 --20
size += 20; size += 20;
...@@ -82,7 +81,6 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format, ...@@ -82,7 +81,6 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
/// fixed: Format identifier 1, VRB2PRB 1, MCS 5, NDI 1, RV 2, HARQ PID 4, DAI 2, PUCCH TPC 2, PUCCH RInd 3, PDSCH to HARQ TInd 3 Time Domain assgnmt 4 -- 28 /// fixed: Format identifier 1, VRB2PRB 1, MCS 5, NDI 1, RV 2, HARQ PID 4, DAI 2, PUCCH TPC 2, PUCCH RInd 3, PDSCH to HARQ TInd 3 Time Domain assgnmt 4 -- 28
size += 28; size += 28;
size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment
break; break;
case NFAPI_NR_DL_DCI_FORMAT_1_1: case NFAPI_NR_DL_DCI_FORMAT_1_1:
...@@ -95,7 +93,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format, ...@@ -95,7 +93,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
// PRB bundling size indicator // PRB bundling size indicator
// Rate matching indicator // Rate matching indicator
// ZP CSI-RS trigger // ZP CSI-RS trigger
/// TB1- MCS 5, NDI 1, RV 2 /// TB1- MCS 5, NDI 1, RV 2
size += 8; size += 8;
// TB2 // TB2
size += 4 ; // HARQ PID size += 4 ; // HARQ PID
...@@ -109,7 +107,6 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format, ...@@ -109,7 +107,6 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
// CBGTI // CBGTI
// CBGFI // CBGFI
size += 1; // DMRS sequence init size += 1; // DMRS sequence init
break; break;
case NFAPI_NR_DL_DCI_FORMAT_2_0: case NFAPI_NR_DL_DCI_FORMAT_2_0:
...@@ -124,8 +121,8 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format, ...@@ -124,8 +121,8 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
case NFAPI_NR_DL_DCI_FORMAT_2_3: case NFAPI_NR_DL_DCI_FORMAT_2_3:
break; break;
default: default:
AssertFatal(1==0, "Invalid NR DCI format %d\n", format); AssertFatal(1==0, "Invalid NR DCI format %d\n", format);
} }
return size; return size;
...@@ -135,11 +132,9 @@ void nr_pdcch_scrambling(uint32_t *in, ...@@ -135,11 +132,9 @@ void nr_pdcch_scrambling(uint32_t *in,
uint16_t size, uint16_t size,
uint32_t Nid, uint32_t Nid,
uint32_t n_RNTI, uint32_t n_RNTI,
uint32_t* out) { uint32_t *out) {
uint8_t reset; uint8_t reset;
uint32_t x1, x2, s=0; uint32_t x1, x2, s=0;
reset = 1; reset = 1;
x2 = (n_RNTI<<16) + Nid; x2 = (n_RNTI<<16) + Nid;
...@@ -147,26 +142,24 @@ void nr_pdcch_scrambling(uint32_t *in, ...@@ -147,26 +142,24 @@ void nr_pdcch_scrambling(uint32_t *in,
if ((i&0x1f)==0) { if ((i&0x1f)==0) {
s = lte_gold_generic(&x1, &x2, reset); s = lte_gold_generic(&x1, &x2, reset);
reset = 0; reset = 0;
if (i){
in++; if (i) {
out++; in++;
out++;
} }
} }
(*out) ^= ((((*in)>>(i&0x1f))&1) ^ ((s>>(i&0x1f))&1))<<(i&0x1f); (*out) ^= ((((*in)>>(i&0x1f))&1) ^ ((s>>(i&0x1f))&1))<<(i&0x1f);
//printf("nr_pdcch_scrambling: in %d seq 0x%08x => out %d\n",((*in)>>(i&0x1f))&1,s,((*out)>>(i&0x1f))&1); //printf("nr_pdcch_scrambling: in %d seq 0x%08x => out %d\n",((*in)>>(i&0x1f))&1,s,((*out)>>(i&0x1f))&1);
} }
} }
uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
t_nrPolar_paramsPtr *nrPolar_params,
uint32_t **gold_pdcch_dmrs, uint32_t **gold_pdcch_dmrs,
int32_t* txdataF, int32_t *txdataF,
int16_t amp, int16_t amp,
NR_DL_FRAME_PARMS frame_parms, NR_DL_FRAME_PARMS frame_parms,
nfapi_nr_config_request_t config) nfapi_nr_config_request_t config) {
{
int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1]; // 3 for the max coreset duration int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1]; // 3 for the max coreset duration
uint32_t dmrs_seq[NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD]; uint32_t dmrs_seq[NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD];
uint16_t dmrs_offset=0; uint16_t dmrs_offset=0;
...@@ -176,7 +169,6 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, ...@@ -176,7 +169,6 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
nr_cce_t cce; nr_cce_t cce;
nr_reg_t reg; nr_reg_t reg;
nr_reg_t reg_mapping_list[NR_MAX_PDCCH_AGG_LEVEL*NR_NB_REG_PER_CCE]; nr_reg_t reg_mapping_list[NR_MAX_PDCCH_AGG_LEVEL*NR_NB_REG_PER_CCE];
/*First iteration: single DCI*/ /*First iteration: single DCI*/
NR_gNB_DCI_ALLOC_t dci_alloc = pdcch_vars.dci_alloc[0]; NR_gNB_DCI_ALLOC_t dci_alloc = pdcch_vars.dci_alloc[0];
nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc.pdcch_params; nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc.pdcch_params;
...@@ -185,184 +177,193 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, ...@@ -185,184 +177,193 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
* in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0 * in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0
* or the rb_offset for other coresets * or the rb_offset for other coresets
* in time: by its first slot and its first symbol*/ * in time: by its first slot and its first symbol*/
if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_MIB_SIB1){ if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_MIB_SIB1) {
cset_start_sc = frame_parms.first_carrier_offset + (frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB + cset_start_sc = frame_parms.first_carrier_offset + (frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB +
pdcch_params.rb_offset)*NR_NB_SC_PER_RB; pdcch_params.rb_offset)*NR_NB_SC_PER_RB;
} } else
else
cset_start_sc = frame_parms.first_carrier_offset + pdcch_params.rb_offset*NR_NB_SC_PER_RB; cset_start_sc = frame_parms.first_carrier_offset + pdcch_params.rb_offset*NR_NB_SC_PER_RB;
cset_start_symb = pdcch_params.first_symbol; cset_start_symb = pdcch_params.first_symbol;
cset_nsymb = pdcch_params.n_symb; cset_nsymb = pdcch_params.n_symb;
dci_idx = 0; dci_idx = 0;
LOG_I(PHY, "Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb); LOG_I(PHY, "Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb);
// DMRS length is per OFDM symbol // DMRS length is per OFDM symbol
uint16_t dmrs_length = (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS)? uint16_t dmrs_length = (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS)?
(pdcch_params.n_rb*6) : (dci_alloc.L*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE) (pdcch_params.n_rb*6) : (dci_alloc.L*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE)
uint16_t encoded_length = dci_alloc.L*108; //2(QPSK)*9(per RB)*6(REG per CCE) uint16_t encoded_length = dci_alloc.L*108; //2(QPSK)*9(per RB)*6(REG per CCE)
LOG_I(PHY, "DMRS length per symbol %d\t DCI encoded length %d\n", dmrs_length, encoded_length); LOG_I(PHY, "DMRS length per symbol %d\t DCI encoded length %d\n", dmrs_length, encoded_length);
/// DMRS QPSK modulation /// DMRS QPSK modulation
/*There is a need to shift from which index the pregenerated DMRS sequence is used /*There is a need to shift from which index the pregenerated DMRS sequence is used
* see 38211 r15.2.0 section 7.4.1.3.2: assumption is the reference point for k refers to the DMRS sequence*/ * see 38211 r15.2.0 section 7.4.1.3.2: assumption is the reference point for k refers to the DMRS sequence*/
if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) { if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) {
for (int symb=cset_start_symb; symb<cset_start_symb + pdcch_params.n_symb; symb++) for (int symb=cset_start_symb; symb<cset_start_symb + pdcch_params.n_symb; symb++)
gold_pdcch_dmrs[symb] += (pdcch_params.rb_offset*3)>>5; gold_pdcch_dmrs[symb] += (pdcch_params.rb_offset*3)>>5;
dmrs_offset = (pdcch_params.rb_offset*3)&0x1f; dmrs_offset = (pdcch_params.rb_offset*3)&0x1f;
LOG_I(PHY, "PDCCH DMRS offset %d\n", dmrs_offset); LOG_I(PHY, "PDCCH DMRS offset %d\n", dmrs_offset);
} }
for (int symb=cset_start_symb; symb<cset_start_symb + pdcch_params.n_symb; symb++) { for (int symb=cset_start_symb; symb<cset_start_symb + pdcch_params.n_symb; symb++) {
if (dmrs_offset) { if (dmrs_offset) {
// a non zero offset requires the DMRS sequence to be rearranged // a non zero offset requires the DMRS sequence to be rearranged
memset(dmrs_seq,0, NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t)); memset(dmrs_seq,0, NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
for (int i=0; i<dmrs_length; i++) { for (int i=0; i<dmrs_length; i++) {
dmrs_seq[(i>>5)] |= ((gold_pdcch_dmrs[symb][(i+dmrs_offset)>>5]>>((i+dmrs_offset)&0x1f))&1)<<(i&0x1f); dmrs_seq[(i>>5)] |= ((gold_pdcch_dmrs[symb][(i+dmrs_offset)>>5]>>((i+dmrs_offset)&0x1f))&1)<<(i&0x1f);
#ifdef DEBUG_PDCCH_DMRS #ifdef DEBUG_PDCCH_DMRS
//printf("out 0x%08x in 0x%08x \n", dmrs_seq[(i>>5)], gold_pdcch_dmrs[symb][(i+dmrs_offset)>>5]); //printf("out 0x%08x in 0x%08x \n", dmrs_seq[(i>>5)], gold_pdcch_dmrs[symb][(i+dmrs_offset)>>5]);
#endif #endif
} }
nr_modulation(dmrs_seq, dmrs_length, MOD_QPSK, mod_dmrs[symb]); nr_modulation(dmrs_seq, dmrs_length, MOD_QPSK, mod_dmrs[symb]);
} } else
else
nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, MOD_QPSK, mod_dmrs[symb]); nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, MOD_QPSK, mod_dmrs[symb]);
#ifdef DEBUG_PDCCH_DMRS #ifdef DEBUG_PDCCH_DMRS
for (int i=0; i<dmrs_length>>1; i++)
if (dmrs_offset)
printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i, dmrs_seq[i>>5],
mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] );
else
printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i,
gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] );
#endif
} for (int i=0; i<dmrs_length>>1; i++)
if (dmrs_offset)
printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i, dmrs_seq[i>>5],
mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] );
else
printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i,
gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] );
#endif
}
/// DCI payload processing /// DCI payload processing
// CRC attachment + Scrambling + Channel coding + Rate matching // CRC attachment + Scrambling + Channel coding + Rate matching
uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD]; uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD];
uint16_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? pdcch_params.rnti:0; uint16_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? pdcch_params.rnti:0;
uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)?
pdcch_params.scrambling_id : config.sch_config.physical_cell_id.value; pdcch_params.scrambling_id : config.sch_config.physical_cell_id.value;
t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L);
nr_polar_init(nrPolar_params, NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L);
t_nrPolar_paramsPtr currentPtr = nr_polar_params(*nrPolar_params, NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L);
polar_encoder_fast(dci_alloc.dci_pdu, encoder_output, pdcch_params.rnti,currentPtr); polar_encoder_fast(dci_alloc.dci_pdu, encoder_output, pdcch_params.rnti,currentPtr);
#ifdef DEBUG_CHANNEL_CODING #ifdef DEBUG_CHANNEL_CODING
printf("polar rnti %d\n",pdcch_params.rnti); printf("polar rnti %d\n",pdcch_params.rnti);
printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n", printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n",
dci_alloc.dci_pdu[0], dci_alloc.dci_pdu[1]); dci_alloc.dci_pdu[0], dci_alloc.dci_pdu[1]);
printf("Encoded Payload (length:%d dwords):\n", encoded_length>>5); printf("Encoded Payload (length:%d dwords):\n", encoded_length>>5);
for (int i=0;i<encoded_length>>5;i++)
for (int i=0; i<encoded_length>>5; i++)
printf("[%d]->0x%08x \t", i,encoder_output[i]); printf("[%d]->0x%08x \t", i,encoder_output[i]);
printf("\n"); printf("\n");
#endif #endif
/// Scrambling /// Scrambling
uint32_t scrambled_output[NR_MAX_DCI_SIZE_DWORD]={0}; uint32_t scrambled_output[NR_MAX_DCI_SIZE_DWORD]= {0};
nr_pdcch_scrambling(encoder_output, encoded_length, Nid, n_RNTI, scrambled_output); nr_pdcch_scrambling(encoder_output, encoded_length, Nid, n_RNTI, scrambled_output);
#ifdef DEBUG_CHANNEL_CODING #ifdef DEBUG_CHANNEL_CODING
printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\t [4]->0x%08x\t [5]->0x%08x\t \ printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\t [4]->0x%08x\t [5]->0x%08x\t \
[6]->0x%08x \t [7]->0x%08x \t [8]->0x%08x \t [9]->0x%08x\t [10]->0x%08x\t [11]->0x%08x\n", [6]->0x%08x \t [7]->0x%08x \t [8]->0x%08x \t [9]->0x%08x\t [10]->0x%08x\t [11]->0x%08x\n",
scrambled_output[0], scrambled_output[1], scrambled_output[2], scrambled_output[3], scrambled_output[4],scrambled_output[5], scrambled_output[0], scrambled_output[1], scrambled_output[2], scrambled_output[3], scrambled_output[4],scrambled_output[5],
scrambled_output[6], scrambled_output[7], scrambled_output[8], scrambled_output[9], scrambled_output[10],scrambled_output[11] ); scrambled_output[6], scrambled_output[7], scrambled_output[8], scrambled_output[9], scrambled_output[10],scrambled_output[11] );
#endif #endif
/// QPSK modulation /// QPSK modulation
int16_t mod_dci[NR_MAX_DCI_SIZE>>1]; int16_t mod_dci[NR_MAX_DCI_SIZE>>1];
nr_modulation(scrambled_output, encoded_length, MOD_QPSK, mod_dci); nr_modulation(scrambled_output, encoded_length, MOD_QPSK, mod_dci);
#ifdef DEBUG_DCI #ifdef DEBUG_DCI
for (int i=0; i<encoded_length>>1; i++) for (int i=0; i<encoded_length>>1; i++)
printf("i %d mod_dci %d %d\n", i, mod_dci[i<<1], mod_dci[(i<<1)+1] ); printf("i %d mod_dci %d %d\n", i, mod_dci[i<<1], mod_dci[(i<<1)+1] );
#endif #endif
/// Resource mapping /// Resource mapping
if (cset_start_sc >= frame_parms.ofdm_symbol_size) if (cset_start_sc >= frame_parms.ofdm_symbol_size)
cset_start_sc -= frame_parms.ofdm_symbol_size; cset_start_sc -= frame_parms.ofdm_symbol_size;
/*Reorder REG list for a freq first mapping*/
uint8_t symb_idx[NR_MAX_CSET_DURATION] = {0,0,0};
uint8_t nb_regs = dci_alloc.L*NR_NB_REG_PER_CCE;
uint8_t regs_per_symb = nb_regs/cset_nsymb;
/*Reorder REG list for a freq first mapping*/ for (int cce_idx=0; cce_idx<dci_alloc.L; cce_idx++) {
uint8_t symb_idx[NR_MAX_CSET_DURATION] = {0,0,0}; cce = dci_alloc.cce_list[cce_idx];
uint8_t nb_regs = dci_alloc.L*NR_NB_REG_PER_CCE;
uint8_t regs_per_symb = nb_regs/cset_nsymb; for (int reg_idx=0; reg_idx<NR_NB_REG_PER_CCE; reg_idx++) {
for (int cce_idx=0; cce_idx<dci_alloc.L; cce_idx++){ reg = cce.reg_list[reg_idx];
cce = dci_alloc.cce_list[cce_idx]; reg_mapping_list[reg.symb_idx*regs_per_symb + symb_idx[reg.symb_idx]++] = reg;
for (int reg_idx=0; reg_idx<NR_NB_REG_PER_CCE; reg_idx++) {
reg = cce.reg_list[reg_idx];
reg_mapping_list[reg.symb_idx*regs_per_symb + symb_idx[reg.symb_idx]++] = reg;
}
} }
}
#ifdef DEBUG_DCI #ifdef DEBUG_DCI
printf("\n Ordered REG list:\n"); printf("\n Ordered REG list:\n");
for (int i=0; i<nb_regs; i++)
printf("%d\t",reg_mapping_list[i].reg_idx ); for (int i=0; i<nb_regs; i++)
printf("\n"); printf("%d\t",reg_mapping_list[i].reg_idx );
printf("\n");
#endif #endif
if (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS) { if (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS) {
/*in this case the DMRS are mapped on all the coreset*/ /*in this case the DMRS are mapped on all the coreset*/
for (l=cset_start_symb; l<cset_start_symb+ cset_nsymb; l++) { for (l=cset_start_symb; l<cset_start_symb+ cset_nsymb; l++) {
dmrs_idx = 0; dmrs_idx = 0;
k = cset_start_sc + 1; k = cset_start_sc + 1;
while (dmrs_idx<3*pdcch_params.n_rb) {
((int16_t*)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = ((amp>>1) * mod_dmrs[l][dmrs_idx<<1]) >> 15; while (dmrs_idx<3*pdcch_params.n_rb) {
((int16_t*)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = ((amp>>1) * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; ((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = ((amp>>1) * mod_dmrs[l][dmrs_idx<<1]) >> 15;
((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = ((amp>>1) * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
#ifdef DEBUG_PDCCH_DMRS #ifdef DEBUG_PDCCH_DMRS
printf("symbol %d position %d => (%d,%d)\n",l,k,((int16_t*)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] , printf("symbol %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
((int16_t*)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
#endif #endif
k+=4; k+=4;
if (k >= frame_parms.ofdm_symbol_size)
k -= frame_parms.ofdm_symbol_size;
dmrs_idx++;
}
}
}
/*Now mapping the encoded DCI based on newly constructed REG list if (k >= frame_parms.ofdm_symbol_size)
* and the DMRS for the precoder granularity same as REG bundle*/
for (int reg_idx=0; reg_idx<nb_regs; reg_idx++) {
reg = reg_mapping_list[reg_idx];
k = cset_start_sc + reg.start_sc_idx;
if (k >= frame_parms.ofdm_symbol_size)
k -= frame_parms.ofdm_symbol_size; k -= frame_parms.ofdm_symbol_size;
l = cset_start_symb + reg.symb_idx;
dmrs_idx = (reg.reg_idx/cset_nsymb)*3; dmrs_idx++;
k_prime = 0; }
for (int m=0; m<NR_NB_SC_PER_RB; m++) { }
if ( m == (k_prime<<2)+1) { // DMRS if not already mapped }
if (pdcch_params.precoder_granularity == NFAPI_NR_CSET_SAME_AS_REG_BUNDLE) {
((int16_t*)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = ((amp>>1) * mod_dmrs[l][dmrs_idx<<1]) >> 15; /*Now mapping the encoded DCI based on newly constructed REG list
((int16_t*)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = ((amp>>1) * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; * and the DMRS for the precoder granularity same as REG bundle*/
for (int reg_idx=0; reg_idx<nb_regs; reg_idx++) {
reg = reg_mapping_list[reg_idx];
k = cset_start_sc + reg.start_sc_idx;
if (k >= frame_parms.ofdm_symbol_size)
k -= frame_parms.ofdm_symbol_size;
l = cset_start_symb + reg.symb_idx;
dmrs_idx = (reg.reg_idx/cset_nsymb)*3;
k_prime = 0;
for (int m=0; m<NR_NB_SC_PER_RB; m++) {
if ( m == (k_prime<<2)+1) { // DMRS if not already mapped
if (pdcch_params.precoder_granularity == NFAPI_NR_CSET_SAME_AS_REG_BUNDLE) {
((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = ((amp>>1) * mod_dmrs[l][dmrs_idx<<1]) >> 15;
((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = ((amp>>1) * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
#ifdef DEBUG_PDCCH_DMRS #ifdef DEBUG_PDCCH_DMRS
printf("l %d position %d => (%d,%d)\n",l,k,((int16_t*)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] , printf("l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
((int16_t*)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
#endif #endif
dmrs_idx++; dmrs_idx++;
}
k_prime++;
} }
else { // DCI payload
((int16_t*)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dci[dci_idx<<1]) >> 15; k_prime++;
((int16_t*)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dci[(dci_idx<<1) + 1]) >> 15; } else { // DCI payload
((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dci[dci_idx<<1]) >> 15;
((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dci[(dci_idx<<1) + 1]) >> 15;
#ifdef DEBUG_DCI #ifdef DEBUG_DCI
printf("l %d position %d => (%d,%d)\n",l,k,((int16_t*)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] , printf("l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
((int16_t*)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
#endif #endif
dci_idx++; dci_idx++;
}
k++;
if (k >= frame_parms.ofdm_symbol_size)
k -= frame_parms.ofdm_symbol_size;
} }
k++;
if (k >= frame_parms.ofdm_symbol_size)
k -= frame_parms.ofdm_symbol_size;
} }
}
return 0; return 0;
} }
...@@ -28,14 +28,13 @@ ...@@ -28,14 +28,13 @@
typedef unsigned __int128 uint128_t; typedef unsigned __int128 uint128_t;
uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format, uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
nfapi_nr_rnti_type_e rnti_type, nfapi_nr_rnti_type_e rnti_type,
uint16_t N_RB, uint16_t N_RB,
nfapi_nr_config_request_t* config); nfapi_nr_config_request_t *config);
uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
t_nrPolar_paramsPtr *nrPolar_params,
uint32_t **gold_pdcch_dmrs, uint32_t **gold_pdcch_dmrs,
int32_t* txdataF, int32_t *txdataF,
int16_t amp, int16_t amp,
NR_DL_FRAME_PARMS frame_parms, NR_DL_FRAME_PARMS frame_parms,
nfapi_nr_config_request_t config); nfapi_nr_config_request_t config);
...@@ -44,7 +43,7 @@ void nr_pdcch_scrambling(uint32_t *in, ...@@ -44,7 +43,7 @@ void nr_pdcch_scrambling(uint32_t *in,
uint16_t size, uint16_t size,
uint32_t Nid, uint32_t Nid,
uint32_t n_RNTI, uint32_t n_RNTI,
uint32_t* out); uint32_t *out);
void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB, void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
int frame, int frame,
...@@ -54,7 +53,7 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB, ...@@ -54,7 +53,7 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
nfapi_nr_dl_config_dci_dl_pdu *pdu, nfapi_nr_dl_config_dci_dl_pdu *pdu,
nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu); nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu);
void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m); void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t *dci_alloc, uint16_t n_shift, uint8_t m);
#endif //__PHY_NR_TRANSPORT_DCI__H #endif //__PHY_NR_TRANSPORT_DCI__H
...@@ -43,21 +43,20 @@ ...@@ -43,21 +43,20 @@
extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT]; extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
uint8_t nr_pbch_payload_interleaving_pattern[32] = {16, 23, 18, 17, 8, 30, 10, 6, 24, 7, 0, 5, 3, 2, 1, 4, uint8_t nr_pbch_payload_interleaving_pattern[32] = {16, 23, 18, 17, 8, 30, 10, 6, 24, 7, 0, 5, 3, 2, 1, 4,
9, 11, 12, 13, 14, 15, 19, 20, 21, 22, 25, 26, 27, 28, 29, 31}; 9, 11, 12, 13, 14, 15, 19, 20, 21, 22, 25, 26, 27, 28, 29, 31
};
int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
int32_t *txdataF, int32_t *txdataF,
int16_t amp, int16_t amp,
uint8_t ssb_start_symbol, uint8_t ssb_start_symbol,
nfapi_nr_config_request_t* config, nfapi_nr_config_request_t *config,
NR_DL_FRAME_PARMS *frame_parms) NR_DL_FRAME_PARMS *frame_parms) {
{
int k,l; int k,l;
//int16_t a; //int16_t a;
int16_t mod_dmrs[NR_PBCH_DMRS_LENGTH<<1]; int16_t mod_dmrs[NR_PBCH_DMRS_LENGTH<<1];
uint8_t idx=0; uint8_t idx=0;
uint8_t nushift = config->sch_config.physical_cell_id.value &3; uint8_t nushift = config->sch_config.physical_cell_id.value &3;
LOG_D(PHY, "PBCH DMRS mapping started at symbol %d shift %d\n", ssb_start_symbol+1, nushift); LOG_D(PHY, "PBCH DMRS mapping started at symbol %d shift %d\n", ssb_start_symbol+1, nushift);
/// QPSK modulation /// QPSK modulation
...@@ -66,79 +65,75 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, ...@@ -66,79 +65,75 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
mod_dmrs[m<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; mod_dmrs[m<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
mod_dmrs[(m<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; mod_dmrs[(m<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
#ifdef DEBUG_PBCH_DMRS #ifdef DEBUG_PBCH_DMRS
printf("m %d idx %d gold seq %d b0-b1 %d-%d mod_dmrs %d %d\n", m, idx, gold_pbch_dmrs[(m<<1)>>5], (((gold_pbch_dmrs[(m<<1)>>5])>>((m<<1)&0x1f))&1), printf("m %d idx %d gold seq %d b0-b1 %d-%d mod_dmrs %d %d\n", m, idx, gold_pbch_dmrs[(m<<1)>>5], (((gold_pbch_dmrs[(m<<1)>>5])>>((m<<1)&0x1f))&1),
(((gold_pbch_dmrs[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1), mod_dmrs[(m<<1)], mod_dmrs[(m<<1)+1]); (((gold_pbch_dmrs[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1), mod_dmrs[(m<<1)], mod_dmrs[(m<<1)+1]);
#endif #endif
} }
/// Resource mapping /// Resource mapping
// PBCH DMRS are mapped within the SSB block on every fourth subcarrier starting from nushift of symbols 1, 2, 3
///symbol 1 [0+nushift:4:236+nushift] -- 60 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
l = ssb_start_symbol + 1;
for (int m = 0; m < 60; m++) {
// PBCH DMRS are mapped within the SSB block on every fourth subcarrier starting from nushift of symbols 1, 2, 3
///symbol 1 [0+nushift:4:236+nushift] -- 60 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
l = ssb_start_symbol + 1;
for (int m = 0; m < 60; m++) {
#ifdef DEBUG_PBCH_DMRS #ifdef DEBUG_PBCH_DMRS
printf("m %d at k %d of l %d\n", m, k, l); printf("m %d at k %d of l %d\n", m, k, l);
#endif #endif
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[m<<1]) >> 15; ((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[m<<1]) >> 15;
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[(m<<1) + 1]) >> 15; ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[(m<<1) + 1]) >> 15;
#ifdef DEBUG_PBCH_DMRS #ifdef DEBUG_PBCH_DMRS
printf("(%d,%d)\n", printf("(%d,%d)\n",
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1], ((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]); ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
#endif #endif
k+=4; k+=4;
if (k >= frame_parms->ofdm_symbol_size) if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size; k-=frame_parms->ofdm_symbol_size;
} }
///symbol 2 [0+u:4:44+nushift ; 192+nu:4:236+nushift] -- 24 mod symbols ///symbol 2 [0+u:4:44+nushift ; 192+nu:4:236+nushift] -- 24 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift; k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
l++; l++;
for (int m = 60; m < 84; m++) { for (int m = 60; m < 84; m++) {
#ifdef DEBUG_PBCH_DMRS #ifdef DEBUG_PBCH_DMRS
printf("m %d at k %d of l %d\n", m, k, l); printf("m %d at k %d of l %d\n", m, k, l);
#endif #endif
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[m<<1]) >> 15; ((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[m<<1]) >> 15;
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[(m<<1) + 1]) >> 15; ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[(m<<1) + 1]) >> 15;
#ifdef DEBUG_PBCH_DMRS #ifdef DEBUG_PBCH_DMRS
printf("(%d,%d)\n", printf("(%d,%d)\n",
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1], ((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]); ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
#endif #endif
k+=(m==71)?148:4; // Jump from 44+nu to 192+nu k+=(m==71)?148:4; // Jump from 44+nu to 192+nu
if (k >= frame_parms->ofdm_symbol_size) if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size; k-=frame_parms->ofdm_symbol_size;
} }
///symbol 3 [0+nushift:4:236+nushift] -- 60 mod symbols ///symbol 3 [0+nushift:4:236+nushift] -- 60 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift; k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
l++; l++;
for (int m = 84; m < NR_PBCH_DMRS_LENGTH; m++) { for (int m = 84; m < NR_PBCH_DMRS_LENGTH; m++) {
#ifdef DEBUG_PBCH_DMRS #ifdef DEBUG_PBCH_DMRS
printf("m %d at k %d of l %d\n", m, k, l); printf("m %d at k %d of l %d\n", m, k, l);
#endif #endif
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[m<<1]) >> 15; ((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[m<<1]) >> 15;
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[(m<<1) + 1]) >> 15; ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[(m<<1) + 1]) >> 15;
#ifdef DEBUG_PBCH_DMRS #ifdef DEBUG_PBCH_DMRS
printf("(%d,%d)\n", printf("(%d,%d)\n",
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1], ((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]); ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
#endif #endif
k+=4; k+=4;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
#ifdef DEBUG_PBCH_DMRS #ifdef DEBUG_PBCH_DMRS
write_output("txdataF_pbch_dmrs.m", "txdataF_pbch_dmrs", txdataF[0], frame_parms->samples_per_frame_wCP>>1, 1, 1); write_output("txdataF_pbch_dmrs.m", "txdataF_pbch_dmrs", txdataF[0], frame_parms->samples_per_frame_wCP>>1, 1, 1);
...@@ -186,6 +181,7 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch, ...@@ -186,6 +181,7 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
s = lte_gold_generic(&x1, &x2, reset); s = lte_gold_generic(&x1, &x2, reset);
reset = 0; reset = 0;
} }
pbch->pbch_a_prime ^= (((pbch->pbch_a_interleaved>>i)&1) ^ ((s>>((k+offset)&0x1f))&1))<<i; pbch->pbch_a_prime ^= (((pbch->pbch_a_interleaved>>i)&1) ^ ((s>>((k+offset)&0x1f))&1))<<i;
k++; /// k increase only when payload bit is not special bit k++; /// k increase only when payload bit is not special bit
} }
...@@ -206,11 +202,11 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch, ...@@ -206,11 +202,11 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
void nr_init_pbch_interleaver(uint8_t *interleaver) { void nr_init_pbch_interleaver(uint8_t *interleaver) {
uint8_t j_sfn=0, j_hrf=10, j_ssb=11, j_other=14; uint8_t j_sfn=0, j_hrf=10, j_ssb=11, j_other=14;
memset((void*)interleaver,0, NR_POLAR_PBCH_PAYLOAD_BITS); memset((void *)interleaver,0, NR_POLAR_PBCH_PAYLOAD_BITS);
for (uint8_t i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++) for (uint8_t i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++)
if (!i) // choice bit:1 if (!i) // choice bit:1
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_other++); *(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_other++);
else if (i<7) //Sfn bits:6 else if (i<7) //Sfn bits:6
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_sfn++); *(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_sfn++);
else if (i<24) // other:17 else if (i<24) // other:17
...@@ -221,11 +217,9 @@ void nr_init_pbch_interleaver(uint8_t *interleaver) { ...@@ -221,11 +217,9 @@ void nr_init_pbch_interleaver(uint8_t *interleaver) {
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_hrf); *(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_hrf);
else // Ssb bits:3 else // Ssb bits:3
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_ssb++); *(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_ssb++);
} }
int nr_generate_pbch(NR_gNB_PBCH *pbch, int nr_generate_pbch(NR_gNB_PBCH *pbch,
t_nrPolar_paramsPtr polar_params,
uint8_t *pbch_pdu, uint8_t *pbch_pdu,
uint8_t *interleaver, uint8_t *interleaver,
int32_t *txdataF, int32_t *txdataF,
...@@ -235,10 +229,8 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, ...@@ -235,10 +229,8 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
uint8_t Lmax, uint8_t Lmax,
uint8_t ssb_index, uint8_t ssb_index,
int sfn, int sfn,
nfapi_nr_config_request_t* config, nfapi_nr_config_request_t *config,
NR_DL_FRAME_PARMS *frame_parms) NR_DL_FRAME_PARMS *frame_parms) {
{
int k,l,m; int k,l,m;
//int16_t a; //int16_t a;
int16_t mod_pbch_e[NR_POLAR_PBCH_E]; int16_t mod_pbch_e[NR_POLAR_PBCH_E];
...@@ -247,22 +239,23 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, ...@@ -247,22 +239,23 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
uint8_t nushift; uint8_t nushift;
uint32_t unscrambling_mask; uint32_t unscrambling_mask;
uint64_t a_reversed=0; uint64_t a_reversed=0;
LOG_I(PHY, "PBCH generation started\n"); LOG_I(PHY, "PBCH generation started\n");
///Payload generation ///Payload generation
memset((void *)pbch, 0, sizeof(NR_gNB_PBCH));
memset((void*)pbch, 0, sizeof(NR_gNB_PBCH));
pbch->pbch_a=0; pbch->pbch_a=0;
for (int i=0; i<NR_PBCH_PDU_BITS; i++) for (int i=0; i<NR_PBCH_PDU_BITS; i++)
pbch->pbch_a |= ((pbch_pdu[2-(i>>3)]>>(7-(i&7)))&1)<<i; pbch->pbch_a |= ((pbch_pdu[2-(i>>3)]>>(7-(i&7)))&1)<<i;
#ifdef DEBUG_PBCH_ENCODING #ifdef DEBUG_PBCH_ENCODING
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
printf("pbch_pdu[%d]: 0x%02x\n", i, pbch_pdu[i]); printf("pbch_pdu[%d]: 0x%02x\n", i, pbch_pdu[i]);
printf("PBCH payload = 0x%08x\n",pbch->pbch_a); printf("PBCH payload = 0x%08x\n",pbch->pbch_a);
#endif #endif
// Extra byte generation // Extra byte generation
for (int i=0; i<4; i++) for (int i=0; i<4; i++)
pbch->pbch_a |= ((sfn>>(3-i))&1)<<(24+i); // resp. 4th, 3rd, 2nd ans 1st lsb of sfn pbch->pbch_a |= ((sfn>>(3-i))&1)<<(24+i); // resp. 4th, 3rd, 2nd ans 1st lsb of sfn
...@@ -276,12 +269,12 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, ...@@ -276,12 +269,12 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
LOG_I(PHY,"After extra byte: pbch_a = 0x%08x\n",pbch->pbch_a); LOG_I(PHY,"After extra byte: pbch_a = 0x%08x\n",pbch->pbch_a);
// Payload interleaving // Payload interleaving
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++) { for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++) {
pbch->pbch_a_interleaved |= ((pbch->pbch_a>>i)&1)<<(*(interleaver+i)); pbch->pbch_a_interleaved |= ((pbch->pbch_a>>i)&1)<<(*(interleaver+i));
#ifdef DEBUG_PBCH_ENCODING #ifdef DEBUG_PBCH_ENCODING
printf("i %d out 0x%08x ilv %d (in>>i)&1) %d\n", i, pbch->pbch_a_interleaved, *(interleaver+i), (pbch->pbch_a>>i)&1); printf("i %d out 0x%08x ilv %d (in>>i)&1) %d\n", i, pbch->pbch_a_interleaved, *(interleaver+i), (pbch->pbch_a>>i)&1);
#endif #endif
} }
...@@ -289,8 +282,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, ...@@ -289,8 +282,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
printf("Interleaving:\n"); printf("Interleaving:\n");
printf("pbch_a_interleaved: 0x%08x\n", pbch->pbch_a_interleaved); printf("pbch_a_interleaved: 0x%08x\n", pbch->pbch_a_interleaved);
#endif #endif
// Scrambling
// Scrambling
unscrambling_mask = (Lmax ==64)? 0x100006D:0x1000041; unscrambling_mask = (Lmax ==64)? 0x100006D:0x1000041;
M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3); M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3);
nushift = (((sfn>>2)&1)<<1) ^ ((sfn>>1)&1); nushift = (((sfn>>2)&1)<<1) ^ ((sfn>>1)&1);
...@@ -301,148 +293,141 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, ...@@ -301,148 +293,141 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
printf("pbch_a_prime: 0x%08x\n", pbch->pbch_a_prime); printf("pbch_a_prime: 0x%08x\n", pbch->pbch_a_prime);
#endif #endif
// Encoder reversal // Encoder reversal
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++) for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++)
a_reversed |= (((uint64_t)pbch->pbch_a_prime>>i)&1)<<(31-i); a_reversed |= (((uint64_t)pbch->pbch_a_prime>>i)&1)<<(31-i);
/// CRC, coding and rate matching /// CRC, coding and rate matching
polar_encoder_fast (&a_reversed, (uint32_t*)pbch->pbch_e, 0, polar_params); polar_encoder_fast (&a_reversed, (uint32_t *)pbch->pbch_e, 0,
nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL)
);
#ifdef DEBUG_PBCH_ENCODING #ifdef DEBUG_PBCH_ENCODING
printf("Channel coding:\n"); printf("Channel coding:\n");
for (int i=0; i<NR_POLAR_PBCH_E_DWORD; i++) for (int i=0; i<NR_POLAR_PBCH_E_DWORD; i++)
printf("pbch_e[%d]: 0x%08x\t", i, pbch->pbch_e[i]); printf("pbch_e[%d]: 0x%08x\t", i, pbch->pbch_e[i]);
printf("\n"); printf("\n");
#endif #endif
/// Scrambling /// Scrambling
M = NR_POLAR_PBCH_E; M = NR_POLAR_PBCH_E;
nushift = (Lmax==4)? ssb_index&3 : ssb_index&7; nushift = (Lmax==4)? ssb_index&3 : ssb_index&7;
nr_pbch_scrambling(pbch, (uint32_t)config->sch_config.physical_cell_id.value, nushift, M, NR_POLAR_PBCH_E, 1, 0); nr_pbch_scrambling(pbch, (uint32_t)config->sch_config.physical_cell_id.value, nushift, M, NR_POLAR_PBCH_E, 1, 0);
#ifdef DEBUG_PBCH_ENCODING #ifdef DEBUG_PBCH_ENCODING
printf("Scrambling:\n"); printf("Scrambling:\n");
for (int i=0; i<NR_POLAR_PBCH_E_DWORD; i++) for (int i=0; i<NR_POLAR_PBCH_E_DWORD; i++)
printf("pbch_e[%d]: 0x%08x\t", i, pbch->pbch_e[i]); printf("pbch_e[%d]: 0x%08x\t", i, pbch->pbch_e[i]);
printf("\n"); printf("\n");
#endif #endif
/// QPSK modulation /// QPSK modulation
for (int i=0; i<NR_POLAR_PBCH_E>>1; i++){ for (int i=0; i<NR_POLAR_PBCH_E>>1; i++) {
idx = (((pbch->pbch_e[(i<<1)>>5]>>((i<<1)&0x1f))&1)<<1) ^ ((pbch->pbch_e[((i<<1)+1)>>5]>>(((i<<1)+1)&0x1f))&1); idx = (((pbch->pbch_e[(i<<1)>>5]>>((i<<1)&0x1f))&1)<<1) ^ ((pbch->pbch_e[((i<<1)+1)>>5]>>(((i<<1)+1)&0x1f))&1);
mod_pbch_e[i<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; mod_pbch_e[i<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
mod_pbch_e[(i<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1)+1]; mod_pbch_e[(i<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1)+1];
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
printf("i %d idx %d mod_pbch %d %d\n", i, idx, mod_pbch_e[2*i], mod_pbch_e[2*i+1]); printf("i %d idx %d mod_pbch %d %d\n", i, idx, mod_pbch_e[2*i], mod_pbch_e[2*i+1]);
#endif #endif
} }
/// Resource mapping /// Resource mapping
nushift = config->sch_config.physical_cell_id.value &3; nushift = config->sch_config.physical_cell_id.value &3;
// PBCH modulated symbols are mapped within the SSB block on symbols 1, 2, 3 excluding the subcarriers used for the PBCH DMRS
///symbol 1 [0:239] -- 180 mod symbols
// PBCH modulated symbols are mapped within the SSB block on symbols 1, 2, 3 excluding the subcarriers used for the PBCH DMRS k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
///symbol 1 [0:239] -- 180 mod symbols l = ssb_start_symbol + 1;
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; m = 0;
l = ssb_start_symbol + 1;
m = 0; for (int ssb_sc_idx = 0; ssb_sc_idx < 240; ssb_sc_idx++) {
if ((ssb_sc_idx&3) == nushift) { //skip DMRS
for (int ssb_sc_idx = 0; ssb_sc_idx < 240; ssb_sc_idx++) { k++;
continue;
if ((ssb_sc_idx&3) == nushift) { //skip DMRS } else {
k++;
continue;
}
else {
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l); printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
#endif #endif
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15; ((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15;
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15; ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15;
k++; k++;
m++; m++;
}
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
} }
///symbol 2 [0:47 ; 192:239] -- 72 mod symbols if (k >= frame_parms->ofdm_symbol_size)
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; k-=frame_parms->ofdm_symbol_size;
l++; }
m=180;
for (int ssb_sc_idx = 0; ssb_sc_idx < 48; ssb_sc_idx++) { ///symbol 2 [0:47 ; 192:239] -- 72 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
l++;
m=180;
if ((ssb_sc_idx&3) == nushift) { for (int ssb_sc_idx = 0; ssb_sc_idx < 48; ssb_sc_idx++) {
k++; if ((ssb_sc_idx&3) == nushift) {
continue; k++;
} continue;
else { } else {
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l); printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
#endif #endif
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15; ((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15;
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15; ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15;
k++; k++;
m++; m++;
}
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
} }
k += 144;
if (k >= frame_parms->ofdm_symbol_size) if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size; k-=frame_parms->ofdm_symbol_size;
}
m=216; k += 144;
for (int ssb_sc_idx = 192; ssb_sc_idx < 240; ssb_sc_idx++) { if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
if ((ssb_sc_idx&3) == nushift) { m=216;
k++;
continue; for (int ssb_sc_idx = 192; ssb_sc_idx < 240; ssb_sc_idx++) {
} if ((ssb_sc_idx&3) == nushift) {
else { k++;
continue;
} else {
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l); printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
#endif #endif
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15; ((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15;
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15; ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15;
k++; k++;
m++; m++;
}
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
} }
///symbol 3 [0:239] -- 180 mod symbols if (k >= frame_parms->ofdm_symbol_size)
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; k-=frame_parms->ofdm_symbol_size;
l++; }
m=252;
for (int ssb_sc_idx = 0; ssb_sc_idx < 240; ssb_sc_idx++) { ///symbol 3 [0:239] -- 180 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
l++;
m=252;
if ((ssb_sc_idx&3) == nushift) { for (int ssb_sc_idx = 0; ssb_sc_idx < 240; ssb_sc_idx++) {
k++; if ((ssb_sc_idx&3) == nushift) {
continue; k++;
} continue;
else { } else {
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l); printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
#endif #endif
((int16_t*)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15; ((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15;
((int16_t*)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15; ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15;
k++; k++;
m++; m++;
}
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
} }
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
return 0; return 0;
} }
...@@ -36,7 +36,7 @@ int nr_generate_pss( int16_t *d_pss, ...@@ -36,7 +36,7 @@ int nr_generate_pss( int16_t *d_pss,
int32_t *txdataF, int32_t *txdataF,
int16_t amp, int16_t amp,
uint8_t ssb_start_symbol, uint8_t ssb_start_symbol,
nfapi_nr_config_request_t* config, nfapi_nr_config_request_t *config,
NR_DL_FRAME_PARMS *frame_parms); NR_DL_FRAME_PARMS *frame_parms);
/*! /*!
...@@ -49,7 +49,7 @@ int nr_generate_sss( int16_t *d_sss, ...@@ -49,7 +49,7 @@ int nr_generate_sss( int16_t *d_sss,
int32_t *txdataF, int32_t *txdataF,
int16_t amp, int16_t amp,
uint8_t ssb_start_symbol, uint8_t ssb_start_symbol,
nfapi_nr_config_request_t* config, nfapi_nr_config_request_t *config,
NR_DL_FRAME_PARMS *frame_parms); NR_DL_FRAME_PARMS *frame_parms);
/*! /*!
...@@ -62,7 +62,7 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, ...@@ -62,7 +62,7 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
int32_t *txdataF, int32_t *txdataF,
int16_t amp, int16_t amp,
uint8_t ssb_start_symbol, uint8_t ssb_start_symbol,
nfapi_nr_config_request_t* config, nfapi_nr_config_request_t *config,
NR_DL_FRAME_PARMS *frame_parms); NR_DL_FRAME_PARMS *frame_parms);
/*! /*!
...@@ -85,7 +85,6 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch, ...@@ -85,7 +85,6 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
@returns 0 on success @returns 0 on success
*/ */
int nr_generate_pbch(NR_gNB_PBCH *pbch, int nr_generate_pbch(NR_gNB_PBCH *pbch,
t_nrPolar_paramsPtr polar_params,
uint8_t *pbch_pdu, uint8_t *pbch_pdu,
uint8_t *interleaver, uint8_t *interleaver,
int32_t *txdataF, int32_t *txdataF,
...@@ -95,7 +94,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, ...@@ -95,7 +94,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
uint8_t Lmax, uint8_t Lmax,
uint8_t ssb_index, uint8_t ssb_index,
int sfn, int sfn,
nfapi_nr_config_request_t* config, nfapi_nr_config_request_t *config,
NR_DL_FRAME_PARMS *frame_parms); NR_DL_FRAME_PARMS *frame_parms);
/*! /*!
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
//#define DEBUG_PBCH_ENCODING //#define DEBUG_PBCH_ENCODING
#ifdef OPENAIR2 #ifdef OPENAIR2
//#include "PHY_INTERFACE/defs.h" //#include "PHY_INTERFACE/defs.h"
#endif #endif
#define PBCH_A 24 #define PBCH_A 24
...@@ -47,42 +47,39 @@ ...@@ -47,42 +47,39 @@
#define print_shorts(s,x) printf("%s : %d,%d,%d,%d,%d,%d,%d,%d\n",s,((int16_t*)x)[0],((int16_t*)x)[1],((int16_t*)x)[2],((int16_t*)x)[3],((int16_t*)x)[4],((int16_t*)x)[5],((int16_t*)x)[6],((int16_t*)x)[7]) #define print_shorts(s,x) printf("%s : %d,%d,%d,%d,%d,%d,%d,%d\n",s,((int16_t*)x)[0],((int16_t*)x)[1],((int16_t*)x)[2],((int16_t*)x)[3],((int16_t*)x)[4],((int16_t*)x)[5],((int16_t*)x)[6],((int16_t*)x)[7])
uint16_t nr_pbch_extract(int **rxdataF, uint16_t nr_pbch_extract(int **rxdataF,
int **dl_ch_estimates, int **dl_ch_estimates,
int **rxdataF_ext, int **rxdataF_ext,
int **dl_ch_estimates_ext, int **dl_ch_estimates_ext,
uint32_t symbol, uint32_t symbol,
uint32_t s_offset, uint32_t s_offset,
uint32_t high_speed_flag, uint32_t high_speed_flag,
NR_DL_FRAME_PARMS *frame_parms) NR_DL_FRAME_PARMS *frame_parms) {
{
uint16_t rb; uint16_t rb;
uint8_t i,j,aarx; uint8_t i,j,aarx;
int32_t *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; int32_t *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
int nushiftmod4 = frame_parms->nushift; int nushiftmod4 = frame_parms->nushift;
unsigned int rx_offset = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; //and unsigned int rx_offset = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; //and
if (rx_offset>= frame_parms->ofdm_symbol_size) rx_offset-=frame_parms->ofdm_symbol_size; if (rx_offset>= frame_parms->ofdm_symbol_size) rx_offset-=frame_parms->ofdm_symbol_size;
AssertFatal(symbol>=1 && symbol<5, AssertFatal(symbol>=1 && symbol<5,
"symbol %d illegal for PBCH extraction\n", "symbol %d illegal for PBCH extraction\n",
symbol); symbol);
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
rxF = &rxdataF[aarx][(symbol+s_offset)*frame_parms->ofdm_symbol_size]; rxF = &rxdataF[aarx][(symbol+s_offset)*frame_parms->ofdm_symbol_size];
rxF_ext = &rxdataF_ext[aarx][symbol*20*12]; rxF_ext = &rxdataF_ext[aarx][symbol*20*12];
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
printf("extract_rbs (nushift %d): rx_offset=%d, symbol %d\n",frame_parms->nushift, printf("extract_rbs (nushift %d): rx_offset=%d, symbol %d\n",frame_parms->nushift,
(rx_offset + ((symbol+s_offset)*(frame_parms->ofdm_symbol_size))),symbol); (rx_offset + ((symbol+s_offset)*(frame_parms->ofdm_symbol_size))),symbol);
int16_t *p = (int16_t *)rxF; int16_t *p = (int16_t *)rxF;
for (int i =0; i<8;i++){
printf("rxF [%d]= %d\n",i,rxF[i]); for (int i =0; i<8; i++) {
printf("pbch extract rxF %d %d addr %p\n", p[2*i], p[2*i+1], &p[2*i]); printf("rxF [%d]= %d\n",i,rxF[i]);
printf("rxF ext addr %p\n", &rxF_ext[i]); printf("pbch extract rxF %d %d addr %p\n", p[2*i], p[2*i+1], &p[2*i]);
} printf("rxF ext addr %p\n", &rxF_ext[i]);
}
#endif #endif
for (rb=0; rb<20; rb++) { for (rb=0; rb<20; rb++) {
...@@ -95,41 +92,43 @@ uint16_t nr_pbch_extract(int **rxdataF, ...@@ -95,41 +92,43 @@ uint16_t nr_pbch_extract(int **rxdataF,
(i!=(nushiftmod4+8))) { (i!=(nushiftmod4+8))) {
rxF_ext[j]=rxF[rx_offset]; rxF_ext[j]=rxF[rx_offset];
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
printf("rxF ext[%d] = (%d,%d) rxF [%d]= (%d,%d)\n",(9*rb) + j, printf("rxF ext[%d] = (%d,%d) rxF [%d]= (%d,%d)\n",(9*rb) + j,
((int16_t*)&rxF_ext[j])[0], ((int16_t *)&rxF_ext[j])[0],
((int16_t*)&rxF_ext[j])[1], ((int16_t *)&rxF_ext[j])[1],
rx_offset, rx_offset,
((int16_t*)&rxF[rx_offset])[0], ((int16_t *)&rxF[rx_offset])[0],
((int16_t*)&rxF[rx_offset])[1]); ((int16_t *)&rxF[rx_offset])[1]);
#endif #endif
j++; j++;
} }
rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1);
rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1);
} }
rxF_ext+=9; rxF_ext+=9;
} else { //symbol 2 } else { //symbol 2
if ((rb < 4) || (rb >15)){ if ((rb < 4) || (rb >15)) {
for (i=0; i<12; i++) { for (i=0; i<12; i++) {
if ((i!=nushiftmod4) && if ((i!=nushiftmod4) &&
(i!=(nushiftmod4+4)) && (i!=(nushiftmod4+4)) &&
(i!=(nushiftmod4+8))) { (i!=(nushiftmod4+8))) {
rxF_ext[j]=rxF[rx_offset]; rxF_ext[j]=rxF[rx_offset];
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
printf("rxF ext[%d] = (%d,%d) rxF [%d]= (%d,%d)\n",(rb<4) ? (9*rb) + j : (9*(rb-12))+j, printf("rxF ext[%d] = (%d,%d) rxF [%d]= (%d,%d)\n",(rb<4) ? (9*rb) + j : (9*(rb-12))+j,
((int16_t*)&rxF_ext[j])[0], ((int16_t *)&rxF_ext[j])[0],
((int16_t*)&rxF_ext[j])[1], ((int16_t *)&rxF_ext[j])[1],
rx_offset, rx_offset,
((int16_t*)&rxF[rx_offset])[0], ((int16_t *)&rxF[rx_offset])[0],
((int16_t*)&rxF[rx_offset])[1]); ((int16_t *)&rxF[rx_offset])[1]);
#endif #endif
j++; j++;
} }
rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1);
} rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1);
rxF_ext+=9; }
}
else rx_offset = (rx_offset+12)&(frame_parms->ofdm_symbol_size-1); rxF_ext+=9;
} else rx_offset = (rx_offset+12)&(frame_parms->ofdm_symbol_size-1);
} }
} }
...@@ -137,56 +136,59 @@ uint16_t nr_pbch_extract(int **rxdataF, ...@@ -137,56 +136,59 @@ uint16_t nr_pbch_extract(int **rxdataF,
dl_ch0 = &dl_ch_estimates[aarx][((symbol+s_offset)*(frame_parms->ofdm_symbol_size))]; dl_ch0 = &dl_ch_estimates[aarx][((symbol+s_offset)*(frame_parms->ofdm_symbol_size))];
else else
dl_ch0 = &dl_ch_estimates[aarx][0]; dl_ch0 = &dl_ch_estimates[aarx][0];
//printf("dl_ch0 addr %p\n",dl_ch0); //printf("dl_ch0 addr %p\n",dl_ch0);
dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*20*12]; dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*20*12];
for (rb=0; rb<20; rb++) { for (rb=0; rb<20; rb++) {
j=0; j=0;
if (symbol==1 || symbol==3) { if (symbol==1 || symbol==3) {
for (i=0; i<12; i++) { for (i=0; i<12; i++) {
if ((i!=nushiftmod4) && if ((i!=nushiftmod4) &&
(i!=(nushiftmod4+4)) && (i!=(nushiftmod4+4)) &&
(i!=(nushiftmod4+8))) { (i!=(nushiftmod4+8))) {
dl_ch0_ext[j]=dl_ch0[i]; dl_ch0_ext[j]=dl_ch0[i];
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
if ((rb==0) && (i<2))
printf("dl ch0 ext[%d] = (%d,%d) dl_ch0 [%d]= (%d,%d)\n",j, if ((rb==0) && (i<2))
((int16_t*)&dl_ch0_ext[j])[0], printf("dl ch0 ext[%d] = (%d,%d) dl_ch0 [%d]= (%d,%d)\n",j,
((int16_t*)&dl_ch0_ext[j])[1], ((int16_t *)&dl_ch0_ext[j])[0],
i, ((int16_t *)&dl_ch0_ext[j])[1],
((int16_t*)&dl_ch0[i])[0], i,
((int16_t*)&dl_ch0[i])[1]); ((int16_t *)&dl_ch0[i])[0],
((int16_t *)&dl_ch0[i])[1]);
#endif #endif
j++; j++;
} }
} }
dl_ch0+=12; dl_ch0+=12;
dl_ch0_ext+=9; dl_ch0_ext+=9;
} } else {
else { if ((rb < 4) || (rb >15)) {
if ((rb < 4) || (rb >15)){ for (i=0; i<12; i++) {
for (i=0; i<12; i++) { if ((i!=nushiftmod4) &&
if ((i!=nushiftmod4) && (i!=(nushiftmod4+4)) &&
(i!=(nushiftmod4+4)) && (i!=(nushiftmod4+8))) {
(i!=(nushiftmod4+8))) { dl_ch0_ext[j]=dl_ch0[i];
dl_ch0_ext[j]=dl_ch0[i];
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
printf("dl ch0 ext[%d] = (%d,%d) dl_ch0 [%d]= (%d,%d)\n",j, printf("dl ch0 ext[%d] = (%d,%d) dl_ch0 [%d]= (%d,%d)\n",j,
((int16_t*)&dl_ch0_ext[j])[0], ((int16_t *)&dl_ch0_ext[j])[0],
((int16_t*)&dl_ch0_ext[j])[1], ((int16_t *)&dl_ch0_ext[j])[1],
i, i,
((int16_t*)&dl_ch0[i])[0], ((int16_t *)&dl_ch0[i])[0],
((int16_t*)&dl_ch0[i])[1]); ((int16_t *)&dl_ch0[i])[1]);
#endif #endif
j++; j++;
} }
} }
dl_ch0_ext+=9;
} dl_ch0_ext+=9;
dl_ch0+=12; }
dl_ch0+=12;
} }
} }
} }
...@@ -198,13 +200,10 @@ uint16_t nr_pbch_extract(int **rxdataF, ...@@ -198,13 +200,10 @@ uint16_t nr_pbch_extract(int **rxdataF,
//compute average channel_level on each (TX,RX) antenna pair //compute average channel_level on each (TX,RX) antenna pair
int nr_pbch_channel_level(int **dl_ch_estimates_ext, int nr_pbch_channel_level(int **dl_ch_estimates_ext,
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
uint32_t symbol) uint32_t symbol) {
{
int16_t rb, nb_rb=20; int16_t rb, nb_rb=20;
uint8_t aarx; uint8_t aarx;
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
__m128i avg128; __m128i avg128;
__m128i *dl_ch128; __m128i *dl_ch128;
...@@ -216,75 +215,70 @@ int nr_pbch_channel_level(int **dl_ch_estimates_ext, ...@@ -216,75 +215,70 @@ int nr_pbch_channel_level(int **dl_ch_estimates_ext,
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
//clear average level //clear average level
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
avg128 = _mm_setzero_si128(); avg128 = _mm_setzero_si128();
dl_ch128=(__m128i *)&dl_ch_estimates_ext[aarx][symbol*20*12]; dl_ch128=(__m128i *)&dl_ch_estimates_ext[aarx][symbol*20*12];
#elif defined(__arm__) #elif defined(__arm__)
avg128 = vdupq_n_s32(0); avg128 = vdupq_n_s32(0);
dl_ch128=(int16x8_t *)&dl_ch_estimates_ext[aarx][symbol*20*12]; dl_ch128=(int16x8_t *)&dl_ch_estimates_ext[aarx][symbol*20*12];
#endif #endif
for (rb=0; rb<nb_rb; rb++) { for (rb=0; rb<nb_rb; rb++) {
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0])); avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0]));
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[1],dl_ch128[1])); avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[1],dl_ch128[1]));
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[2],dl_ch128[2])); avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[2],dl_ch128[2]));
#elif defined(__arm__) #elif defined(__arm__)
// to be filled in // to be filled in
#endif #endif
dl_ch128+=3; dl_ch128+=3;
/* /*
if (rb==0) { if (rb==0) {
print_shorts("dl_ch128",&dl_ch128[0]); print_shorts("dl_ch128",&dl_ch128[0]);
print_shorts("dl_ch128",&dl_ch128[1]); print_shorts("dl_ch128",&dl_ch128[1]);
print_shorts("dl_ch128",&dl_ch128[2]); print_shorts("dl_ch128",&dl_ch128[2]);
}*/ }*/
} }
avg1 = (((int*)&avg128)[0] + avg1 = (((int *)&avg128)[0] +
((int*)&avg128)[1] + ((int *)&avg128)[1] +
((int*)&avg128)[2] + ((int *)&avg128)[2] +
((int*)&avg128)[3])/(nb_rb*12); ((int *)&avg128)[3])/(nb_rb*12);
if (avg1>avg2) if (avg1>avg2)
avg2 = avg1; avg2 = avg1;
//LOG_I(PHY,"Channel level : %d, %d\n",avg1, avg2); //LOG_I(PHY,"Channel level : %d, %d\n",avg1, avg2);
} }
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
_mm_empty(); _mm_empty();
_m_empty(); _m_empty();
#endif #endif
return(avg2); return(avg2);
} }
void nr_pbch_channel_compensation(int **rxdataF_ext, void nr_pbch_channel_compensation(int **rxdataF_ext,
int **dl_ch_estimates_ext, int **dl_ch_estimates_ext,
int **rxdataF_comp, int **rxdataF_comp,
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
uint32_t symbol, uint32_t symbol,
uint8_t output_shift) { uint8_t output_shift) {
const uint16_t nb_re=symbol == 2 ? 72 : 180; const uint16_t nb_re=symbol == 2 ? 72 : 180;
AssertFatal((symbol > 0 && symbol < 4), AssertFatal((symbol > 0 && symbol < 4),
"symbol %d is illegal for PBCH DM-RS\n", "symbol %d is illegal for PBCH DM-RS\n",
symbol); symbol);
// printf("comp: symbol %d : nb_re %d\n",symbol,nb_re); // printf("comp: symbol %d : nb_re %d\n",symbol,nb_re);
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
vect128 *dl_ch128 = (vect128 *)&dl_ch_estimates_ext[aarx][symbol*20*12]; vect128 *dl_ch128 = (vect128 *)&dl_ch_estimates_ext[aarx][symbol*20*12];
vect128 *rxdataF128 = (vect128 *)&rxdataF_ext[aarx][symbol*20*12]; vect128 *rxdataF128 = (vect128 *)&rxdataF_ext[aarx][symbol*20*12];
vect128 *rxdataF_comp128 = (vect128 *)&rxdataF_comp[aarx][symbol*20*12]; vect128 *rxdataF_comp128 = (vect128 *)&rxdataF_comp[aarx][symbol*20*12];
/* /*
printf("ch compensation dl_ch ext addr %p \n", &dl_ch_estimates_ext[aarx][symbol*20*12]); printf("ch compensation dl_ch ext addr %p \n", &dl_ch_estimates_ext[aarx][symbol*20*12]);
printf("rxdataf ext addr %p symbol %d\n", &rxdataF_ext[aarx][symbol*20*12], symbol); printf("rxdataf ext addr %p symbol %d\n", &rxdataF_ext[aarx][symbol*20*12], symbol);
printf("rxdataf_comp addr %p\n",&rxdataF_comp[aarx][symbol*20*12]); printf("rxdataf_comp addr %p\n",&rxdataF_comp[aarx][symbol*20*12]);
*/ */
for (int re=0; re<nb_re; re+=12) { for (int re=0; re<nb_re; re+=12) {
...@@ -296,10 +290,8 @@ void nr_pbch_channel_compensation(int **rxdataF_ext, ...@@ -296,10 +290,8 @@ void nr_pbch_channel_compensation(int **rxdataF_ext,
} }
void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
int **rxdataF_comp, int **rxdataF_comp,
uint8_t symbol) uint8_t symbol) {
{
uint8_t symbol_mod; uint8_t symbol_mod;
int i, nb_rb=6; int i, nb_rb=6;
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
...@@ -311,23 +303,22 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, ...@@ -311,23 +303,22 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
if (frame_parms->nb_antennas_rx>1) { if (frame_parms->nb_antennas_rx>1) {
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][symbol_mod*6*12]; rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][symbol_mod*6*12];
rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[1][symbol_mod*6*12]; rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[1][symbol_mod*6*12];
#elif defined(__arm__) #elif defined(__arm__)
rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[0][symbol_mod*6*12]; rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[0][symbol_mod*6*12];
rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[1][symbol_mod*6*12]; rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[1][symbol_mod*6*12];
#endif #endif
// MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
for (i=0; i<nb_rb*3; i++) { // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
for (i=0; i<nb_rb*3; i++) {
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1)); rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
#elif defined(__arm__) #elif defined(__arm__)
rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]); rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
#endif #endif
}
} }
}
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
_mm_empty(); _mm_empty();
...@@ -336,19 +327,16 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, ...@@ -336,19 +327,16 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
} }
void nr_pbch_unscrambling(NR_UE_PBCH *pbch, void nr_pbch_unscrambling(NR_UE_PBCH *pbch,
uint16_t Nid, uint16_t Nid,
uint8_t nushift, uint8_t nushift,
uint16_t M, uint16_t M,
uint16_t length, uint16_t length,
uint8_t bitwise, uint8_t bitwise,
uint32_t unscrambling_mask) uint32_t unscrambling_mask) {
{
uint8_t reset, offset; uint8_t reset, offset;
uint32_t x1, x2, s=0; uint32_t x1, x2, s=0;
uint8_t k=0; uint8_t k=0;
int16_t *demod_pbch_e = pbch->llr; int16_t *demod_pbch_e = pbch->llr;
reset = 1; reset = 1;
// x1 is set in first call to lte_gold_generic // x1 is set in first call to lte_gold_generic
x2 = Nid; //this is c_init x2 = Nid; //this is c_init
...@@ -358,48 +346,49 @@ void nr_pbch_unscrambling(NR_UE_PBCH *pbch, ...@@ -358,48 +346,49 @@ void nr_pbch_unscrambling(NR_UE_PBCH *pbch,
s = lte_gold_generic(&x1, &x2, reset); s = lte_gold_generic(&x1, &x2, reset);
reset = 0; reset = 0;
} }
// Scrambling is now done with offset (nushift*M)%32 // Scrambling is now done with offset (nushift*M)%32
offset = (nushift*M)&0x1f; offset = (nushift*M)&0x1f;
for (int i=0; i<length; i++) { for (int i=0; i<length; i++) {
/*if (((i+offset)&0x1f)==0) { /*if (((i+offset)&0x1f)==0) {
s = lte_gold_generic(&x1, &x2, reset); s = lte_gold_generic(&x1, &x2, reset);
reset = 0; reset = 0;
}*/ }*/
if (bitwise) {
if (bitwise) {
if (((k+offset)&0x1f)==0 && (!((unscrambling_mask>>i)&1))) { if (((k+offset)&0x1f)==0 && (!((unscrambling_mask>>i)&1))) {
s = lte_gold_generic(&x1, &x2, reset); s = lte_gold_generic(&x1, &x2, reset);
reset = 0; reset = 0;
} }
(pbch->pbch_a_interleaved) ^= ((unscrambling_mask>>i)&1)? ((pbch->pbch_a_prime>>i)&1)<<i : (((pbch->pbch_a_prime>>i)&1) ^ ((s>>((k+offset)&0x1f))&1))<<i;
k += (!((unscrambling_mask>>i)&1)); (pbch->pbch_a_interleaved) ^= ((unscrambling_mask>>i)&1)? ((pbch->pbch_a_prime>>i)&1)<<i : (((pbch->pbch_a_prime>>i)&1) ^ ((s>>((k+offset)&0x1f))&1))<<i;
k += (!((unscrambling_mask>>i)&1));
#ifdef DEBUG_PBCH_ENCODING #ifdef DEBUG_PBCH_ENCODING
printf("i %d k %d offset %d (unscrambling_mask>>i)&1) %d s: %08x\t pbch_a_interleaved 0x%08x (!((unscrambling_mask>>i)&1)) %d\n", i, k, offset, (unscrambling_mask>>i)&1, s, pbch->pbch_a_interleaved, (!((unscrambling_mask>>i)&1))); printf("i %d k %d offset %d (unscrambling_mask>>i)&1) %d s: %08x\t pbch_a_interleaved 0x%08x (!((unscrambling_mask>>i)&1)) %d\n", i, k, offset, (unscrambling_mask>>i)&1, s, pbch->pbch_a_interleaved,
(!((unscrambling_mask>>i)&1)));
#endif #endif
} } else {
else {
if (((i+offset)&0x1f)==0) { if (((i+offset)&0x1f)==0) {
s = lte_gold_generic(&x1, &x2, reset); s = lte_gold_generic(&x1, &x2, reset);
reset = 0; reset = 0;
} }
if (((s>>((i+offset)&0x1f))&1)==1)
demod_pbch_e[i] = -demod_pbch_e[i]; if (((s>>((i+offset)&0x1f))&1)==1)
demod_pbch_e[i] = -demod_pbch_e[i];
#ifdef DEBUG_PBCH_ENCODING #ifdef DEBUG_PBCH_ENCODING
if (i<8)
printf("s %d demod_pbch_e[i] %d\n", ((s>>((i+offset)&0x1f))&1), demod_pbch_e[i]); if (i<8)
printf("s %d demod_pbch_e[i] %d\n", ((s>>((i+offset)&0x1f))&1), demod_pbch_e[i]);
#endif #endif
} }
} }
} }
void nr_pbch_quantize(int16_t *pbch_llr8, void nr_pbch_quantize(int16_t *pbch_llr8,
int16_t *pbch_llr, int16_t *pbch_llr,
uint16_t len) uint16_t len) {
{
uint16_t i; uint16_t i;
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
...@@ -409,7 +398,6 @@ void nr_pbch_quantize(int16_t *pbch_llr8, ...@@ -409,7 +398,6 @@ void nr_pbch_quantize(int16_t *pbch_llr8,
pbch_llr8[i]=-32; pbch_llr8[i]=-32;
else else
pbch_llr8[i] = (char)(pbch_llr[i]); pbch_llr8[i] = (char)(pbch_llr[i]);
} }
} }
/* /*
...@@ -419,20 +407,16 @@ unsigned char sign(int8_t x) { ...@@ -419,20 +407,16 @@ unsigned char sign(int8_t x) {
*/ */
uint8_t pbch_deinterleaving_pattern[32] = {28,0,31,30,7,29,25,27,5,8,24,9,10,11,12,13,1,4,3,14,15,16,17,2,26,18,19,20,21,22,6,23}; uint8_t pbch_deinterleaving_pattern[32] = {28,0,31,30,7,29,25,27,5,8,24,9,10,11,12,13,1,4,3,14,15,16,17,2,26,18,19,20,21,22,6,23};
int nr_rx_pbch( PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
NR_UE_PBCH *nr_ue_pbch_vars,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t eNB_id,
MIMO_mode_t mimo_mode,
uint32_t high_speed_flag)
{
int nr_rx_pbch( PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
NR_UE_PBCH *nr_ue_pbch_vars,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t eNB_id,
MIMO_mode_t mimo_mode,
uint32_t high_speed_flag) {
NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars; NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars;
int max_h=0; int max_h=0;
int symbol; int symbol;
//uint8_t pbch_a[64]; //uint8_t pbch_a[64];
uint8_t *pbch_a = malloc(sizeof(uint8_t) * 32); uint8_t *pbch_a = malloc(sizeof(uint8_t) * 32);
...@@ -447,44 +431,37 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, ...@@ -447,44 +431,37 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
//unsigned short idx_demod =0; //unsigned short idx_demod =0;
uint32_t decoderState=0; uint32_t decoderState=0;
//uint8_t decoderListSize = 8, pathMetricAppr = 0; //uint8_t decoderListSize = 8, pathMetricAppr = 0;
//time_stats_t polar_decoder_init,polar_rate_matching,decoding,bit_extraction,deinterleaving; //time_stats_t polar_decoder_init,polar_rate_matching,decoding,bit_extraction,deinterleaving;
//time_stats_t path_metric,sorting,update_LLR; //time_stats_t path_metric,sorting,update_LLR;
memset(&pbch_a[0], 0, sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS); memset(&pbch_a[0], 0, sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS);
//printf("nr_pbch_ue nid_cell %d\n",frame_parms->Nid_cell); //printf("nr_pbch_ue nid_cell %d\n",frame_parms->Nid_cell);
int subframe_rx = proc->subframe_rx; int subframe_rx = proc->subframe_rx;
pbch_e_rx = &nr_ue_pbch_vars->llr[0]; pbch_e_rx = &nr_ue_pbch_vars->llr[0];
// clear LLR buffer // clear LLR buffer
memset(nr_ue_pbch_vars->llr,0,NR_POLAR_PBCH_E); memset(nr_ue_pbch_vars->llr,0,NR_POLAR_PBCH_E);
int symbol_offset=1; int symbol_offset=1;
if (ue->is_synchronized > 0) if (ue->is_synchronized > 0)
symbol_offset=4; symbol_offset=4;
else else
symbol_offset=0; symbol_offset=0;
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
//printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF); //printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF);
write_output("rxdataF0_pbch.m","rxF0pbch", write_output("rxdataF0_pbch.m","rxF0pbch",
&nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1); &nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1);
#endif #endif
// symbol refers to symbol within SSB. symbol_offset is the offset of the SSB wrt start of slot // symbol refers to symbol within SSB. symbol_offset is the offset of the SSB wrt start of slot
for (symbol=1; symbol<4; symbol++) { for (symbol=1; symbol<4; symbol++) {
nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF, nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF,
nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].dl_ch_estimates[eNB_id], nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].dl_ch_estimates[eNB_id],
nr_ue_pbch_vars->rxdataF_ext, nr_ue_pbch_vars->rxdataF_ext,
nr_ue_pbch_vars->dl_ch_estimates_ext, nr_ue_pbch_vars->dl_ch_estimates_ext,
symbol, symbol,
symbol_offset, symbol_offset,
high_speed_flag, high_speed_flag,
frame_parms); frame_parms);
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
LOG_I(PHY,"[PHY] PBCH Symbol %d ofdm size %d\n",symbol, frame_parms->ofdm_symbol_size ); LOG_I(PHY,"[PHY] PBCH Symbol %d ofdm size %d\n",symbol, frame_parms->ofdm_symbol_size );
LOG_I(PHY,"[PHY] PBCH starting channel_level\n"); LOG_I(PHY,"[PHY] PBCH starting channel_level\n");
...@@ -492,113 +469,90 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, ...@@ -492,113 +469,90 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
if (symbol == 1) { if (symbol == 1) {
max_h = nr_pbch_channel_level(nr_ue_pbch_vars->dl_ch_estimates_ext, max_h = nr_pbch_channel_level(nr_ue_pbch_vars->dl_ch_estimates_ext,
frame_parms, frame_parms,
symbol); symbol);
nr_ue_pbch_vars->log2_maxh = 3+(log2_approx(max_h)/2); nr_ue_pbch_vars->log2_maxh = 3+(log2_approx(max_h)/2);
} }
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
LOG_I(PHY,"[PHY] PBCH log2_maxh = %d (%d)\n",nr_ue_pbch_vars->log2_maxh,max_h); LOG_I(PHY,"[PHY] PBCH log2_maxh = %d (%d)\n",nr_ue_pbch_vars->log2_maxh,max_h);
#endif #endif
nr_pbch_channel_compensation(nr_ue_pbch_vars->rxdataF_ext, nr_pbch_channel_compensation(nr_ue_pbch_vars->rxdataF_ext,
nr_ue_pbch_vars->dl_ch_estimates_ext, nr_ue_pbch_vars->dl_ch_estimates_ext,
nr_ue_pbch_vars->rxdataF_comp, nr_ue_pbch_vars->rxdataF_comp,
frame_parms, frame_parms,
symbol, symbol,
nr_ue_pbch_vars->log2_maxh); // log2_maxh+I0_shift nr_ue_pbch_vars->log2_maxh); // log2_maxh+I0_shift
/*if (frame_parms->nb_antennas_rx > 1) /*if (frame_parms->nb_antennas_rx > 1)
pbch_detection_mrc(frame_parms, pbch_detection_mrc(frame_parms,
nr_ue_pbch_vars->rxdataF_comp, nr_ue_pbch_vars->rxdataF_comp,
symbol);*/ symbol);*/
/* /*
if (mimo_mode == ALAMOUTI) { if (mimo_mode == ALAMOUTI) {
nr_pbch_alamouti(frame_parms,nr_ue_pbch_vars->rxdataF_comp,symbol); nr_pbch_alamouti(frame_parms,nr_ue_pbch_vars->rxdataF_comp,symbol);
} else if (mimo_mode != SISO) { } else if (mimo_mode != SISO) {
LOG_I(PHY,"[PBCH][RX] Unsupported MIMO mode\n"); LOG_I(PHY,"[PBCH][RX] Unsupported MIMO mode\n");
return(-1); return(-1);
} }
*/ */
if (symbol==1) { if (symbol==1) {
nr_pbch_quantize(pbch_e_rx, nr_pbch_quantize(pbch_e_rx,
(short*)&(nr_ue_pbch_vars->rxdataF_comp[0][symbol*240]), (short *)&(nr_ue_pbch_vars->rxdataF_comp[0][symbol*240]),
144); 144);
pbch_e_rx+=144; pbch_e_rx+=144;
} else { } else {
nr_pbch_quantize(pbch_e_rx, nr_pbch_quantize(pbch_e_rx,
(short*)&(nr_ue_pbch_vars->rxdataF_comp[0][symbol*240]), (short *)&(nr_ue_pbch_vars->rxdataF_comp[0][symbol*240]),
360); 360);
pbch_e_rx+=360; pbch_e_rx+=360;
} }
} }
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
write_output("rxdataF_comp.m","rxFcomp",&nr_ue_pbch_vars->rxdataF_comp[0][240],240*3,1,1); write_output("rxdataF_comp.m","rxFcomp",&nr_ue_pbch_vars->rxdataF_comp[0][240],240*3,1,1);
#endif #endif
pbch_e_rx = nr_ue_pbch_vars->llr; pbch_e_rx = nr_ue_pbch_vars->llr;
//demod_pbch_e = nr_ue_pbch_vars->demod_pbch_e; //demod_pbch_e = nr_ue_pbch_vars->demod_pbch_e;
pbch_a = nr_ue_pbch_vars->pbch_a; pbch_a = nr_ue_pbch_vars->pbch_a;
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
//pbch_e_rx = &nr_ue_pbch_vars->llr[0]; //pbch_e_rx = &nr_ue_pbch_vars->llr[0];
short *p = (short *)&(nr_ue_pbch_vars->rxdataF_comp[0][20*12]); short *p = (short *)&(nr_ue_pbch_vars->rxdataF_comp[0][20*12]);
for (int cnt = 0; cnt < 864 ; cnt++) for (int cnt = 0; cnt < 864 ; cnt++)
printf("pbch rx llr %d\n",*(pbch_e_rx+cnt)); printf("pbch rx llr %d\n",*(pbch_e_rx+cnt));
#endif #endif
//un-scrambling //un-scrambling
M = NR_POLAR_PBCH_E; M = NR_POLAR_PBCH_E;
nushift = (Lmax==4)? ssb_index&3 : ssb_index&7; nushift = (Lmax==4)? ssb_index&3 : ssb_index&7;
uint32_t unscrambling_mask = (Lmax==64)?0x100006D:0x1000041; uint32_t unscrambling_mask = (Lmax==64)?0x100006D:0x1000041;
nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_E,0,0); nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_E,0,0);
//polar decoding de-rate matching //polar decoding de-rate matching
const t_nrPolar_params *currentPtr = nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL);
decoderState = polar_decoder_int16(pbch_e_rx,(uint64_t *)&nr_ue_pbch_vars->pbch_a_prime,currentPtr);
nr_polar_init(&nr_ue_pbch_vars->nrPolar_params,
NR_POLAR_PBCH_MESSAGE_TYPE,
NR_POLAR_PBCH_PAYLOAD_BITS,
NR_POLAR_PBCH_AGGREGATION_LEVEL);
AssertFatal(nr_ue_pbch_vars->nrPolar_params != NULL,"nr_ue_pbch_vars->nrPolar_params is null\n");
t_nrPolar_params *currentPtr = nr_polar_params(nr_ue_pbch_vars->nrPolar_params, NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL);
decoderState = polar_decoder_int16(pbch_e_rx,(uint64_t*)&nr_ue_pbch_vars->pbch_a_prime,currentPtr);
if(decoderState) return(decoderState); if(decoderState) return(decoderState);
// printf("polar decoder output 0x%08x\n",nr_ue_pbch_vars->pbch_a_prime);
// printf("polar decoder output 0x%08x\n",nr_ue_pbch_vars->pbch_a_prime);
// Decoder reversal // Decoder reversal
uint32_t a_reversed=0; uint32_t a_reversed=0;
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++) for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++)
a_reversed |= (((uint64_t)nr_ue_pbch_vars->pbch_a_prime>>i)&1)<<(31-i); a_reversed |= (((uint64_t)nr_ue_pbch_vars->pbch_a_prime>>i)&1)<<(31-i);
nr_ue_pbch_vars->pbch_a_prime = a_reversed; nr_ue_pbch_vars->pbch_a_prime = a_reversed;
//payload un-scrambling //payload un-scrambling
memset(&nr_ue_pbch_vars->pbch_a_interleaved, 0, sizeof(uint32_t) ); memset(&nr_ue_pbch_vars->pbch_a_interleaved, 0, sizeof(uint32_t) );
M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3); M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3);
nushift = ((nr_ue_pbch_vars->pbch_a_prime>>24)&1) ^ (((nr_ue_pbch_vars->pbch_a_prime>>6)&1)<<1); nushift = ((nr_ue_pbch_vars->pbch_a_prime>>24)&1) ^ (((nr_ue_pbch_vars->pbch_a_prime>>6)&1)<<1);
nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_PAYLOAD_BITS,1,unscrambling_mask); nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_PAYLOAD_BITS,1,unscrambling_mask);
//printf("nushift %d sfn 3rd %d 2nd %d", nushift,((nr_ue_pbch_vars->pbch_a_prime>>6)&1), ((nr_ue_pbch_vars->pbch_a_prime>>24)&1) ); //printf("nushift %d sfn 3rd %d 2nd %d", nushift,((nr_ue_pbch_vars->pbch_a_prime>>6)&1), ((nr_ue_pbch_vars->pbch_a_prime>>24)&1) );
//payload deinterleaving //payload deinterleaving
//uint32_t in=0; //uint32_t in=0;
uint32_t out=0; uint32_t out=0;
for (int i=0; i<32; i++) { for (int i=0; i<32; i++) {
out |= ((nr_ue_pbch_vars->pbch_a_interleaved>>i)&1)<<(pbch_deinterleaving_pattern[i]); out |= ((nr_ue_pbch_vars->pbch_a_interleaved>>i)&1)<<(pbch_deinterleaving_pattern[i]);
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
...@@ -606,36 +560,37 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, ...@@ -606,36 +560,37 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
#endif #endif
} }
uint32_t payload = 0; uint32_t payload = 0;
uint8_t xtra_byte = 0; uint8_t xtra_byte = 0;
xtra_byte = (out>>24)&0xff; xtra_byte = (out>>24)&0xff;
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++) for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++)
payload |= ((out>>i)&1)<<(NR_POLAR_PBCH_PAYLOAD_BITS-i-1); payload |= ((out>>i)&1)<<(NR_POLAR_PBCH_PAYLOAD_BITS-i-1);
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
decoded_output[i] = (uint8_t)((payload>>((3-i)<<3))&0xff); decoded_output[i] = (uint8_t)((payload>>((3-i)<<3))&0xff);
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
printf("xtra_byte %x payload %x\n", xtra_byte, payload); printf("xtra_byte %x payload %x\n", xtra_byte, payload);
for (int i=0; i<(NR_POLAR_PBCH_PAYLOAD_BITS>>3); i++){
// printf("unscrambling pbch_a[%d] = %x \n", i,pbch_a[i]);
printf("[PBCH] decoder payload[%d] = %x\n",i,decoded_output[i]);
}
#endif
ue->dl_indication.rx_ind = &ue->rx_ind; // hang on rx_ind instance for (int i=0; i<(NR_POLAR_PBCH_PAYLOAD_BITS>>3); i++) {
//ue->rx_ind.sfn_slot = 0; //should be set by higher-1-layer, i.e. clean_and_set_if_instance() // printf("unscrambling pbch_a[%d] = %x \n", i,pbch_a[i]);
ue->rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_MIB; printf("[PBCH] decoder payload[%d] = %x\n",i,decoded_output[i]);
ue->rx_ind.rx_indication_body[0].mib_pdu.pdu = &decoded_output[0]; }
ue->rx_ind.rx_indication_body[0].mib_pdu.additional_bits = xtra_byte;
ue->rx_ind.rx_indication_body[0].mib_pdu.ssb_index = ssb_index; // confirm with TCL
ue->rx_ind.rx_indication_body[0].mib_pdu.ssb_length = Lmax; // confirm with TCL
ue->rx_ind.rx_indication_body[0].mib_pdu.cell_id = frame_parms->Nid_cell; // confirm with TCL
ue->rx_ind.number_pdus = 1;
if (ue->if_inst && ue->if_inst->dl_indication)
ue->if_inst->dl_indication(&ue->dl_indication);
return 0; #endif
ue->dl_indication.rx_ind = &ue->rx_ind; // hang on rx_ind instance
//ue->rx_ind.sfn_slot = 0; //should be set by higher-1-layer, i.e. clean_and_set_if_instance()
ue->rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_MIB;
ue->rx_ind.rx_indication_body[0].mib_pdu.pdu = &decoded_output[0];
ue->rx_ind.rx_indication_body[0].mib_pdu.additional_bits = xtra_byte;
ue->rx_ind.rx_indication_body[0].mib_pdu.ssb_index = ssb_index; // confirm with TCL
ue->rx_ind.rx_indication_body[0].mib_pdu.ssb_length = Lmax; // confirm with TCL
ue->rx_ind.rx_indication_body[0].mib_pdu.cell_id = frame_parms->Nid_cell; // confirm with TCL
ue->rx_ind.number_pdus = 1;
if (ue->if_inst && ue->if_inst->dl_indication)
ue->if_inst->dl_indication(&ue->dl_indication);
return 0;
} }
...@@ -391,7 +391,6 @@ typedef struct PHY_VARS_gNB_s { ...@@ -391,7 +391,6 @@ typedef struct PHY_VARS_gNB_s {
Sched_Rsp_t Sched_INFO; Sched_Rsp_t Sched_INFO;
NR_gNB_PDCCH pdcch_vars; NR_gNB_PDCCH pdcch_vars;
NR_gNB_PBCH pbch; NR_gNB_PBCH pbch;
t_nrPolar_paramsPtr nrPolar_params;
LTE_eNB_PHICH phich_vars[2]; LTE_eNB_PHICH phich_vars[2];
NR_gNB_COMMON common_vars; NR_gNB_COMMON common_vars;
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h" #include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#define _GNU_SOURCE #define _GNU_SOURCE
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <malloc.h> #include <malloc.h>
...@@ -49,28 +49,28 @@ ...@@ -49,28 +49,28 @@
//#include <complex.h> //#include <complex.h>
#include "assertions.h" #include "assertions.h"
#ifdef MEX #ifdef MEX
# define msg mexPrintf #define msg mexPrintf
#else #else
# ifdef OPENAIR2 #ifdef OPENAIR2
# if ENABLE_RAL #if ENABLE_RAL
# include "collection/hashtable/hashtable.h" #include "collection/hashtable/hashtable.h"
# include "COMMON/ral_messages_types.h" #include "COMMON/ral_messages_types.h"
# include "UTIL/queue.h" #include "UTIL/queue.h"
# endif #endif
# define msg(aRGS...) LOG_D(PHY, ##aRGS) #define msg(aRGS...) LOG_D(PHY, ##aRGS)
# else #else
# define msg printf #define msg printf
# endif #endif
#endif #endif
//use msg in the real-time thread context //use msg in the real-time thread context
#define msg_nrt printf #define msg_nrt printf
//use msg_nrt in the non real-time context (for initialization, ...) //use msg_nrt in the non real-time context (for initialization, ...)
#ifndef malloc16 #ifndef malloc16
# ifdef __AVX2__ #ifdef __AVX2__
# define malloc16(x) memalign(32,x) #define malloc16(x) memalign(32,x)
# else #else
# define malloc16(x) memalign(16,x) #define malloc16(x) memalign(16,x)
# endif #endif
#endif #endif
#define free16(y,x) free(y) #define free16(y,x) free(y)
#define bigmalloc malloc #define bigmalloc malloc
...@@ -146,7 +146,7 @@ ...@@ -146,7 +146,7 @@
#if defined(UPGRADE_RAT_NR) #if defined(UPGRADE_RAT_NR)
#include "PHY/NR_REFSIG/ss_pbch_nr.h" #include "PHY/NR_REFSIG/ss_pbch_nr.h"
#endif #endif
...@@ -167,12 +167,12 @@ typedef struct { ...@@ -167,12 +167,12 @@ typedef struct {
uint8_t CC_id; uint8_t CC_id;
/// timestamp transmitted to HW /// timestamp transmitted to HW
openair0_timestamp timestamp_tx; openair0_timestamp timestamp_tx;
//#ifdef UE_NR_PHY_DEMO //#ifdef UE_NR_PHY_DEMO
/// NR TTI index within subframe_tx [0 .. ttis_per_subframe - 1] to act upon for transmission /// NR TTI index within subframe_tx [0 .. ttis_per_subframe - 1] to act upon for transmission
int nr_tti_tx; int nr_tti_tx;
/// NR TTI index within subframe_rx [0 .. ttis_per_subframe - 1] to act upon for reception /// NR TTI index within subframe_rx [0 .. ttis_per_subframe - 1] to act upon for reception
int nr_tti_rx; int nr_tti_rx;
//#endif //#endif
/// subframe to act upon for transmission /// subframe to act upon for transmission
int subframe_tx; int subframe_tx;
/// subframe to act upon for reception /// subframe to act upon for reception
...@@ -202,7 +202,7 @@ typedef struct { ...@@ -202,7 +202,7 @@ typedef struct {
//pthread_t pthread_slot0_dl_processing; //pthread_t pthread_slot0_dl_processing;
pthread_t pthread_slot1_dl_processing; pthread_t pthread_slot1_dl_processing;
/// pthread attributes for fep_slot1 processing thread /// pthread attributes for fep_slot1 processing thread
// pthread_attr_t attr_slot0_dl_processing; // pthread_attr_t attr_slot0_dl_processing;
pthread_attr_t attr_slot1_dl_processing; pthread_attr_t attr_slot1_dl_processing;
/// condition variable for UE fep_slot1 thread; /// condition variable for UE fep_slot1 thread;
//pthread_cond_t cond_slot0_dl_processing; //pthread_cond_t cond_slot0_dl_processing;
...@@ -216,7 +216,7 @@ typedef struct { ...@@ -216,7 +216,7 @@ typedef struct {
//pthread_t pthread_slot0_dl_processing; //pthread_t pthread_slot0_dl_processing;
pthread_t pthread_dlsch_td; pthread_t pthread_dlsch_td;
/// pthread attributes for fep_slot1 processing thread /// pthread attributes for fep_slot1 processing thread
// pthread_attr_t attr_slot0_dl_processing; // pthread_attr_t attr_slot0_dl_processing;
pthread_attr_t attr_dlsch_td; pthread_attr_t attr_dlsch_td;
/// condition variable for UE fep_slot1 thread; /// condition variable for UE fep_slot1 thread;
//pthread_cond_t cond_slot0_dl_processing; //pthread_cond_t cond_slot0_dl_processing;
...@@ -250,7 +250,7 @@ typedef struct { ...@@ -250,7 +250,7 @@ typedef struct {
//pthread_t pthread_slot0_dl_processing; //pthread_t pthread_slot0_dl_processing;
pthread_t pthread_dlsch_td1; pthread_t pthread_dlsch_td1;
/// pthread attributes for fep_slot1 processing thread /// pthread attributes for fep_slot1 processing thread
// pthread_attr_t attr_slot0_dl_processing; // pthread_attr_t attr_slot0_dl_processing;
pthread_attr_t attr_dlsch_td1; pthread_attr_t attr_dlsch_td1;
/// condition variable for UE fep_slot1 thread; /// condition variable for UE fep_slot1 thread;
//pthread_cond_t cond_slot0_dl_processing; //pthread_cond_t cond_slot0_dl_processing;
...@@ -394,23 +394,23 @@ typedef struct { ...@@ -394,23 +394,23 @@ typedef struct {
typedef struct { typedef struct {
/// \brief Holds the received data in the frequency domain. /// \brief Holds the received data in the frequency domain.
/// - first index: rx antenna [0..nb_antennas_rx[ /// - first index: rx antenna [0..nb_antennas_rx[
/// - second index: symbol [0..28*ofdm_symbol_size[ /// - second index: symbol [0..28*ofdm_symbol_size[
int32_t **rxdataF; int32_t **rxdataF;
/// \brief Hold the channel estimates in frequency domain. /// \brief Hold the channel estimates in frequency domain.
/// - first index: eNB id [0..6] (hard coded) /// - first index: eNB id [0..6] (hard coded)
/// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
/// - third index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[ /// - third index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[
int32_t **dl_ch_estimates[7]; int32_t **dl_ch_estimates[7];
/// \brief Hold the channel estimates in time domain (used for tracking). /// \brief Hold the channel estimates in time domain (used for tracking).
/// - first index: eNB id [0..6] (hard coded) /// - first index: eNB id [0..6] (hard coded)
/// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
/// - third index: samples? [0..2*ofdm_symbol_size[ /// - third index: samples? [0..2*ofdm_symbol_size[
int32_t **dl_ch_estimates_time[7]; int32_t **dl_ch_estimates_time[7];
}NR_UE_COMMON_PER_THREAD; } NR_UE_COMMON_PER_THREAD;
typedef struct { typedef struct {
/// \brief Holds the transmit data in time domain. /// \brief Holds the transmit data in time domain.
...@@ -512,9 +512,9 @@ typedef struct { ...@@ -512,9 +512,9 @@ typedef struct {
int16_t *llr[2]; int16_t *llr[2];
/// \f$\log_2(\max|H_i|^2)\f$ /// \f$\log_2(\max|H_i|^2)\f$
int16_t log2_maxh; int16_t log2_maxh;
/// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer1 channel compensation /// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer1 channel compensation
int16_t log2_maxh0; int16_t log2_maxh0;
/// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer2 channel commpensation /// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer2 channel commpensation
int16_t log2_maxh1; int16_t log2_maxh1;
/// \brief LLR shifts for subband scaling. /// \brief LLR shifts for subband scaling.
/// - first index: ? [0..168*N_RB_DL[ /// - first index: ? [0..168*N_RB_DL[
...@@ -663,7 +663,8 @@ typedef enum { ...@@ -663,7 +663,8 @@ typedef enum {
_format_2_0_found=4, _format_2_0_found=4,
_format_2_1_found=5, _format_2_1_found=5,
_format_2_2_found=6, _format_2_2_found=6,
_format_2_3_found=7} format_found_t; _format_2_3_found=7
} format_found_t;
#define TOTAL_NBR_SCRAMBLED_VALUES 13 #define TOTAL_NBR_SCRAMBLED_VALUES 13
#define _C_RNTI_ 0 #define _C_RNTI_ 0
#define _CS_RNTI_ 1 #define _CS_RNTI_ 1
...@@ -678,20 +679,21 @@ typedef enum { ...@@ -678,20 +679,21 @@ typedef enum {
#define _TPC_PUSCH_RNTI_ 10 #define _TPC_PUSCH_RNTI_ 10
#define _TPC_PUCCH_RNTI_ 11 #define _TPC_PUCCH_RNTI_ 11
#define _TPC_SRS_RNTI_ 12 #define _TPC_SRS_RNTI_ 12
typedef enum { /* see 38.321 Table 7.1-2 RNTI usage */ typedef enum { /* see 38.321 Table 7.1-2 RNTI usage */
_c_rnti = _C_RNTI_, /* Cell RNTI */ _c_rnti = _C_RNTI_, /* Cell RNTI */
_cs_rnti = _CS_RNTI_, /* Configured Scheduling RNTI */ _cs_rnti = _CS_RNTI_, /* Configured Scheduling RNTI */
_new_rnti = _NEW_RNTI_, /* ? */ _new_rnti = _NEW_RNTI_, /* ? */
_tc_rnti = _TC_RNTI_, /* Temporary C-RNTI */ _tc_rnti = _TC_RNTI_, /* Temporary C-RNTI */
_p_rnti = _P_RNTI_, /* Paging RNTI */ _p_rnti = _P_RNTI_, /* Paging RNTI */
_si_rnti = _SI_RNTI_, /* System information RNTI */ _si_rnti = _SI_RNTI_, /* System information RNTI */
_ra_rnti = _RA_RNTI_, /* Random Access RNTI */ _ra_rnti = _RA_RNTI_, /* Random Access RNTI */
_sp_csi_rnti = _SP_CSI_RNTI_, /* Semipersistent CSI reporting on PUSCH */ _sp_csi_rnti = _SP_CSI_RNTI_, /* Semipersistent CSI reporting on PUSCH */
_sfi_rnti = _SFI_RNTI_, /* Slot Format Indication on the given cell */ _sfi_rnti = _SFI_RNTI_, /* Slot Format Indication on the given cell */
_int_rnti = _INT_RNTI_, /* Indication pre-emption in DL */ _int_rnti = _INT_RNTI_, /* Indication pre-emption in DL */
_tpc_pusch_rnti = _TPC_PUSCH_RNTI_, /* PUSCH power control */ _tpc_pusch_rnti = _TPC_PUSCH_RNTI_, /* PUSCH power control */
_tpc_pucch_rnti = _TPC_PUCCH_RNTI_, /* PUCCH power control */ _tpc_pucch_rnti = _TPC_PUCCH_RNTI_, /* PUCCH power control */
_tpc_srs_rnti = _TPC_SRS_RNTI_} crc_scrambled_t; _tpc_srs_rnti = _TPC_SRS_RNTI_
} crc_scrambled_t;
typedef enum {bundle_n2=2,bundle_n3=3,bundle_n6=6} NR_UE_CORESET_REG_bundlesize_t; typedef enum {bundle_n2=2,bundle_n3=3,bundle_n6=6} NR_UE_CORESET_REG_bundlesize_t;
...@@ -712,33 +714,33 @@ typedef struct { ...@@ -712,33 +714,33 @@ typedef struct {
/* /*
* define CORESET structure according to 38.331 * define CORESET structure according to 38.331
* *
* controlResourceSetId: Corresponds to L1 parameter 'CORESET-ID' * controlResourceSetId: Corresponds to L1 parameter 'CORESET-ID'
* Value 0 identifies the common CORESET configured in MIB and in ServingCellConfigCommon * Value 0 identifies the common CORESET configured in MIB and in ServingCellConfigCommon
* Values 1..maxNrofControlResourceSets-1 identify CORESETs configured by dedicated signalling * Values 1..maxNrofControlResourceSets-1 identify CORESETs configured by dedicated signalling
* frequencyDomainResources: BIT STRING (SIZE (45)) * frequencyDomainResources: BIT STRING (SIZE (45))
* Corresponds to L1 parameter 'CORESET-freq-dom'(see 38.211, section 7.3.2.2) * Corresponds to L1 parameter 'CORESET-freq-dom'(see 38.211, section 7.3.2.2)
* Frequency domain resources for the CORESET. Each bit corresponds a group of 6 RBs, with grouping starting from PRB 0, * Frequency domain resources for the CORESET. Each bit corresponds a group of 6 RBs, with grouping starting from PRB 0,
* which is fully contained in the bandwidth part within which the CORESET is configured. * which is fully contained in the bandwidth part within which the CORESET is configured.
* duration: INTEGER (1..maxCoReSetDuration) * duration: INTEGER (1..maxCoReSetDuration)
* Corresponds to L1 parameter 'CORESET-time-duration' (see 38.211, section 7.3.2.2FFS_Section) * Corresponds to L1 parameter 'CORESET-time-duration' (see 38.211, section 7.3.2.2FFS_Section)
* Contiguous time duration of the CORESET in number of symbols * Contiguous time duration of the CORESET in number of symbols
* cce-REG-MappingType: interleaved * cce-REG-MappingType: interleaved
* reg-BundleSize: ENUMERATED {n2, n3, n6} * reg-BundleSize: ENUMERATED {n2, n3, n6}
* interleaverSize: ENUMERATED {n2, n3, n6} * interleaverSize: ENUMERATED {n2, n3, n6}
* shiftIndex: INTEGER * shiftIndex: INTEGER
* nonInterleaved NULL * nonInterleaved NULL
* precoderGranularity: ENUMERATED {sameAsREG-bundle, allContiguousRBs} * precoderGranularity: ENUMERATED {sameAsREG-bundle, allContiguousRBs}
* Corresponds to L1 parameter 'CORESET-precoder-granuality' (see 38.211, sections 7.3.2.2 and 7.4.1.3.2) * Corresponds to L1 parameter 'CORESET-precoder-granuality' (see 38.211, sections 7.3.2.2 and 7.4.1.3.2)
* tci-StatesPDCCH: SEQUENCE(SIZE (1..maxNrofTCI-StatesPDCCH)) OF TCI-StateId OPTIONAL * tci-StatesPDCCH: SEQUENCE(SIZE (1..maxNrofTCI-StatesPDCCH)) OF TCI-StateId OPTIONAL
* A subset of the TCI states defined in TCI-States used for providing QCL relationships between the DL RS(s) * A subset of the TCI states defined in TCI-States used for providing QCL relationships between the DL RS(s)
* in one RS Set (TCI-State) and the PDCCH DMRS ports. * in one RS Set (TCI-State) and the PDCCH DMRS ports.
* Corresponds to L1 parameter 'TCI-StatesPDCCH' (see 38.214, section FFS_Section) * Corresponds to L1 parameter 'TCI-StatesPDCCH' (see 38.214, section FFS_Section)
* tci-PresentInDCI: ENUMERATED {enabled} OPTIONAL * tci-PresentInDCI: ENUMERATED {enabled} OPTIONAL
* Corresponds to L1 parameter 'TCI-PresentInDCI' (see 38,213, section 5.1.5) * Corresponds to L1 parameter 'TCI-PresentInDCI' (see 38,213, section 5.1.5)
* pdcch-DMRS-ScramblingID: BIT STRING (SIZE (16)) OPTIONAL * pdcch-DMRS-ScramblingID: BIT STRING (SIZE (16)) OPTIONAL
* PDCCH DMRS scrambling initalization. * PDCCH DMRS scrambling initalization.
* Corresponds to L1 parameter 'PDCCH-DMRS-Scrambling-ID' (see 38.214, section 5.1) * Corresponds to L1 parameter 'PDCCH-DMRS-Scrambling-ID' (see 38.214, section 5.1)
* When the field is absent the UE applies the value '0'. * When the field is absent the UE applies the value '0'.
*/ */
int controlResourceSetId; int controlResourceSetId;
uint64_t frequencyDomainResources; uint64_t frequencyDomainResources;
...@@ -762,21 +764,21 @@ typedef enum {uformat0_0_and_1_0=0,uformat0_1_and_1_1=1} NR_UE_SEARCHSPACE_USS_D ...@@ -762,21 +764,21 @@ typedef enum {uformat0_0_and_1_0=0,uformat0_1_and_1_1=1} NR_UE_SEARCHSPACE_USS_D
// Corresponds to L1 parameter 'SRS-Num-PDCCH-cand' (see 38.212, 38.213, section 7.3.1, 11.3) // Corresponds to L1 parameter 'SRS-Num-PDCCH-cand' (see 38.212, 38.213, section 7.3.1, 11.3)
typedef enum {mp1=1,mp2=2,mp4=4,mp5=5,mp8=8,mp10=10,mp16=16,mp20=20} NR_UE_SEARCHSPACE_MON_PERIOD_t; typedef enum {mp1=1,mp2=2,mp4=4,mp5=5,mp8=8,mp10=10,mp16=16,mp20=20} NR_UE_SEARCHSPACE_MON_PERIOD_t;
//typedef enum {n1=1,n2=2} NR_UE_SEARCHSPACE_nbrCAND_2_3_t; //typedef enum {n1=1,n2=2} NR_UE_SEARCHSPACE_nbrCAND_2_3_t;
// The number of PDCCH candidates for DCI format 2-3 for the configured aggregation level. // The number of PDCCH candidates for DCI format 2-3 for the configured aggregation level.
// Corresponds to L1 parameter 'SRS-Num-PDCCH-cand' (see 38.212, 38.213, section 7.3.1, 11.3) // Corresponds to L1 parameter 'SRS-Num-PDCCH-cand' (see 38.212, 38.213, section 7.3.1, 11.3)
typedef enum {common=0,ue_specific=1} NR_SEARCHSPACE_TYPE_t; typedef enum {common=0,ue_specific=1} NR_SEARCHSPACE_TYPE_t;
typedef struct { typedef struct {
/* /*
* searchSpaceType: Indicates whether this is a common search space (present) or a UE specific search space (CHOICE) * searchSpaceType: Indicates whether this is a common search space (present) or a UE specific search space (CHOICE)
* as well as DCI formats to monitor for (description in struct NR_UE_PDCCH_SEARCHSPACE_TYPE * as well as DCI formats to monitor for (description in struct NR_UE_PDCCH_SEARCHSPACE_TYPE
* common: Configures this search space as common search space (CSS) and DCI formats to monitor * common: Configures this search space as common search space (CSS) and DCI formats to monitor
* ue-Specific: Configures this search space as UE specific search space (USS) * ue-Specific: Configures this search space as UE specific search space (USS)
* The UE monitors the DCI format with CRC scrambled by * The UE monitors the DCI format with CRC scrambled by
* C-RNTI, CS-RNTI (if configured), TC-RNTI (if a certain condition is met), * C-RNTI, CS-RNTI (if configured), TC-RNTI (if a certain condition is met),
* and SP-CSI-RNTI (if configured) * and SP-CSI-RNTI (if configured)
*/ */
NR_SEARCHSPACE_TYPE_t type; NR_SEARCHSPACE_TYPE_t type;
NR_UE_SEARCHSPACE_CSS_DCI_FORMAT_t common_dci_formats; NR_UE_SEARCHSPACE_CSS_DCI_FORMAT_t common_dci_formats;
...@@ -793,32 +795,32 @@ typedef struct { ...@@ -793,32 +795,32 @@ typedef struct {
} NR_UE_PDCCH_SEARCHSPACE_TYPE; } NR_UE_PDCCH_SEARCHSPACE_TYPE;
typedef struct { typedef struct {
/* /*
* define SearchSpace structure according to 38.331 * define SearchSpace structure according to 38.331
* *
* searchSpaceId: Identity of the search space. SearchSpaceId = 0 identifies the SearchSpace configured via PBCH (MIB) * searchSpaceId: Identity of the search space. SearchSpaceId = 0 identifies the SearchSpace configured via PBCH (MIB)
* The searchSpaceId is unique among the BWPs of a Serving Cell * The searchSpaceId is unique among the BWPs of a Serving Cell
* controlResourceSetId: CORESET applicable for this SearchSpace * controlResourceSetId: CORESET applicable for this SearchSpace
* 0 identifies the common CORESET configured in MIB * 0 identifies the common CORESET configured in MIB
* 1..maxNrofControlResourceSets-1 identify CORESETs configured by dedicated signalling * 1..maxNrofControlResourceSets-1 identify CORESETs configured by dedicated signalling
* monitoringSlotPeriodicityAndOffset: * monitoringSlotPeriodicityAndOffset:
* Slots for PDCCH Monitoring configured as periodicity and offset. * Slots for PDCCH Monitoring configured as periodicity and offset.
* Corresponds to L1 parameters 'Montoring-periodicity-PDCCH-slot' and * Corresponds to L1 parameters 'Montoring-periodicity-PDCCH-slot' and
* 'Montoring-offset-PDCCH-slot' (see 38.213, section 10) * 'Montoring-offset-PDCCH-slot' (see 38.213, section 10)
* monitoringSymbolsWithinSlot: * monitoringSymbolsWithinSlot:
* Symbols for PDCCH monitoring in the slots configured for PDCCH monitoring * Symbols for PDCCH monitoring in the slots configured for PDCCH monitoring
* The most significant (left) bit represents the first OFDM in a slot * The most significant (left) bit represents the first OFDM in a slot
* *
* nrofCandidates: Number of PDCCH candidates per aggregation level * nrofCandidates: Number of PDCCH candidates per aggregation level
* *
* searchSpaceType: Indicates whether this is a common search space (present) or a UE specific search space * searchSpaceType: Indicates whether this is a common search space (present) or a UE specific search space
* as well as DCI formats to monitor for (description in struct NR_UE_PDCCH_SEARCHSPACE_TYPE * as well as DCI formats to monitor for (description in struct NR_UE_PDCCH_SEARCHSPACE_TYPE
* common: Configures this search space as common search space (CSS) and DCI formats to monitor * common: Configures this search space as common search space (CSS) and DCI formats to monitor
* ue-Specific: Configures this search space as UE specific search space (USS) * ue-Specific: Configures this search space as UE specific search space (USS)
* The UE monitors the DCI format with CRC scrambled by * The UE monitors the DCI format with CRC scrambled by
* C-RNTI, CS-RNTI (if configured), TC-RNTI (if a certain condition is met), * C-RNTI, CS-RNTI (if configured), TC-RNTI (if a certain condition is met),
* and SP-CSI-RNTI (if configured) * and SP-CSI-RNTI (if configured)
*/ */
// INTEGER (0..maxNrofSearchSpaces-1) (0..40-1) // INTEGER (0..maxNrofSearchSpaces-1) (0..40-1)
int searchSpaceId; int searchSpaceId;
int controlResourceSetId; int controlResourceSetId;
...@@ -892,18 +894,17 @@ typedef struct { ...@@ -892,18 +894,17 @@ typedef struct {
//Check for specific DCIFormat and AgregationLevel //Check for specific DCIFormat and AgregationLevel
uint8_t dciFormat; uint8_t dciFormat;
uint8_t agregationLevel; uint8_t agregationLevel;
t_nrPolar_paramsPtr nrPolar_params; #ifdef NR_PDCCH_DEFS_NR_UE
#ifdef NR_PDCCH_DEFS_NR_UE
int nb_searchSpaces; int nb_searchSpaces;
// CORESET structure, where maximum number of CORESETs to be handled is 3 (according to 38.331 V15.1.0) // CORESET structure, where maximum number of CORESETs to be handled is 3 (according to 38.331 V15.1.0)
NR_UE_PDCCH_CORESET coreset[NR_NBR_CORESET_ACT_BWP]; NR_UE_PDCCH_CORESET coreset[NR_NBR_CORESET_ACT_BWP];
// SEARCHSPACE structure, where maximum number of SEARCHSPACEs to be handled is 10 (according to 38.331 V15.1.0) // SEARCHSPACE structure, where maximum number of SEARCHSPACEs to be handled is 10 (according to 38.331 V15.1.0)
// Each SearchSpace is associated with one ControlResourceSet // Each SearchSpace is associated with one ControlResourceSet
NR_UE_PDCCH_SEARCHSPACE searchSpace[NR_NBR_SEARCHSPACE_ACT_BWP]; NR_UE_PDCCH_SEARCHSPACE searchSpace[NR_NBR_SEARCHSPACE_ACT_BWP];
int n_RB_BWP[NR_NBR_SEARCHSPACE_ACT_BWP]; int n_RB_BWP[NR_NBR_SEARCHSPACE_ACT_BWP];
uint32_t nb_search_space; uint32_t nb_search_space;
#endif #endif
} NR_UE_PDCCH; } NR_UE_PDCCH;
#define PBCH_A 24 #define PBCH_A 24
...@@ -933,8 +934,6 @@ typedef struct { ...@@ -933,8 +934,6 @@ typedef struct {
/// \brief Pointer to PBCH decoded output. /// \brief Pointer to PBCH decoded output.
/// - first index: ? [0..63] (hard coded) /// - first index: ? [0..63] (hard coded)
uint8_t *decoded_output; uint8_t *decoded_output;
/// polar decoder parameters
t_nrPolar_paramsPtr nrPolar_params;
/// \brief Total number of PDU errors. /// \brief Total number of PDU errors.
uint32_t pdu_errors; uint32_t pdu_errors;
/// \brief Total number of PDU errors 128 frames ago. /// \brief Total number of PDU errors 128 frames ago.
...@@ -1192,7 +1191,7 @@ typedef struct { ...@@ -1192,7 +1191,7 @@ typedef struct {
PUCCH_CONFIG_DEDICATED pucch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; PUCCH_CONFIG_DEDICATED pucch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX];
//#if defined(UPGRADE_RAT_NR) //#if defined(UPGRADE_RAT_NR)
#if 1 #if 1
SystemInformationBlockType1_nr_t systemInformationBlockType1_nr; SystemInformationBlockType1_nr_t systemInformationBlockType1_nr;
...@@ -1234,7 +1233,7 @@ typedef struct { ...@@ -1234,7 +1233,7 @@ typedef struct {
/// Scheduling Request Config /// Scheduling Request Config
SCHEDULING_REQUEST_CONFIG scheduling_request_config[NUMBER_OF_CONNECTED_eNB_MAX]; SCHEDULING_REQUEST_CONFIG scheduling_request_config[NUMBER_OF_CONNECTED_eNB_MAX];
//#if defined(UPGRADE_RAT_NR) //#if defined(UPGRADE_RAT_NR)
#if 1 #if 1
scheduling_request_config_t scheduling_request_config_nr[NUMBER_OF_CONNECTED_eNB_MAX]; scheduling_request_config_t scheduling_request_config_nr[NUMBER_OF_CONNECTED_eNB_MAX];
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#include <time.h> #include <time.h>
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
# include "intertask_interface.h" #include "intertask_interface.h"
#endif #endif
extern uint8_t nfapi_mode; extern uint8_t nfapi_mode;
...@@ -77,31 +77,29 @@ int return_ssb_type(nfapi_config_request_t *cfg) ...@@ -77,31 +77,29 @@ int return_ssb_type(nfapi_config_request_t *cfg)
}*/ }*/
// First SSB starting symbol candidate is used and type B is chosen for 30kHz SCS // First SSB starting symbol candidate is used and type B is chosen for 30kHz SCS
int nr_get_ssb_start_symbol(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *fp) int nr_get_ssb_start_symbol(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *fp) {
{
int mu = cfg->subframe_config.numerology_index_mu.value; int mu = cfg->subframe_config.numerology_index_mu.value;
int symbol = 0; int symbol = 0;
switch(mu) { switch(mu) {
case NR_MU_0:
symbol = 2;
break;
case NR_MU_0: case NR_MU_1: // case B
symbol = 2; symbol = 4;
break; break;
case NR_MU_1: // case B
symbol = 4;
break;
case NR_MU_3: case NR_MU_3:
symbol = 4; symbol = 4;
break; break;
case NR_MU_4: case NR_MU_4:
symbol = 8; symbol = 8;
break; break;
default: default:
AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu); AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu);
} }
if (cfg->sch_config.half_frame_index.value) if (cfg->sch_config.half_frame_index.value)
...@@ -110,101 +108,90 @@ int nr_get_ssb_start_symbol(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *f ...@@ -110,101 +108,90 @@ int nr_get_ssb_start_symbol(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *f
return symbol; return symbol;
} }
void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *fp) void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *fp) {
{
fp->ssb_start_subcarrier = (12 * cfg->sch_config.n_ssb_crb.value + cfg->sch_config.ssb_subcarrier_offset.value)/(1<<cfg->subframe_config.numerology_index_mu.value); fp->ssb_start_subcarrier = (12 * cfg->sch_config.n_ssb_crb.value + cfg->sch_config.ssb_subcarrier_offset.value)/(1<<cfg->subframe_config.numerology_index_mu.value);
LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->sch_config.n_ssb_crb.value,cfg->sch_config.ssb_subcarrier_offset.value); LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->sch_config.n_ssb_crb.value,cfg->sch_config.ssb_subcarrier_offset.value);
} }
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) { void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) {
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms; NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
nfapi_nr_config_request_t *cfg = &gNB->gNB_config; nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
int **txdataF = gNB->common_vars.txdataF; int **txdataF = gNB->common_vars.txdataF;
uint8_t *pbch_pdu=&gNB->pbch_pdu[0]; uint8_t *pbch_pdu=&gNB->pbch_pdu[0];
int ss_slot = (cfg->sch_config.half_frame_index.value)? 10 : 0; int ss_slot = (cfg->sch_config.half_frame_index.value)? 10 : 0;
uint8_t Lmax, ssb_index=0, n_hf=0; uint8_t Lmax, ssb_index=0, n_hf=0;
LOG_D(PHY,"common_signal_procedures: frame %d, slot %d\n",frame,slot); LOG_D(PHY,"common_signal_procedures: frame %d, slot %d\n",frame,slot);
int ssb_start_symbol = nr_get_ssb_start_symbol(cfg, fp); int ssb_start_symbol = nr_get_ssb_start_symbol(cfg, fp);
nr_set_ssb_first_subcarrier(cfg, fp); nr_set_ssb_first_subcarrier(cfg, fp);
Lmax = (fp->dl_CarrierFreq < 3e9)? 4:8; Lmax = (fp->dl_CarrierFreq < 3e9)? 4:8;
if (slot == ss_slot) {
if (slot == ss_slot)
{
// Current implementation is based on SSB in first half frame, first candidate // Current implementation is based on SSB in first half frame, first candidate
LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol); LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol);
nr_generate_pss(gNB->d_pss, txdataF[0], AMP, ssb_start_symbol, cfg, fp); nr_generate_pss(gNB->d_pss, txdataF[0], AMP, ssb_start_symbol, cfg, fp);
nr_generate_sss(gNB->d_sss, txdataF[0], AMP, ssb_start_symbol, cfg, fp); nr_generate_sss(gNB->d_sss, txdataF[0], AMP, ssb_start_symbol, cfg, fp);
if (!(frame&7)){ if (!(frame&7)) {
LOG_D(PHY,"%d.%d : pbch_configured %d\n",frame,slot,gNB->pbch_configured); LOG_D(PHY,"%d.%d : pbch_configured %d\n",frame,slot,gNB->pbch_configured);
if (gNB->pbch_configured != 1)return; if (gNB->pbch_configured != 1)return;
gNB->pbch_configured = 0; gNB->pbch_configured = 0;
} }
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index],txdataF[0], AMP, ssb_start_symbol, cfg, fp); nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index],txdataF[0], AMP, ssb_start_symbol, cfg, fp);
nr_generate_pbch(&gNB->pbch, nr_generate_pbch(&gNB->pbch,
gNB->nrPolar_params, pbch_pdu,
pbch_pdu, gNB->nr_pbch_interleaver,
gNB->nr_pbch_interleaver, txdataF[0],
txdataF[0], AMP,
AMP, ssb_start_symbol,
ssb_start_symbol, n_hf,Lmax,ssb_index,
n_hf,Lmax,ssb_index, frame, cfg, fp);
frame, cfg, fp);
} }
} }
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
gNB_L1_rxtx_proc_t *proc, gNB_L1_rxtx_proc_t *proc,
int do_meas) int do_meas) {
{
int aa; int aa;
int frame=proc->frame_tx; int frame=proc->frame_tx;
int slot=proc->slot_tx; int slot=proc->slot_tx;
uint8_t num_dci=0,num_pdsch_rnti; uint8_t num_dci=0,num_pdsch_rnti;
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms; NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
nfapi_nr_config_request_t *cfg = &gNB->gNB_config; nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
int offset = gNB->CC_id; int offset = gNB->CC_id;
if ((cfg->subframe_config.duplex_mode.value == TDD) && (nr_slot_select(cfg,slot)==SF_UL)) return; if ((cfg->subframe_config.duplex_mode.value == TDD) && (nr_slot_select(cfg,slot)==SF_UL)) return;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,1);
if (do_meas==1) start_meas(&gNB->phy_proc_tx); if (do_meas==1) start_meas(&gNB->phy_proc_tx);
// clear the transmit data array for the current subframe // clear the transmit data array for the current subframe
for (aa=0; aa<1/*15*/; aa++) { for (aa=0; aa<1/*15*/; aa++) {
memset(gNB->common_vars.txdataF[aa],0,fp->samples_per_slot_wCP*sizeof(int32_t)); memset(gNB->common_vars.txdataF[aa],0,fp->samples_per_slot_wCP*sizeof(int32_t));
} }
if (nfapi_mode == 0 || nfapi_mode == 1) { if (nfapi_mode == 0 || nfapi_mode == 1) {
nr_common_signal_procedures(gNB,frame, slot); nr_common_signal_procedures(gNB,frame, slot);
//if (frame == 9) //if (frame == 9)
//write_output("txdataF.m","txdataF",gNB->common_vars.txdataF[aa],fp->samples_per_frame_wCP, 1, 1); //write_output("txdataF.m","txdataF",gNB->common_vars.txdataF[aa],fp->samples_per_frame_wCP, 1, 1);
} }
num_dci = gNB->pdcch_vars.num_dci; num_dci = gNB->pdcch_vars.num_dci;
num_pdsch_rnti = gNB->pdcch_vars.num_pdsch_rnti; num_pdsch_rnti = gNB->pdcch_vars.num_pdsch_rnti;
if (num_dci) { if (num_dci) {
LOG_I(PHY, "[gNB %d] Frame %d slot %d \ LOG_I(PHY, "[gNB %d] Frame %d slot %d \
Calling nr_generate_dci_top (number of DCI %d)\n", gNB->Mod_id, frame, slot, num_dci); Calling nr_generate_dci_top (number of DCI %d)\n", gNB->Mod_id, frame, slot, num_dci);
if (nfapi_mode == 0 || nfapi_mode == 1){ if (nfapi_mode == 0 || nfapi_mode == 1) {
nr_generate_dci_top(gNB->pdcch_vars, nr_generate_dci_top(gNB->pdcch_vars,
&gNB->nrPolar_params,
gNB->nr_gold_pdcch_dmrs[slot], gNB->nr_gold_pdcch_dmrs[slot],
gNB->common_vars.txdataF[0], gNB->common_vars.txdataF[0],
AMP, *fp, *cfg); AMP, *fp, *cfg);
if (num_pdsch_rnti) { if (num_pdsch_rnti) {
LOG_I(PHY, "PDSCH generation started (%d)\n", num_pdsch_rnti); LOG_I(PHY, "PDSCH generation started (%d)\n", num_pdsch_rnti);
nr_generate_pdsch(*gNB->dlsch[0][0], nr_generate_pdsch(*gNB->dlsch[0][0],
...@@ -215,6 +202,6 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, ...@@ -215,6 +202,6 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
} }
} }
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,0);
} }
...@@ -82,6 +82,17 @@ void removeCirBuf(rfsimulator_state_t *bridge, int sock) { ...@@ -82,6 +82,17 @@ void removeCirBuf(rfsimulator_state_t *bridge, int sock) {
bridge->buf[sock].conn_sock=-1; bridge->buf[sock].conn_sock=-1;
} }
void socketError(rfsimulator_state_t *bridge, int sock) {
if (bridge->buf[sock].conn_sock!=-1) {
LOG_W(HW,"Lost socket \n");
removeCirBuf(bridge, sock);
if (bridge->typeStamp==MAGICUE)
exit(1);
}
}
#define helpTxt "\ #define helpTxt "\
\x1b[31m\ \x1b[31m\
rfsimulator: error: you have to run one UE and one eNB\n\ rfsimulator: error: you have to run one UE and one eNB\n\
...@@ -108,32 +119,28 @@ void setblocking(int sock, enum blocking_t active) { ...@@ -108,32 +119,28 @@ void setblocking(int sock, enum blocking_t active) {
static bool flushInput(rfsimulator_state_t *t); static bool flushInput(rfsimulator_state_t *t);
int fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) { void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) {
char *buf = _buf; char *buf = _buf;
int ret = 0;
int l; int l;
setblocking(fd, notBlocking); setblocking(fd, notBlocking);
while (count) { while (count) {
l = write(fd, buf, count); l = write(fd, buf, count);
if (l <= 0) { if (l <= 0) {
if (errno==EINTR) if (errno==EINTR)
continue; continue;
if(errno==EAGAIN) { if(errno==EAGAIN) {
flushInput(t); flushInput(t);
continue; continue;
} } else
else return;
return -1;
} }
count -= l; count -= l;
buf += l; buf += l;
ret += l;
} }
return ret;
} }
int server_start(openair0_device *device) { int server_start(openair0_device *device) {
...@@ -143,9 +150,12 @@ int server_start(openair0_device *device) { ...@@ -143,9 +150,12 @@ int server_start(openair0_device *device) {
int enable = 1; int enable = 1;
AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, ""); AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, "");
struct sockaddr_in addr = { struct sockaddr_in addr = {
sin_family: AF_INET, sin_family:
sin_port: htons(PORT), AF_INET,
sin_addr: { s_addr: INADDR_ANY } sin_port:
htons(PORT),
sin_addr:
{ s_addr: INADDR_ANY }
}; };
bind(t->listen_sock, (struct sockaddr *)&addr, sizeof(addr)); bind(t->listen_sock, (struct sockaddr *)&addr, sizeof(addr));
AssertFatal(listen(t->listen_sock, 5) == 0, ""); AssertFatal(listen(t->listen_sock, 5) == 0, "");
...@@ -162,9 +172,12 @@ int start_ue(openair0_device *device) { ...@@ -162,9 +172,12 @@ int start_ue(openair0_device *device) {
int sock; int sock;
AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
struct sockaddr_in addr = { struct sockaddr_in addr = {
sin_family: AF_INET, sin_family:
sin_port: htons(PORT), AF_INET,
sin_addr: { s_addr: INADDR_ANY } sin_port:
htons(PORT),
sin_addr:
{ s_addr: INADDR_ANY }
}; };
addr.sin_addr.s_addr = inet_addr(t->ip); addr.sin_addr.s_addr = inet_addr(t->ip);
bool connected=false; bool connected=false;
...@@ -195,8 +208,7 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi ...@@ -195,8 +208,7 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi
if (ptr->conn_sock >= 0 ) { if (ptr->conn_sock >= 0 ) {
transferHeader header= {t->typeStamp, nsamps, nbAnt, timestamp}; transferHeader header= {t->typeStamp, nsamps, nbAnt, timestamp};
int n=-1; fullwrite(ptr->conn_sock,&header, sizeof(header), t);
AssertFatal( fullwrite(ptr->conn_sock,&header, sizeof(header), t) == sizeof(header), "");
sample_t tmpSamples[nsamps][nbAnt]; sample_t tmpSamples[nsamps][nbAnt];
for(int a=0; a<nbAnt; a++) { for(int a=0; a<nbAnt; a++) {
...@@ -206,13 +218,8 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi ...@@ -206,13 +218,8 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi
tmpSamples[s][a]=in[s]; tmpSamples[s][a]=in[s];
} }
n = fullwrite(ptr->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t); if (ptr->conn_sock >= 0 )
fullwrite(ptr->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t);
if (n != sampleToByte(nsamps,nbAnt) ) {
LOG_E(HW,"rfsimulator: write error ret %d (wanted %ld) error %s\n", n, sampleToByte(nsamps,nbAnt), strerror(errno));
abort();
}
} }
} }
...@@ -241,17 +248,11 @@ static bool flushInput(rfsimulator_state_t *t) { ...@@ -241,17 +248,11 @@ static bool flushInput(rfsimulator_state_t *t) {
int conn_sock; int conn_sock;
AssertFatal( (conn_sock = accept(t->listen_sock,NULL,NULL)) != -1, ""); AssertFatal( (conn_sock = accept(t->listen_sock,NULL,NULL)) != -1, "");
setblocking(conn_sock, notBlocking); setblocking(conn_sock, notBlocking);
allocCirBuf(t, conn_sock); allocCirBuf(t, conn_sock);
LOG_I(HW,"A ue connected\n"); LOG_I(HW,"A ue connected\n");
} else { } else {
if ( events[nbEv].events & (EPOLLHUP | EPOLLERR | EPOLLRDHUP) ) { if ( events[nbEv].events & (EPOLLHUP | EPOLLERR | EPOLLRDHUP) ) {
LOG_W(HW,"Lost socket\n"); socketError(t,fd);
removeCirBuf(t, fd);
if (t->typeStamp==MAGICUE)
exit(1);
continue; continue;
} }
...@@ -292,7 +293,8 @@ static bool flushInput(rfsimulator_state_t *t) { ...@@ -292,7 +293,8 @@ static bool flushInput(rfsimulator_state_t *t) {
AssertFatal( (t->typeStamp == MAGICUE && b->th.magic==MAGICeNB) || AssertFatal( (t->typeStamp == MAGICUE && b->th.magic==MAGICeNB) ||
(t->typeStamp == MAGICeNB && b->th.magic==MAGICUE), "Socket Error in protocol"); (t->typeStamp == MAGICeNB && b->th.magic==MAGICUE), "Socket Error in protocol");
b->headerMode=false; b->headerMode=false;
b->alreadyRead=true; b->alreadyRead=true;
if ( b->lastReceivedTS != b->th.timestamp) { if ( b->lastReceivedTS != b->th.timestamp) {
int nbAnt= b->th.nbAnt; int nbAnt= b->th.nbAnt;
...@@ -331,7 +333,10 @@ static bool flushInput(rfsimulator_state_t *t) { ...@@ -331,7 +333,10 @@ static bool flushInput(rfsimulator_state_t *t) {
} }
int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) { int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) {
if (nbAnt != 1) { LOG_E(HW, "rfsimulator: only 1 antenna tested\n"); exit(1); } if (nbAnt != 1) {
LOG_E(HW, "rfsimulator: only 1 antenna tested\n");
exit(1);
}
rfsimulator_state_t *t = device->priv; rfsimulator_state_t *t = device->priv;
LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextTimestamp+nsamps); LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextTimestamp+nsamps);
...@@ -351,7 +356,6 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo ...@@ -351,7 +356,6 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
t->nextTimestamp+=nsamps; t->nextTimestamp+=nsamps;
LOG_W(HW,"Generated void samples for Rx: %ld\n", t->nextTimestamp); LOG_W(HW,"Generated void samples for Rx: %ld\n", t->nextTimestamp);
*ptimestamp = t->nextTimestamp-nsamps; *ptimestamp = t->nextTimestamp-nsamps;
return nsamps; return nsamps;
} }
...@@ -443,8 +447,8 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { ...@@ -443,8 +447,8 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
} }
rfsimulator->typeStamp = strncasecmp(rfsimulator->ip,"enb",3) == 0 ? rfsimulator->typeStamp = strncasecmp(rfsimulator->ip,"enb",3) == 0 ?
MAGICeNB: MAGICeNB:
MAGICUE; MAGICUE;
LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == MAGICeNB ? "eNB" : "UE"); LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == MAGICeNB ? "eNB" : "UE");
device->trx_start_func = rfsimulator->typeStamp == MAGICeNB ? device->trx_start_func = rfsimulator->typeStamp == MAGICeNB ?
server_start : server_start :
......
...@@ -60,9 +60,9 @@ ...@@ -60,9 +60,9 @@
#include "T.h" #include "T.h"
#ifdef XFORMS #ifdef XFORMS
#include "PHY/TOOLS/nr_phy_scope.h" #include "PHY/TOOLS/nr_phy_scope.h"
extern char do_forms; extern char do_forms;
#endif #endif
...@@ -138,9 +138,9 @@ extern double cpuf; ...@@ -138,9 +138,9 @@ extern double cpuf;
#define FIFO_PRIORITY 40 #define FIFO_PRIORITY 40
typedef enum { typedef enum {
pss=0, pss=0,
pbch=1, pbch=1,
si=2 si=2
} sync_mode_t; } sync_mode_t;
void init_UE_threads(PHY_VARS_NR_UE *UE); void init_UE_threads(PHY_VARS_NR_UE *UE);
...@@ -155,71 +155,69 @@ int32_t **txdata; ...@@ -155,71 +155,69 @@ int32_t **txdata;
#define SAIF_ENABLED #define SAIF_ENABLED
#ifdef SAIF_ENABLED #ifdef SAIF_ENABLED
uint64_t g_ue_rx_thread_busy = 0; uint64_t g_ue_rx_thread_busy = 0;
#endif #endif
typedef struct eutra_band_s { typedef struct eutra_band_s {
int16_t band; int16_t band;
uint32_t ul_min; uint32_t ul_min;
uint32_t ul_max; uint32_t ul_max;
uint32_t dl_min; uint32_t dl_min;
uint32_t dl_max; uint32_t dl_max;
lte_frame_type_t frame_type; lte_frame_type_t frame_type;
} eutra_band_t; } eutra_band_t;
typedef struct band_info_s { typedef struct band_info_s {
int nbands; int nbands;
eutra_band_t band_info[100]; eutra_band_t band_info[100];
} band_info_t; } band_info_t;
band_info_t bands_to_scan; band_info_t bands_to_scan;
static const eutra_band_t eutra_bands[] = { static const eutra_band_t eutra_bands[] = {
{ 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD},
{ 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD},
{ 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD},
{ 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD},
{ 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD},
{ 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD},
{ 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD},
{ 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD},
{ 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD},
{10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD},
{11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD},
{12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD},
{13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD},
{14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD},
{17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD},
{20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD},
{22, 3510 * MHz, 3590 * MHz, 3410 * MHz, 3490 * MHz, FDD}, {22, 3510 * MHz, 3590 * MHz, 3410 * MHz, 3490 * MHz, FDD},
{33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD},
{34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD},
{35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD},
{36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD},
{37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD},
{38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD},
{39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD},
{40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD},
{41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD},
{42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD},
{43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD},
{44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD},
}; };
PHY_VARS_NR_UE* init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms, PHY_VARS_NR_UE *init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms,
uint8_t UE_id, uint8_t UE_id,
uint8_t abstraction_flag) uint8_t abstraction_flag)
{ {
PHY_VARS_NR_UE *ue;
PHY_VARS_NR_UE* ue;
if (frame_parms!=(NR_DL_FRAME_PARMS *)NULL) { // if we want to give initial frame parms, allocate the PHY_VARS_UE structure and put them in if (frame_parms!=(NR_DL_FRAME_PARMS *)NULL) { // if we want to give initial frame parms, allocate the PHY_VARS_UE structure and put them in
ue = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE)); ue = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE));
memset(ue,0,sizeof(PHY_VARS_NR_UE)); memset(ue,0,sizeof(PHY_VARS_NR_UE));
memcpy(&(ue->frame_parms), frame_parms, sizeof(NR_DL_FRAME_PARMS)); memcpy(&(ue->frame_parms), frame_parms, sizeof(NR_DL_FRAME_PARMS));
} } else ue = PHY_vars_UE_g[UE_id][0];
else ue = PHY_vars_UE_g[UE_id][0];
ue->Mod_id = UE_id; ue->Mod_id = UE_id;
ue->mac_enabled = 1; ue->mac_enabled = 1;
...@@ -227,97 +225,99 @@ PHY_VARS_NR_UE* init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms, ...@@ -227,97 +225,99 @@ PHY_VARS_NR_UE* init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms,
init_nr_ue_signal(ue,1,abstraction_flag); init_nr_ue_signal(ue,1,abstraction_flag);
// intialize transport // intialize transport
init_nr_ue_transport(ue,abstraction_flag); init_nr_ue_transport(ue,abstraction_flag);
return(ue); return(ue);
} }
void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char * name) { void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char *name) {
#ifdef DEADLINE_SCHEDULER #ifdef DEADLINE_SCHEDULER
if (sched_runtime!=0) {
struct sched_attr attr= {0}; if (sched_runtime!=0) {
attr.size = sizeof(attr); struct sched_attr attr= {0};
attr.sched_policy = SCHED_DEADLINE; attr.size = sizeof(attr);
attr.sched_runtime = sched_runtime; attr.sched_policy = SCHED_DEADLINE;
attr.sched_deadline = sched_deadline; attr.sched_runtime = sched_runtime;
attr.sched_period = 0; attr.sched_deadline = sched_deadline;
AssertFatal(sched_setattr(0, &attr, 0) == 0, attr.sched_period = 0;
"[SCHED] %s thread: sched_setattr failed %s \n", name, strerror(errno)); AssertFatal(sched_setattr(0, &attr, 0) == 0,
LOG_I(HW,"[SCHED][eNB] %s deadline thread %lu started on CPU %d\n", "[SCHED] %s thread: sched_setattr failed %s \n", name, strerror(errno));
name, (unsigned long)gettid(), sched_getcpu()); LOG_I(HW,"[SCHED][eNB] %s deadline thread %lu started on CPU %d\n",
} name, (unsigned long)gettid(), sched_getcpu());
}
#else #else
if (CPU_COUNT(cpuset) > 0)
AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), cpuset), "");
struct sched_param sp;
sp.sched_priority = sched_fifo;
AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0,
"Can't set thread priority, Are you root?\n");
/* Check the actual affinity mask assigned to the thread */
cpu_set_t *cset=CPU_ALLOC(CPU_SETSIZE);
if (0 == pthread_getaffinity_np(pthread_self(), CPU_ALLOC_SIZE(CPU_SETSIZE), cset)) {
char txt[512]={0};
for (int j = 0; j < CPU_SETSIZE; j++)
if (CPU_ISSET(j, cset))
sprintf(txt+strlen(txt), " %d ", j);
printf("CPU Affinity of thread %s is %s\n", name, txt);
}
CPU_FREE(cset);
#endif
// Lock memory from swapping. This is a process wide call (not constraint to this thread). if (CPU_COUNT(cpuset) > 0)
mlockall(MCL_CURRENT | MCL_FUTURE); AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), cpuset), "");
pthread_setname_np( pthread_self(), name );
struct sched_param sp;
// LTS: this sync stuff should be wrong sp.sched_priority = sched_fifo;
printf("waiting for sync (%s)\n",name); AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0,
pthread_mutex_lock(&sync_mutex); "Can't set thread priority, Are you root?\n");
printf("Locked sync_mutex, waiting (%s)\n",name); /* Check the actual affinity mask assigned to the thread */
while (sync_var<0) cpu_set_t *cset=CPU_ALLOC(CPU_SETSIZE);
pthread_cond_wait(&sync_cond, &sync_mutex);
pthread_mutex_unlock(&sync_mutex); if (0 == pthread_getaffinity_np(pthread_self(), CPU_ALLOC_SIZE(CPU_SETSIZE), cset)) {
printf("started %s as PID: %ld\n",name, gettid()); char txt[512]= {0};
for (int j = 0; j < CPU_SETSIZE; j++)
if (CPU_ISSET(j, cset))
sprintf(txt+strlen(txt), " %d ", j);
printf("CPU Affinity of thread %s is %s\n", name, txt);
}
CPU_FREE(cset);
#endif
// Lock memory from swapping. This is a process wide call (not constraint to this thread).
mlockall(MCL_CURRENT | MCL_FUTURE);
pthread_setname_np( pthread_self(), name );
// LTS: this sync stuff should be wrong
printf("waiting for sync (%s)\n",name);
pthread_mutex_lock(&sync_mutex);
printf("Locked sync_mutex, waiting (%s)\n",name);
while (sync_var<0)
pthread_cond_wait(&sync_cond, &sync_mutex);
pthread_mutex_unlock(&sync_mutex);
printf("started %s as PID: %ld\n",name, gettid());
} }
void init_UE(int nb_inst) void init_UE(int nb_inst) {
{ int inst;
int inst; NR_UE_MAC_INST_t *mac_inst;
NR_UE_MAC_INST_t *mac_inst;
for (inst=0; inst < nb_inst; inst++) { for (inst=0; inst < nb_inst; inst++) {
// UE->rfdevice.type = NONE_DEV; // UE->rfdevice.type = NONE_DEV;
//PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0]; //PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0];
LOG_I(PHY,"Initializing memory for UE instance %d (%p)\n",inst,PHY_vars_UE_g[inst]); LOG_I(PHY,"Initializing memory for UE instance %d (%p)\n",inst,PHY_vars_UE_g[inst]);
PHY_vars_UE_g[inst][0] = init_nr_ue_vars(NULL,inst,0); PHY_vars_UE_g[inst][0] = init_nr_ue_vars(NULL,inst,0);
PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0]; PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0];
AssertFatal((UE->if_inst = nr_ue_if_module_init(inst)) != NULL, "can not initial IF module\n");
AssertFatal((UE->if_inst = nr_ue_if_module_init(inst)) != NULL, "can not initial IF module\n"); nr_l3_init_ue();
nr_l3_init_ue(); nr_l2_init_ue();
nr_l2_init_ue(); mac_inst = get_mac_inst(0);
mac_inst->if_module = UE->if_inst;
mac_inst = get_mac_inst(0); UE->if_inst->scheduled_response = nr_ue_scheduled_response;
mac_inst->if_module = UE->if_inst; UE->if_inst->phy_config_request = nr_ue_phy_config_request;
UE->if_inst->scheduled_response = nr_ue_scheduled_response; LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]);
UE->if_inst->phy_config_request = nr_ue_phy_config_request; //init_UE_threads(inst);
//UE = PHY_vars_UE_g[inst][0];
LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]); AssertFatal(0 == pthread_create(&UE->proc.pthread_ue,
//init_UE_threads(inst); &UE->proc.attr_ue,
//UE = PHY_vars_UE_g[inst][0]; UE_thread,
(void *)UE), "");
}
AssertFatal(0 == pthread_create(&UE->proc.pthread_ue,
&UE->proc.attr_ue,
UE_thread,
(void*)UE), "");
}
printf("UE threads created by %ld\n", gettid()); printf("UE threads created by %ld\n", gettid());
#if 0 #if 0
#if defined(ENABLE_USE_MME) #if defined(ENABLE_USE_MME)
extern volatile int start_UE; extern volatile int start_UE;
while (start_UE == 0) { while (start_UE == 0) {
sleep(1); sleep(1);
} }
#endif #endif
#endif #endif
} }
...@@ -329,290 +329,344 @@ void init_UE(int nb_inst) ...@@ -329,290 +329,344 @@ void init_UE(int nb_inst)
* \returns a pointer to an int. The storage is not on the heap and must not be freed. * \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/ */
static void *UE_thread_synch(void *arg) { static void *UE_thread_synch(void *arg) {
static int __thread UE_thread_synch_retval; static int __thread UE_thread_synch_retval;
int i, hw_slot_offset; int i, hw_slot_offset;
PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE*) arg; PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
int current_band = 0; int current_band = 0;
int current_offset = 0; int current_offset = 0;
sync_mode_t sync_mode = pbch; sync_mode_t sync_mode = pbch;
int CC_id = UE->CC_id; int CC_id = UE->CC_id;
int freq_offset=0; int freq_offset=0;
char threadname[128]; char threadname[128];
cpu_set_t cpuset;
cpu_set_t cpuset; CPU_ZERO(&cpuset);
CPU_ZERO(&cpuset);
if ( threads.sync != -1 ) if ( threads.sync != -1 )
CPU_SET(threads.sync, &cpuset); CPU_SET(threads.sync, &cpuset);
// this thread priority must be lower that the main acquisition thread
sprintf(threadname, "sync UE %d", UE->Mod_id); // this thread priority must be lower that the main acquisition thread
init_thread(100000, 500000, FIFO_PRIORITY-1, &cpuset, threadname); sprintf(threadname, "sync UE %d", UE->Mod_id);
init_thread(100000, 500000, FIFO_PRIORITY-1, &cpuset, threadname);
UE->is_synchronized = 0; UE->is_synchronized = 0;
if (UE->UE_scan == 0) { if (UE->UE_scan == 0) {
int ind; int ind;
for ( ind=0;
ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]); for ( ind=0;
ind++) { ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]);
current_band = eutra_bands[ind].band; ind++) {
LOG_D(PHY, "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min); current_band = eutra_bands[ind].band;
if ( eutra_bands[ind].dl_min <= downlink_frequency[0][0] && eutra_bands[ind].dl_max >= downlink_frequency[0][0] ) { LOG_D(PHY, "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min);
for (i=0; i<4; i++)
uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min; if ( eutra_bands[ind].dl_min <= downlink_frequency[0][0] && eutra_bands[ind].dl_max >= downlink_frequency[0][0] ) {
break; for (i=0; i<4; i++)
} uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min;
}
AssertFatal( ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]), "Can't find EUTRA band for frequency"); break;
}
LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", }
downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0],
oai_exit, openair0_cfg[0].rx_num_channels);
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { AssertFatal( ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]), "Can't find EUTRA band for frequency");
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n",
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0],
downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; oai_exit, openair0_cfg[0].rx_num_channels);
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
if (uplink_frequency_offset[CC_id][i] != 0) // for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD; openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
else //FDD openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD; downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
} openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
sync_mode = pbch;
if (uplink_frequency_offset[CC_id][i] != 0) //
openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD;
else //FDD
openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD;
}
} else { sync_mode = pbch;
current_band=0; } else {
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { current_band=0;
downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min;
uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min; downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min;
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] =
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min;
downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
} downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;
} }
}
// AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n"); // AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n");
while (oai_exit==0) { while (oai_exit==0) {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
while (UE->proc.instance_cnt_synch < 0)
// the thread waits here most of the time
pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch );
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
switch (sync_mode) { while (UE->proc.instance_cnt_synch < 0)
case pss: // the thread waits here most of the time
LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch );
//lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
current_offset += 20000000; // increase by 20 MHz
if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) { AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
current_band++;
current_offset=0;
}
if (current_band==bands_to_scan.nbands) { switch (sync_mode) {
current_band=0; case pss:
oai_exit=1; LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
} //lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
current_offset += 20000000; // increase by 20 MHz
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) {
downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset; current_band++;
uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset; current_offset=0;
}
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; if (current_band==bands_to_scan.nbands) {
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; current_band=0;
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; oai_exit=1;
if (UE->UE_scan_carrier) { }
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
}
} for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset;
uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset;
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;
break; if (UE->UE_scan_carrier) {
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
}
}
case pbch: break;
case pbch:
#if DISABLE_LOG_X #if DISABLE_LOG_X
printf("[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); printf("[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
#else #else
LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
#endif #endif
if (nr_initial_sync( UE, UE->mode ) == 0) {
if (nr_initial_sync( UE, UE->mode ) == 0) {
//write_output("txdata_sym.m", "txdata_sym", UE->common_vars.rxdata[0], (10*UE->frame_parms.samples_per_slot), 1, 1); //write_output("txdata_sym.m", "txdata_sym", UE->common_vars.rxdata[0], (10*UE->frame_parms.samples_per_slot), 1, 1);
freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync
freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_slot;
hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_slot; printf("Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n",
printf("Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n", hw_slot_offset,
hw_slot_offset, freq_offset,
freq_offset, UE->rx_total_gain_dB,
UE->rx_total_gain_dB, downlink_frequency[0][0]+freq_offset,
downlink_frequency[0][0]+freq_offset, downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset,
downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset, UE->UE_scan_carrier );
UE->UE_scan_carrier );
// rerun with new cell parameters and frequency-offset
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
// rerun with new cell parameters and frequency-offset openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; if (freq_offset >= 0)
if (freq_offset >= 0) openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(freq_offset);
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(freq_offset); else
else openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(freq_offset);
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(freq_offset);
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i];
downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i];
} }
// reconfigure for potentially different bandwidth // reconfigure for potentially different bandwidth
switch(UE->frame_parms.N_RB_DL) { switch(UE->frame_parms.N_RB_DL) {
case 6: case 6:
openair0_cfg[UE->rf_map.card].sample_rate =1.92e6; openair0_cfg[UE->rf_map.card].sample_rate =1.92e6;
openair0_cfg[UE->rf_map.card].rx_bw =.96e6; openair0_cfg[UE->rf_map.card].rx_bw =.96e6;
openair0_cfg[UE->rf_map.card].tx_bw =.96e6; openair0_cfg[UE->rf_map.card].tx_bw =.96e6;
// openair0_cfg[0].rx_gain[0] -= 12; // openair0_cfg[0].rx_gain[0] -= 12;
break; break;
case 25:
openair0_cfg[UE->rf_map.card].sample_rate =7.68e6; case 25:
openair0_cfg[UE->rf_map.card].rx_bw =2.5e6; openair0_cfg[UE->rf_map.card].sample_rate =7.68e6;
openair0_cfg[UE->rf_map.card].tx_bw =2.5e6; openair0_cfg[UE->rf_map.card].rx_bw =2.5e6;
// openair0_cfg[0].rx_gain[0] -= 6; openair0_cfg[UE->rf_map.card].tx_bw =2.5e6;
break; // openair0_cfg[0].rx_gain[0] -= 6;
case 50: break;
openair0_cfg[UE->rf_map.card].sample_rate =15.36e6;
openair0_cfg[UE->rf_map.card].rx_bw =5.0e6; case 50:
openair0_cfg[UE->rf_map.card].tx_bw =5.0e6; openair0_cfg[UE->rf_map.card].sample_rate =15.36e6;
// openair0_cfg[0].rx_gain[0] -= 3; openair0_cfg[UE->rf_map.card].rx_bw =5.0e6;
break; openair0_cfg[UE->rf_map.card].tx_bw =5.0e6;
case 100: // openair0_cfg[0].rx_gain[0] -= 3;
openair0_cfg[UE->rf_map.card].sample_rate=30.72e6; break;
openair0_cfg[UE->rf_map.card].rx_bw=10.0e6;
openair0_cfg[UE->rf_map.card].tx_bw=10.0e6; case 100:
// openair0_cfg[0].rx_gain[0] -= 0; openair0_cfg[UE->rf_map.card].sample_rate=30.72e6;
break; openair0_cfg[UE->rf_map.card].rx_bw=10.0e6;
} openair0_cfg[UE->rf_map.card].tx_bw=10.0e6;
// openair0_cfg[0].rx_gain[0] -= 0;
if (UE->mode != loop_through_memory) { break;
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); }
//UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]);
//UE->rfdevice.trx_stop_func(&UE->rfdevice); if (UE->mode != loop_through_memory) {
// sleep(1); UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
//nr_init_frame_parms_ue(&UE->frame_parms); //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]);
/*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { //UE->rfdevice.trx_stop_func(&UE->rfdevice);
LOG_E(HW,"Could not start the device\n"); // sleep(1);
oai_exit=1; //nr_init_frame_parms_ue(&UE->frame_parms);
}*/ /*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) {
} LOG_E(HW,"Could not start the device\n");
oai_exit=1;
if (UE->UE_scan_carrier == 1) { }*/
}
UE->UE_scan_carrier = 0;
if (UE->UE_scan_carrier == 1) {
UE->UE_scan_carrier = 0;
} else {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
UE->is_synchronized = 1;
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
if( UE->mode == rx_dump_frame ) {
FILE *fd;
if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present
if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) {
fwrite((void *)&UE->common_vars.rxdata[0][0],
sizeof(int32_t),
10*UE->frame_parms.samples_per_subframe,
fd);
LOG_I(PHY,"Dummping Frame ... bye bye \n");
fclose(fd);
exit(0);
} else { } else {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); LOG_E(PHY,"Cannot open file for writing\n");
UE->is_synchronized = 1; exit(0);
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
if( UE->mode == rx_dump_frame ) {
FILE *fd;
if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present
if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) {
fwrite((void*)&UE->common_vars.rxdata[0][0],
sizeof(int32_t),
10*UE->frame_parms.samples_per_subframe,
fd);
LOG_I(PHY,"Dummping Frame ... bye bye \n");
fclose(fd);
exit(0);
} else {
LOG_E(PHY,"Cannot open file for writing\n");
exit(0);
}
} else {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
UE->is_synchronized = 0;
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
}
}
}
} else {
// initial sync failed
// calculate new offset and try again
if (UE->UE_scan_carrier == 1) {
if (freq_offset >= 0)
freq_offset += 100;
freq_offset *= -1;
if (abs(freq_offset) > 7500) {
LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" );
FILE *fd;
if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) {
fwrite((void*)&UE->common_vars.rxdata[0][0],
sizeof(int32_t),
10*UE->frame_parms.samples_per_subframe,
fd);
LOG_I(PHY,"Dummping Frame ... bye bye \n");
fclose(fd);
exit(0);
}
//mac_xface->macphy_exit("No cell synchronization found, abandoning"); new mac
return &UE_thread_synch_retval; // not reached
}
} }
} else {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
UE->is_synchronized = 0;
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
}
}
}
} else {
// initial sync failed
// calculate new offset and try again
if (UE->UE_scan_carrier == 1) {
if (freq_offset >= 0)
freq_offset += 100;
freq_offset *= -1;
if (abs(freq_offset) > 7500) {
LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" );
FILE *fd;
if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) {
fwrite((void *)&UE->common_vars.rxdata[0][0],
sizeof(int32_t),
10*UE->frame_parms.samples_per_subframe,
fd);
LOG_I(PHY,"Dummping Frame ... bye bye \n");
fclose(fd);
exit(0);
}
//mac_xface->macphy_exit("No cell synchronization found, abandoning"); new mac
return &UE_thread_synch_retval; // not reached
}
}
#if DISABLE_LOG_X #if DISABLE_LOG_X
printf("[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", printf("[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n",
freq_offset, freq_offset,
UE->rx_total_gain_dB, UE->rx_total_gain_dB,
downlink_frequency[0][0]+freq_offset, downlink_frequency[0][0]+freq_offset,
downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset );
#else #else
LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n",
freq_offset, freq_offset,
UE->rx_total_gain_dB, UE->rx_total_gain_dB,
downlink_frequency[0][0]+freq_offset, downlink_frequency[0][0]+freq_offset,
downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset );
#endif #endif
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset; openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset;
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset; openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset;
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
if (UE->UE_scan_carrier==1)
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; if (UE->UE_scan_carrier==1)
} openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
if (UE->mode != loop_through_memory) }
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
}// initial_sync=0 if (UE->mode != loop_through_memory)
break; UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
case si: }// initial_sync=0
default:
break; break;
}
case si:
default:
break;
}
#if 0 //defined XFORMS #if 0 //defined XFORMS
if (do_forms) {
extern FD_lte_phy_scope_ue *form_ue[NUMBER_OF_UE_MAX];
phy_scope_UE(form_ue[0],
PHY_vars_UE_g[0][0],
0,0,1);
}
#endif
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); if (do_forms) {
// indicate readiness extern FD_lte_phy_scope_ue *form_ue[NUMBER_OF_UE_MAX];
UE->proc.instance_cnt_synch--; phy_scope_UE(form_ue[0],
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); PHY_vars_UE_g[0][0],
0,0,1);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 ); #endif
} // while !oai_exit AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
// indicate readiness
UE->proc.instance_cnt_synch--;
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 );
} // while !oai_exit
return &UE_thread_synch_retval;
}
void processSubframeRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
// Process Rx data for one sub-frame
if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_DOWNLINK_SLOT) {
//clean previous FAPI MESSAGE
UE->rx_ind.number_pdus = 0;
UE->dci_ind.number_of_dcis = 0;
//clean previous FAPI MESSAGE
// call L2 for DL_CONFIG (DCI)
UE->dcireq.module_id = UE->Mod_id;
UE->dcireq.gNB_index = 0;
UE->dcireq.cc_id = 0;
UE->dcireq.frame = proc->frame_rx;
UE->dcireq.slot = proc->nr_tti_rx;
nr_ue_dcireq(&UE->dcireq); //to be replaced with function pointer later
NR_UE_MAC_INST_t *UE_mac = get_mac_inst(0);
UE_mac->scheduled_response.dl_config = &UE->dcireq.dl_config_req;
UE_mac->scheduled_response.slot = proc->nr_tti_rx;
nr_ue_scheduled_response(&UE_mac->scheduled_response);
//write_output("uerxdata_frame.m", "uerxdata_frame", UE->common_vars.rxdata[0], UE->frame_parms.samples_per_frame, 1, 1);
printf("Processing slot %d\n",proc->nr_tti_rx);
#ifdef UE_SLOT_PARALLELISATION
phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
#else
phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode);
// printf(">>> nr_ue_pdcch_procedures ended\n");
#endif
}
return &UE_thread_synch_retval; if (UE->mac_enabled==1) {
// trigger L2 to run ue_scheduler thru IF module
// [TODO] mapping right after NR initial sync
if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) {
UE->ul_indication.module_id = 0;
UE->ul_indication.gNB_index = 0;
UE->ul_indication.cc_id = 0;
UE->ul_indication.frame = proc->frame_rx;
UE->ul_indication.slot = proc->nr_tti_rx;
UE->if_inst->ul_indication(&UE->ul_indication);
}
}
} }
/*! /*!
...@@ -624,146 +678,173 @@ static void *UE_thread_synch(void *arg) { ...@@ -624,146 +678,173 @@ static void *UE_thread_synch(void *arg) {
*/ */
static void *UE_thread_rxn_txnp4(void *arg) { static void *UE_thread_rxn_txnp4(void *arg) {
static __thread int UE_thread_rxtx_retval; struct nr_rxtx_thread_data *rtd = arg;
struct nr_rxtx_thread_data *rtd = arg; UE_nr_rxtx_proc_t *proc = rtd->proc;
UE_nr_rxtx_proc_t *proc = rtd->proc; PHY_VARS_NR_UE *UE = rtd->UE;
PHY_VARS_NR_UE *UE = rtd->UE; //proc->counter_decoder = 0;
proc->instance_cnt_rxtx=-1;
//proc->counter_decoder = 0; proc->subframe_rx=proc->sub_frame_start;
proc->instance_cnt_rxtx=-1; proc->dci_err_cnt=0;
proc->subframe_rx=proc->sub_frame_start; char threadname[256];
sprintf(threadname,"UE_%d_proc_%d", UE->Mod_id, proc->sub_frame_start);
proc->dci_err_cnt=0; cpu_set_t cpuset;
char threadname[256]; CPU_ZERO(&cpuset);
sprintf(threadname,"UE_%d_proc_%d", UE->Mod_id, proc->sub_frame_start); char timing_proc_name[256];
cpu_set_t cpuset; sprintf(timing_proc_name,"Delay to process sub-frame proc %d",proc->sub_frame_start);
CPU_ZERO(&cpuset);
char timing_proc_name[256]; if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.one != -1 )
sprintf(timing_proc_name,"Delay to process sub-frame proc %d",proc->sub_frame_start); CPU_SET(threads.one, &cpuset);
if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.one != -1 ) if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.two != -1 )
CPU_SET(threads.one, &cpuset); CPU_SET(threads.two, &cpuset);
if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.two != -1 )
CPU_SET(threads.two, &cpuset); if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.three != -1 )
if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.three != -1 ) CPU_SET(threads.three, &cpuset);
CPU_SET(threads.three, &cpuset);
//CPU_SET(threads.three, &cpuset); //CPU_SET(threads.three, &cpuset);
init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset, init_thread(900000,1000000, FIFO_PRIORITY-1, &cpuset,
threadname); threadname);
while (!oai_exit) { while (!oai_exit) {
if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { AssertFatal( 0 == pthread_mutex_lock(&proc->mutex_rxtx), "[SCHED][UE] error locking mutex for UE RXTX\n" );
LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
exit_fun("nothing to add"); while (proc->instance_cnt_rxtx < 0) {
} // most of the time, the thread is waiting here
while (proc->instance_cnt_rxtx < 0) { pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx );
// most of the time, the thread is waiting here }
pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx );
}
if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" );
exit_fun("nothing to add");
}
// initRefTimes(t2);
// initRefTimes(t3);
// pickTime(current);
// updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)");
// Process Rx data for one sub-frame
if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_DOWNLINK_SLOT) {
//clean previous FAPI MESSAGE
UE->rx_ind.number_pdus = 0;
UE->dci_ind.number_of_dcis = 0;
//clean previous FAPI MESSAGE
// call L2 for DL_CONFIG (DCI)
UE->dcireq.module_id = UE->Mod_id;
UE->dcireq.gNB_index = 0;
UE->dcireq.cc_id = 0;
UE->dcireq.frame = proc->frame_rx;
UE->dcireq.slot = proc->nr_tti_rx;
nr_ue_dcireq(&UE->dcireq); //to be replaced with function pointer later
NR_UE_MAC_INST_t *UE_mac = get_mac_inst(0);
UE_mac->scheduled_response.dl_config = &UE->dcireq.dl_config_req;
UE_mac->scheduled_response.slot = proc->nr_tti_rx;
nr_ue_scheduled_response(&UE_mac->scheduled_response);
#ifdef UE_SLOT_PARALLELISATION
phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
#else
phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode);
// printf(">>> nr_ue_pdcch_procedures ended\n");
#endif
}
#if UE_TIMING_TRACE
start_meas(&UE->generic_stat);
#endif
//printf(">>> mac init\n");
if (UE->mac_enabled==1) {
// trigger L2 to run ue_scheduler thru IF module
// [TODO] mapping right after NR initial sync
if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL){
UE->ul_indication.module_id = 0;
UE->ul_indication.gNB_index = 0;
UE->ul_indication.cc_id = 0;
UE->ul_indication.frame = proc->frame_rx;
UE->ul_indication.slot = proc->nr_tti_rx;
UE->if_inst->ul_indication(&UE->ul_indication);
}
}
#if UE_TIMING_TRACE
stop_meas(&UE->generic_stat);
#endif
//printf(">>> mac ended\n");
// Prepare the future Tx data AssertFatal ( 0== pthread_mutex_unlock(&proc->mutex_rxtx), "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" );
processSubframeRX(UE, proc);
//printf(">>> mac ended\n");
// Prepare the future Tx data
#if 0 #if 0
#ifndef NO_RAT_NR #ifndef NO_RAT_NR
if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_UPLINK_SLOT)
if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_UPLINK_SLOT)
#else #else
if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
(UE->frame_parms.frame_type == FDD) ) (UE->frame_parms.frame_type == FDD) )
#endif #endif
if (UE->mode != loop_through_memory) if (UE->mode != loop_through_memory)
phy_procedures_nrUE_TX(UE,proc,0,0,UE->mode,no_relay); phy_procedures_nrUE_TX(UE,proc,0,0,UE->mode,no_relay);
//phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay);
//phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay);
#endif #endif
#if 0 #if 0
if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) &&
(UE->frame_parms.frame_type == TDD)) if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) &&
if (UE->mode != loop_through_memory) (UE->frame_parms.frame_type == TDD))
//phy_procedures_UE_S_TX(UE,0,0,no_relay); if (UE->mode != loop_through_memory)
//phy_procedures_UE_S_TX(UE,0,0,no_relay);
updateTimes(current, &t3, 10000, timing_proc_name); updateTimes(current, &t3, 10000, timing_proc_name);
#endif
if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { #endif
LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); AssertFatal( 0 == pthread_mutex_lock(&proc->mutex_rxtx), "[SCHED][UE] error locking mutex for UE RXTX\n" );
exit_fun("noting to add"); proc->instance_cnt_rxtx--;
}
proc->instance_cnt_rxtx--;
#if BASIC_SIMULATOR #if BASIC_SIMULATOR
if (pthread_cond_signal(&proc->cond_rxtx) != 0) abort(); if (pthread_cond_signal(&proc->cond_rxtx) != 0) abort();
#endif #endif
if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { AssertFatal (0 == pthread_mutex_unlock(&proc->mutex_rxtx), "[SCHED][UE] error unlocking mutex for UE RXTX\n" );
LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" ); }
exit_fun("noting to add");
} // thread finished
free(arg);
return NULL;
}
void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
void *rxp[NB_ANTENNAS_RX];
void *dummy_tx[UE->frame_parms.nb_antennas_tx];
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4);
for(int x=0; x<10; x++) {
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
rxp[i] = ((void *)&UE->common_vars.rxdata[i][0]) + 4*x*UE->frame_parms.samples_per_subframe;
AssertFatal( UE->frame_parms.samples_per_subframe ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
timestamp,
rxp,
UE->frame_parms.samples_per_subframe,
UE->frame_parms.nb_antennas_rx), "");
}
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
free(dummy_tx[i]);
}
void trashFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
void *dummy_tx[UE->frame_parms.nb_antennas_tx];
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4);
void *dummy_rx[UE->frame_parms.nb_antennas_rx];
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
dummy_rx[i]=malloc16(UE->frame_parms.samples_per_subframe*4);
for (int sf=0; sf<NR_NUMBER_OF_SUBFRAMES_PER_FRAME; sf++) {
// printf("Reading dummy sf %d\n",sf);
UE->rfdevice.trx_read_func(&UE->rfdevice,
timestamp,
dummy_rx,
UE->frame_parms.samples_per_subframe,
UE->frame_parms.nb_antennas_rx);
usleep(500); // this sleep improves in the case of simulated RF and doesn't harm with true radio
}
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
free(dummy_tx[i]);
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
free(dummy_rx[i]);
}
void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
if (UE->no_timing_correction==0) {
LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
void *dummy_tx[UE->frame_parms.nb_antennas_tx];
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4);
for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) {
int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ;
AssertFatal(unitTransfer ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
timestamp,
(void **)UE->common_vars.rxdata,
unitTransfer,
UE->frame_parms.nb_antennas_rx),"");
} }
// thread finished for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
free(arg); free(dummy_tx[i]);
return &UE_thread_rxtx_retval; }
}
int computeSamplesShift(PHY_VARS_NR_UE *UE) {
if ( getenv("RFSIMULATOR") != 0) {
LOG_E(PHY,"SET rx_offset %d \n",UE->rx_offset);
//UE->rx_offset_diff=0;
return 0;
}
// compute TO compensation that should be applied for this frame
if ( UE->rx_offset < 5*UE->frame_parms.samples_per_slot &&
UE->rx_offset > 0 )
return -1 ;
if ( UE->rx_offset > 5*UE->frame_parms.samples_per_slot &&
UE->rx_offset < 10*UE->frame_parms.samples_per_slot )
return 1;
return 0;
} }
/*! /*!
...@@ -777,389 +858,266 @@ static void *UE_thread_rxn_txnp4(void *arg) { ...@@ -777,389 +858,266 @@ static void *UE_thread_rxn_txnp4(void *arg) {
*/ */
void *UE_thread(void *arg) { void *UE_thread(void *arg) {
PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg; // int tx_enabled = 0;
// int tx_enabled = 0; openair0_timestamp timestamp;
openair0_timestamp timestamp; void *rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX];
void* rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX]; int start_rx_stream = 0;
int start_rx_stream = 0; int i;
int i; char threadname[128];
char threadname[128]; int th_id;
int th_id; const uint16_t table_sf_slot[20] = {0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9};
for (int i=0; i< RX_NB_TH_MAX; i++ )
UE->proc.proc_rxtx[i].counter_decoder = 0; for (int i=0; i< RX_NB_TH_MAX; i++ )
UE->proc.proc_rxtx[i].counter_decoder = 0;
static uint8_t thread_idx = 0;
uint16_t table_sf_slot[20] = {0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9}; static uint8_t thread_idx = 0;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
cpu_set_t cpuset;
CPU_ZERO(&cpuset); if ( threads.main != -1 )
if ( threads.main != -1 ) CPU_SET(threads.main, &cpuset);
CPU_SET(threads.main, &cpuset);
sprintf(threadname, "Main UE %d", UE->Mod_id); sprintf(threadname, "Main UE %d", UE->Mod_id);
init_thread(100000, 500000, FIFO_PRIORITY, &cpuset,threadname); init_thread(100000, 500000, FIFO_PRIORITY, &cpuset,threadname);
if ((oaisim_flag == 0) && (UE->mode !=loop_through_memory)) if ((oaisim_flag == 0) && (UE->mode !=loop_through_memory))
AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), ""); AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), "");
UE->rfdevice.host_type = RAU_HOST;
UE->rfdevice.host_type = RAU_HOST;
init_UE_threads(UE); init_UE_threads(UE);
#ifdef NAS_UE #ifdef NAS_UE
//MessageDef *message_p; //MessageDef *message_p;
//message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); //message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE);
//itti_send_msg_to_task (TASK_NAS_UE, UE->Mod_id + NB_eNB_INST, message_p); //itti_send_msg_to_task (TASK_NAS_UE, UE->Mod_id + NB_eNB_INST, message_p);
#endif #endif
int nb_slot_frame = 10*UE->frame_parms.slots_per_subframe;
int slot_nr=-1;
//int cumulated_shift=0;
if ((oaisim_flag == 0) && (UE->mode != loop_through_memory))
AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n");
int nb_slot_frame = 10*UE->frame_parms.slots_per_subframe; while (!oai_exit) {
int slot_nr=-1; AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
//int cumulated_shift=0; int instance_cnt_synch = UE->proc.instance_cnt_synch;
if ((oaisim_flag == 0) && (UE->mode != loop_through_memory)) int is_synchronized = UE->is_synchronized;
AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n"); AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
while (!oai_exit) {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); if (is_synchronized == 0) {
int instance_cnt_synch = UE->proc.instance_cnt_synch;
int is_synchronized = UE->is_synchronized;
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
if (is_synchronized == 0) {
#if BASIC_SIMULATOR #if BASIC_SIMULATOR
while (!((instance_cnt_synch = UE->proc.instance_cnt_synch) < 0)) {
printf("ue sync not ready\n"); while (!((instance_cnt_synch = UE->proc.instance_cnt_synch) < 0)) {
usleep(500*1000); printf("ue sync not ready\n");
} usleep(500*1000);
}
#endif #endif
LOG_W(PHY,"is_synchro %d\n" , is_synchronized );
if (instance_cnt_synch < 0) { // we can invoke the synch
// grab 10 ms of signal and wakeup synch thread
if (UE->mode != loop_through_memory) {
void *dummy_tx[UE->frame_parms.nb_antennas_tx];
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4);
for(int x=0; x<10; x++) {
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
rxp[i] = ((void*)&UE->common_vars.rxdata[i][0]) + 4*x*UE->frame_parms.samples_per_subframe;
AssertFatal( UE->frame_parms.samples_per_subframe ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
rxp,
UE->frame_parms.samples_per_subframe,
UE->frame_parms.nb_antennas_rx), "");
}
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
free(dummy_tx[i]);
}
AssertFatal( 0 == pthread_mutex_lock(&UE->proc.mutex_synch), "");
AssertFatal( 0 == ++UE->proc.instance_cnt_synch, "[SCHED][UE] UE sync thread busy!!\n" );
AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), "");
AssertFatal( 0 == pthread_mutex_unlock(&UE->proc.mutex_synch), "");
} else {
// grab 10 ms of signal into dummy buffer to wait result of sync detection
if (UE->mode != loop_through_memory) {
void *dummy_tx[UE->frame_parms.nb_antennas_tx];
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4);
void *dummy_rx[UE->frame_parms.nb_antennas_rx];
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
dummy_rx[i]=malloc16(UE->frame_parms.samples_per_subframe*4);
for (int sf=0; sf<NR_NUMBER_OF_SUBFRAMES_PER_FRAME; sf++) {
// printf("Reading dummy sf %d\n",sf);
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
dummy_rx,
UE->frame_parms.samples_per_subframe,
UE->frame_parms.nb_antennas_rx);
usleep(500); // this sleep improves in the case of simulated RF and doesn't harm with true radio
}
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
free(dummy_tx[i]);
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
free(dummy_rx[i]);
}
}
} // UE->is_synchronized==0 if (UE->mode != loop_through_memory) {
else { if (instance_cnt_synch < 0) { // we can invoke the synch
if (start_rx_stream==0) { // grab 10 ms of signal and wakeup synch thread
start_rx_stream=1; readFrame(UE, &timestamp);
if (UE->mode != loop_through_memory) { AssertFatal( 0 == pthread_mutex_lock(&UE->proc.mutex_synch), "");
if (UE->no_timing_correction==0) { AssertFatal( 0 == ++UE->proc.instance_cnt_synch, "[SCHED][UE] UE sync thread busy!!\n" );
LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode); AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), "");
void *dummy_tx[UE->frame_parms.nb_antennas_tx]; AssertFatal( 0 == pthread_mutex_unlock(&UE->proc.mutex_synch), "");
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++) } else {
dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4); // grab 10 ms of signal into dummy buffer to wait result of sync detection
for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) { trashFrame(UE, &timestamp);
int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ; }
AssertFatal(unitTransfer == }
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp, continue;
(void**)UE->common_vars.rxdata, }
unitTransfer,
UE->frame_parms.nb_antennas_rx),"");
}
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
free(dummy_tx[i]);
}
UE->rx_offset=0;
UE->time_sync_cell=0;
UE->proc.proc_rxtx[0].frame_rx++;
//UE->proc.proc_rxtx[1].frame_rx++;
for (th_id=1; th_id < RX_NB_TH; th_id++) {
UE->proc.proc_rxtx[th_id].frame_rx = UE->proc.proc_rxtx[0].frame_rx;
}
//printf("first stream frame rx %d\n",UE->proc.proc_rxtx[0].frame_rx);
// read in first symbol
AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
(void**)UE->common_vars.rxdata,
UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0,
UE->frame_parms.nb_antennas_rx),"");
//write_output("txdata_sym.m", "txdata_sym", UE->common_vars.rxdata[0], (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0), 1, 1);
//nr_slot_fep(UE,0, 0, 0, 1, 1, NR_PDCCH_EST);
} //UE->mode != loop_through_memory
else
rt_sleep_ns(1000*1000);
} else {
thread_idx++;
if(thread_idx>=RX_NB_TH)
thread_idx = 0;
//printf("slot_nr %d nb slot frame %d\n",slot_nr, nb_slot_frame);
slot_nr++;
slot_nr %= nb_slot_frame;
UE_nr_rxtx_proc_t *proc = &UE->proc.proc_rxtx[thread_idx];
// update thread index for received subframe
UE->current_thread_id[slot_nr] = thread_idx;
if (start_rx_stream==0) {
start_rx_stream=1;
if (UE->mode != loop_through_memory) {
syncInFrame(UE, &timestamp);
UE->rx_offset=0;
UE->time_sync_cell=0;
UE->proc.proc_rxtx[0].frame_rx++;
//UE->proc.proc_rxtx[1].frame_rx++;
for (th_id=1; th_id < RX_NB_TH; th_id++) {
UE->proc.proc_rxtx[th_id].frame_rx = UE->proc.proc_rxtx[0].frame_rx;
}
//printf("first stream frame rx %d\n",UE->proc.proc_rxtx[0].frame_rx);
// read in first symbol
AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
(void **)UE->common_vars.rxdata,
UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0,
UE->frame_parms.nb_antennas_rx),"");
//write_output("txdata_sym.m", "txdata_sym", UE->common_vars.rxdata[0], (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0), 1, 1);
//nr_slot_fep(UE,0, 0, 0, 1, 1, NR_PDCCH_EST);
} //UE->mode != loop_through_memory
else
rt_sleep_ns(1000*1000);
continue;
}
thread_idx++;
thread_idx%=RX_NB_TH;
//printf("slot_nr %d nb slot frame %d\n",slot_nr, nb_slot_frame);
slot_nr++;
slot_nr %= nb_slot_frame;
UE_nr_rxtx_proc_t *proc = &UE->proc.proc_rxtx[thread_idx];
// update thread index for received subframe
UE->current_thread_id[slot_nr] = thread_idx;
#if BASIC_SIMULATOR #if BASIC_SIMULATOR
{
int t; for (int t = 0; t < RX_NB_TH; t++) {
for (t = 0; t < RX_NB_TH; t++) { UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[t];
UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[t]; pthread_mutex_lock(&proc->mutex_rxtx);
pthread_mutex_lock(&proc->mutex_rxtx);
while (proc->instance_cnt_rxtx >= 0) pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); while (proc->instance_cnt_rxtx >= 0) pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx );
pthread_mutex_unlock(&proc->mutex_rxtx);
} pthread_mutex_unlock(&proc->mutex_rxtx);
} }
#endif #endif
LOG_D(PHY,"Process slot %d thread Idx %d \n", slot_nr, UE->current_thread_id[slot_nr]);
proc->nr_tti_rx=slot_nr;
proc->subframe_rx=table_sf_slot[slot_nr];
proc->frame_tx = proc->frame_rx;
proc->nr_tti_tx= slot_nr + DURATION_RX_TO_TX;
if (proc->nr_tti_tx > nb_slot_frame) {
proc->frame_tx = (proc->frame_tx + 1)%MAX_FRAME_NUMBER;
proc->nr_tti_tx %= nb_slot_frame;
}
if(slot_nr == 0) {
UE->proc.proc_rxtx[0].frame_rx++;
//UE->proc.proc_rxtx[1].frame_rx++;
for (th_id=1; th_id < RX_NB_TH; th_id++) {
UE->proc.proc_rxtx[th_id].frame_rx = UE->proc.proc_rxtx[0].frame_rx;
}
}
if (UE->mode != loop_through_memory) {
for (i=0; i<UE->frame_parms.nb_antennas_rx; i++)
rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+
UE->frame_parms.nb_prefix_samples0+
slot_nr*UE->frame_parms.samples_per_slot];
for (i=0; i<UE->frame_parms.nb_antennas_tx; i++)
txp[i] = (void *)&UE->common_vars.txdata[i][((slot_nr+2)%NR_NUMBER_OF_SUBFRAMES_PER_FRAME)*UE->frame_parms.samples_per_slot];
LOG_D(PHY,"Process slot %d thread Idx %d \n", slot_nr, UE->current_thread_id[slot_nr]); int readBlockSize, writeBlockSize;
if (slot_nr<(nb_slot_frame - 1)) {
if (UE->mode != loop_through_memory) { readBlockSize=UE->frame_parms.samples_per_slot;
for (i=0; i<UE->frame_parms.nb_antennas_rx; i++) writeBlockSize=UE->frame_parms.samples_per_slot;
rxp[i] = (void*)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+ } else {
UE->frame_parms.nb_prefix_samples0+ UE->rx_offset_diff = computeSamplesShift(UE);
slot_nr*UE->frame_parms.samples_per_slot]; readBlockSize=UE->frame_parms.samples_per_slot -
for (i=0; i<UE->frame_parms.nb_antennas_tx; i++) UE->frame_parms.ofdm_symbol_size -
txp[i] = (void*)&UE->common_vars.txdata[i][((slot_nr+2)%NR_NUMBER_OF_SUBFRAMES_PER_FRAME)*UE->frame_parms.samples_per_slot]; UE->frame_parms.nb_prefix_samples0 -
UE->rx_offset_diff;
int readBlockSize, writeBlockSize; writeBlockSize=UE->frame_parms.samples_per_slot -
if (slot_nr<(nb_slot_frame - 1)) { UE->rx_offset_diff;
readBlockSize=UE->frame_parms.samples_per_slot; }
writeBlockSize=UE->frame_parms.samples_per_slot;
} else { AssertFatal(readBlockSize ==
// set TO compensation to zero UE->rfdevice.trx_read_func(&UE->rfdevice,
UE->rx_offset_diff = 0; &timestamp,
// compute TO compensation that should be applied for this frame rxp,
if ( UE->rx_offset < 5*UE->frame_parms.samples_per_slot && readBlockSize,
UE->rx_offset > 0 ) UE->frame_parms.nb_antennas_rx),"");
UE->rx_offset_diff = -1 ; AssertFatal( writeBlockSize ==
if ( UE->rx_offset > 5*UE->frame_parms.samples_per_slot && UE->rfdevice.trx_write_func(&UE->rfdevice,
UE->rx_offset < 10*UE->frame_parms.samples_per_slot ) timestamp+
UE->rx_offset_diff = 1; (2*UE->frame_parms.samples_per_slot) -
UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
openair0_cfg[0].tx_sample_advance,
txp,
if ( getenv("RFSIMULATOR") != 0) { writeBlockSize,
LOG_E(PHY,"AbsSubframe %d.%d TTI SET rx_off_diff to %d rx_offset %d \n", UE->frame_parms.nb_antennas_tx,
proc->frame_rx,slot_nr,UE->rx_offset_diff,UE->rx_offset); 1),"");
//UE->rx_offset_diff=0;
} if( slot_nr==(nb_slot_frame-1)) {
readBlockSize=UE->frame_parms.samples_per_slot - // read in first symbol of next frame and adjust for timing drift
UE->frame_parms.ofdm_symbol_size - int first_symbols=writeBlockSize-readBlockSize;
UE->frame_parms.nb_prefix_samples0 -
UE->rx_offset_diff; if ( first_symbols > 0 )
writeBlockSize=UE->frame_parms.samples_per_slot - AssertFatal(first_symbols ==
UE->rx_offset_diff; UE->rfdevice.trx_read_func(&UE->rfdevice,
} &timestamp,
(void **)UE->common_vars.rxdata,
AssertFatal(readBlockSize == first_symbols,
UE->rfdevice.trx_read_func(&UE->rfdevice, UE->frame_parms.nb_antennas_rx),"");
&timestamp, else
rxp, LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols);
readBlockSize, }
UE->frame_parms.nb_antennas_rx),"");
AssertFatal( writeBlockSize == pickTime(gotIQs);
UE->rfdevice.trx_write_func(&UE->rfdevice, // operate on thread sf mod 2
timestamp+ AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,"");
(2*UE->frame_parms.samples_per_slot) -
UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
openair0_cfg[0].tx_sample_advance,
txp,
writeBlockSize,
UE->frame_parms.nb_antennas_tx,
1),"");
if( slot_nr==(nb_slot_frame-1)) {
// read in first symbol of next frame and adjust for timing drift
int first_symbols=writeBlockSize-readBlockSize;
if ( first_symbols > 0 )
AssertFatal(first_symbols ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
(void**)UE->common_vars.rxdata,
first_symbols,
UE->frame_parms.nb_antennas_rx),"");
if ( first_symbols <0 )
LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols);
}
pickTime(gotIQs);
// operate on thread sf mod 2
AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,"");
if(slot_nr == 0) {
UE->proc.proc_rxtx[0].frame_rx++;
//UE->proc.proc_rxtx[1].frame_rx++;
for (th_id=1; th_id < RX_NB_TH; th_id++) {
UE->proc.proc_rxtx[th_id].frame_rx = UE->proc.proc_rxtx[0].frame_rx;
}
#ifdef SAIF_ENABLED #ifdef SAIF_ENABLED
if (!(proc->frame_rx%4000))
{ if (!(proc->frame_rx%4000)) {
printf("frame_rx=%d rx_thread_busy=%ld - rate %8.3f\n", printf("frame_rx=%d rx_thread_busy=%ld - rate %8.3f\n",
proc->frame_rx, g_ue_rx_thread_busy, proc->frame_rx, g_ue_rx_thread_busy,
(float)g_ue_rx_thread_busy/(proc->frame_rx*10+1)*100.0); (float)g_ue_rx_thread_busy/(proc->frame_rx*10+1)*100.0);
fflush(stdout); fflush(stdout);
} }
#endif #endif
}
//UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs); //UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs);
//UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs); //UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs);
for (th_id=0; th_id < RX_NB_TH; th_id++) { for (th_id=0; th_id < RX_NB_TH; th_id++) {
UE->proc.proc_rxtx[th_id].gotIQs=readTime(gotIQs); UE->proc.proc_rxtx[th_id].gotIQs=readTime(gotIQs);
} }
proc->nr_tti_rx=slot_nr; proc->subframe_tx=proc->nr_tti_rx;
proc->subframe_rx=table_sf_slot[slot_nr]; proc->timestamp_tx = timestamp+
(DURATION_RX_TO_TX*UE->frame_parms.samples_per_slot)-
proc->frame_tx = proc->frame_rx; UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0;
proc->nr_tti_tx= slot_nr + DURATION_RX_TO_TX; proc->instance_cnt_rxtx++;
if (proc->nr_tti_tx > nb_slot_frame) { LOG_D( PHY, "[SCHED][UE %d] UE RX instance_cnt_rxtx %d subframe %d !!\n", UE->Mod_id, proc->instance_cnt_rxtx,proc->subframe_rx);
proc->frame_tx = (proc->frame_tx + 1)%MAX_FRAME_NUMBER;
proc->nr_tti_tx %= nb_slot_frame; if (proc->instance_cnt_rxtx != 0) {
}
proc->subframe_tx=proc->nr_tti_rx;
proc->timestamp_tx = timestamp+
(DURATION_RX_TO_TX*UE->frame_parms.samples_per_slot)-
UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0;
proc->instance_cnt_rxtx++;
LOG_D( PHY, "[SCHED][UE %d] UE RX instance_cnt_rxtx %d subframe %d !!\n", UE->Mod_id, proc->instance_cnt_rxtx,proc->subframe_rx);
if (proc->instance_cnt_rxtx == 0) {
if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id);
exit_fun("nothing to add");
}
} else {
#ifdef SAIF_ENABLED #ifdef SAIF_ENABLED
g_ue_rx_thread_busy++; g_ue_rx_thread_busy++;
#endif #endif
if ( getenv("RFSIMULATOR") != NULL ) {
do { if ( getenv("RFSIMULATOR") != NULL ) {
AssertFatal (pthread_mutex_unlock(&proc->mutex_rxtx) == 0, ""); do {
usleep(100); AssertFatal (pthread_mutex_unlock(&proc->mutex_rxtx) == 0, "");
AssertFatal (pthread_mutex_lock(&proc->mutex_rxtx) == 0, ""); usleep(100);
} while ( proc->instance_cnt_rxtx >= 0); AssertFatal (pthread_mutex_lock(&proc->mutex_rxtx) == 0, "");
} while ( proc->instance_cnt_rxtx >= 0);
} else } else
LOG_E( PHY, "[SCHED][UE %d] !! UE RX thread busy (IC %d)!!\n", UE->Mod_id, proc->instance_cnt_rxtx); LOG_E( PHY, "[SCHED][UE %d] !! UE RX thread busy (IC %d)!!\n", UE->Mod_id, proc->instance_cnt_rxtx);
if (proc->instance_cnt_rxtx > 4)
{ AssertFatal( proc->instance_cnt_rxtx <= 4, "[SCHED][UE %d] !!! UE instance_cnt_rxtx > 2 (IC %d) (Proc %d)!!",
char exit_fun_string[256]; UE->Mod_id, proc->instance_cnt_rxtx,
sprintf(exit_fun_string,"[SCHED][UE %d] !!! UE instance_cnt_rxtx > 2 (IC %d) (Proc %d)!!", UE->current_thread_id[slot_nr]);
UE->Mod_id, proc->instance_cnt_rxtx, }
UE->current_thread_id[slot_nr]);
printf("%s\n",exit_fun_string); AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0,"");
fflush(stdout); AssertFatal (pthread_mutex_unlock(&proc->mutex_rxtx) ==0,"");
sleep(1); // initRefTimes(t1);
exit_fun(exit_fun_string); // initStaticTime(lastTime);
} // updateTimes(lastTime, &t1, 20000, "Delay between two IQ acquisitions (case 1)");
} // pickStaticTime(lastTime);
} //UE->mode != loop_through_memory
AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0 ,""); else {
AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); processSubframeRX(UE,proc);
// initRefTimes(t1); getchar();
// initStaticTime(lastTime); } // else loop_through_memory
// updateTimes(lastTime, &t1, 20000, "Delay between two IQ acquisitions (case 1)"); } // while !oai_exit
// pickStaticTime(lastTime);
} //UE->mode != loop_through_memory return NULL;
else {
proc->nr_tti_rx=slot_nr;
proc->subframe_rx=table_sf_slot[slot_nr];
if(slot_nr == 0) {
for (th_id=0; th_id < RX_NB_TH; th_id++) {
UE->proc.proc_rxtx[th_id].frame_rx++;
}
}
proc->frame_tx = proc->frame_rx;
proc->nr_tti_tx= slot_nr + DURATION_RX_TO_TX;
if (proc->nr_tti_tx > nb_slot_frame) {
proc->frame_tx = (proc->frame_tx + 1)%MAX_FRAME_NUMBER;
proc->nr_tti_tx %= nb_slot_frame;
}
proc->subframe_tx=table_sf_slot[proc->nr_tti_tx];
if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_DOWNLINK_SLOT) {
//clean previous FAPI MESSAGE
UE->rx_ind.number_pdus = 0;
UE->dci_ind.number_of_dcis = 0;
//clean previous FAPI MESSAGE
// call L2 for DL_CONFIG (DCI)
UE->dcireq.module_id = UE->Mod_id;
UE->dcireq.gNB_index = 0;
UE->dcireq.cc_id = 0;
UE->dcireq.frame = proc->frame_rx;
UE->dcireq.slot = proc->nr_tti_rx;
nr_ue_dcireq(&UE->dcireq); //to be replaced with function pointer later
NR_UE_MAC_INST_t *UE_mac = get_mac_inst(0);
UE_mac->scheduled_response.dl_config = &UE->dcireq.dl_config_req;
UE_mac->scheduled_response.slot = proc->nr_tti_rx;
nr_ue_scheduled_response(&UE_mac->scheduled_response);
//write_output("uerxdata_frame.m", "uerxdata_frame", UE->common_vars.rxdata[0], UE->frame_parms.samples_per_frame, 1, 1);
printf("Processing slot %d\n",proc->nr_tti_rx);
phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode);
}
if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL){
UE->ul_indication.module_id = 0;
UE->ul_indication.gNB_index = 0;
UE->ul_indication.cc_id = 0;
UE->ul_indication.frame = proc->frame_rx;
UE->ul_indication.slot = proc->nr_tti_rx;
UE->if_inst->ul_indication(&UE->ul_indication);
}
getchar();
} // else loop_through_memory
} // start_rx_stream==1
} // UE->is_synchronized==1
} // while !oai_exit
return NULL;
} }
/*! /*!
...@@ -1175,84 +1133,79 @@ void *UE_thread(void *arg) { ...@@ -1175,84 +1133,79 @@ void *UE_thread(void *arg) {
* and the locking between them. * and the locking between them.
*/ */
void init_UE_threads(PHY_VARS_NR_UE *UE) { void init_UE_threads(PHY_VARS_NR_UE *UE) {
struct nr_rxtx_thread_data *rtd; struct nr_rxtx_thread_data *rtd;
pthread_attr_init (&UE->proc.attr_ue);
pthread_attr_init (&UE->proc.attr_ue); pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN);
pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); pthread_mutex_init(&UE->proc.mutex_synch,NULL);
pthread_cond_init(&UE->proc.cond_synch,NULL);
pthread_mutex_init(&UE->proc.mutex_synch,NULL); UE->proc.instance_cnt_synch = -1;
pthread_cond_init(&UE->proc.cond_synch,NULL);
UE->proc.instance_cnt_synch = -1; // the threads are not yet active, therefore access is allowed without locking
for (int i=0; i<RX_NB_TH; i++) {
// the threads are not yet active, therefore access is allowed without locking rtd = calloc(1, sizeof(struct nr_rxtx_thread_data));
int nb_threads=RX_NB_TH;
for (int i=0; i<nb_threads; i++) { if (rtd == NULL) abort();
rtd = calloc(1, sizeof(struct nr_rxtx_thread_data));
if (rtd == NULL) abort(); rtd->UE = UE;
rtd->UE = UE; rtd->proc = &UE->proc.proc_rxtx[i];
rtd->proc = &UE->proc.proc_rxtx[i]; pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL);
pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL);
pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); UE->proc.proc_rxtx[i].sub_frame_start=i;
pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); UE->proc.proc_rxtx[i].sub_frame_step=RX_NB_TH;
UE->proc.proc_rxtx[i].sub_frame_start=i; printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,RX_NB_TH, i);
UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_thread_rxn_txnp4, rtd);
printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i);
pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_thread_rxn_txnp4, rtd);
#ifdef UE_DLSCH_PARALLELISATION #ifdef UE_DLSCH_PARALLELISATION
pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_dlsch_td,NULL); pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_dlsch_td,NULL);
pthread_cond_init(&UE->proc.proc_rxtx[i].cond_dlsch_td,NULL); pthread_cond_init(&UE->proc.proc_rxtx[i].cond_dlsch_td,NULL);
pthread_create(&UE->proc.proc_rxtx[i].pthread_dlsch_td,NULL,nr_dlsch_decoding_2thread0, rtd); pthread_create(&UE->proc.proc_rxtx[i].pthread_dlsch_td,NULL,nr_dlsch_decoding_2thread0, rtd);
//thread 2 //thread 2
pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_dlsch_td1,NULL); pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_dlsch_td1,NULL);
pthread_cond_init(&UE->proc.proc_rxtx[i].cond_dlsch_td1,NULL); pthread_cond_init(&UE->proc.proc_rxtx[i].cond_dlsch_td1,NULL);
pthread_create(&UE->proc.proc_rxtx[i].pthread_dlsch_td1,NULL,nr_dlsch_decoding_2thread1, rtd); pthread_create(&UE->proc.proc_rxtx[i].pthread_dlsch_td1,NULL,nr_dlsch_decoding_2thread1, rtd);
#endif #endif
#ifdef UE_SLOT_PARALLELISATION #ifdef UE_SLOT_PARALLELISATION
//pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot0_dl_processing,NULL); //pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot0_dl_processing,NULL);
//pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot0_dl_processing,NULL); //pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot0_dl_processing,NULL);
//pthread_create(&UE->proc.proc_rxtx[i].pthread_slot0_dl_processing,NULL,UE_thread_slot0_dl_processing, rtd); //pthread_create(&UE->proc.proc_rxtx[i].pthread_slot0_dl_processing,NULL,UE_thread_slot0_dl_processing, rtd);
pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot1_dl_processing,NULL);
pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot1_dl_processing,NULL); pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot1_dl_processing,NULL);
pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot1_dl_processing,NULL); pthread_create(&UE->proc.proc_rxtx[i].pthread_slot1_dl_processing,NULL,UE_thread_slot1_dl_processing, rtd);
pthread_create(&UE->proc.proc_rxtx[i].pthread_slot1_dl_processing,NULL,UE_thread_slot1_dl_processing, rtd);
#endif #endif
}
} pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void *)UE);
pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE);
} }
#ifdef OPENAIR2 #ifdef OPENAIR2
/* /*
void fill_ue_band_info(void) { void fill_ue_band_info(void) {
UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability; UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability;
int i,j; int i,j;
bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count; bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count;
for (i=0; i<bands_to_scan.nbands; i++) { for (i=0; i<bands_to_scan.nbands; i++) {
for (j=0; j<sizeof (eutra_bands) / sizeof (eutra_bands[0]); j++) for (j=0; j<sizeof (eutra_bands) / sizeof (eutra_bands[0]); j++)
if (eutra_bands[j].band == UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA) { if (eutra_bands[j].band == UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA) {
memcpy(&bands_to_scan.band_info[i], memcpy(&bands_to_scan.band_info[i],
&eutra_bands[j], &eutra_bands[j],
sizeof(eutra_band_t)); sizeof(eutra_band_t));
printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n", printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n",
bands_to_scan.band_info[i].band, bands_to_scan.band_info[i].band,
UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA, UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA,
bands_to_scan.band_info[i].dl_min, bands_to_scan.band_info[i].dl_min,
bands_to_scan.band_info[i].dl_max, bands_to_scan.band_info[i].dl_max,
bands_to_scan.band_info[i].ul_min, bands_to_scan.band_info[i].ul_min,
bands_to_scan.band_info[i].ul_max, bands_to_scan.band_info[i].ul_max,
(bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD"); (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD");
break; break;
} }
} }
}*/ }*/
#endif #endif
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment