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,7 +17,6 @@
//#define DEBUG_CRC
int main(int argc, char *argv[]) {
//Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.)
time_stats_t timeEncoder,timeDecoder;
opp_enabled=1;
......@@ -27,11 +26,9 @@ int main(int argc, char *argv[]) {
reset_meas(&timeDecoder);
randominit(0);
crcTableInit();
//Default simulation values (Aim for iterations = 1000000.)
int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI
double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB
double SNR, SNR_lin;
int16_t nBitError = 0; // -1 = Decoding failed (All list entries have failed the CRC checks).
uint32_t decoderState=0, blockErrorState=0; //0 = Success, -1 = Decoding failed, 1 = Block Error.
......@@ -40,8 +37,7 @@ int main(int argc, char *argv[]) {
uint8_t aggregation_level = 8, decoderListSize = 8, pathMetricAppr = 0;
while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:hqg")) != -1)
switch (arguments)
{
switch (arguments) {
case 's':
SNRstart = atof(optarg);
break;
......@@ -103,65 +99,54 @@ int main(int argc, char *argv[]) {
//coderLength = ;
}
//Logging
time_t currentTime;
time (&currentTime);
char fileName[512], currentTimeInfo[25];
char folderName[] = ".";
/*
folderName=getenv("HOME");
strcat(folderName,"/Desktop/polartestResults");
*/
#ifdef DEBUG_POLAR_TIMING
#ifdef DEBUG_POLAR_TIMING
sprintf(fileName,"%s/TIMING_ListSize_%d_pmAppr_%d_Payload_%d_Itr_%d",folderName,decoderListSize,pathMetricAppr,testLength,iterations);
#else
#else
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;
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
fprintf(logFile,",timeEncoderCRCByte[us],timeEncoderCRCBit[us],timeEncoderInterleaver[us],timeEncoderBitInsertion[us],timeEncoder1[us],timeEncoder2[us],timeEncoderRateMatching[us],timeEncoderByte2Bit[us]\n");
fprintf(logFile,
",timeEncoderCRCByte[us],timeEncoderCRCBit[us],timeEncoderInterleaver[us],timeEncoderBitInsertion[us],timeEncoder1[us],timeEncoder2[us],timeEncoderRateMatching[us],timeEncoderByte2Bit[us]\n");
#else
fprintf(logFile,",SNR,nBitError,blockErrorState,t_encoder[us],t_decoder[us]\n");
#endif
uint8_t testArrayLength = ceil(testLength / 32.0);
uint8_t coderArrayLength = ceil(coderLength / 32.0);
uint32_t testInput[testArrayLength]; //generate randomly
uint32_t encoderOutput[coderArrayLength];
uint32_t estimatedOutput[testArrayLength]; //decoder output
memset(testInput,0,sizeof(uint32_t) * testArrayLength);
memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength);
memset(estimatedOutput,0,sizeof(uint32_t) * testArrayLength);
uint8_t encoderOutputByte[coderLength];
double modulatedInput[coderLength]; //channel input
double channelOutput[coderLength]; //add noise
int16_t channelOutput_int16[coderLength];
t_nrPolar_paramsPtr nrPolar_params = NULL, currentPtr = NULL;
nr_polar_init(&nrPolar_params, polarMessageType, testLength, aggregation_level);
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
uint32_t dci_pdu[4];
memset(dci_pdu,0,sizeof(uint32_t)*4);
......@@ -173,11 +158,10 @@ int main(int argc, char *argv[]) {
uint16_t size=41;
uint16_t rnti=3;
aggregation_level=8;
nr_polar_init(&nrPolar_params, 1, size, aggregation_level);
t_nrPolar_paramsPtr currentPtrDCI=nr_polar_params(nrPolar_params, 1, size, aggregation_level);
t_nrPolar_params *currentPtrDCI=nr_polar_params(1, size, aggregation_level);
polar_encoder_dci(dci_pdu, encoder_output, currentPtrDCI, rnti);
for (int i=0;i<54;i++)
for (int i=0; i<54; i++)
printf("encoder_output: [%2d]->0x%08x \n",i, encoder_output[i]);
uint8_t *encoder_outputByte = malloc(sizeof(uint8_t) * currentPtrDCI->encoderLength);
......@@ -188,13 +172,15 @@ int main(int argc, char *argv[]) {
dci_estimation[0], dci_estimation[1], dci_estimation[2], dci_estimation[3]);
nr_bit2byte_uint32_8_t(encoder_output, currentPtrDCI->encoderLength, encoder_outputByte);
printf("[polartest] encoder_outputByte: ");
for (int i = 0; i < currentPtrDCI->encoderLength; i++) printf("%d-", encoder_outputByte[i]);
printf("\n");
for(int i=0; i<currentPtrDCI->encoderLength; i++) {
if (encoder_outputByte[i] == 0) {
channel_output[i]=1/sqrt(2);
}
else {
} else {
channel_output[i]=(-1)/sqrt(2);
}
}
......@@ -211,7 +197,6 @@ int main(int argc, char *argv[]) {
free(channel_output);
return 0;
#endif
#ifdef DEBUG_CRC
uint32_t crc;
unsigned int poly24c = 0xb2b11700;
......@@ -221,10 +206,8 @@ int main(int argc, char *argv[]) {
testInputCRC[1]=0x00000000;
testInputCRC[2]=0x00000000;
testInputCRC[3]=0x00000000;
uint32_t testInputcrc=0x01189400;
uint32_t testInputcrc2=0x00291880;
uint8_t testInputCRC2[8];
nr_crc_bit2bit_uint32_8_t(testInputCRC, 32, testInputCRC2);
printf("testInputCRC2: [0]->%x \t [1]->%x \t [2]->%x \t [3]->%x\n"
......@@ -234,35 +217,38 @@ int main(int argc, char *argv[]) {
unsigned int crc41 = crc24c(testInputCRC, 32);
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;
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));
testInputCRC[testLength>>3] = ((uint8_t*)&crc)[2];
testInputCRC[1+(testLength>>3)] = ((uint8_t*)&crc)[1];
testInputCRC[2+(testLength>>3)] = ((uint8_t*)&crc)[0];
testInputCRC[testLength>>3] = ((uint8_t *)&crc)[2];
testInputCRC[1+(testLength>>3)] = ((uint8_t *)&crc)[1];
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",
testInputCRC[0], testInputCRC[1], testInputCRC[2], testInputCRC[3]);
//uint32_t trial32 = 0xffffffff;
uint32_t trial32 = 0xf10fffff;
uint8_t a[4];
//memcpy(a, &trial32, sizeof(trial32));
*(uint32_t *)a = trial32;
unsigned char trial[4];
trial[0]=0xff; trial[1]=0xff; trial[2]=0x0f; trial[3]=0xf1;
trial[0]=0xff;
trial[1]=0xff;
trial[2]=0x0f;
trial[3]=0xf1;
uint32_t trialcrc = crc24c(trial, 32);
uint32_t trialcrc32 = crc24c((uint8_t *)&trial32, 32);
//uint32_t trialcrc32 = crc24c(a, 32);
printf("crcbit(trial = %x\n", crcbit(trial, 4, poly24c));
printf("trialcrc = %x\n", trialcrc);
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);
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};
......@@ -273,16 +259,19 @@ int main(int argc, char *argv[]) {
nr_polar_crc,
32,
24);
for (uint8_t i = 0; i < 24; i++){
for (uint8_t i = 0; i < 24; i++) {
nr_polar_crc[i] = (nr_polar_crc[i] % 2);
printf("nr_polar_crc[%d]=%d\n",i,nr_polar_crc[i]);
}
return 0;
#endif
#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++) {
......@@ -290,10 +279,12 @@ int main(int argc, char *argv[]) {
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);
......@@ -302,43 +293,41 @@ int main(int argc, char *argv[]) {
free(estimatedOutput);
return (0);
#endif
// We assume no a priori knowledge available about the payload.
double aPrioriArray[currentPtr->payloadBits];
for (int i=0; i<currentPtr->payloadBits; i++) aPrioriArray[i] = NAN;
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
printf("SNR %f\n",SNR);
SNR_lin = pow(10, SNR/10);
for (itr = 1; itr <= iterations; itr++) {
for (itr = 1; itr <= iterations; itr++) {
for (int i = 0; i < testArrayLength; i++) {
for (int j = 0; j < (sizeof(testInput[0])*8)-1; j++) {
testInput[i] |= ( ((uint32_t) (rand()%2)) &1);
testInput[i]<<=1;
}
testInput[i] |= ( ((uint32_t) (rand()%2)) &1);
}
/*printf("testInput: [0]->0x%08x\n", testInput[0]);
for (int i=0; i<32; i++)
printf("%d\n",(testInput[0]>>i)&1);*/
int len_mod64=currentPtr->payloadBits&63;
((uint64_t*)testInput)[currentPtr->payloadBits/64]&=((((uint64_t)1)<<len_mod64)-1);
((uint64_t *)testInput)[currentPtr->payloadBits/64]&=((((uint64_t)1)<<len_mod64)-1);
start_meas(&timeEncoder);
if (decoder_int16==0)
polar_encoder(testInput, encoderOutput, currentPtr);
else
polar_encoder_fast((uint64_t*)testInput, encoderOutput,0, currentPtr);
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]);
printf("encoderOutput: [1]->0x%08x\n", encoderOutput[1]);*/
//Bit-to-byte:
nr_bit2byte_uint32_8_t(encoderOutput, coderLength, encoderOutputByte);
......@@ -351,17 +340,15 @@ int main(int argc, char *argv[]) {
channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin)));
if (decoder_int16==1) {
if (channelOutput[i] > 15) channelOutput_int16[i] = 127;
else if (channelOutput[i] < -16) channelOutput_int16[i] = -128;
else channelOutput_int16[i] = (int16_t) (8*channelOutput[i]);
}
}
start_meas(&timeDecoder);
/*decoderState = polar_decoder(channelOutput,
estimatedOutput,
currentPtr,
......@@ -377,15 +364,13 @@ int main(int argc, char *argv[]) {
aPrioriArray);
else
decoderState = polar_decoder_int16(channelOutput_int16,
(uint64_t*)estimatedOutput,
(uint64_t *)estimatedOutput,
currentPtr);
stop_meas(&timeDecoder);
/*printf("testInput: [0]->0x%08x\n", testInput[0]);
printf("estimatedOutput: [0]->0x%08x\n", estimatedOutput[0]);*/
//calculate errors
if (decoderState!=0) {
blockErrorState=-1;
......@@ -393,10 +378,10 @@ int main(int argc, char *argv[]) {
} else {
for (int j = 0; j < currentPtr->payloadBits; j++) {
if (((estimatedOutput[0]>>j) & 1) != ((testInput[0]>>j) & 1)) nBitError++;
// printf("bit %d: %d => %d\n",j,(testInput[0]>>j)&1,(estimatedOutput[0]>>j)&1);
}
if (nBitError>0) {
blockErrorState=1;
// printf("Error: Input %x, Output %x\n",testInput[0],estimatedOutput[0]);
......@@ -420,8 +405,8 @@ int main(int argc, char *argv[]) {
decoderState=0;
nBitError=0;
blockErrorState=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),
......@@ -432,13 +417,14 @@ int main(int argc, char *argv[]) {
if (blockErrorCumulative==0 && bitErrorCumulative==0)
break;
blockErrorCumulative = 0; bitErrorCumulative = 0;
timeEncoderCumulative = 0; timeDecoderCumulative = 0;
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);
}
......@@ -42,12 +42,10 @@
int8_t polar_decoder(
double *input,
uint8_t *out,
t_nrPolar_paramsPtr polarParams,
t_nrPolar_params *polarParams,
uint8_t listSize,
uint8_t pathMetricAppr)
{
uint8_t pathMetricAppr) {
//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 **llrUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
......@@ -60,6 +58,7 @@ int8_t polar_decoder(
pathMetric[i] = 0;
crcState[i]=1;
}
for (int i=0; i<polarParams->N; i++) {
llrUpdated[i][polarParams->n]=1;
bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2);
......@@ -67,7 +66,8 @@ int8_t polar_decoder(
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
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));
tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
}
......@@ -77,9 +77,10 @@ int8_t polar_decoder(
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 ){
if( (i-polarParams->payloadBits) == j ) {
tempECGM[i][j]=1;
} else {
tempECGM[i][j]=0;
......@@ -95,6 +96,7 @@ int8_t polar_decoder(
//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;
......@@ -103,21 +105,21 @@ int8_t polar_decoder(
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];
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++){
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.
......@@ -127,12 +129,18 @@ int8_t polar_decoder(
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];}}}
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;
......@@ -140,12 +148,14 @@ int8_t polar_decoder(
//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);
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];
......@@ -154,6 +164,7 @@ int8_t polar_decoder(
swaps++;
}
}
if (swaps == 0)
break;
}
......@@ -167,11 +178,13 @@ int8_t polar_decoder(
}
}
}
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.
......@@ -181,6 +194,7 @@ int8_t polar_decoder(
} 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];
......@@ -188,28 +202,32 @@ int8_t polar_decoder(
}
}
}
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;
......@@ -226,6 +244,7 @@ int8_t polar_decoder(
}
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);
......@@ -244,6 +263,7 @@ int8_t polar_decoder(
}
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++) {
......@@ -252,11 +272,9 @@ int8_t polar_decoder(
//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];
......@@ -272,7 +290,6 @@ int8_t polar_decoder(
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.
*/
......@@ -282,11 +299,10 @@ int8_t polar_decoder(
int8_t polar_decoder_aPriori(double *input,
uint32_t *out,
t_nrPolar_paramsPtr polarParams,
t_nrPolar_params *polarParams,
uint8_t listSize,
uint8_t pathMetricAppr,
double *aPrioriPayload)
{
double *aPrioriPayload) {
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 **llrUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
......@@ -299,6 +315,7 @@ int8_t polar_decoder_aPriori(double *input,
pathMetric[i] = 0;
crcState[i]=1;
}
for (int i=0; i<polarParams->N; i++) {
llrUpdated[i][polarParams->n]=1;
bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2);
......@@ -306,7 +323,8 @@ int8_t polar_decoder_aPriori(double *input,
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
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));
tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
}
......@@ -316,9 +334,10 @@ int8_t polar_decoder_aPriori(double *input,
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 ){
if( (i-polarParams->payloadBits) == j ) {
tempECGM[i][j]=1;
} else {
tempECGM[i][j]=0;
......@@ -334,6 +353,7 @@ int8_t polar_decoder_aPriori(double *input,
//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;
......@@ -342,22 +362,21 @@ int8_t polar_decoder_aPriori(double *input,
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];
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++){
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.
......@@ -370,7 +389,9 @@ int8_t polar_decoder_aPriori(double *input,
(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 {
......@@ -380,12 +401,18 @@ int8_t polar_decoder_aPriori(double *input,
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];}}}
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;
......@@ -393,12 +420,14 @@ int8_t polar_decoder_aPriori(double *input,
//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);
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];
......@@ -407,6 +436,7 @@ int8_t polar_decoder_aPriori(double *input,
swaps++;
}
}
if (swaps == 0)
break;
}
......@@ -420,11 +450,13 @@ int8_t polar_decoder_aPriori(double *input,
}
}
}
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.
......@@ -434,6 +466,7 @@ int8_t polar_decoder_aPriori(double *input,
} 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];
......@@ -441,24 +474,29 @@ int8_t polar_decoder_aPriori(double *input,
}
}
}
for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) {
copyIndex = listIndex[(2*listSize-1)-k];
} else { //Use the backup.
copyIndex = listIndex[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;
}
}
......@@ -479,6 +517,7 @@ int8_t polar_decoder_aPriori(double *input,
}
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);
......@@ -497,6 +536,7 @@ int8_t polar_decoder_aPriori(double *input,
}
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++) {
......@@ -505,13 +545,13 @@ int8_t polar_decoder_aPriori(double *input,
//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;
}
}
......@@ -524,28 +564,23 @@ int8_t polar_decoder_aPriori(double *input,
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,
uint32_t *out,
t_nrPolar_paramsPtr polarParams,
t_nrPolar_params *polarParams,
uint8_t listSize,
uint8_t pathMetricAppr,
double *aPrioriPayload,
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 **llrUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
......@@ -558,6 +593,7 @@ int8_t polar_decoder_aPriori_timing(double *input,
pathMetric[i] = 0;
crcState[i]=1;
}
for (int i=0; i<polarParams->N; i++) {
llrUpdated[i][polarParams->n]=1;
bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2);
......@@ -565,7 +601,8 @@ int8_t polar_decoder_aPriori_timing(double *input,
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
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));
tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
}
......@@ -575,9 +612,10 @@ int8_t polar_decoder_aPriori_timing(double *input,
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 ){
if( (i-polarParams->payloadBits) == j ) {
tempECGM[i][j]=1;
} else {
tempECGM[i][j]=0;
......@@ -593,6 +631,7 @@ int8_t polar_decoder_aPriori_timing(double *input,
//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;
......@@ -601,21 +640,21 @@ int8_t polar_decoder_aPriori_timing(double *input,
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];
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++){
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.
......@@ -628,7 +667,9 @@ int8_t polar_decoder_aPriori_timing(double *input,
(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 {
......@@ -638,12 +679,18 @@ int8_t polar_decoder_aPriori_timing(double *input,
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];}}}
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;
......@@ -651,12 +698,14 @@ int8_t polar_decoder_aPriori_timing(double *input,
//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);
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];
......@@ -665,6 +714,7 @@ int8_t polar_decoder_aPriori_timing(double *input,
swaps++;
}
}
if (swaps == 0)
break;
}
......@@ -678,11 +728,13 @@ int8_t polar_decoder_aPriori_timing(double *input,
}
}
}
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.
......@@ -692,6 +744,7 @@ int8_t polar_decoder_aPriori_timing(double *input,
} 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];
......@@ -699,24 +752,29 @@ int8_t polar_decoder_aPriori_timing(double *input,
}
}
}
for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) {
copyIndex = listIndex[(2*listSize-1)-k];
} else { //Use the backup.
copyIndex = listIndex[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;
}
}
......@@ -737,6 +795,7 @@ int8_t polar_decoder_aPriori_timing(double *input,
}
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);
......@@ -755,6 +814,7 @@ int8_t polar_decoder_aPriori_timing(double *input,
}
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++) {
......@@ -763,7 +823,6 @@ int8_t polar_decoder_aPriori_timing(double *input,
//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);
......@@ -782,7 +841,6 @@ int8_t polar_decoder_aPriori_timing(double *input,
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.
*/
......@@ -793,12 +851,10 @@ int8_t polar_decoder_aPriori_timing(double *input,
int8_t polar_decoder_dci(double *input,
uint32_t *out,
t_nrPolar_paramsPtr polarParams,
t_nrPolar_params *polarParams,
uint8_t listSize,
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 **llrUpdated = nr_alloc_uint8_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
......@@ -812,6 +868,7 @@ int8_t polar_decoder_dci(double *input,
pathMetric[i] = 0;
crcState[i]=1;
}
for (int i=0; i<polarParams->N; i++) {
llrUpdated[i][polarParams->n]=1;
bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2);
......@@ -819,7 +876,8 @@ int8_t polar_decoder_dci(double *input,
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
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));
tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
}
......@@ -829,9 +887,10 @@ int8_t polar_decoder_dci(double *input,
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++) {
if( (i-polarParams->payloadBits) == j ){
if( (i-polarParams->payloadBits) == j ) {
tempECGM[i][j]=1;
} else {
tempECGM[i][j]=0;
......@@ -847,19 +906,22 @@ int8_t polar_decoder_dci(double *input,
//The index of the last 1-valued bit that appears in each column.
uint16_t last1ind[polarParams->crcParityBits];
for (int j=0; j<polarParams->crcParityBits; j++) {
for (int i=0; i<polarParams->K; i++) {
if (extended_crc_generator_matrix[i][j]==1) last1ind[j]=i;
}
}
for (int i=0;i<8;i++) extended_crc_scrambling_pattern[i]=0;
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;
}
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];
/*
......@@ -868,6 +930,7 @@ int8_t polar_decoder_dci(double *input,
for (int i=0; i<polarParams->crcParityBits; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) crcChecksum[i][0]=crcChecksum[i][0]+polarParams->crc_generator_matrix[j][i];
crcChecksum[i][0]=(crcChecksum[i][0]%2);
}
......@@ -877,8 +940,9 @@ int8_t polar_decoder_dci(double *input,
int16_t checkCrcBits=-1;
uint8_t listIndex[2*listSize], copyIndex;
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++){
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.
......@@ -888,12 +952,18 @@ int8_t polar_decoder_dci(double *input,
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];}}}
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;
......@@ -901,12 +971,14 @@ int8_t polar_decoder_dci(double *input,
//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);
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];
......@@ -915,6 +987,7 @@ int8_t polar_decoder_dci(double *input,
swaps++;
}
}
if (swaps == 0)
break;
}
......@@ -928,11 +1001,13 @@ int8_t polar_decoder_dci(double *input,
}
}
}
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.
......@@ -942,6 +1017,7 @@ int8_t polar_decoder_dci(double *input,
} 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];
......@@ -949,24 +1025,29 @@ int8_t polar_decoder_dci(double *input,
}
}
}
for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) {
copyIndex = listIndex[(2*listSize-1)-k];
} else { //Use the backup.
copyIndex = listIndex[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;
}
......@@ -986,6 +1067,7 @@ int8_t polar_decoder_dci(double *input,
}
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);
......@@ -1004,6 +1086,7 @@ int8_t polar_decoder_dci(double *input,
}
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++) {
......@@ -1012,7 +1095,6 @@ int8_t polar_decoder_dci(double *input,
//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);
......@@ -1031,7 +1113,6 @@ int8_t polar_decoder_dci(double *input,
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.
*/
......@@ -1040,20 +1121,20 @@ int8_t polar_decoder_dci(double *input,
}
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 < 129, "K = %d > 128, is not supported yet\n",polarParams->K);
int bit_i,ip,ipmod64;
int numbytes = polarParams->K>>3;
int residue = polarParams->K&7;
int numbits;
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;
else numbits=residue;
for (int i=0;i<numbits;i++) {
for (int i=0; i<numbits; i++) {
// flip bit endian for B
ip=polarParams->K - 1 - polarParams->interleaving_pattern[(8*byte)+i];
#if 0
......@@ -1061,43 +1142,39 @@ void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) {
#endif
ipmod64 = ip&63;
AssertFatal(ip<128,"ip = %d\n",ip);
for (int val=0;val<256;val++) {
for (int val=0; val<256; val++) {
bit_i=(val>>i)&1;
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,
uint64_t *out,
t_nrPolar_params *polarParams)
{
const t_nrPolar_params *polarParams) {
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);
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;
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);
//Extract the information bits (û to ĉ)
uint64_t Cprime[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);
uint64_t Cprime[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);
//Deinterleaving (ĉ to b)
uint8_t *Cprimebyte = (uint8_t*)Cprime;
uint8_t *Cprimebyte = (uint8_t *)Cprime;
if (polarParams->K<65) {
B[0] = polarParams->B_tab0[0][Cprimebyte[0]] |
polarParams->B_tab0[1][Cprimebyte[1]] |
......@@ -1107,47 +1184,46 @@ uint32_t polar_decoder_int16(int16_t *input,
polarParams->B_tab0[5][Cprimebyte[5]] |
polarParams->B_tab0[6][Cprimebyte[6]] |
polarParams->B_tab0[7][Cprimebyte[7]];
}
else if (polarParams->K<129) {
} else if (polarParams->K<129) {
int len = polarParams->K/8;
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[1] |= polarParams->B_tab1[k][Cprimebyte[k]];
}
}
int len=polarParams->payloadBits;
//int len_mod64=len&63;
int crclen = polarParams->crcParityBits;
uint64_t rxcrc=B[0]&((1<<crclen)-1);
uint32_t crc;
uint64_t Ar;
AssertFatal(len<65,"A must be less than 65 bits\n");
if (len<=32) {
Ar = (uint32_t)(B[0]>>crclen);
uint8_t A32_flip[4];
uint32_t Aprime= (uint32_t)(Ar<<(32-len));
A32_flip[0]=((uint8_t*)&Aprime)[3];
A32_flip[1]=((uint8_t*)&Aprime)[2];
A32_flip[2]=((uint8_t*)&Aprime)[1];
A32_flip[3]=((uint8_t*)&Aprime)[0];
A32_flip[0]=((uint8_t *)&Aprime)[3];
A32_flip[1]=((uint8_t *)&Aprime)[2];
A32_flip[2]=((uint8_t *)&Aprime)[1];
A32_flip[3]=((uint8_t *)&Aprime)[0];
crc = (uint64_t)(crc24c(A32_flip,len)>>8);
}
else if (len<=64) {
} else if (len<=64) {
Ar = (B[0]>>crclen) | (B[1]<<(64-crclen));;
uint8_t A64_flip[8];
uint64_t Aprime= (uint32_t)(Ar<<(64-len));
A64_flip[0]=((uint8_t*)&Aprime)[7];
A64_flip[1]=((uint8_t*)&Aprime)[6];
A64_flip[2]=((uint8_t*)&Aprime)[5];
A64_flip[3]=((uint8_t*)&Aprime)[4];
A64_flip[4]=((uint8_t*)&Aprime)[3];
A64_flip[5]=((uint8_t*)&Aprime)[2];
A64_flip[6]=((uint8_t*)&Aprime)[1];
A64_flip[7]=((uint8_t*)&Aprime)[0];
A64_flip[0]=((uint8_t *)&Aprime)[7];
A64_flip[1]=((uint8_t *)&Aprime)[6];
A64_flip[2]=((uint8_t *)&Aprime)[5];
A64_flip[3]=((uint8_t *)&Aprime)[4];
A64_flip[4]=((uint8_t *)&Aprime)[3];
A64_flip[5]=((uint8_t *)&Aprime)[2];
A64_flip[6]=((uint8_t *)&Aprime)[1];
A64_flip[7]=((uint8_t *)&Aprime)[0];
crc = (uint64_t)(crc24c(A64_flip,len)>>8);
}
......@@ -1157,11 +1233,6 @@ uint32_t polar_decoder_int16(int16_t *input,
B[1],B[0],Cprime[1],Cprime[0],crc,
rxcrc,polarParams->payloadBits);
#endif
out[0]=Ar;
return(crc^rxcrc);
}
......@@ -117,7 +117,7 @@ struct nrPolar_params {
uint64_t cprime_tab1[32][256];
uint64_t B_tab0[32][256];
uint64_t B_tab1[32][256];
uint32_t* crc256Table;
uint32_t *crc256Table;
uint8_t **extended_crc_generator_matrix;
//lowercase: bits, Uppercase: Bits stored in bytes
//polar_encoder vectors
......@@ -136,51 +136,50 @@ struct nrPolar_params {
decoder_tree_t tree;
} __attribute__ ((__packed__));
typedef struct nrPolar_params t_nrPolar_params;
typedef t_nrPolar_params *t_nrPolar_paramsPtr;
void polar_encoder(uint32_t *input,
uint32_t *output,
t_nrPolar_paramsPtr polarParams);
t_nrPolar_params *polarParams);
void polar_encoder_dci(uint32_t *in,
uint32_t *out,
t_nrPolar_paramsPtr polarParams,
t_nrPolar_params *polarParams,
uint16_t n_RNTI);
void polar_encoder_fast(uint64_t *A,
uint32_t *out,
int32_t crcmask,
t_nrPolar_paramsPtr polarParams);
t_nrPolar_params *polarParams);
int8_t polar_decoder(double *input,
uint8_t *output,
t_nrPolar_paramsPtr polarParams,
t_nrPolar_params *polarParams,
uint8_t listSize,
uint8_t pathMetricAppr);
uint32_t polar_decoder_int16(int16_t *input,
uint64_t *out,
t_nrPolar_params *polarParams);
const t_nrPolar_params *polarParams);
int8_t polar_decoder_aPriori(double *input,
uint32_t *output,
t_nrPolar_paramsPtr polarParams,
t_nrPolar_params *polarParams,
uint8_t listSize,
uint8_t pathMetricAppr,
double *aPrioriPayload);
int8_t polar_decoder_aPriori_timing(double *input,
uint32_t *output,
t_nrPolar_paramsPtr polarParams,
t_nrPolar_params *polarParams,
uint8_t listSize,
uint8_t pathMetricAppr,
double *aPrioriPayload,
double cpuFreqGHz,
FILE* logFile);
FILE *logFile);
int8_t polar_decoder_dci(double *input,
uint32_t *out,
t_nrPolar_paramsPtr polarParams,
t_nrPolar_params *polarParams,
uint8_t listSize,
uint8_t pathMetricAppr,
uint16_t n_RNTI);
......@@ -189,26 +188,20 @@ void generic_polar_decoder(t_nrPolar_params *,
decoder_node_t *);
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 nr_polar_init(t_nrPolar_paramsPtr *polarParams,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level);
void nr_polar_print_polarParams(t_nrPolar_paramsPtr polarParams);
void nr_polar_print_polarParams(t_nrPolar_params *polarParams);
t_nrPolar_paramsPtr nr_polar_params (t_nrPolar_paramsPtr polarParams,
int8_t messageType,
t_nrPolar_params *nr_polar_params ( int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level);
uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level);
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)
* @brief Computes...
......@@ -389,16 +382,14 @@ uint8_t **crc6_generator_matrix(uint16_t payloadSizeBits);
static inline void nr_polar_interleaver(uint8_t *input,
uint8_t *output,
uint16_t *pattern,
uint16_t size)
{
uint16_t size) {
for (int i=0; i<size; i++) output[i]=input[pattern[i]];
}
static inline void nr_polar_deinterleaver(uint8_t *input,
uint8_t *output,
uint16_t *pattern,
uint16_t size)
{
uint16_t size) {
for (int i=0; i<size; i++) {
output[pattern[i]]=input[i];
}
......
......@@ -42,40 +42,40 @@
void polar_encoder(uint32_t *in,
uint32_t *out,
t_nrPolar_paramsPtr polarParams)
{
if (polarParams->idx == 0){//PBCH
t_nrPolar_params *polarParams) {
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);
#ifdef DEBUG_POLAR_ENCODER
#ifdef DEBUG_POLAR_ENCODER
printf("polar_B %llx (crc %x)\n",B,crc24c((uint8_t*)in,polarParams->payloadBits)>>8);
#endif
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);
#endif
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);
/*
* Bytewise operations
*/
//Calculate CRC.
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_A,
polarParams->crc_generator_matrix,
polarParams->nr_polar_crc,
polarParams->payloadBits,
polarParams->crcParityBits);
for (uint8_t i = 0; i < polarParams->crcParityBits; i++)
polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
//Attach CRC to the Transport Block. (a to b)
for (uint16_t i = 0; i < polarParams->payloadBits; i++)
polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i];
for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++)
polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
#ifdef DEBUG_POLAR_ENCODER
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);
#endif
/* for (int j=0;j<polarParams->crcParityBits;j++) {
......@@ -83,9 +83,7 @@ nr_bit2byte_uint32_8_t((uint32_t*)&B, polarParams->K, polarParams->nr_polar_B);*
printf("%1d.%1d+",polarParams->crc_generator_matrix[i][j],polarParams->nr_polar_A[i]);
printf(" => %d\n",polarParams->nr_polar_crc[j]);
}*/
} else { //UCI
}
//Interleaving (c to c')
......@@ -93,14 +91,15 @@ nr_bit2byte_uint32_8_t((uint32_t*)&B, polarParams->K, polarParams->nr_polar_B);*
polarParams->nr_polar_CPrime,
polarParams->interleaving_pattern,
polarParams->K);
#ifdef DEBUG_POLAR_ENCODER
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);
if (polarParams->nr_polar_CPrime[i] == 1) printf("pos %d : %llx\n",i,Cprime);
}
printf("polar_Cprime %llx\n",Cprime);
#endif
//Bit insertion (c' to u)
......@@ -111,7 +110,6 @@ nr_bit2byte_uint32_8_t((uint32_t*)&B, polarParams->K, polarParams->nr_polar_B);*
polarParams->Q_I_N,
polarParams->Q_PC_N,
polarParams->n_pc);
//Encoding (u to d)
/* memset(polarParams->nr_polar_U,0,polarParams->N);
polarParams->nr_polar_U[247]=1;
......@@ -121,59 +119,68 @@ nr_bit2byte_uint32_8_t((uint32_t*)&B, polarParams->K, polarParams->nr_polar_B);*
polarParams->nr_polar_D,
polarParams->N,
polarParams->N);
for (uint16_t i = 0; i < polarParams->N; i++)
polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
uint64_t D[8];
memset((void*)D,0,8*sizeof(int64_t));
memset((void *)D,0,8*sizeof(int64_t));
#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",
D[0],D[1],D[2],D[3],D[4],D[5],D[6],D[7]);
#endif
//Rate matching
//Sub-block interleaving (d to y) and Bit selection (y to e)
nr_polar_interleaver(polarParams->nr_polar_D,
polarParams->nr_polar_E,
polarParams->rate_matching_pattern,
polarParams->encoderLength);
/*
* Return bits.
*/
#ifdef DEBUG_POLAR_ENCODER
for (int i=0; i< polarParams->encoderLength;i++) printf("f[%d]=%d\n", i, polarParams->nr_polar_E[i]);
#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);
}
void polar_encoder_dci(uint32_t *in,
uint32_t *out,
t_nrPolar_paramsPtr polarParams,
uint16_t n_RNTI)
{
t_nrPolar_params *polarParams,
uint16_t n_RNTI) {
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] in: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", in[0], in[1], in[2], in[3]);
#endif
/*
* Bytewise operations
*/
//(a to a')
nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_A);
for (int i=0; i<polarParams->crcParityBits; i++) polarParams->nr_polar_APrime[i]=1;
for (int i=0; i<polarParams->payloadBits; i++) polarParams->nr_polar_APrime[i+(polarParams->crcParityBits)]=polarParams->nr_polar_A[i];
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] A: ");
for (int i=0; i<polarParams->payloadBits; i++) printf("%d-", polarParams->nr_polar_A[i]);
printf("\n");
printf("[polar_encoder_dci] APrime: ");
for (int i=0; i<polarParams->K; i++) printf("%d-", polarParams->nr_polar_APrime[i]);
printf("\n");
printf("[polar_encoder_dci] GP: ");
for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->crc_generator_matrix[0][i]);
printf("\n");
#endif
//Calculate CRC.
......@@ -182,18 +189,24 @@ void polar_encoder_dci(uint32_t *in,
polarParams->nr_polar_crc,
polarParams->K,
polarParams->crcParityBits);
for (uint8_t i = 0; i < polarParams->crcParityBits; i++) polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] CRC: ");
for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->nr_polar_crc[i]);
printf("\n");
#endif
//Attach CRC to the Transport Block. (a to b)
for (uint16_t i = 0; i < polarParams->payloadBits; i++)
polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i];
for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++)
polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
//Scrambling (b to c)
for (int i=0; i<16; i++) {
polarParams->nr_polar_B[polarParams->payloadBits+8+i] =
......@@ -234,16 +247,16 @@ void polar_encoder_dci(uint32_t *in,
}*/
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] B: ");
for (int i = 0; i < polarParams->K; i++) printf("%d-", polarParams->nr_polar_B[i]);
printf("\n");
#endif
//Interleaving (c to c')
nr_polar_interleaver(polarParams->nr_polar_B,
polarParams->nr_polar_CPrime,
polarParams->interleaving_pattern,
polarParams->K);
//Bit insertion (c' to u)
nr_polar_bit_insertion(polarParams->nr_polar_CPrime,
polarParams->nr_polar_U,
......@@ -252,13 +265,13 @@ void polar_encoder_dci(uint32_t *in,
polarParams->Q_I_N,
polarParams->Q_PC_N,
polarParams->n_pc);
//Encoding (u to d)
nr_matrix_multiplication_uint8_1D_uint8_2D(polarParams->nr_polar_U,
polarParams->G_N,
polarParams->nr_polar_D,
polarParams->N,
polarParams->N);
for (uint16_t i = 0; i < polarParams->N; i++)
polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
......@@ -268,58 +281,61 @@ void polar_encoder_dci(uint32_t *in,
polarParams->nr_polar_E,
polarParams->rate_matching_pattern,
polarParams->encoderLength);
/*
* Return bits.
*/
nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] E: ");
for (int i = 0; i < polarParams->encoderLength; i++) printf("%d-", polarParams->nr_polar_E[i]);
uint8_t outputInd = ceil(polarParams->encoderLength / 32.0);
printf("\n[polar_encoder_dci] out: ");
for (int i = 0; i < outputInd; i++) {
printf("[%d]->0x%08x\t", i, out[i]);
}
#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_paramsPtr polarParams,void *in,void *out) {
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_params *polarParams,void *in,void *out) {
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
for (int i=0;i<polarParams->encoderLength>>4;i++) {
((uint16_t*)out)[i] = ((uint16_t *)in)[polarParams->rm_tab[i]];
for (int i=0; i<polarParams->encoderLength>>4; 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'
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);
int bit_i,ip;
int numbytes = polarParams->K>>3;
int residue = polarParams->K&7;
int numbits;
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;
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_tab1[byte][val] = 0;
for (int i=0;i<numbits;i++) {
for (int i=0; i<numbits; i++) {
// flip bit endian of B bitstring
ip=polarParams->deinterleaving_pattern[polarParams->K-1-((8*byte)+i)];
AssertFatal(ip<128,"ip = %d\n",ip);
bit_i=(val>>i)&1;
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));
}
......@@ -327,20 +343,24 @@ void build_polar_tables(t_nrPolar_paramsPtr polarParams) {
}
AssertFatal(polarParams->N==512,"N = %d, not done yet\n",polarParams->N);
// build G bit vectors for information bit positions and convert the bit as bytes tables in nr_polar_kronecker_power_matrices.c to 64 bit packed vectors.
// keep only rows of G which correspond to information/crc bits
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;
for (int i=0;i<polarParams->N;i++) {
for (int i=0; i<polarParams->N; i++) {
if (polarParams->information_bit_pattern[i] > 0) {
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));
for (int j=0;j<polarParams->N;j++)
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));
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
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");
#endif
k++;
......@@ -354,10 +374,11 @@ void build_polar_tables(t_nrPolar_paramsPtr polarParams) {
int firstingroup_out=0;
int firstingroup_in=iplast;
int mingroupsize = 1024;
// compute minimum group size of rate-matching pattern
for (int outpos=1; outpos<polarParams->encoderLength; outpos++) {
ip=polarParams->rate_matching_pattern[outpos];
if ((ip - iplast) == 1) ccnt++;
else {
groupcnt++;
......@@ -366,44 +387,44 @@ void build_polar_tables(t_nrPolar_paramsPtr polarParams) {
firstingroup_in,firstingroup_in+ccnt,
firstingroup_out,firstingroup_out+ccnt);
#endif
if ((ccnt+1)<mingroupsize) mingroupsize=ccnt+1;
ccnt=0;
firstingroup_out=outpos;
firstingroup_in=ip;
}
iplast=ip;
}
AssertFatal(mingroupsize==8 || mingroupsize==16,"mingroupsize %d, needs to be handled\n",mingroupsize);
polarParams->groupsize=mingroupsize;
int shift=3;
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
int tcnt=0;
for (int outpos=0;outpos<polarParams->encoderLength; outpos+=mingroupsize,tcnt++)
polarParams->rm_tab[tcnt] = polarParams->rate_matching_pattern[outpos]>>shift;
for (int outpos=0; outpos<polarParams->encoderLength; outpos+=mingroupsize,tcnt++)
polarParams->rm_tab[tcnt] = polarParams->rate_matching_pattern[outpos]>>shift;
}
void polar_encoder_fast(uint64_t *A,
uint32_t *out,
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 < 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);
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;
// append crc
AssertFatal(bitlen<129,"support for payloads <= 128 bits\n");
AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n");
//int bitlen0=bitlen;
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
......@@ -413,39 +434,39 @@ void polar_encoder_fast(uint64_t *A,
if (bitlen<=32) {
uint8_t A32_flip[4];
uint32_t Aprime= (uint32_t)(((uint32_t)*A)<<(32-bitlen));
A32_flip[0]=((uint8_t*)&Aprime)[3];
A32_flip[1]=((uint8_t*)&Aprime)[2];
A32_flip[2]=((uint8_t*)&Aprime)[1];
A32_flip[3]=((uint8_t*)&Aprime)[0];
A32_flip[0]=((uint8_t *)&Aprime)[3];
A32_flip[1]=((uint8_t *)&Aprime)[2];
A32_flip[2]=((uint8_t *)&Aprime)[1];
A32_flip[3]=((uint8_t *)&Aprime)[0];
tcrc = (uint64_t)((crcmask^(crc24c(A32_flip,bitlen)>>8)));
}
else if (bitlen<=64) {
} else if (bitlen<=64) {
uint8_t A64_flip[8];
uint64_t Aprime= (uint32_t)(((uint64_t)*A)<<(64-bitlen));
A64_flip[0]=((uint8_t*)&Aprime)[7];
A64_flip[1]=((uint8_t*)&Aprime)[6];
A64_flip[2]=((uint8_t*)&Aprime)[5];
A64_flip[3]=((uint8_t*)&Aprime)[4];
A64_flip[4]=((uint8_t*)&Aprime)[3];
A64_flip[5]=((uint8_t*)&Aprime)[2];
A64_flip[6]=((uint8_t*)&Aprime)[1];
A64_flip[7]=((uint8_t*)&Aprime)[0];
A64_flip[0]=((uint8_t *)&Aprime)[7];
A64_flip[1]=((uint8_t *)&Aprime)[6];
A64_flip[2]=((uint8_t *)&Aprime)[5];
A64_flip[3]=((uint8_t *)&Aprime)[4];
A64_flip[4]=((uint8_t *)&Aprime)[3];
A64_flip[5]=((uint8_t *)&Aprime)[2];
A64_flip[6]=((uint8_t *)&Aprime)[1];
A64_flip[7]=((uint8_t *)&Aprime)[0];
tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,bitlen)>>8)));
}
int n;
// this is number of quadwords in the bit string
int quadwlen = (polarParams->K>>6);
if ((polarParams->K&63) > 0) quadwlen++;
// 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
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));
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
if (polarParams->K<65)
Cprime[0] = polarParams->cprime_tab0[0][Bbyte[0]] |
......@@ -456,15 +477,15 @@ void polar_encoder_fast(uint64_t *A,
polarParams->cprime_tab0[5][Bbyte[5]] |
polarParams->cprime_tab0[6][Bbyte[6]] |
polarParams->cprime_tab0[7][Bbyte[7]];
else if (polarParams->K < 129) {
for (int i=0;i<1+(polarParams->K/8);i++) {
for (int i=0; i<1+(polarParams->K/8); i++) {
Cprime[0] |= polarParams->cprime_tab0[i][Bbyte[i]];
Cprime[1] |= polarParams->cprime_tab1[i][Bbyte[i]];
}
}
#ifdef DEBUG_POLAR_ENCODER
if (polarParams->K<65)
printf("A %llx B %llx Cprime %llx (payload bits %d,crc %x)\n",
(unsigned long long)(A[0]&(((uint64_t)1<<bitlen)-1)),
......@@ -486,8 +507,9 @@ void polar_encoder_fast(uint64_t *A,
(unsigned long long)(B[1]),(unsigned long long)(B[0]),
(unsigned long long)(Cprime[1]),(unsigned long long)(Cprime[0]),
polarParams->payloadBits,
crc24c((uint8_t*)A,bitlen)>>8);
crc24c((uint8_t *)A,bitlen)>>8);
}
#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("%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",polarParams->cprime_tab[0][Bbyte[0]] ,
......@@ -498,10 +520,8 @@ void polar_encoder_fast(uint64_t *A,
polarParams->cprime_tab[5][Bbyte[5]] ,
polarParams->cprime_tab[6][Bbyte[6]] ,
polarParams->cprime_tab[7][Bbyte[7]]);*/
// now do Gu product (here using 64-bit XORs, we can also do with SIMD after)
// here we're reading out the bits LSB -> MSB, is this correct w.r.t. 3GPP ?
uint64_t Cprime_i;
/* 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],
......@@ -512,15 +532,15 @@ void polar_encoder_fast(uint64_t *A,
polarParams->G_N_tab[0][5],
polarParams->G_N_tab[0][6],
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 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
/*
#ifdef DEBUG_POLAR_ENCODER
#ifdef DEBUG_POLAR_ENCODER
printf("%llx Cprime_%d (%llx) G %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
Cprime_i,off+i,(Cprime[j]>>i) &1,
polarParams->G_N_tab[off+i][0],
......@@ -531,7 +551,7 @@ void polar_encoder_fast(uint64_t *A,
polarParams->G_N_tab[off+i][5],
polarParams->G_N_tab[off+i][6],
polarParams->G_N_tab[off+i][7]);
#endif
#endif
*/
uint64_t *Gi=polarParams->G_N_tab[off+i];
D[0] ^= (Cprime_i & Gi[0]);
......@@ -544,6 +564,7 @@ void polar_encoder_fast(uint64_t *A,
D[7] ^= (Cprime_i & Gi[7]);
}
}
#ifdef DEBUG_POLAR_ENCODER
printf("D %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
D[0],
......@@ -555,7 +576,5 @@ void polar_encoder_fast(uint64_t *A,
D[6],
D[7]);
#endif
polar_rate_matching(polarParams,(void*)D,(void*)out);
polar_rate_matching(polarParams,(void *)D,(void *)out);
}
......@@ -37,16 +37,14 @@
#include "PHY/NR_TRANSPORT/nr_dci.h"
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,
uint16_t messageLength,
uint8_t aggregation_level)
{
t_nrPolar_paramsPtr currentPtr = *polarParams;
uint8_t aggregation_level) {
t_nrPolar_params *currentPtr = *polarParams;
uint16_t aggregation_prime = nr_polar_aggregation_prime(aggregation_level);
//Parse the list. If the node is already created, return without initialization.
......@@ -58,10 +56,9 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
// printf("currentPtr %p (polarParams %p)\n",currentPtr,polarParams);
//Else, initialize and add node to the end of the linked list.
t_nrPolar_paramsPtr newPolarInitNode = malloc(sizeof(t_nrPolar_params));
t_nrPolar_params *newPolarInitNode = malloc(sizeof(t_nrPolar_params));
if (newPolarInitNode != NULL) {
newPolarInitNode->idx = (messageType * messageLength * aggregation_prime);
newPolarInitNode->nextPtr = NULL;
//printf("newPolarInitNode->idx %d, (%d,%d,%d:%d)\n",newPolarInitNode->idx,messageType,messageLength,aggregation_prime,aggregation_level);
......@@ -93,7 +90,6 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
newPolarInitNode->crc_generator_matrix=crc24c_generator_matrix(newPolarInitNode->payloadBits+newPolarInitNode->crcParityBits);//G_P
//printf("Initializing polar parameters for DCI (K %d, E %d, L %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength,aggregation_level);
} else if (messageType == -1) { //UCI
} else {
AssertFatal(1 == 0, "[nr_polar_init] Incorrect Message Type(%d)", messageType);
}
......@@ -102,31 +98,25 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
newPolarInitNode->N = nr_polar_output_length(newPolarInitNode->K, newPolarInitNode->encoderLength, newPolarInitNode->n_max);
newPolarInitNode->n = log2(newPolarInitNode->N);
newPolarInitNode->G_N = nr_polar_kronecker_power_matrices(newPolarInitNode->n);
//polar_encoder vectors:
newPolarInitNode->nr_polar_crc = malloc(sizeof(uint8_t) * newPolarInitNode->crcParityBits);
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);
newPolarInitNode->nr_polar_D = malloc(sizeof(uint8_t) * newPolarInitNode->N);
newPolarInitNode->nr_polar_E = malloc(sizeof(uint8_t) * newPolarInitNode->encoderLength);
//Polar Coding vectors
newPolarInitNode->nr_polar_U = malloc(sizeof(uint8_t) * newPolarInitNode->N); //Decoder: nr_polar_uHat
newPolarInitNode->nr_polar_CPrime = malloc(sizeof(uint8_t) * newPolarInitNode->K); //Decoder: nr_polar_cHat
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
newPolarInitNode->Q_0_Nminus1 = nr_polar_sequence_pattern(newPolarInitNode->n);
newPolarInitNode->interleaving_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->K);
nr_polar_interleaving_pattern(newPolarInitNode->K,
newPolarInitNode->i_il,
newPolarInitNode->interleaving_pattern);
newPolarInitNode->deinterleaving_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->K);
for (int i=0;i<newPolarInitNode->K;i++)
for (int i=0; i<newPolarInitNode->K; i++)
newPolarInitNode->deinterleaving_pattern[newPolarInitNode->interleaving_pattern[i]] = i;
newPolarInitNode->rate_matching_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength);
......@@ -137,13 +127,14 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
newPolarInitNode->K,
newPolarInitNode->N,
newPolarInitNode->encoderLength);
newPolarInitNode->information_bit_pattern = malloc(sizeof(uint8_t) * newPolarInitNode->N);
newPolarInitNode->Q_I_N = malloc(sizeof(int16_t) * (newPolarInitNode->K + newPolarInitNode->n_pc));
newPolarInitNode->Q_F_N = malloc( sizeof(int16_t) * (newPolarInitNode->N + 1)); // Last element shows the final array index assigned a value.
newPolarInitNode->Q_PC_N = malloc( sizeof(int16_t) * (newPolarInitNode->n_pc));
for (int i = 0; i <= newPolarInitNode->N; i++)
newPolarInitNode->Q_F_N[i] = -1; // Empty array.
nr_polar_info_bit_pattern(newPolarInitNode->information_bit_pattern,
newPolarInitNode->Q_I_N,
newPolarInitNode->Q_F_N,
......@@ -154,81 +145,63 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
newPolarInitNode->encoderLength,
newPolarInitNode->n_pc);
// sort the Q_I_N array in ascending order (first K positions)
qsort((void*)newPolarInitNode->Q_I_N,newPolarInitNode->K,sizeof(int16_t),intcmp);
qsort((void *)newPolarInitNode->Q_I_N,newPolarInitNode->K,sizeof(int16_t),intcmp);
newPolarInitNode->channel_interleaver_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength);
nr_polar_channel_interleaver_pattern(newPolarInitNode->channel_interleaver_pattern,
newPolarInitNode->i_bil,
newPolarInitNode->encoderLength);
free(J);
build_decoder_tree(newPolarInitNode);
build_polar_tables(newPolarInitNode);
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;
AssertFatal(1 == 0, "[nr_polar_init] New t_nrPolar_params * could not be created");
}
//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);
//Fixme: the list is not thread safe
//The defect is not critical: we always append (never delete items) and adding two times the same is fine
newPolarInitNode->nextPtr=*polarParams;
*polarParams=newPolarInitNode;
return;
}
void nr_polar_print_polarParams(t_nrPolar_paramsPtr polarParams)
{
void nr_polar_print_polarParams(t_nrPolar_params *polarParams) {
uint8_t i = 0;
if (polarParams == NULL) {
printf("polarParams is empty.\n");
} else {
while (polarParams != NULL){
while (polarParams != NULL) {
printf("polarParams[%d] = %d\n", i, polarParams->idx);
polarParams = polarParams->nextPtr;
i++;
}
}
return;
}
t_nrPolar_paramsPtr nr_polar_params (t_nrPolar_paramsPtr polarParams,
int8_t messageType,
t_nrPolar_params *nr_polar_params ( int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level)
{
t_nrPolar_paramsPtr currentPtr = NULL;
uint8_t aggregation_level) {
static t_nrPolar_params *polarList = NULL;
nr_polar_init(&polarList, messageType,messageLength,aggregation_level);
t_nrPolar_params *polarParams=polarList;
const int tag=messageType * messageLength * nr_polar_aggregation_prime(aggregation_level);
while (polarParams != NULL) {
if (polarParams->idx ==
(messageType * messageLength * (nr_polar_aggregation_prime(aggregation_level)) )) {
currentPtr = polarParams;
break;
} else {
if (polarParams->idx == tag)
return polarParams;
polarParams = polarParams->nextPtr;
}
}
return currentPtr;
AssertFatal(false,"Polar Init tables internal failure\n");
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;
else if (aggregation_level == 1) return NR_POLAR_AGGREGATION_LEVEL_1_PRIME;
else if (aggregation_level == 2) return NR_POLAR_AGGREGATION_LEVEL_2_PRIME;
......
......@@ -41,60 +41,49 @@ extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn);
extern int32_t get_uldl_offset(int nr_bandP);
int l1_north_init_gNB() {
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_CC!=NULL,"nb_nr_L1_CC 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);
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.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]);
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);
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);
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;
}
}
}
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);
}
return(0);
}
int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
unsigned char is_secondary_gNB,
unsigned char abstraction_flag)
{
unsigned char abstraction_flag) {
// shortcuts
NR_DL_FRAME_PARMS* const fp = &gNB->frame_parms;
nfapi_nr_config_request_t* cfg = &gNB->gNB_config;
NR_gNB_COMMON* const common_vars = &gNB->common_vars;
LTE_eNB_PUSCH** const pusch_vars = gNB->pusch_vars;
LTE_eNB_SRS* const srs_vars = gNB->srs_vars;
LTE_eNB_PRACH* const prach_vars = &gNB->prach_vars;
NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms;
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars;
LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;
int i, UE_id;
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_transmitted_bits = 0;
gNB->total_system_throughput = 0;
......@@ -103,7 +92,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
while(gNB->configured == 0) usleep(10000);
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",
gNB->Mod_id,
fp->N_RB_DL,fp->phich_config_common.phich_resource,
......@@ -117,28 +106,21 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset
);*/
LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_gNB][MOD %02"PRIu8"][]\n", gNB->Mod_id);
crcTableInit();
init_dfts();
// PBCH DMRS gold sequences generation
nr_init_pbch_dmrs(gNB);
// 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
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;
AssertFatal(pdcch_dmrs!=NULL, "NR init: pdcch_dmrs malloc failed\n");
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);
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));
AssertFatal(pdcch_dmrs[slot][symb]!=NULL, "NR init: pdcch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
}
......@@ -146,19 +128,20 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
nr_init_pdcch_dmrs(gNB, cfg->sch_config.physical_cell_id.value);
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***));
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**));
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);
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);
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);
}
}
......@@ -168,7 +151,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
/// Transport init necessary for NR synchro
init_nr_transport(gNB);
/*
/*
lte_gold(fp,gNB->lte_gold_table,fp->Nid_cell);
generate_pcfich_reg_mapping(fp);
generate_phich_reg_mapping(fp);*/
......@@ -176,97 +159,84 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; 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.
// clear whole structure
bzero( &gNB->UE_stats[UE_id], sizeof(LTE_eNB_UE_stats) );
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->txdataF = (int32_t **)malloc16(15*sizeof(int32_t*));
common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t*));
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 = (int32_t **)malloc16(15*sizeof(int32_t *));
common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t *));
for (i=0; i<15; i++) {
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",
i,common_vars->txdataF[i],
fp->samples_per_frame_wCP*sizeof(int32_t));
}
// Channel estimates for SRS
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_time = (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 *) );
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_time[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
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 );
}
} //UE_id
/*generate_ul_ref_sigs_rx();
init_ulsch_power_LUT();*/
// SRS
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_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
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));
prach_vars->prach_ifft[0] = (int32_t **)malloc16_clear(64*sizeof(int32_t *));
prach_vars->rxsigF[0] = (int16_t**)malloc16_clear(64*sizeof(int16_t*));
for (i=0; i<64; i++) prach_vars->prach_ifft[0][i] = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t));
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
prach_vars->rxsigF[0] = (int16_t **)malloc16_clear(64*sizeof(int16_t *));
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
//FIXME
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_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_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]->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] = (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_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_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]->ul_ch_mag = (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++) {
// RK 2 times because of output format of FFT!
// 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_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_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]->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]->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]->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]->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_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
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; 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
return (0);
}
/*
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;
//nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
NR_gNB_COMMON* const common_vars = &gNB->common_vars;
LTE_eNB_PUSCH** const pusch_vars = gNB->pusch_vars;
LTE_eNB_SRS* const srs_vars = gNB->srs_vars;
LTE_eNB_PRACH* const prach_vars = &gNB->prach_vars;
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars;
LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
int i, UE_id;
for (i = 0; i < 15; i++) {
free_and_zero(common_vars->txdataF[i]);
/* rxdataF[i] is not allocated -> don't free */
}
free_and_zero(common_vars->txdataF);
free_and_zero(common_vars->rxdataF);
// PDCCH DMRS sequences
free_and_zero(pdcch_dmrs);
......@@ -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_time[i]);
}
free_and_zero(srs_vars[UE_id].srs_ch_estimates);
free_and_zero(srs_vars[UE_id].srs_ch_estimates_time);
} //UE_id
......@@ -351,8 +320,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_and_zero(prach_vars->prachF);
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]);
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)
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]->rxdataF_ext);
free_and_zero(pusch_vars[UE_id]->rxdataF_ext2);
free_and_zero(pusch_vars[UE_id]->drs_ch_estimates);
......@@ -387,11 +357,9 @@ void install_schedule_handlers(IF_Module_t *if_inst)
/// 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;
nfapi_nr_config_request_t *gNB_config = &gNB->gNB_config;
//overwrite for new NR parameters
gNB_config->nfapi_config.rf_bands.rf_band[0] = 78;
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,
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.physical_cell_id.value=Nid_cell;
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->ul_CarrierFreq = fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
fp->threequarter_fs = 0;
nr_init_frame_parms(gNB_config, fp);
gNB->configured = 1;
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;
int CC_id = phy_config->CC_id;
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;
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->subframe_config.numerology_index_mu.value = phy_config->cfg->subframe_config.numerology_index_mu.value;//1
......@@ -441,17 +399,14 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config)
if (phy_config->cfg->subframe_config.duplex_mode.value == 0) {
gNB_config->subframe_config.duplex_mode.value = TDD;
}
else {
} else {
gNB_config->subframe_config.duplex_mode.value = FDD;
}
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->ul_CarrierFreq = fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
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",
Mod_id,
CC_id,
......@@ -460,38 +415,35 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config)
gNB_config->rf_config.ul_carrier_bandwidth.value,
gNB_config->sch_config.physical_cell_id.value,
fp->dl_CarrierFreq );
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");
return;
}
RC.gNB[Mod_id][CC_id]->configured = 1;
LOG_I(PHY,"gNB %d/%d configured\n",Mod_id,CC_id);
}
void init_nr_transport(PHY_VARS_gNB *gNB) {
int i;
int j;
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
LOG_I(PHY, "Initialise nr transport\n");
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
for (j=0; j<2; j++) {
gNB->dlsch[i][j] = new_gNB_dlsch(1,16,NSOFT,0,fp,cfg);
if (!gNB->dlsch[i][j]) {
LOG_E(PHY,"Can't get gNB dlsch structures for UE %d \n", i);
exit(-1);
}/* 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);
}*/
......@@ -499,19 +451,17 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
//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);
/*if (!gNB->ulsch[1+i]) {
LOG_E(PHY,"Can't get gNB ulsch structures\n");
exit(-1);
}*/
// 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
//gNB->transmission_mode[i] = fp->nb_antenna_ports_gNB==1 ? 1 : 2;
}
// ULSCH for RA
//gNB->ulsch[0] = new_gNB_ulsch(MAX_TURBO_ITERATIONS, fp->N_RB_UL, 0);
/*if (!gNB->ulsch[0]) {
LOG_E(PHY,"Can't get gNB ulsch structures\n");
exit(-1);
......@@ -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);
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);
gNB->rx_total_gain_dB=130;
for(i=0; i<NUMBER_OF_UE_MAX; i++)
gNB->mu_mimo_mode[i].dl_pow_off = 2;
gNB->check_for_total_transmissions = 0;
gNB->check_for_MUMIMO_transmissions = 0;
gNB->FULL_MUMIMO_transmissions = 0;
gNB->check_for_SUMIMO_transmissions = 0;
//fp->pucch_config_common.deltaPUCCH_Shift = 1;
}
......@@ -42,12 +42,11 @@ extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
nfapi_nr_rnti_type_e rnti_type,
uint16_t N_RB,
nfapi_nr_config_request_t* config)
{
nfapi_nr_config_request_t *config) {
uint16_t size = 0;
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:
/// 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;
......@@ -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
size += 28;
size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment
break;
case NFAPI_NR_DL_DCI_FORMAT_1_1:
......@@ -109,7 +107,6 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
// CBGTI
// CBGFI
size += 1; // DMRS sequence init
break;
case NFAPI_NR_DL_DCI_FORMAT_2_0:
......@@ -135,11 +132,9 @@ void nr_pdcch_scrambling(uint32_t *in,
uint16_t size,
uint32_t Nid,
uint32_t n_RNTI,
uint32_t* out) {
uint32_t *out) {
uint8_t reset;
uint32_t x1, x2, s=0;
reset = 1;
x2 = (n_RNTI<<16) + Nid;
......@@ -147,26 +142,24 @@ void nr_pdcch_scrambling(uint32_t *in,
if ((i&0x1f)==0) {
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
if (i){
if (i) {
in++;
out++;
}
}
(*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);
}
}
uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
t_nrPolar_paramsPtr *nrPolar_params,
uint32_t **gold_pdcch_dmrs,
int32_t* txdataF,
int32_t *txdataF,
int16_t amp,
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
uint32_t dmrs_seq[NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD];
uint16_t dmrs_offset=0;
......@@ -176,7 +169,6 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
nr_cce_t cce;
nr_reg_t reg;
nr_reg_t reg_mapping_list[NR_MAX_PDCCH_AGG_LEVEL*NR_NB_REG_PER_CCE];
/*First iteration: single DCI*/
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;
......@@ -185,31 +177,29 @@ 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
* or the rb_offset for other coresets
* 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 +
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_symb = pdcch_params.first_symbol;
cset_nsymb = pdcch_params.n_symb;
dci_idx = 0;
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
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)
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);
/// DMRS QPSK modulation
/*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*/
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++)
gold_pdcch_dmrs[symb] += (pdcch_params.rb_offset*3)>>5;
dmrs_offset = (pdcch_params.rb_offset*3)&0x1f;
LOG_I(PHY, "PDCCH DMRS offset %d\n", dmrs_offset);
}
......@@ -218,18 +208,20 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
if (dmrs_offset) {
// 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));
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);
#ifdef DEBUG_PDCCH_DMRS
//printf("out 0x%08x in 0x%08x \n", dmrs_seq[(i>>5)], gold_pdcch_dmrs[symb][(i+dmrs_offset)>>5]);
#endif
}
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]);
#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],
......@@ -237,49 +229,46 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
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
#endif
}
/// DCI payload processing
// CRC attachment + Scrambling + Channel coding + Rate matching
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 Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)?
pdcch_params.scrambling_id : config.sch_config.physical_cell_id.value;
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);
t_nrPolar_params *currentPtr = nr_polar_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);
#ifdef DEBUG_CHANNEL_CODING
printf("polar rnti %d\n",pdcch_params.rnti);
printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n",
dci_alloc.dci_pdu[0], dci_alloc.dci_pdu[1]);
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("\n");
#endif
/// 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);
#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",
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] );
#endif
/// QPSK modulation
int16_t mod_dci[NR_MAX_DCI_SIZE>>1];
nr_modulation(scrambled_output, encoded_length, MOD_QPSK, mod_dci);
#ifdef DEBUG_DCI
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] );
#endif
/// Resource mapping
......@@ -287,22 +276,26 @@ printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%0
if (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;
for (int cce_idx=0; cce_idx<dci_alloc.L; cce_idx++){
for (int cce_idx=0; cce_idx<dci_alloc.L; cce_idx++) {
cce = dci_alloc.cce_list[cce_idx];
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
printf("\n Ordered REG list:\n");
for (int i=0; i<nb_regs; i++)
printf("%d\t",reg_mapping_list[i].reg_idx );
printf("\n");
#endif
......@@ -311,16 +304,19 @@ printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%0
for (l=cset_start_symb; l<cset_start_symb+ cset_nsymb; l++) {
dmrs_idx = 0;
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;
((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
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]);
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]);
#endif
k+=4;
if (k >= frame_parms.ofdm_symbol_size)
k -= frame_parms.ofdm_symbol_size;
dmrs_idx++;
}
}
......@@ -331,34 +327,39 @@ printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%0
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;
((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
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]);
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]);
#endif
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;
((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
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]);
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]);
#endif
dci_idx++;
}
k++;
if (k >= frame_parms.ofdm_symbol_size)
k -= frame_parms.ofdm_symbol_size;
}
......
......@@ -30,12 +30,11 @@ typedef unsigned __int128 uint128_t;
uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
nfapi_nr_rnti_type_e rnti_type,
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,
t_nrPolar_paramsPtr *nrPolar_params,
uint32_t **gold_pdcch_dmrs,
int32_t* txdataF,
int32_t *txdataF,
int16_t amp,
NR_DL_FRAME_PARMS frame_parms,
nfapi_nr_config_request_t config);
......@@ -44,7 +43,7 @@ void nr_pdcch_scrambling(uint32_t *in,
uint16_t size,
uint32_t Nid,
uint32_t n_RNTI,
uint32_t* out);
uint32_t *out);
void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
int frame,
......@@ -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_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
......@@ -43,21 +43,20 @@
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,
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,
int32_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
nfapi_nr_config_request_t* config,
NR_DL_FRAME_PARMS *frame_parms)
{
nfapi_nr_config_request_t *config,
NR_DL_FRAME_PARMS *frame_parms) {
int k,l;
//int16_t a;
int16_t mod_dmrs[NR_PBCH_DMRS_LENGTH<<1];
uint8_t idx=0;
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);
/// QPSK modulation
......@@ -72,8 +71,6 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
}
/// 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;
......@@ -83,12 +80,12 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
#ifdef DEBUG_PBCH_DMRS
printf("m %d at k %d of l %d\n", m, k, l);
#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) + 1] = (amp * mod_dmrs[(m<<1) + 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;
#ifdef DEBUG_PBCH_DMRS
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)+1]);
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
#endif
k+=4;
......@@ -104,12 +101,12 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
#ifdef DEBUG_PBCH_DMRS
printf("m %d at k %d of l %d\n", m, k, l);
#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) + 1] = (amp * mod_dmrs[(m<<1) + 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;
#ifdef DEBUG_PBCH_DMRS
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)+1]);
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
#endif
k+=(m==71)?148:4; // Jump from 44+nu to 192+nu
......@@ -125,12 +122,12 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
#ifdef DEBUG_PBCH_DMRS
printf("m %d at k %d of l %d\n", m, k, l);
#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) + 1] = (amp * mod_dmrs[(m<<1) + 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;
#ifdef DEBUG_PBCH_DMRS
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)+1]);
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
#endif
k+=4;
......@@ -138,8 +135,6 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
k-=frame_parms->ofdm_symbol_size;
}
#ifdef DEBUG_PBCH_DMRS
write_output("txdataF_pbch_dmrs.m", "txdataF_pbch_dmrs", txdataF[0], frame_parms->samples_per_frame_wCP>>1, 1, 1);
#endif
......@@ -186,6 +181,7 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
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
}
......@@ -206,7 +202,7 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
void nr_init_pbch_interleaver(uint8_t *interleaver) {
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++)
if (!i) // choice bit:1
......@@ -221,11 +217,9 @@ void nr_init_pbch_interleaver(uint8_t *interleaver) {
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_hrf);
else // Ssb bits:3
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_ssb++);
}
int nr_generate_pbch(NR_gNB_PBCH *pbch,
t_nrPolar_paramsPtr polar_params,
uint8_t *pbch_pdu,
uint8_t *interleaver,
int32_t *txdataF,
......@@ -235,10 +229,8 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
uint8_t Lmax,
uint8_t ssb_index,
int sfn,
nfapi_nr_config_request_t* config,
NR_DL_FRAME_PARMS *frame_parms)
{
nfapi_nr_config_request_t *config,
NR_DL_FRAME_PARMS *frame_parms) {
int k,l,m;
//int16_t a;
int16_t mod_pbch_e[NR_POLAR_PBCH_E];
......@@ -247,18 +239,19 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
uint8_t nushift;
uint32_t unscrambling_mask;
uint64_t a_reversed=0;
LOG_I(PHY, "PBCH generation started\n");
///Payload generation
memset((void*)pbch, 0, sizeof(NR_gNB_PBCH));
memset((void *)pbch, 0, sizeof(NR_gNB_PBCH));
pbch->pbch_a=0;
for (int i=0; i<NR_PBCH_PDU_BITS; i++)
pbch->pbch_a |= ((pbch_pdu[2-(i>>3)]>>(7-(i&7)))&1)<<i;
#ifdef DEBUG_PBCH_ENCODING
for (int i=0; i<3; i++)
printf("pbch_pdu[%d]: 0x%02x\n", i, pbch_pdu[i]);
printf("PBCH payload = 0x%08x\n",pbch->pbch_a);
#endif
......@@ -289,7 +282,6 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
printf("Interleaving:\n");
printf("pbch_a_interleaved: 0x%08x\n", pbch->pbch_a_interleaved);
#endif
// Scrambling
unscrambling_mask = (Lmax ==64)? 0x100006D:0x1000041;
M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3);
......@@ -301,37 +293,40 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
printf("pbch_a_prime: 0x%08x\n", pbch->pbch_a_prime);
#endif
// Encoder reversal
// Encoder reversal
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++)
a_reversed |= (((uint64_t)pbch->pbch_a_prime>>i)&1)<<(31-i);
/// 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
printf("Channel coding:\n");
for (int i=0; i<NR_POLAR_PBCH_E_DWORD; i++)
printf("pbch_e[%d]: 0x%08x\t", i, pbch->pbch_e[i]);
printf("\n");
#endif
/// Scrambling
M = NR_POLAR_PBCH_E;
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);
#ifdef DEBUG_PBCH_ENCODING
printf("Scrambling:\n");
for (int i=0; i<NR_POLAR_PBCH_E_DWORD; i++)
printf("pbch_e[%d]: 0x%08x\t", i, pbch->pbch_e[i]);
printf("\n");
#endif
/// 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);
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];
#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]);
#endif
......@@ -339,8 +334,6 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
/// Resource mapping
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
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
......@@ -348,17 +341,15 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
m = 0;
for (int ssb_sc_idx = 0; ssb_sc_idx < 240; ssb_sc_idx++) {
if ((ssb_sc_idx&3) == nushift) { //skip DMRS
k++;
continue;
}
else {
} else {
#ifdef DEBUG_PBCH
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
#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) + 1] = (amp * mod_pbch_e[(m<<1) + 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;
k++;
m++;
}
......@@ -373,17 +364,15 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
m=180;
for (int ssb_sc_idx = 0; ssb_sc_idx < 48; ssb_sc_idx++) {
if ((ssb_sc_idx&3) == nushift) {
k++;
continue;
}
else {
} else {
#ifdef DEBUG_PBCH
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
#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) + 1] = (amp * mod_pbch_e[(m<<1) + 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;
k++;
m++;
}
......@@ -393,23 +382,22 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
}
k += 144;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
m=216;
for (int ssb_sc_idx = 192; ssb_sc_idx < 240; ssb_sc_idx++) {
if ((ssb_sc_idx&3) == nushift) {
k++;
continue;
}
else {
} else {
#ifdef DEBUG_PBCH
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
#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) + 1] = (amp * mod_pbch_e[(m<<1) + 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;
k++;
m++;
}
......@@ -424,17 +412,15 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
m=252;
for (int ssb_sc_idx = 0; ssb_sc_idx < 240; ssb_sc_idx++) {
if ((ssb_sc_idx&3) == nushift) {
k++;
continue;
}
else {
} else {
#ifdef DEBUG_PBCH
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
#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) + 1] = (amp * mod_pbch_e[(m<<1) + 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;
k++;
m++;
}
......@@ -443,6 +429,5 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
k-=frame_parms->ofdm_symbol_size;
}
return 0;
}
......@@ -36,7 +36,7 @@ int nr_generate_pss( int16_t *d_pss,
int32_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
nfapi_nr_config_request_t* config,
nfapi_nr_config_request_t *config,
NR_DL_FRAME_PARMS *frame_parms);
/*!
......@@ -49,7 +49,7 @@ int nr_generate_sss( int16_t *d_sss,
int32_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
nfapi_nr_config_request_t* config,
nfapi_nr_config_request_t *config,
NR_DL_FRAME_PARMS *frame_parms);
/*!
......@@ -62,7 +62,7 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
int32_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
nfapi_nr_config_request_t* config,
nfapi_nr_config_request_t *config,
NR_DL_FRAME_PARMS *frame_parms);
/*!
......@@ -85,7 +85,6 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
@returns 0 on success
*/
int nr_generate_pbch(NR_gNB_PBCH *pbch,
t_nrPolar_paramsPtr polar_params,
uint8_t *pbch_pdu,
uint8_t *interleaver,
int32_t *txdataF,
......@@ -95,7 +94,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
uint8_t Lmax,
uint8_t ssb_index,
int sfn,
nfapi_nr_config_request_t* config,
nfapi_nr_config_request_t *config,
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 @@
//#define DEBUG_PBCH_ENCODING
#ifdef OPENAIR2
//#include "PHY_INTERFACE/defs.h"
//#include "PHY_INTERFACE/defs.h"
#endif
#define PBCH_A 24
......@@ -53,17 +53,13 @@ uint16_t nr_pbch_extract(int **rxdataF,
uint32_t symbol,
uint32_t s_offset,
uint32_t high_speed_flag,
NR_DL_FRAME_PARMS *frame_parms)
{
NR_DL_FRAME_PARMS *frame_parms) {
uint16_t rb;
uint8_t i,j,aarx;
int32_t *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
int nushiftmod4 = frame_parms->nushift;
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;
AssertFatal(symbol>=1 && symbol<5,
......@@ -71,18 +67,19 @@ uint16_t nr_pbch_extract(int **rxdataF,
symbol);
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
rxF = &rxdataF[aarx][(symbol+s_offset)*frame_parms->ofdm_symbol_size];
rxF_ext = &rxdataF_ext[aarx][symbol*20*12];
#ifdef DEBUG_PBCH
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);
int16_t *p = (int16_t *)rxF;
for (int i =0; i<8;i++){
for (int i =0; i<8; i++) {
printf("rxF [%d]= %d\n",i,rxF[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
for (rb=0; rb<20; rb++) {
......@@ -96,19 +93,21 @@ uint16_t nr_pbch_extract(int **rxdataF,
rxF_ext[j]=rxF[rx_offset];
#ifdef DEBUG_PBCH
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])[1],
((int16_t *)&rxF_ext[j])[0],
((int16_t *)&rxF_ext[j])[1],
rx_offset,
((int16_t*)&rxF[rx_offset])[0],
((int16_t*)&rxF[rx_offset])[1]);
((int16_t *)&rxF[rx_offset])[0],
((int16_t *)&rxF[rx_offset])[1]);
#endif
j++;
}
rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1);
}
rxF_ext+=9;
} else { //symbol 2
if ((rb < 4) || (rb >15)){
if ((rb < 4) || (rb >15)) {
for (i=0; i<12; i++) {
if ((i!=nushiftmod4) &&
(i!=(nushiftmod4+4)) &&
......@@ -116,20 +115,20 @@ uint16_t nr_pbch_extract(int **rxdataF,
rxF_ext[j]=rxF[rx_offset];
#ifdef DEBUG_PBCH
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])[1],
((int16_t *)&rxF_ext[j])[0],
((int16_t *)&rxF_ext[j])[1],
rx_offset,
((int16_t*)&rxF[rx_offset])[0],
((int16_t*)&rxF[rx_offset])[1]);
((int16_t *)&rxF[rx_offset])[0],
((int16_t *)&rxF[rx_offset])[1]);
#endif
j++;
}
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);
}
}
......@@ -139,11 +138,11 @@ uint16_t nr_pbch_extract(int **rxdataF,
dl_ch0 = &dl_ch_estimates[aarx][0];
//printf("dl_ch0 addr %p\n",dl_ch0);
dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*20*12];
for (rb=0; rb<20; rb++) {
j=0;
if (symbol==1 || symbol==3) {
for (i=0; i<12; i++) {
if ((i!=nushiftmod4) &&
......@@ -151,13 +150,15 @@ uint16_t nr_pbch_extract(int **rxdataF,
(i!=(nushiftmod4+8))) {
dl_ch0_ext[j]=dl_ch0[i];
#ifdef DEBUG_PBCH
if ((rb==0) && (i<2))
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])[1],
((int16_t *)&dl_ch0_ext[j])[0],
((int16_t *)&dl_ch0_ext[j])[1],
i,
((int16_t*)&dl_ch0[i])[0],
((int16_t*)&dl_ch0[i])[1]);
((int16_t *)&dl_ch0[i])[0],
((int16_t *)&dl_ch0[i])[1]);
#endif
j++;
}
......@@ -165,9 +166,8 @@ uint16_t nr_pbch_extract(int **rxdataF,
dl_ch0+=12;
dl_ch0_ext+=9;
}
else {
if ((rb < 4) || (rb >15)){
} else {
if ((rb < 4) || (rb >15)) {
for (i=0; i<12; i++) {
if ((i!=nushiftmod4) &&
(i!=(nushiftmod4+4)) &&
......@@ -175,17 +175,19 @@ uint16_t nr_pbch_extract(int **rxdataF,
dl_ch0_ext[j]=dl_ch0[i];
#ifdef DEBUG_PBCH
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])[1],
((int16_t *)&dl_ch0_ext[j])[0],
((int16_t *)&dl_ch0_ext[j])[1],
i,
((int16_t*)&dl_ch0[i])[0],
((int16_t*)&dl_ch0[i])[1]);
((int16_t *)&dl_ch0[i])[0],
((int16_t *)&dl_ch0[i])[1]);
#endif
j++;
}
}
dl_ch0_ext+=9;
}
dl_ch0+=12;
}
}
......@@ -199,12 +201,9 @@ uint16_t nr_pbch_extract(int **rxdataF,
//compute average channel_level on each (TX,RX) antenna pair
int nr_pbch_channel_level(int **dl_ch_estimates_ext,
NR_DL_FRAME_PARMS *frame_parms,
uint32_t symbol)
{
uint32_t symbol) {
int16_t rb, nb_rb=20;
uint8_t aarx;
#if defined(__x86_64__) || defined(__i386__)
__m128i avg128;
__m128i *dl_ch128;
......@@ -216,22 +215,21 @@ int nr_pbch_channel_level(int **dl_ch_estimates_ext,
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
//clear average level
#if defined(__x86_64__) || defined(__i386__)
avg128 = _mm_setzero_si128();
dl_ch128=(__m128i *)&dl_ch_estimates_ext[aarx][symbol*20*12];
#elif defined(__arm__)
avg128 = vdupq_n_s32(0);
dl_ch128=(int16x8_t *)&dl_ch_estimates_ext[aarx][symbol*20*12];
#endif
for (rb=0; rb<nb_rb; rb++) {
#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[1],dl_ch128[1]));
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[2],dl_ch128[2]));
#elif defined(__arm__)
// to be filled in
// to be filled in
#endif
dl_ch128+=3;
/*
......@@ -240,25 +238,24 @@ int nr_pbch_channel_level(int **dl_ch_estimates_ext,
print_shorts("dl_ch128",&dl_ch128[1]);
print_shorts("dl_ch128",&dl_ch128[2]);
}*/
}
avg1 = (((int*)&avg128)[0] +
((int*)&avg128)[1] +
((int*)&avg128)[2] +
((int*)&avg128)[3])/(nb_rb*12);
avg1 = (((int *)&avg128)[0] +
((int *)&avg128)[1] +
((int *)&avg128)[2] +
((int *)&avg128)[3])/(nb_rb*12);
if (avg1>avg2)
avg2 = avg1;
//LOG_I(PHY,"Channel level : %d, %d\n",avg1, avg2);
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
return(avg2);
}
void nr_pbch_channel_compensation(int **rxdataF_ext,
......@@ -267,9 +264,7 @@ void nr_pbch_channel_compensation(int **rxdataF_ext,
NR_DL_FRAME_PARMS *frame_parms,
uint32_t symbol,
uint8_t output_shift) {
const uint16_t nb_re=symbol == 2 ? 72 : 180;
AssertFatal((symbol > 0 && symbol < 4),
"symbol %d is illegal for PBCH DM-RS\n",
symbol);
......@@ -277,7 +272,6 @@ void nr_pbch_channel_compensation(int **rxdataF_ext,
// printf("comp: symbol %d : nb_re %d\n",symbol,nb_re);
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
vect128 *dl_ch128 = (vect128 *)&dl_ch_estimates_ext[aarx][symbol*20*12];
vect128 *rxdataF128 = (vect128 *)&rxdataF_ext[aarx][symbol*20*12];
vect128 *rxdataF_comp128 = (vect128 *)&rxdataF_comp[aarx][symbol*20*12];
......@@ -297,9 +291,7 @@ void nr_pbch_channel_compensation(int **rxdataF_ext,
void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
int **rxdataF_comp,
uint8_t symbol)
{
uint8_t symbol) {
uint8_t symbol_mod;
int i, nb_rb=6;
#if defined(__x86_64__) || defined(__i386__)
......@@ -316,15 +308,14 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
#elif defined(__arm__)
rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[0][symbol_mod*6*12];
rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[1][symbol_mod*6*12];
#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++) {
#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));
#elif defined(__arm__)
rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
#endif
}
}
......@@ -341,14 +332,11 @@ void nr_pbch_unscrambling(NR_UE_PBCH *pbch,
uint16_t M,
uint16_t length,
uint8_t bitwise,
uint32_t unscrambling_mask)
{
uint32_t unscrambling_mask) {
uint8_t reset, offset;
uint32_t x1, x2, s=0;
uint8_t k=0;
int16_t *demod_pbch_e = pbch->llr;
reset = 1;
// x1 is set in first call to lte_gold_generic
x2 = Nid; //this is c_init
......@@ -358,6 +346,7 @@ void nr_pbch_unscrambling(NR_UE_PBCH *pbch,
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
// Scrambling is now done with offset (nushift*M)%32
offset = (nushift*M)&0x1f;
......@@ -366,40 +355,40 @@ void nr_pbch_unscrambling(NR_UE_PBCH *pbch,
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}*/
if (bitwise) {
if (((k+offset)&0x1f)==0 && (!((unscrambling_mask>>i)&1))) {
s = lte_gold_generic(&x1, &x2, reset);
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));
#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
}
else {
} else {
if (((i+offset)&0x1f)==0) {
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
if (((s>>((i+offset)&0x1f))&1)==1)
demod_pbch_e[i] = -demod_pbch_e[i];
#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]);
#endif
}
}
}
void nr_pbch_quantize(int16_t *pbch_llr8,
int16_t *pbch_llr,
uint16_t len)
{
uint16_t len) {
uint16_t i;
for (i=0; i<len; i++) {
......@@ -409,7 +398,6 @@ void nr_pbch_quantize(int16_t *pbch_llr8,
pbch_llr8[i]=-32;
else
pbch_llr8[i] = (char)(pbch_llr[i]);
}
}
/*
......@@ -426,13 +414,9 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t eNB_id,
MIMO_mode_t mimo_mode,
uint32_t high_speed_flag)
{
uint32_t high_speed_flag) {
NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars;
int max_h=0;
int symbol;
//uint8_t pbch_a[64];
uint8_t *pbch_a = malloc(sizeof(uint8_t) * 32);
......@@ -447,22 +431,16 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
//unsigned short idx_demod =0;
uint32_t decoderState=0;
//uint8_t decoderListSize = 8, pathMetricAppr = 0;
//time_stats_t polar_decoder_init,polar_rate_matching,decoding,bit_extraction,deinterleaving;
//time_stats_t path_metric,sorting,update_LLR;
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);
int subframe_rx = proc->subframe_rx;
pbch_e_rx = &nr_ue_pbch_vars->llr[0];
// clear LLR buffer
memset(nr_ue_pbch_vars->llr,0,NR_POLAR_PBCH_E);
int symbol_offset=1;
if (ue->is_synchronized > 0)
symbol_offset=4;
else
......@@ -476,7 +454,6 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
// symbol refers to symbol within SSB. symbol_offset is the offset of the SSB wrt start of slot
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_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,
......@@ -500,7 +477,6 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
#ifdef DEBUG_PBCH
LOG_I(PHY,"[PHY] PBCH log2_maxh = %d (%d)\n",nr_ue_pbch_vars->log2_maxh,max_h);
#endif
nr_pbch_channel_compensation(nr_ue_pbch_vars->rxdataF_ext,
nr_ue_pbch_vars->dl_ch_estimates_ext,
nr_ue_pbch_vars->rxdataF_comp,
......@@ -513,92 +489,70 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
nr_ue_pbch_vars->rxdataF_comp,
symbol);*/
/*
/*
if (mimo_mode == ALAMOUTI) {
nr_pbch_alamouti(frame_parms,nr_ue_pbch_vars->rxdataF_comp,symbol);
} else if (mimo_mode != SISO) {
LOG_I(PHY,"[PBCH][RX] Unsupported MIMO mode\n");
return(-1);
}
*/
*/
if (symbol==1) {
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);
pbch_e_rx+=144;
} else {
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);
pbch_e_rx+=360;
}
}
#ifdef DEBUG_PBCH
write_output("rxdataF_comp.m","rxFcomp",&nr_ue_pbch_vars->rxdataF_comp[0][240],240*3,1,1);
#endif
pbch_e_rx = nr_ue_pbch_vars->llr;
//demod_pbch_e = nr_ue_pbch_vars->demod_pbch_e;
pbch_a = nr_ue_pbch_vars->pbch_a;
#ifdef DEBUG_PBCH
//pbch_e_rx = &nr_ue_pbch_vars->llr[0];
short *p = (short *)&(nr_ue_pbch_vars->rxdataF_comp[0][20*12]);
for (int cnt = 0; cnt < 864 ; cnt++)
printf("pbch rx llr %d\n",*(pbch_e_rx+cnt));
#endif
//un-scrambling
M = NR_POLAR_PBCH_E;
nushift = (Lmax==4)? ssb_index&3 : ssb_index&7;
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);
//polar decoding de-rate matching
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);
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);
if(decoderState) return(decoderState);
// printf("polar decoder output 0x%08x\n",nr_ue_pbch_vars->pbch_a_prime);
// Decoder reversal
uint32_t a_reversed=0;
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);
nr_ue_pbch_vars->pbch_a_prime = a_reversed;
//payload un-scrambling
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);
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);
//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
//uint32_t in=0;
uint32_t out=0;
for (int i=0; i<32; i++) {
out |= ((nr_ue_pbch_vars->pbch_a_interleaved>>i)&1)<<(pbch_deinterleaving_pattern[i]);
#ifdef DEBUG_PBCH
......@@ -618,12 +572,13 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
#ifdef DEBUG_PBCH
printf("xtra_byte %x payload %x\n", xtra_byte, payload);
for (int i=0; i<(NR_POLAR_PBCH_PAYLOAD_BITS>>3); i++){
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
#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;
......
......@@ -391,7 +391,6 @@ typedef struct PHY_VARS_gNB_s {
Sched_Rsp_t Sched_INFO;
NR_gNB_PDCCH pdcch_vars;
NR_gNB_PBCH pbch;
t_nrPolar_paramsPtr nrPolar_params;
LTE_eNB_PHICH phich_vars[2];
NR_gNB_COMMON common_vars;
......
......@@ -49,28 +49,28 @@
//#include <complex.h>
#include "assertions.h"
#ifdef MEX
# define msg mexPrintf
#define msg mexPrintf
#else
# ifdef OPENAIR2
# if ENABLE_RAL
# include "collection/hashtable/hashtable.h"
# include "COMMON/ral_messages_types.h"
# include "UTIL/queue.h"
# endif
# define msg(aRGS...) LOG_D(PHY, ##aRGS)
# else
# define msg printf
# endif
#ifdef OPENAIR2
#if ENABLE_RAL
#include "collection/hashtable/hashtable.h"
#include "COMMON/ral_messages_types.h"
#include "UTIL/queue.h"
#endif
#define msg(aRGS...) LOG_D(PHY, ##aRGS)
#else
#define msg printf
#endif
#endif
//use msg in the real-time thread context
#define msg_nrt printf
//use msg_nrt in the non real-time context (for initialization, ...)
#ifndef malloc16
# ifdef __AVX2__
# define malloc16(x) memalign(32,x)
# else
# define malloc16(x) memalign(16,x)
# endif
#ifdef __AVX2__
#define malloc16(x) memalign(32,x)
#else
#define malloc16(x) memalign(16,x)
#endif
#endif
#define free16(y,x) free(y)
#define bigmalloc malloc
......@@ -146,7 +146,7 @@
#if defined(UPGRADE_RAT_NR)
#include "PHY/NR_REFSIG/ss_pbch_nr.h"
#include "PHY/NR_REFSIG/ss_pbch_nr.h"
#endif
......@@ -167,12 +167,12 @@ typedef struct {
uint8_t CC_id;
/// timestamp transmitted to HW
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
int nr_tti_tx;
/// NR TTI index within subframe_rx [0 .. ttis_per_subframe - 1] to act upon for reception
int nr_tti_rx;
//#endif
//#endif
/// subframe to act upon for transmission
int subframe_tx;
/// subframe to act upon for reception
......@@ -410,7 +410,7 @@ typedef struct {
/// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
/// - third index: samples? [0..2*ofdm_symbol_size[
int32_t **dl_ch_estimates_time[7];
}NR_UE_COMMON_PER_THREAD;
} NR_UE_COMMON_PER_THREAD;
typedef struct {
/// \brief Holds the transmit data in time domain.
......@@ -663,7 +663,8 @@ typedef enum {
_format_2_0_found=4,
_format_2_1_found=5,
_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 _C_RNTI_ 0
#define _CS_RNTI_ 1
......@@ -678,7 +679,7 @@ typedef enum {
#define _TPC_PUSCH_RNTI_ 10
#define _TPC_PUCCH_RNTI_ 11
#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 */
_cs_rnti = _CS_RNTI_, /* Configured Scheduling RNTI */
_new_rnti = _NEW_RNTI_, /* ? */
......@@ -691,7 +692,8 @@ typedef enum {
_int_rnti = _INT_RNTI_, /* Indication pre-emption in DL */
_tpc_pusch_rnti = _TPC_PUSCH_RNTI_, /* PUSCH 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;
......@@ -762,13 +764,13 @@ 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)
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;
// 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)
// 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)
typedef enum {common=0,ue_specific=1} NR_SEARCHSPACE_TYPE_t;
typedef struct {
/*
/*
* 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
* common: Configures this search space as common search space (CSS) and DCI formats to monitor
......@@ -793,7 +795,7 @@ typedef struct {
} NR_UE_PDCCH_SEARCHSPACE_TYPE;
typedef struct {
/*
/*
* define SearchSpace structure according to 38.331
*
* searchSpaceId: Identity of the search space. SearchSpaceId = 0 identifies the SearchSpace configured via PBCH (MIB)
......@@ -892,8 +894,7 @@ typedef struct {
//Check for specific DCIFormat and AgregationLevel
uint8_t dciFormat;
uint8_t agregationLevel;
t_nrPolar_paramsPtr nrPolar_params;
#ifdef NR_PDCCH_DEFS_NR_UE
#ifdef NR_PDCCH_DEFS_NR_UE
int nb_searchSpaces;
// 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];
......@@ -903,7 +904,7 @@ typedef struct {
int n_RB_BWP[NR_NBR_SEARCHSPACE_ACT_BWP];
uint32_t nb_search_space;
#endif
#endif
} NR_UE_PDCCH;
#define PBCH_A 24
......@@ -933,8 +934,6 @@ typedef struct {
/// \brief Pointer to PBCH decoded output.
/// - first index: ? [0..63] (hard coded)
uint8_t *decoded_output;
/// polar decoder parameters
t_nrPolar_paramsPtr nrPolar_params;
/// \brief Total number of PDU errors.
uint32_t pdu_errors;
/// \brief Total number of PDU errors 128 frames ago.
......@@ -1192,7 +1191,7 @@ typedef struct {
PUCCH_CONFIG_DEDICATED pucch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX];
//#if defined(UPGRADE_RAT_NR)
//#if defined(UPGRADE_RAT_NR)
#if 1
SystemInformationBlockType1_nr_t systemInformationBlockType1_nr;
......@@ -1234,7 +1233,7 @@ typedef struct {
/// Scheduling Request Config
SCHEDULING_REQUEST_CONFIG scheduling_request_config[NUMBER_OF_CONNECTED_eNB_MAX];
//#if defined(UPGRADE_RAT_NR)
//#if defined(UPGRADE_RAT_NR)
#if 1
scheduling_request_config_t scheduling_request_config_nr[NUMBER_OF_CONNECTED_eNB_MAX];
......
......@@ -39,7 +39,7 @@
#include <time.h>
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#include "intertask_interface.h"
#endif
extern uint8_t nfapi_mode;
......@@ -77,13 +77,11 @@ int return_ssb_type(nfapi_config_request_t *cfg)
}*/
// 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 symbol = 0;
switch(mu) {
case NR_MU_0:
symbol = 2;
break;
......@@ -110,46 +108,39 @@ int nr_get_ssb_start_symbol(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *f
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);
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) {
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
int **txdataF = gNB->common_vars.txdataF;
uint8_t *pbch_pdu=&gNB->pbch_pdu[0];
int ss_slot = (cfg->sch_config.half_frame_index.value)? 10 : 0;
uint8_t Lmax, ssb_index=0, n_hf=0;
LOG_D(PHY,"common_signal_procedures: frame %d, slot %d\n",frame,slot);
int ssb_start_symbol = nr_get_ssb_start_symbol(cfg, fp);
nr_set_ssb_first_subcarrier(cfg, fp);
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
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_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);
if (gNB->pbch_configured != 1)return;
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(&gNB->pbch,
gNB->nrPolar_params,
pbch_pdu,
gNB->nr_pbch_interleaver,
txdataF[0],
......@@ -158,27 +149,23 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) {
n_hf,Lmax,ssb_index,
frame, cfg, fp);
}
}
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
gNB_L1_rxtx_proc_t *proc,
int do_meas)
{
int do_meas) {
int aa;
int frame=proc->frame_tx;
int slot=proc->slot_tx;
uint8_t num_dci=0,num_pdsch_rnti;
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
int offset = gNB->CC_id;
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);
if (do_meas==1) start_meas(&gNB->phy_proc_tx);
// clear the transmit data array for the current subframe
......@@ -193,18 +180,18 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
}
num_dci = gNB->pdcch_vars.num_dci;
num_pdsch_rnti = gNB->pdcch_vars.num_pdsch_rnti;
if (num_dci) {
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);
if (nfapi_mode == 0 || nfapi_mode == 1){
if (nfapi_mode == 0 || nfapi_mode == 1) {
nr_generate_dci_top(gNB->pdcch_vars,
&gNB->nrPolar_params,
gNB->nr_gold_pdcch_dmrs[slot],
gNB->common_vars.txdataF[0],
AMP, *fp, *cfg);
if (num_pdsch_rnti) {
LOG_I(PHY, "PDSCH generation started (%d)\n", num_pdsch_rnti);
nr_generate_pdsch(*gNB->dlsch[0][0],
......@@ -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) {
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 "\
\x1b[31m\
rfsimulator: error: you have to run one UE and one eNB\n\
......@@ -108,32 +119,28 @@ void setblocking(int sock, enum blocking_t active) {
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;
int ret = 0;
int l;
setblocking(fd, notBlocking);
while (count) {
l = write(fd, buf, count);
if (l <= 0) {
if (errno==EINTR)
continue;
if(errno==EAGAIN) {
flushInput(t);
continue;
}
else
return -1;
} else
return;
}
count -= l;
buf += l;
ret += l;
}
return ret;
}
int server_start(openair0_device *device) {
......@@ -143,9 +150,12 @@ int server_start(openair0_device *device) {
int enable = 1;
AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, "");
struct sockaddr_in addr = {
sin_family: AF_INET,
sin_port: htons(PORT),
sin_addr: { s_addr: INADDR_ANY }
sin_family:
AF_INET,
sin_port:
htons(PORT),
sin_addr:
{ s_addr: INADDR_ANY }
};
bind(t->listen_sock, (struct sockaddr *)&addr, sizeof(addr));
AssertFatal(listen(t->listen_sock, 5) == 0, "");
......@@ -162,9 +172,12 @@ int start_ue(openair0_device *device) {
int sock;
AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
struct sockaddr_in addr = {
sin_family: AF_INET,
sin_port: htons(PORT),
sin_addr: { s_addr: INADDR_ANY }
sin_family:
AF_INET,
sin_port:
htons(PORT),
sin_addr:
{ s_addr: INADDR_ANY }
};
addr.sin_addr.s_addr = inet_addr(t->ip);
bool connected=false;
......@@ -195,8 +208,7 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi
if (ptr->conn_sock >= 0 ) {
transferHeader header= {t->typeStamp, nsamps, nbAnt, timestamp};
int n=-1;
AssertFatal( fullwrite(ptr->conn_sock,&header, sizeof(header), t) == sizeof(header), "");
fullwrite(ptr->conn_sock,&header, sizeof(header), t);
sample_t tmpSamples[nsamps][nbAnt];
for(int a=0; a<nbAnt; a++) {
......@@ -206,13 +218,8 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi
tmpSamples[s][a]=in[s];
}
n = 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();
}
if (ptr->conn_sock >= 0 )
fullwrite(ptr->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t);
}
}
......@@ -241,17 +248,11 @@ static bool flushInput(rfsimulator_state_t *t) {
int conn_sock;
AssertFatal( (conn_sock = accept(t->listen_sock,NULL,NULL)) != -1, "");
setblocking(conn_sock, notBlocking);
allocCirBuf(t, conn_sock);
LOG_I(HW,"A ue connected\n");
} else {
if ( events[nbEv].events & (EPOLLHUP | EPOLLERR | EPOLLRDHUP) ) {
LOG_W(HW,"Lost socket\n");
removeCirBuf(t, fd);
if (t->typeStamp==MAGICUE)
exit(1);
socketError(t,fd);
continue;
}
......@@ -293,6 +294,7 @@ static bool flushInput(rfsimulator_state_t *t) {
(t->typeStamp == MAGICeNB && b->th.magic==MAGICUE), "Socket Error in protocol");
b->headerMode=false;
b->alreadyRead=true;
if ( b->lastReceivedTS != b->th.timestamp) {
int nbAnt= b->th.nbAnt;
......@@ -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) {
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;
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
t->nextTimestamp+=nsamps;
LOG_W(HW,"Generated void samples for Rx: %ld\n", t->nextTimestamp);
*ptimestamp = t->nextTimestamp-nsamps;
return nsamps;
}
......
......@@ -60,9 +60,9 @@
#include "T.h"
#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
......@@ -155,7 +155,7 @@ int32_t **txdata;
#define SAIF_ENABLED
#ifdef SAIF_ENABLED
uint64_t g_ue_rx_thread_busy = 0;
uint64_t g_ue_rx_thread_busy = 0;
#endif
typedef struct eutra_band_s {
......@@ -206,20 +206,18 @@ static const eutra_band_t eutra_bands[] = {
{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 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
ue = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE));
memset(ue,0,sizeof(PHY_VARS_NR_UE));
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->mac_enabled = 1;
......@@ -227,13 +225,12 @@ PHY_VARS_NR_UE* init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms,
init_nr_ue_signal(ue,1,abstraction_flag);
// intialize transport
init_nr_ue_transport(ue,abstraction_flag);
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
if (sched_runtime!=0) {
struct sched_attr attr= {0};
attr.size = sizeof(attr);
......@@ -248,76 +245,79 @@ void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_
}
#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};
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;
NR_UE_MAC_INST_t *mac_inst;
for (inst=0; inst < nb_inst; inst++) {
// UE->rfdevice.type = NONE_DEV;
//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]);
PHY_vars_UE_g[inst][0] = init_nr_ue_vars(NULL,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");
nr_l3_init_ue();
nr_l2_init_ue();
mac_inst = get_mac_inst(0);
mac_inst->if_module = UE->if_inst;
UE->if_inst->scheduled_response = nr_ue_scheduled_response;
UE->if_inst->phy_config_request = nr_ue_phy_config_request;
LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]);
//init_UE_threads(inst);
//UE = PHY_vars_UE_g[inst][0];
AssertFatal(0 == pthread_create(&UE->proc.pthread_ue,
&UE->proc.attr_ue,
UE_thread,
(void*)UE), "");
(void *)UE), "");
}
printf("UE threads created by %ld\n", gettid());
#if 0
#if defined(ENABLE_USE_MME)
extern volatile int start_UE;
while (start_UE == 0) {
sleep(1);
}
#endif
#endif
}
......@@ -331,39 +331,42 @@ void init_UE(int nb_inst)
static void *UE_thread_synch(void *arg) {
static int __thread UE_thread_synch_retval;
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_offset = 0;
sync_mode_t sync_mode = pbch;
int CC_id = UE->CC_id;
int freq_offset=0;
char threadname[128];
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
if ( threads.sync != -1 )
CPU_SET(threads.sync, &cpuset);
// this thread priority must be lower that the main acquisition thread
sprintf(threadname, "sync UE %d", UE->Mod_id);
init_thread(100000, 500000, FIFO_PRIORITY-1, &cpuset, threadname);
UE->is_synchronized = 0;
if (UE->UE_scan == 0) {
int ind;
for ( ind=0;
ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]);
ind++) {
current_band = eutra_bands[ind].band;
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);
if ( eutra_bands[ind].dl_min <= downlink_frequency[0][0] && eutra_bands[ind].dl_max >= downlink_frequency[0][0] ) {
for (i=0; i<4; i++)
uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min;
break;
}
}
AssertFatal( ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]), "Can't find EUTRA band for frequency");
AssertFatal( ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]), "Can't find EUTRA band for frequency");
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);
......@@ -373,15 +376,17 @@ static void *UE_thread_synch(void *arg) {
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].autocal[UE->rf_map.chain+i] = 1;
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;
}
sync_mode = pbch;
sync_mode = pbch;
} else {
current_band=0;
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[CC_id].dl_min;
uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] =
......@@ -397,9 +402,11 @@ static void *UE_thread_synch(void *arg) {
while (oai_exit==0) {
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) {
......@@ -421,29 +428,26 @@ static void *UE_thread_synch(void *arg) {
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;
if (UE->UE_scan_carrier) {
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
}
}
break;
case pbch:
#if DISABLE_LOG_X
printf("[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
#else
LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
#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);
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;
printf("Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n",
......@@ -454,14 +458,15 @@ static void *UE_thread_synch(void *arg) {
downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset,
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++) {
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)
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(freq_offset);
else
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].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];
......@@ -475,18 +480,21 @@ static void *UE_thread_synch(void *arg) {
openair0_cfg[UE->rf_map.card].tx_bw =.96e6;
// openair0_cfg[0].rx_gain[0] -= 12;
break;
case 25:
openair0_cfg[UE->rf_map.card].sample_rate =7.68e6;
openair0_cfg[UE->rf_map.card].rx_bw =2.5e6;
openair0_cfg[UE->rf_map.card].tx_bw =2.5e6;
// openair0_cfg[0].rx_gain[0] -= 6;
break;
case 50:
openair0_cfg[UE->rf_map.card].sample_rate =15.36e6;
openair0_cfg[UE->rf_map.card].rx_bw =5.0e6;
openair0_cfg[UE->rf_map.card].tx_bw =5.0e6;
// openair0_cfg[0].rx_gain[0] -= 3;
break;
case 100:
openair0_cfg[UE->rf_map.card].sample_rate=30.72e6;
openair0_cfg[UE->rf_map.card].rx_bw=10.0e6;
......@@ -508,7 +516,6 @@ static void *UE_thread_synch(void *arg) {
}
if (UE->UE_scan_carrier == 1) {
UE->UE_scan_carrier = 0;
} else {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
......@@ -517,9 +524,10 @@ static void *UE_thread_synch(void *arg) {
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],
fwrite((void *)&UE->common_vars.rxdata[0][0],
sizeof(int32_t),
10*UE->frame_parms.samples_per_subframe,
fd);
......@@ -534,24 +542,24 @@ static void *UE_thread_synch(void *arg) {
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],
fwrite((void *)&UE->common_vars.rxdata[0][0],
sizeof(int32_t),
10*UE->frame_parms.samples_per_subframe,
fd);
......@@ -559,6 +567,7 @@ static void *UE_thread_synch(void *arg) {
fclose(fd);
exit(0);
}
//mac_xface->macphy_exit("No cell synchronization found, abandoning"); new mac
return &UE_thread_synch_retval; // not reached
}
......@@ -582,39 +591,84 @@ static void *UE_thread_synch(void *arg) {
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].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->mode != loop_through_memory)
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
}// initial_sync=0
break;
case si:
default:
break;
}
#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
#endif
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
}
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);
}
}
}
/*!
* \brief This is the UE thread for RX subframe n and TX subframe n+4.
* This thread performs the phy_procedures_UE_RX() on every received slot.
......@@ -624,15 +678,12 @@ static void *UE_thread_synch(void *arg) {
*/
static void *UE_thread_rxn_txnp4(void *arg) {
static __thread int UE_thread_rxtx_retval;
struct nr_rxtx_thread_data *rtd = arg;
UE_nr_rxtx_proc_t *proc = rtd->proc;
PHY_VARS_NR_UE *UE = rtd->UE;
//proc->counter_decoder = 0;
proc->instance_cnt_rxtx=-1;
proc->subframe_rx=proc->sub_frame_start;
proc->dci_err_cnt=0;
char threadname[256];
sprintf(threadname,"UE_%d_proc_%d", UE->Mod_id, proc->sub_frame_start);
......@@ -643,93 +694,32 @@ static void *UE_thread_rxn_txnp4(void *arg) {
if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.one != -1 )
CPU_SET(threads.one, &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 )
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);
while (!oai_exit) {
if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
exit_fun("nothing to add");
}
AssertFatal( 0 == pthread_mutex_lock(&proc->mutex_rxtx), "[SCHED][UE] error locking mutex for UE RXTX\n" );
while (proc->instance_cnt_rxtx < 0) {
// 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
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
#ifndef NO_RAT_NR
if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_UPLINK_SLOT)
#else
if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
......@@ -737,33 +727,124 @@ static void *UE_thread_rxn_txnp4(void *arg) {
#endif
if (UE->mode != loop_through_memory)
phy_procedures_nrUE_TX(UE,proc,0,0,UE->mode,no_relay);
//phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay);
#endif
#if 0
if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) &&
(UE->frame_parms.frame_type == TDD))
if (UE->mode != loop_through_memory)
//phy_procedures_UE_S_TX(UE,0,0,no_relay);
updateTimes(current, &t3, 10000, timing_proc_name);
#endif
if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
exit_fun("noting to add");
}
#endif
AssertFatal( 0 == pthread_mutex_lock(&proc->mutex_rxtx), "[SCHED][UE] error locking mutex for UE RXTX\n" );
proc->instance_cnt_rxtx--;
#if BASIC_SIMULATOR
if (pthread_cond_signal(&proc->cond_rxtx) != 0) abort();
#endif
if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" );
exit_fun("noting to add");
}
AssertFatal (0 == pthread_mutex_unlock(&proc->mutex_rxtx), "[SCHED][UE] error unlocking mutex for UE RXTX\n" );
}
// thread finished
// thread finished
free(arg);
return &UE_thread_rxtx_retval;
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),"");
}
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
free(dummy_tx[i]);
}
}
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,46 +858,46 @@ static void *UE_thread_rxn_txnp4(void *arg) {
*/
void *UE_thread(void *arg) {
PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
// int tx_enabled = 0;
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 i;
char threadname[128];
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;
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};
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
if ( threads.main != -1 )
CPU_SET(threads.main, &cpuset);
sprintf(threadname, "Main UE %d", UE->Mod_id);
init_thread(100000, 500000, FIFO_PRIORITY, &cpuset,threadname);
if ((oaisim_flag == 0) && (UE->mode !=loop_through_memory))
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);
#ifdef NAS_UE
//MessageDef *message_p;
//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);
#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");
while (!oai_exit) {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
int instance_cnt_synch = UE->proc.instance_cnt_synch;
......@@ -825,98 +906,51 @@ void *UE_thread(void *arg) {
if (is_synchronized == 0) {
#if BASIC_SIMULATOR
while (!((instance_cnt_synch = UE->proc.instance_cnt_synch) < 0)) {
printf("ue sync not ready\n");
usleep(500*1000);
}
#endif
LOG_W(PHY,"is_synchro %d\n" , is_synchronized );
if (UE->mode != loop_through_memory) {
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]);
}
readFrame(UE, &timestamp);
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
trashFrame(UE, &timestamp);
}
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]);
}
continue;
}
} // UE->is_synchronized==0
else {
if (start_rx_stream==0) {
start_rx_stream=1;
if (UE->mode != loop_through_memory) {
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),"");
}
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
free(dummy_tx[i]);
}
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,
(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);
......@@ -925,64 +959,65 @@ void *UE_thread(void *arg) {
else
rt_sleep_ns(1000*1000);
} else {
thread_idx++;
if(thread_idx>=RX_NB_TH)
thread_idx = 0;
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
{
int t;
for (t = 0; t < RX_NB_TH; t++) {
for (int t = 0; t < RX_NB_TH; t++) {
UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[t];
pthread_mutex_lock(&proc->mutex_rxtx);
while (proc->instance_cnt_rxtx >= 0) pthread_cond_wait( &proc->cond_rxtx, &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+
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];
txp[i] = (void *)&UE->common_vars.txdata[i][((slot_nr+2)%NR_NUMBER_OF_SUBFRAMES_PER_FRAME)*UE->frame_parms.samples_per_slot];
int readBlockSize, writeBlockSize;
if (slot_nr<(nb_slot_frame - 1)) {
readBlockSize=UE->frame_parms.samples_per_slot;
writeBlockSize=UE->frame_parms.samples_per_slot;
} else {
// set TO compensation to zero
UE->rx_offset_diff = 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 )
UE->rx_offset_diff = -1 ;
if ( UE->rx_offset > 5*UE->frame_parms.samples_per_slot &&
UE->rx_offset < 10*UE->frame_parms.samples_per_slot )
UE->rx_offset_diff = 1;
if ( getenv("RFSIMULATOR") != 0) {
LOG_E(PHY,"AbsSubframe %d.%d TTI SET rx_off_diff to %d rx_offset %d \n",
proc->frame_rx,slot_nr,UE->rx_offset_diff,UE->rx_offset);
//UE->rx_offset_diff=0;
}
UE->rx_offset_diff = computeSamplesShift(UE);
readBlockSize=UE->frame_parms.samples_per_slot -
UE->frame_parms.ofdm_symbol_size -
UE->frame_parms.nb_prefix_samples0 -
......@@ -1011,154 +1046,77 @@ void *UE_thread(void *arg) {
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,
(void **)UE->common_vars.rxdata,
first_symbols,
UE->frame_parms.nb_antennas_rx),"");
if ( first_symbols <0 )
else
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
if (!(proc->frame_rx%4000))
{
if (!(proc->frame_rx%4000)) {
printf("frame_rx=%d rx_thread_busy=%ld - rate %8.3f\n",
proc->frame_rx, g_ue_rx_thread_busy,
(float)g_ue_rx_thread_busy/(proc->frame_rx*10+1)*100.0);
fflush(stdout);
}
#endif
}
//UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs);
//UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs);
for (th_id=0; th_id < RX_NB_TH; th_id++) {
UE->proc.proc_rxtx[th_id].gotIQs=readTime(gotIQs);
}
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;
}
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 {
if (proc->instance_cnt_rxtx != 0) {
#ifdef SAIF_ENABLED
g_ue_rx_thread_busy++;
#endif
if ( getenv("RFSIMULATOR") != NULL ) {
do {
AssertFatal (pthread_mutex_unlock(&proc->mutex_rxtx) == 0, "");
usleep(100);
AssertFatal (pthread_mutex_lock(&proc->mutex_rxtx) == 0, "");
} while ( proc->instance_cnt_rxtx >= 0);
} else
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)
{
char exit_fun_string[256];
sprintf(exit_fun_string,"[SCHED][UE %d] !!! UE instance_cnt_rxtx > 2 (IC %d) (Proc %d)!!",
AssertFatal( proc->instance_cnt_rxtx <= 4, "[SCHED][UE %d] !!! UE instance_cnt_rxtx > 2 (IC %d) (Proc %d)!!",
UE->Mod_id, proc->instance_cnt_rxtx,
UE->current_thread_id[slot_nr]);
printf("%s\n",exit_fun_string);
fflush(stdout);
sleep(1);
exit_fun(exit_fun_string);
}
}
AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0 ,"");
AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,"");
// initRefTimes(t1);
// initStaticTime(lastTime);
// updateTimes(lastTime, &t1, 20000, "Delay between two IQ acquisitions (case 1)");
// pickStaticTime(lastTime);
AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0,"");
AssertFatal (pthread_mutex_unlock(&proc->mutex_rxtx) ==0,"");
// initRefTimes(t1);
// initStaticTime(lastTime);
// updateTimes(lastTime, &t1, 20000, "Delay between two IQ acquisitions (case 1)");
// pickStaticTime(lastTime);
} //UE->mode != loop_through_memory
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);
}
processSubframeRX(UE,proc);
getchar();
} // else loop_through_memory
} // start_rx_stream==1
} // UE->is_synchronized==1
} // while !oai_exit
return NULL;
}
......@@ -1176,29 +1134,26 @@ void *UE_thread(void *arg) {
*/
void init_UE_threads(PHY_VARS_NR_UE *UE) {
struct nr_rxtx_thread_data *rtd;
pthread_attr_init (&UE->proc.attr_ue);
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);
UE->proc.instance_cnt_synch = -1;
// the threads are not yet active, therefore access is allowed without locking
int nb_threads=RX_NB_TH;
for (int i=0; i<nb_threads; i++) {
for (int i=0; i<RX_NB_TH; i++) {
rtd = calloc(1, sizeof(struct nr_rxtx_thread_data));
if (rtd == NULL) abort();
rtd->UE = UE;
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);
UE->proc.proc_rxtx[i].sub_frame_start=i;
UE->proc.proc_rxtx[i].sub_frame_step=nb_threads;
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);
UE->proc.proc_rxtx[i].sub_frame_step=RX_NB_TH;
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);
pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_thread_rxn_txnp4, rtd);
#ifdef UE_DLSCH_PARALLELISATION
pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_dlsch_td,NULL);
pthread_cond_init(&UE->proc.proc_rxtx[i].cond_dlsch_td,NULL);
......@@ -1208,25 +1163,23 @@ void init_UE_threads(PHY_VARS_NR_UE *UE) {
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);
#endif
#ifdef UE_SLOT_PARALLELISATION
//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_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_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);
#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
/*
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;
int i,j;
......@@ -1252,7 +1205,7 @@ void fill_ue_band_info(void) {
break;
}
}
}*/
}*/
#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