rebase on develop

This commit is contained in:
Laurent Thomas
2022-03-02 11:26:16 +01:00
530 changed files with 6312 additions and 21042 deletions
+17 -42
View File
@@ -25,6 +25,7 @@
#include <string.h>
#include "assertions.h"
#include "SIMULATION/TOOLS/sim.h"
#include "common/utils/load_module_shlib.h"
#include "PHY/CODING/nrLDPC_extern.h"
//#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
#include "openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.h"
@@ -118,15 +119,13 @@ int test_ldpc(short No_iteration,
//short test_input[block_length];
unsigned char *test_input[MAX_NUM_NR_DLSCH_SEGMENTS]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};;
//short *c; //padded codeword
unsigned char *estimated_output[MAX_NUM_DLSCH_SEGMENTS];
unsigned char *estimated_output_bit[MAX_NUM_DLSCH_SEGMENTS];
unsigned char *test_input_bit;
unsigned char estimated_output[MAX_NUM_DLSCH_SEGMENTS][block_length];
memset(estimated_output, 0, sizeof(estimated_output));
unsigned char *channel_input[MAX_NUM_DLSCH_SEGMENTS];
unsigned char *channel_output_uncoded[MAX_NUM_DLSCH_SEGMENTS];
unsigned char *channel_input_optim[MAX_NUM_DLSCH_SEGMENTS];
double *channel_output;
double *modulated_input[MAX_NUM_DLSCH_SEGMENTS];
char *channel_output_fixed[MAX_NUM_DLSCH_SEGMENTS];
//double channel_output[68 * 384];
double modulated_input[MAX_NUM_DLSCH_SEGMENTS][68 * 384] = { 0 };
char channel_output_fixed[MAX_NUM_DLSCH_SEGMENTS][68 * 384] = { 0 };
unsigned int i,j,trial=0;
short BG=0,nrows=0;//,ncols;
int no_punctured_columns,removed_bit;
@@ -155,24 +154,12 @@ int test_ldpc(short No_iteration,
// generate input block
for(j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
test_input[j]=(unsigned char *)malloc16(sizeof(unsigned char) * block_length/8);
memset(test_input[j], 0, sizeof(unsigned char) * block_length / 8);
channel_input[j] = (unsigned char *)malloc16(sizeof(unsigned char) * 68*384);
memset(channel_input[j], 0, sizeof(unsigned char) * 68 * 384);
channel_input_optim[j] = (unsigned char *)malloc16(sizeof(unsigned char) * 68*384);
channel_output_uncoded[j] = (unsigned char *)malloc16(sizeof(unsigned char) * 68*384);
estimated_output[j] = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
estimated_output_bit[j] = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
modulated_input[j] = (double *)malloc16(sizeof(double) * 68*384);
channel_output_fixed[j] = (char *)malloc16(sizeof( char) * 68*384);
memset(channel_input_optim[j], 0, sizeof(unsigned char) * 68 * 384);
}
//modulated_input = (double *)malloc(sizeof(double) * 68*384);
//channel_output = (double *)malloc(sizeof(double) * 68*384);
//channel_output_fixed = (char *)malloc16(sizeof(char) * 68*384);
//modulated_input = (double *)calloc(68*384, sizeof(double));
channel_output = (double *)calloc(68*384, sizeof(double));
//channel_output_fixed = (double *)calloc(68*384, sizeof(double));
//channel_output_fixed = (unsigned char*)calloc(68*384, sizeof(unsigned char*));
//estimated_output = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);///8);
//estimated_output_bit = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
test_input_bit = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
reset_meas(&time);
reset_meas(time_optim);
@@ -319,7 +306,6 @@ int test_ldpc(short No_iteration,
for (i = 0; i < block_length+(nrows-no_punctured_columns) * Zc - removed_bit; i++)
if (channel_input[j][i]!=channel_input_optim[j][i]) {
printf("differ in seg %u pos %u (%u,%u)\n", j, i, channel_input[j][i], channel_input_optim[j][i]);
free(channel_output);
return (-1);
}
//else{
@@ -367,12 +353,9 @@ int test_ldpc(short No_iteration,
//channel_output_fixed[i] = (char)quantize(1,channel_output_fixed[i],qbits);
//Uncoded BER
if (channel_output_fixed[j][i]<0)
channel_output_uncoded[j][i]=1; //QPSK demod
else
channel_output_uncoded[j][i]=0;
unsigned char channel_output_uncoded = channel_output_fixed[j][i]<0 ? 1 /* QPSK demod */ : 0;
if (channel_output_uncoded[j][i] != channel_input_optim[j][i-2*Zc])
if (channel_output_uncoded != channel_input_optim[j][i-2*Zc])
*errors_bit_uncoded = (*errors_bit_uncoded) + 1;
}
@@ -423,12 +406,10 @@ int test_ldpc(short No_iteration,
for (i=0; i<block_length; i++)
{
estimated_output_bit[j][i] = (estimated_output[j][i/8]&(1<<(i&7)))>>(i&7);
test_input_bit[i] = (test_input[j][i/8]&(1<<(i&7)))>>(i&7); // Further correct for multiple segments
if (estimated_output_bit[j][i] != test_input_bit[i])
{
unsigned char estoutputbit = (estimated_output[j][i/8]&(1<<(i&7)))>>(i&7);
unsigned char inputbit = (test_input[j][i/8]&(1<<(i&7)))>>(i&7); // Further correct for multiple segments
if (estoutputbit != inputbit)
*errors_bit = (*errors_bit) + 1;
}
}
//if (*errors == 1000)
@@ -460,17 +441,8 @@ int test_ldpc(short No_iteration,
for(j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
free(test_input[j]);
free(channel_input[j]);
free(channel_output_uncoded[j]);
free(channel_input_optim[j]);
free(modulated_input[j]);
free(channel_output_fixed[j]);
free(estimated_output[j]);
free(estimated_output_bit[j]);
}
//free(modulated_input);
free(channel_output);
//free(channel_output_fixed);
//free(estimated_output);
nrLDPC_free_mem(p_nrLDPC_procBuf);
@@ -728,5 +700,8 @@ int main(int argc, char *argv[])
}
fclose(fd);
loader_reset();
logTerm();
return(0);
}
+31 -24
View File
@@ -20,7 +20,7 @@
int main(int argc, char *argv[])
{
//Default simulation values (Aim for iterations = 1000000.)
//Default simulation values (Aim for iterations = 1000000.)
int decoder_int16=0;
int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, 2=UCI
double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB
@@ -158,20 +158,25 @@ if (logFlag){
#endif
}
uint8_t testArrayLength = ceil(testLength / 32.0);
uint8_t coderArrayLength = ceil(coderLength / 32.0);
uint32_t testInput[testArrayLength]; //generate randomly
const uint8_t testArrayLength = ceil(testLength / 32.0);
const uint8_t coderArrayLength = ceil(coderLength / 32.0);
// in the polar code, often uint64_t arrays are used, but we work with
// uint32_t arrays below, so realArrayLength is the length that always
// satisfies uint64_t array length
const uint8_t realArrayLength = ((testArrayLength + 1) / 2) * 2;
printf("testArrayLength %d realArrayLength %d\n", testArrayLength, realArrayLength);
uint32_t testInput[realArrayLength]; //generate randomly
uint32_t encoderOutput[coderArrayLength];
uint32_t estimatedOutput[testArrayLength]; //decoder output
memset(testInput,0,sizeof(uint32_t) * testArrayLength);
uint32_t estimatedOutput[realArrayLength]; //decoder output
memset(testInput,0,sizeof(uint32_t) * realArrayLength); // does not reset all
memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength);
memset(estimatedOutput,0,sizeof(uint32_t) * testArrayLength);
memset(estimatedOutput,0,sizeof(uint32_t) * realArrayLength);
uint8_t encoderOutputByte[coderLength];
double modulatedInput[coderLength]; //channel input
double channelOutput[coderLength]; //add noise
int16_t channelOutput_int16[coderLength];
t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level, 1, NULL);
t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level, true);
#ifdef DEBUG_DCI_POLAR_PARAMS
uint32_t dci_pdu[4];
@@ -206,7 +211,8 @@ if (logFlag){
modulated_input[i]=(-1)/sqrt(2);
channel_output[i] = modulated_input[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin)));
}
decoderState = polar_decoder_dci(channel_output, dci_est, currentPtrDCI, NR_POLAR_DECODER_LISTSIZE, rnti);
decoderState = polar_decoder_dci(channel_output, dci_est, NR_POLAR_DECODER_LISTSIZE, rnti,
1, size, aggregation_level);
printf("dci_est: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", dci_est[0], dci_est[1], dci_est[2], dci_est[3]);
free(encoder_outputByte);
free(channel_output);
@@ -239,13 +245,13 @@ if (logFlag){
start_meas(&timeEncoder);
if (decoder_int16==1) {
polar_encoder_fast((uint64_t *)testInput, encoderOutput, 0, 0, currentPtr);
polar_encoder_fast((uint64_t *)testInput, encoderOutput, 0, 0, polarMessageType, testLength, aggregation_level);
//polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0,0,currentPtr);
} else { //0 --> PBCH, 1 --> DCI, -1 --> UCI
if (polarMessageType == 0)
polar_encoder(testInput, encoderOutput, currentPtr);
polar_encoder(testInput, encoderOutput, polarMessageType, testLength, aggregation_level);
else if (polarMessageType == 1)
polar_encoder_dci(testInput, encoderOutput, currentPtr, rnti);
polar_encoder_dci(testInput, encoderOutput, rnti, polarMessageType, testLength, aggregation_level);
}
stop_meas(&timeEncoder);
@@ -276,19 +282,20 @@ if (logFlag){
start_meas(&timeDecoder);
if (decoder_int16==1) {
decoderState = polar_decoder_int16(channelOutput_int16, (uint64_t *)estimatedOutput, 0, currentPtr);
decoderState = polar_decoder_int16(channelOutput_int16, (uint64_t *)estimatedOutput, 0,
polarMessageType, testLength, aggregation_level);
} else { //0 --> PBCH, 1 --> DCI, -1 --> UCI
if (polarMessageType == 0) {
decoderState = polar_decoder(channelOutput,
estimatedOutput,
currentPtr,
decoderListSize);
decoderState = polar_decoder(channelOutput,
estimatedOutput,
decoderListSize,
polarMessageType, testLength, aggregation_level);
} else if (polarMessageType == 1) {
decoderState = polar_decoder_dci(channelOutput,
estimatedOutput,
currentPtr,
decoderListSize,
rnti);
decoderState = polar_decoder_dci(channelOutput,
estimatedOutput,
decoderListSize,
rnti,
polarMessageType, testLength, aggregation_level);
}
}
stop_meas(&timeDecoder);
@@ -334,9 +341,9 @@ if (logFlag){
decoderState=0;
nBitError=0;
blockErrorState=0;
memset(testInput,0,sizeof(uint32_t) * testArrayLength);
memset(testInput,0,sizeof(uint32_t) * realArrayLength);
memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength);
memset(estimatedOutput,0,sizeof(uint32_t) * testArrayLength);
memset(estimatedOutput,0,sizeof(uint32_t) * realArrayLength);
}
//Calculate error statistics for the SNR.
@@ -29,12 +29,13 @@ uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits){
uint8_t crcPolynomialSize = 24;
uint8_t temp1[crcPolynomialSize], temp2[crcPolynomialSize];
uint8_t **crc_generator_matrix = malloc(payloadSizeBits * sizeof(uint8_t *));
uint8_t **crc_generator_matrix = malloc(payloadSizeBits*sizeof(uint8_t *) + payloadSizeBits*crcPolynomialSize*sizeof(uint8_t));
if (crc_generator_matrix)
for (int i = 0; i < payloadSizeBits; i++)
crc_generator_matrix[i] = malloc(crcPolynomialSize * sizeof(uint8_t));
crc_generator_matrix[i] = ((uint8_t*)&crc_generator_matrix[payloadSizeBits])+i*crcPolynomialSize;
for (int i = 0; i < crcPolynomialSize; i++) crc_generator_matrix[payloadSizeBits-1][i]=crcPolynomialPattern[i+1];
for (int i = 0; i < crcPolynomialSize; i++)
crc_generator_matrix[payloadSizeBits-1][i]=crcPolynomialPattern[i+1];
for (int i = payloadSizeBits-2; i >= 0; i--){
for (int j = 0; j < crcPolynomialSize-1; j++) temp1[j]=crc_generator_matrix[i+1][j+1];
@@ -39,19 +39,44 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "assertions.h"
static inline void updateCrcChecksum2(int xlen,
int ylen,
uint8_t crcChecksum[xlen][ylen],
int gxlen,
int gylen,
uint8_t crcGen[gxlen][gylen],
uint8_t listSize,
uint32_t i2,
uint8_t len)
{
for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) {
crcChecksum[j][i+listSize] = ( (crcChecksum[j][i] + crcGen[i2][j]) % 2 );
}
}
}
int8_t polar_decoder(double *input,
uint32_t *out,
const t_nrPolar_params *polarParams,
uint8_t listSize)
uint8_t listSize,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level
)
{
t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, true);
//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
double ***llr = nr_alloc_double_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
uint8_t **crcChecksum = nr_alloc_uint8_2D_array(polarParams->crcParityBits, 2*listSize);
double *pathMetric = malloc(sizeof(double)*(2*listSize));
uint8_t *crcState = malloc(sizeof(uint8_t)*(2*listSize)); //0=False, 1=True
uint8_t bit[polarParams->N][polarParams->n+1][2*listSize];
memset(bit,0,sizeof bit);
uint8_t bitUpdated[polarParams->N][polarParams->n+1]; //0=False, 1=True
memset(bitUpdated,0,sizeof bitUpdated);
uint8_t llrUpdated[polarParams->N][polarParams->n+1]; //0=False, 1=True
memset(llrUpdated,0,sizeof llrUpdated);
double llr[polarParams->N][polarParams->n+1][2*listSize];
uint8_t crcChecksum[polarParams->crcParityBits][2*listSize];
memset(crcChecksum,0,sizeof crcChecksum);
double pathMetric[2*listSize];
uint8_t crcState[2*listSize]; //0=False, 1=True
for (int i=0; i<(2*listSize); i++) {
pathMetric[i] = 0;
@@ -63,13 +88,8 @@ int8_t polar_decoder(double *input,
bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2);
}
uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3
uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2
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));
}
uint8_t extended_crc_generator_matrix[polarParams->K][polarParams->crcParityBits]; //G_P3
uint8_t tempECGM[polarParams->K][polarParams->crcParityBits]; //G_P2
for (int i=0; i<polarParams->payloadBits; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) {
@@ -102,7 +122,7 @@ int8_t polar_decoder(double *input,
}
}
double *d_tilde = malloc(sizeof(double) * polarParams->N);
double d_tilde[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];
@@ -117,31 +137,33 @@ int8_t polar_decoder(double *input,
uint8_t listIndex[2*listSize], copyIndex;
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++) {
updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1));
updateLLR(currentListSize, currentBit, 0, polarParams->N, polarParams->n+1, 2*listSize, llr, llrUpdated, bit, bitUpdated);
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit);
updatePathMetric(pathMetric, currentListSize, 0, currentBit, polarParams->N, polarParams->n+1, 2*listSize, llr);
} else { //Information or CRC bit.
updatePathMetric2(pathMetric, llr, currentListSize, currentBit);
updatePathMetric2(pathMetric, currentListSize, currentBit, polarParams->N, polarParams->n+1, 2*listSize, llr);
for (int i = 0; i < currentListSize; i++) {
for (int j = 0; j < polarParams->N; j++) {
for (int k = 0; k < (polarParams->n+1); k++) {
for (int j = 0; j < polarParams->N; j++) {
for (int k = 0; k < (polarParams->n+1); k++) {
bit[j][k][i+currentListSize]=bit[j][k][i];
llr[j][k][i+currentListSize]=llr[j][k][i];
}
}
}
}
for (int i = 0; i < currentListSize; i++) {
bit[currentBit][0][i]=0;
crcState[i+currentListSize]=crcState[i];
}
for (int i = 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);
updateCrcChecksum2(polarParams->crcParityBits, 2*listSize, crcChecksum,
polarParams->K, polarParams->crcParityBits, extended_crc_generator_matrix,
currentListSize, nonFrozenBit, polarParams->crcParityBits);
currentListSize*=2;
//Keep only the best "listSize" number of entries.
@@ -246,14 +268,7 @@ int8_t polar_decoder(double *input,
if (decoderIterationCheck==0) {
//perror("[SCL polar decoder] All list entries have failed the CRC checks.");
free(d_tilde);
free(pathMetric);
free(crcState);
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
free(tempECGM);
return(-1);
polarReturn(-1);
}
nonFrozenBit++;
@@ -282,33 +297,34 @@ int8_t polar_decoder(double *input,
}
}
free(d_tilde);
free(pathMetric);
free(crcState);
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
nr_free_uint8_2D_array(extended_crc_generator_matrix, polarParams->K);
nr_free_uint8_2D_array(tempECGM, polarParams->K);
/*
* Return bits.
*/
nr_byte2bit_uint8_32(polarParams->nr_polar_A, polarParams->payloadBits, out);
return(0);
polarReturn 0;
}
int8_t polar_decoder_dci(double *input,
uint32_t *out,
const t_nrPolar_params *polarParams,
uint8_t listSize,
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
double ***llr = nr_alloc_double_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
uint8_t **crcChecksum = nr_alloc_uint8_2D_array(polarParams->crcParityBits, 2*listSize);
double *pathMetric = malloc(sizeof(double)*(2*listSize));
uint8_t *crcState = malloc(sizeof(uint8_t)*(2*listSize)); //0=False, 1=True
uint16_t n_RNTI,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level ) {
t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, true);
uint8_t bit[polarParams->N][polarParams->n+1][2*listSize];
memset(bit,0,sizeof bit);
uint8_t bitUpdated[polarParams->N][polarParams->n+1]; //0=False, 1=True
memset(bitUpdated,0,sizeof bitUpdated);
uint8_t llrUpdated[polarParams->N][polarParams->n+1]; //0=False, 1=True
memset(llrUpdated,0,sizeof llrUpdated);
double llr[polarParams->N][polarParams->n+1][2*listSize];
uint8_t crcChecksum[polarParams->crcParityBits][2*listSize];
memset(crcChecksum,0,sizeof crcChecksum);
double pathMetric[2*listSize];
uint8_t crcState[2*listSize]; //0=False, 1=True
uint8_t extended_crc_scrambling_pattern[polarParams->crcParityBits];
for (int i=0; i<(2*listSize); i++) {
@@ -321,13 +337,8 @@ int8_t polar_decoder_dci(double *input,
bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2);
}
uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3: K-by-P
uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2: K-by-P
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));
}
uint8_t extended_crc_generator_matrix[polarParams->K][polarParams->crcParityBits]; //G_P3: K-by-P
uint8_t tempECGM[polarParams->K][polarParams->crcParityBits]; //G_P2: K-by-P
for (int i=0; i<polarParams->payloadBits; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) {
@@ -366,17 +377,19 @@ int8_t polar_decoder_dci(double *input,
extended_crc_scrambling_pattern[i]=(n_RNTI>>(23-i))&1;
}
double *d_tilde = malloc(sizeof(double) * polarParams->N);
double d_tilde[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.
*/
for (int i=0; i<polarParams->crcParityBits; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) crcChecksum[i][0]=crcChecksum[i][0]+polarParams->crc_generator_matrix[j][i];
for (int 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);
}
@@ -388,12 +401,12 @@ int8_t polar_decoder_dci(double *input,
uint8_t listIndex[2*listSize], copyIndex;
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++) {
updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1));
updateLLR(currentListSize, currentBit, 0, polarParams->N, polarParams->n+1, 2*listSize, llr, llrUpdated, bit, bitUpdated);
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit);
updatePathMetric(pathMetric, currentListSize, 0, currentBit,polarParams->N, polarParams->n+1, 2*listSize, llr);
} else { //Information or CRC bit.
updatePathMetric2(pathMetric, llr, currentListSize, currentBit);
updatePathMetric2(pathMetric, currentListSize, currentBit, polarParams->N, polarParams->n+1, 2*listSize, llr);
for (int i = 0; i < currentListSize; i++) {
for (int j = 0; j < polarParams->N; j++) {
@@ -412,7 +425,9 @@ int8_t polar_decoder_dci(double *input,
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);
updateCrcChecksum2(polarParams->crcParityBits, 2*listSize, crcChecksum,
polarParams->K, polarParams->crcParityBits, extended_crc_generator_matrix,
currentListSize, nonFrozenBit, polarParams->crcParityBits);
currentListSize*=2;
//Keep only the best "listSize" number of entries.
@@ -513,18 +528,12 @@ int8_t polar_decoder_dci(double *input,
}
}
for (uint8_t i = 0; i < currentListSize; i++) decoderIterationCheck+=crcState[i];
for (uint8_t i = 0; i < currentListSize; i++)
decoderIterationCheck+=crcState[i];
if (decoderIterationCheck==0) {
//perror("[SCL polar decoder] All list entries have failed the CRC checks.");
free(d_tilde);
free(pathMetric);
free(crcState);
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
free(tempECGM);
return(-1);
polarReturn -1;
}
nonFrozenBit++;
@@ -553,19 +562,12 @@ int8_t polar_decoder_dci(double *input,
}
}
free(d_tilde);
free(pathMetric);
free(crcState);
nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1));
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits);
nr_free_uint8_2D_array(extended_crc_generator_matrix, polarParams->K);
nr_free_uint8_2D_array(tempECGM, polarParams->K);
/*
* Return bits.
*/
nr_byte2bit_uint8_32(polarParams->nr_polar_A, polarParams->payloadBits, out);
return(0);
polarReturn 0;
}
void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) {
@@ -604,8 +606,11 @@ void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) {
uint32_t polar_decoder_int16(int16_t *input,
uint64_t *out,
uint8_t ones_flag,
const t_nrPolar_params *polarParams)
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level )
{
t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, true);
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);
@@ -702,5 +707,6 @@ uint32_t polar_decoder_int16(int16_t *input,
rxcrc,polarParams->payloadBits);
#endif
out[0]=Ar;
return(crc^rxcrc);
polarReturn crc^rxcrc;
}
@@ -36,51 +36,25 @@
//#define DEBUG_NEW_IMPL 1
void updateLLR(double ***llr,
uint8_t **llrU,
uint8_t ***bit,
uint8_t **bitU,
uint8_t listSize,
uint16_t row,
uint16_t col,
uint16_t xlen,
uint8_t ylen)
{
uint16_t offset = (xlen/(pow(2,(ylen-col-1))));
for (uint8_t i=0; i<listSize; i++) {
if (( (row) % (2*offset) ) >= offset ) {
if(bitU[row-offset][col]==0) updateBit(bit, bitU, listSize, (row-offset), col, xlen, ylen);
if(llrU[row-offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row-offset), (col+1), xlen, ylen);
if(llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen);
llr[row][col][i] = (pow((-1),bit[row-offset][col][i])*llr[row-offset][col+1][i]) + llr[row][col+1][i];
} else {
if(llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen);
if(llrU[row+offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row+offset), (col+1), xlen, ylen);
computeLLR(llr, row, col, i, offset);
}
}
llrU[row][col]=1;
// printf("LLR (a %f, b %f): llr[%d][%d] %f\n",32*a,32*b,col,row,32*llr[col][row]);
}
void updateBit(uint8_t ***bit,
uint8_t **bitU,
uint8_t listSize,
uint16_t row,
uint16_t col,
uint16_t xlen,
uint8_t ylen)
static inline void updateBit(uint8_t listSize,
uint16_t row,
uint16_t col,
uint16_t xlen,
uint8_t ylen,
int zlen,
uint8_t bit[xlen][ylen][zlen],
uint8_t bitU[xlen][ylen])
{
uint16_t offset = ( xlen/(pow(2,(ylen-col))) );
for (uint8_t i=0; i<listSize; i++) {
if (( (row) % (2*offset) ) >= offset ) {
if (bitU[row][col-1]==0) updateBit(bit, bitU, listSize, row, (col-1), xlen, ylen);
if (bitU[row][col-1]==0) updateBit(listSize, row, (col-1), xlen, ylen, zlen, bit, bitU);
bit[row][col][i] = bit[row][col-1][i];
} else {
if (bitU[row][col-1]==0) updateBit(bit, bitU, listSize, row, (col-1), xlen, ylen);
if (bitU[row+offset][col-1]==0) updateBit(bit, bitU, listSize, (row+offset), (col-1), xlen, ylen);
if (bitU[row][col-1]==0) updateBit(listSize, row, (col-1), xlen, ylen, zlen, bit, bitU);
if (bitU[row+offset][col-1]==0) updateBit(listSize, (row+offset), (col-1), xlen, ylen, zlen, bit, bitU);
bit[row][col][i] = ( (bit[row][col-1][i]+bit[row+offset][col-1][i]) % 2);
}
}
@@ -88,11 +62,60 @@ void updateBit(uint8_t ***bit,
bitU[row][col]=1;
}
static inline void computeLLR(uint16_t row,
uint16_t col,
uint8_t i,
uint16_t offset,
int xlen,
int ylen,
int zlen,
double llr[xlen][ylen][zlen])
{
double a = llr[row][col + 1][i];
double b = llr[row + offset][col + 1][i];
llr[row][col][i] = log((exp(a + b) + 1) / (exp(a) + exp(b))); //eq. (8a)
}
void updateLLR(uint8_t listSize,
uint16_t row,
uint16_t col,
uint16_t xlen,
uint8_t ylen,
int zlen,
double llr[xlen][ylen][zlen],
uint8_t llrU[xlen][ylen],
uint8_t bit[xlen][ylen][zlen],
uint8_t bitU[xlen][ylen]
)
{
uint16_t offset = (xlen/(pow(2,(ylen-col-1))));
for (uint8_t i=0; i<listSize; i++) {
if (( (row) % (2*offset) ) >= offset ) {
if(bitU[row-offset][col]==0) updateBit(listSize, (row-offset), col, xlen, ylen, zlen, bit, bitU);
if(llrU[row-offset][col+1]==0) updateLLR(listSize, (row-offset), (col+1), xlen, ylen, zlen, llr, llrU, bit, bitU );
if(llrU[row][col+1]==0) updateLLR(listSize, row, (col+1), xlen, ylen, zlen, llr, llrU, bit, bitU);
llr[row][col][i] = (pow((-1),bit[row-offset][col][i])*llr[row-offset][col+1][i]) + llr[row][col+1][i];
} else {
if(llrU[row][col+1]==0) updateLLR(listSize, row, (col+1), xlen, ylen, zlen, llr, llrU, bit, bitU );
if(llrU[row+offset][col+1]==0) updateLLR(listSize, (row+offset), (col+1), xlen, ylen, zlen, llr, llrU, bit, bitU );
computeLLR(row, col, i, offset, xlen, ylen, zlen, llr);
}
}
llrU[row][col]=1;
// printf("LLR (a %f, b %f): llr[%d][%d] %f\n",32*a,32*b,col,row,32*llr[col][row]);
}
void updatePathMetric(double *pathMetric,
double ***llr,
uint8_t listSize,
uint8_t bitValue,
uint16_t row)
uint8_t listSize,
uint8_t bitValue,
uint16_t row,
int xlen,
int ylen,
int zlen,
double llr[xlen][ylen][zlen]
)
{
int8_t multiplier = (2*bitValue) - 1;
for (uint8_t i=0; i<listSize; i++)
@@ -101,11 +124,14 @@ void updatePathMetric(double *pathMetric,
}
void updatePathMetric2(double *pathMetric,
double ***llr,
uint8_t listSize,
uint16_t row)
uint8_t listSize,
uint16_t row,
int xlen,
int ylen,
int zlen,
double llr[xlen][ylen][zlen])
{
double *tempPM = malloc(sizeof(double) * listSize);
double tempPM[listSize];
memcpy(tempPM, pathMetric, (sizeof(double) * listSize));
uint8_t bitValue = 0;
@@ -118,48 +144,8 @@ void updatePathMetric2(double *pathMetric,
for (uint8_t i = listSize; i < 2*listSize; i++)
pathMetric[i] = tempPM[(i-listSize)] + log(1 + exp(multiplier * llr[row][0][(i-listSize)])); //eq. (11b)
free(tempPM);
}
void computeLLR(double ***llr,
uint16_t row,
uint16_t col,
uint8_t i,
uint16_t offset)
{
double a = llr[row][col + 1][i];
double b = llr[row + offset][col + 1][i];
llr[row][col][i] = log((exp(a + b) + 1) / (exp(a) + exp(b))); //eq. (8a)
}
void updateCrcChecksum(uint8_t **crcChecksum,
uint8_t **crcGen,
uint8_t listSize,
uint32_t i2,
uint8_t len)
{
for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) {
crcChecksum[j][i] = ( (crcChecksum[j][i] + crcGen[i2][j]) % 2 );
}
}
}
void updateCrcChecksum2(uint8_t **crcChecksum,
uint8_t **crcGen,
uint8_t listSize,
uint32_t i2,
uint8_t len)
{
for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) {
crcChecksum[j][i+listSize] = ( (crcChecksum[j][i] + crcGen[i2][j]) % 2 );
}
}
}
decoder_node_t *new_decoder_node(int first_leaf_index, int level) {
decoder_node_t *node=(decoder_node_t *)malloc(sizeof(decoder_node_t));
@@ -222,6 +208,23 @@ decoder_node_t *add_nodes(int level, int first_leaf_index, t_nrPolar_params *pol
return(new_node);
}
void delete_nodes(decoder_node_t * n) {
if (n) {
if(n->left)
delete_nodes(n->left);
if(n->right)
delete_nodes(n->right);
free(n->alpha);
free(n->beta);
free(n);
}
}
void delete_decoder_tree(t_nrPolar_params *polarParams) {
if (polarParams->tree.root)
delete_nodes(polarParams->tree.root);
}
void build_decoder_tree(t_nrPolar_params *polarParams)
{
polarParams->tree.num_nodes=0;
@@ -79,9 +79,10 @@ typedef struct decoder_tree_t_s {
struct nrPolar_params {
//messageType: 0=PBCH, 1=DCI, -1=UCI
int idx; //idx = (messageType * messageLength * aggregation_prime);
struct nrPolar_params *nextPtr;
struct nrPolar_params *nextPtr __attribute__((aligned(16)));
bool busy;
uint32_t idx;
uint8_t n_max;
uint8_t i_il;
uint8_t i_seg;
@@ -138,34 +139,46 @@ typedef struct nrPolar_params t_nrPolar_params;
void polar_encoder(uint32_t *input,
uint32_t *output,
const t_nrPolar_params *polarParams);
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level);
void polar_encoder_dci(uint32_t *in,
uint32_t *out,
const t_nrPolar_params *polarParams,
uint16_t n_RNTI);
uint16_t n_RNTI,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level);
void polar_encoder_fast(uint64_t *A,
void *out,
int32_t crcmask,
uint8_t ones_flag,
const t_nrPolar_params *polarParams);
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level);
int8_t polar_decoder(double *input,
uint32_t *output,
const t_nrPolar_params *polarParams,
uint8_t listSize);
uint8_t listSize,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level);
uint32_t polar_decoder_int16(int16_t *input,
uint64_t *out,
uint8_t ones_flag,
const t_nrPolar_params *polarParams);
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level);
int8_t polar_decoder_dci(double *input,
uint32_t *out,
const t_nrPolar_params *polarParams,
uint8_t listSize,
uint16_t n_RNTI);
uint16_t n_RNTI,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level);
void generic_polar_decoder(const t_nrPolar_params *pp,
decoder_node_t *node);
@@ -183,13 +196,12 @@ void build_decoder_tree(t_nrPolar_params *pp);
void build_polar_tables(t_nrPolar_params *polarParams);
void init_polar_deinterleaver_table(t_nrPolar_params *polarParams);
void nr_polar_print_polarParams(t_nrPolar_params *polarParams);
void nr_polar_print_polarParams(void);
t_nrPolar_params *nr_polar_params (int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level,
int decoder_flag,
t_nrPolar_params **polarList_ext);
int decoder_flag);
uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level);
@@ -278,34 +290,6 @@ void nr_matrix_multiplication_uint8_1D_uint8_2D(uint8_t *matrix1,
uint16_t row,
uint16_t col);
uint8_t ***nr_alloc_uint8_3D_array(uint16_t xlen,
uint16_t ylen,
uint16_t zlen);
uint8_t **nr_alloc_uint8_2D_array(uint16_t xlen,
uint16_t ylen);
double ***nr_alloc_double_3D_array(uint16_t xlen,
uint16_t ylen,
uint16_t zlen);
double **nr_alloc_double_2D_array(uint16_t xlen,
uint16_t ylen);
void nr_free_double_3D_array(double ***input,
uint16_t xlen,
uint16_t ylen);
void nr_free_double_2D_array(double **input,
uint16_t xlen);
void nr_free_uint8_3D_array(uint8_t ***input,
uint16_t xlen,
uint16_t ylen);
void nr_free_uint8_2D_array(uint8_t **input,
uint16_t xlen);
void nr_sort_asc_double_1D_array_ind(double *matrix,
uint8_t *ind,
uint8_t len);
@@ -316,52 +300,33 @@ void nr_sort_asc_int16_1D_array_ind(int32_t *matrix,
void nr_free_double_2D_array(double **input, uint16_t xlen);
void updateLLR(double ***llr,
uint8_t **llrU,
uint8_t ***bit,
uint8_t **bitU,
uint8_t listSize,
uint16_t row,
uint16_t col,
uint16_t xlen,
uint8_t ylen);
void updateBit(uint8_t ***bit,
uint8_t **bitU,
uint8_t listSize,
uint16_t row,
uint16_t col,
uint16_t xlen,
uint8_t ylen);
void updateLLR(uint8_t listSize,
uint16_t row,
uint16_t col,
uint16_t xlen,
uint8_t ylen,
int zlen,
double llr[xlen][ylen][zlen],
uint8_t llrU[xlen][ylen],
uint8_t bit[xlen][ylen][zlen],
uint8_t bitU[xlen][ylen]
);
void updatePathMetric(double *pathMetric,
double ***llr,
uint8_t listSize,
uint8_t bitValue,
uint16_t row);
uint8_t listSize,
uint8_t bitValue,
uint16_t row,
int xlen,
int ylen,
int zlen,
double llr[xlen][ylen][zlen]
);
void updatePathMetric2(double *pathMetric,
double ***llr,
uint8_t listSize,
uint16_t row);
void computeLLR(double ***llr,
uint16_t row,
uint16_t col,
uint8_t i,
uint16_t offset);
void updateCrcChecksum(uint8_t **crcChecksum,
uint8_t **crcGen,
uint8_t listSize,
uint32_t i2,
uint8_t len);
void updateCrcChecksum2(uint8_t **crcChecksum,
uint8_t **crcGen,
uint8_t listSize,
uint32_t i2,
uint8_t len);
uint8_t listSize,
uint16_t row,
int xlen,
int ylen,
int zlen,
double llr[xlen][ylen][zlen]);
//Also nr_polar_rate_matcher
static inline void nr_polar_interleaver(uint8_t *input,
@@ -379,5 +344,13 @@ static inline void nr_polar_deinterleaver(uint8_t *input,
{
for (int i=0; i<size; i++) output[pattern[i]]=input[i];
}
void delete_decoder_tree(t_nrPolar_params *);
extern pthread_mutex_t PolarListMutex;
#define polarReturn \
pthread_mutex_lock(&PolarListMutex); \
polarParams->busy=false; \
pthread_mutex_unlock(&PolarListMutex); \
return
#endif
@@ -43,7 +43,10 @@
void polar_encoder(uint32_t *in,
uint32_t *out,
const t_nrPolar_params *polarParams) {
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level) {
t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, false);
if (1) {//polarParams->idx == 0 || polarParams->idx == 1) { //PBCH or PDCCH
/*
uint64_t B = (((uint64_t)*in)&((((uint64_t)1)<<32)-1)) | (((uint64_t)crc24c((uint8_t*)in,polarParams->payloadBits)>>8)<<polarParams->payloadBits);
@@ -57,10 +60,10 @@ void polar_encoder(uint32_t *in,
*/
//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);
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);
@@ -150,12 +153,19 @@ void polar_encoder(uint32_t *in,
#endif
nr_byte2bit_uint8_32(polarParams->nr_polar_E, polarParams->encoderLength, out);
polarReturn;
}
void polar_encoder_dci(uint32_t *in,
uint32_t *out,
const t_nrPolar_params *polarParams,
uint16_t n_RNTI) {
uint16_t n_RNTI,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level) {
t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, false);
#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
@@ -249,6 +259,7 @@ void polar_encoder_dci(uint32_t *in,
printf("\n[polar_encoder_dci] out: ");
for (int i = 0; i < outputInd; i++) printf("[%d]->0x%08x\t", i, out[i]);
#endif
polarReturn;
}
static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void *in,void *out) __attribute__((always_inline));
@@ -334,7 +345,7 @@ void build_polar_tables(t_nrPolar_params *polarParams) {
AssertFatal(polarParams->N==512 || polarParams->N==256 || polarParams->N==128,"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 + polarParams->n_pc) * sizeof(int64_t *));
polarParams->G_N_tab = (uint64_t **)calloc((polarParams->K + polarParams->n_pc),sizeof(int64_t *));
int k=0;
for (int i=0; i<polarParams->N; i++) {
@@ -418,11 +429,14 @@ void polar_encoder_fast(uint64_t *A,
void *out,
int32_t crcmask,
uint8_t ones_flag,
const t_nrPolar_params *polarParams) {
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level) {
t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, false);
// 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};
int bitlen = polarParams->payloadBits;
// append crc
AssertFatal(bitlen<129,"support for payloads <= 128 bits\n");
@@ -451,9 +465,12 @@ void polar_encoder_fast(uint64_t *A,
A32_flip[1+offset]=((uint8_t *)&Aprime)[2];
A32_flip[2+offset]=((uint8_t *)&Aprime)[1];
A32_flip[3+offset]=((uint8_t *)&Aprime)[0];
if (polarParams->crcParityBits == 24) tcrc = (uint64_t)(((crcmask^(crc24c(A32_flip,8*offset+bitlen)>>8)))&0xffffff);
else if (polarParams->crcParityBits == 11) tcrc = (uint64_t)(((crcmask^(crc11(A32_flip,bitlen)>>21)))&0x7ff);
else if (polarParams->crcParityBits == 6) tcrc = (uint64_t)(((crcmask^(crc6(A32_flip,bitlen)>>26)))&0x3f);
if (polarParams->crcParityBits == 24)
tcrc = (uint64_t)(((crcmask^(crc24c(A32_flip,8*offset+bitlen)>>8)))&0xffffff);
else if (polarParams->crcParityBits == 11)
tcrc = (uint64_t)(((crcmask^(crc11(A32_flip,bitlen)>>21)))&0x7ff);
else if (polarParams->crcParityBits == 6)
tcrc = (uint64_t)(((crcmask^(crc6(A32_flip,bitlen)>>26)))&0x3f);
} else if (bitlen<=64) {
uint8_t A64_flip[8+offset];
if (ones_flag) {
@@ -470,8 +487,10 @@ void polar_encoder_fast(uint64_t *A,
A64_flip[5+offset]=((uint8_t *)&Aprime)[2];
A64_flip[6+offset]=((uint8_t *)&Aprime)[1];
A64_flip[7+offset]=((uint8_t *)&Aprime)[0];
if (polarParams->crcParityBits == 24) tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,8*offset+bitlen)>>8)))&0xffffff;
else if (polarParams->crcParityBits == 11) tcrc = (uint64_t)((crcmask^(crc11(A64_flip,bitlen)>>21)))&0x7ff;
if (polarParams->crcParityBits == 24)
tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,8*offset+bitlen)>>8)))&0xffffff;
else if (polarParams->crcParityBits == 11)
tcrc = (uint64_t)((crcmask^(crc11(A64_flip,bitlen)>>21)))&0x7ff;
}
else if (bitlen<=128) {
uint8_t A128_flip[16+offset];
@@ -481,38 +500,37 @@ void polar_encoder_fast(uint64_t *A,
A128_flip[2] = 0xff;
}
uint128_t Aprime= (uint128_t)(((uint128_t)*A)<<(128-bitlen));
A128_flip[0+offset]=((uint8_t*)&Aprime)[15]; A128_flip[1+offset]=((uint8_t*)&Aprime)[14];
A128_flip[2+offset]=((uint8_t*)&Aprime)[13]; A128_flip[3+offset]=((uint8_t*)&Aprime)[12];
A128_flip[4+offset]=((uint8_t*)&Aprime)[11]; A128_flip[5+offset]=((uint8_t*)&Aprime)[10];
A128_flip[6+offset] =((uint8_t*)&Aprime)[9]; A128_flip[7+offset] =((uint8_t*)&Aprime)[8];
A128_flip[8+offset] =((uint8_t*)&Aprime)[7]; A128_flip[9+offset] =((uint8_t*)&Aprime)[6];
A128_flip[10+offset]=((uint8_t*)&Aprime)[5]; A128_flip[11+offset]=((uint8_t*)&Aprime)[4];
A128_flip[12+offset]=((uint8_t*)&Aprime)[3]; A128_flip[13+offset]=((uint8_t*)&Aprime)[2];
A128_flip[14+offset]=((uint8_t*)&Aprime)[1]; A128_flip[15+offset]=((uint8_t*)&Aprime)[0];
if (polarParams->crcParityBits == 24) tcrc = (uint64_t)((crcmask^(crc24c(A128_flip,8*offset+bitlen)>>8)))&0xffffff;
else if (polarParams->crcParityBits == 11) tcrc = (uint64_t)((crcmask^(crc11(A128_flip,bitlen)>>21)))&0x7ff;
for (int i=0; i<16 ; i++)
A128_flip[i+offset]=((uint8_t*)&Aprime)[15-i];
if (polarParams->crcParityBits == 24)
tcrc = (uint64_t)((crcmask^(crc24c(A128_flip,8*offset+bitlen)>>8)))&0xffffff;
else if (polarParams->crcParityBits == 11)
tcrc = (uint64_t)((crcmask^(crc11(A128_flip,bitlen)>>21)))&0x7ff;
}
int n;
// this is number of quadwords in the bit string
int quadwlen = (polarParams->K>>6);
if ((polarParams->K&63) > 0) quadwlen++;
int quadwlen = (polarParams->K+63)/64;
// Create the B bit string as
// 0, 0, ..., 0, a'_0, a'_1, ..., a'_A-1, p_0, p_1, ..., p_{N_parity-1}
//??? b_{N'-1} b_{N'-2} ... b_{N'-A} b_{N'-A-1} ... b_{N'-A-Nparity} = a_{N-1} a_{N-2} ... a_{N-A} p_{N_parity-1} ... p_0
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));
uint64_t B[4]= {0};
B[0] = (A[0] << polarParams->crcParityBits) | tcrc;
for (n=1; n<quadwlen; n++)
if ((bitlen+63)/64 > n)
B[n] = (A[n] << polarParams->crcParityBits) | (A[n-1]>>(64-polarParams->crcParityBits));
else
B[n] = (A[n-1]>>(64-polarParams->crcParityBits));
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
uint64_t Cprime[4]= {0};
if (polarParams->K<65)
Cprime[0] = polarParams->cprime_tab0[0][Bbyte[0]] |
polarParams->cprime_tab0[1][Bbyte[1]] |
polarParams->cprime_tab0[1][Bbyte[1]] |
polarParams->cprime_tab0[2][Bbyte[2]] |
polarParams->cprime_tab0[3][Bbyte[3]] |
polarParams->cprime_tab0[4][Bbyte[4]] |
@@ -684,4 +702,7 @@ void polar_encoder_fast(uint64_t *A,
}
memset((void*)out,0,polarParams->encoderLength>>3);
polar_rate_matching(polarParams,(void *)D, out);
polarReturn;
}
@@ -43,163 +43,6 @@ void nr_matrix_multiplication_uint8_1D_uint8_2D(uint8_t *matrix1, uint8_t **matr
}
}
uint8_t ***nr_alloc_uint8_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen) {
uint8_t ***output;
int i, j;
if ((output = malloc(xlen * sizeof(*output))) == NULL) {
perror("[nr_alloc_uint8_3D_array] Problem at 1D allocation");
return NULL;
}
for (i = 0; i < xlen; i++)
output[i] = NULL;
for (i = 0; i < xlen; i++)
if ((output[i] = malloc(ylen * sizeof *output[i])) == NULL) {
perror("[nr_alloc_uint8_3D_array] Problem at 2D allocation");
nr_free_uint8_3D_array(output, xlen, ylen);
return NULL;
}
for (i = 0; i < xlen; i++)
for (j = 0; j < ylen; j++)
output[i][j] = NULL;
for (i = 0; i < xlen; i++)
for (j = 0; j < ylen; j++)
if ((output[i][j] = malloc(zlen * sizeof *output[i][j])) == NULL) {
perror("[nr_alloc_uint8_3D_array] Problem at 3D allocation");
nr_free_uint8_3D_array(output, xlen, ylen);
return NULL;
}
return output;
}
uint8_t **nr_alloc_uint8_2D_array(uint16_t xlen, uint16_t ylen) {
uint8_t **output;
int i, j;
if ((output = malloc(xlen * sizeof(*output))) == NULL) {
perror("[nr_alloc_uint8_2D_array] Problem at 1D allocation");
return NULL;
}
for (i = 0; i < xlen; i++)
output[i] = NULL;
for (i = 0; i < xlen; i++)
if ((output[i] = malloc(ylen * sizeof *output[i])) == NULL) {
perror("[nr_alloc_uint8_2D_array] Problem at 2D allocation");
nr_free_uint8_2D_array(output, xlen);
return NULL;
}
for (i = 0; i < xlen; i++)
for (j = 0; j < ylen; j++)
output[i][j] = 0;
return output;
}
double ***nr_alloc_double_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen) {
double ***output;
int i, j;
if ((output = malloc(xlen * sizeof(*output))) == NULL) {
perror("[nr_alloc_double_3D_array] Problem at 1D allocation");
return NULL;
}
for (i = 0; i < xlen; i++)
output[i] = NULL;
for (i = 0; i < xlen; i++)
if ((output[i] = malloc(ylen * sizeof *output[i])) == NULL) {
perror("[nr_alloc_double_3D_array] Problem at 2D allocation");
nr_free_double_3D_array(output, xlen, ylen);
return NULL;
}
for (i = 0; i < xlen; i++)
for (j = 0; j < ylen; j++)
output[i][j] = NULL;
for (i = 0; i < xlen; i++)
for (j = 0; j < ylen; j++)
if ((output[i][j] = malloc(zlen * sizeof *output[i][j])) == NULL) {
perror("[nr_alloc_double_3D_array] Problem at 3D allocation");
nr_free_double_3D_array(output, xlen, ylen);
return NULL;
}
return output;
}
double **nr_alloc_double_2D_array(uint16_t xlen, uint16_t ylen) {
double **output;
int i, j;
if ((output = malloc(xlen * sizeof(*output))) == NULL) {
perror("[nr_alloc_double_3D_array] Problem at 1D allocation");
return NULL;
}
for (i = 0; i < xlen; i++)
output[i] = NULL;
for (i = 0; i < xlen; i++)
if ((output[i] = malloc(ylen * sizeof *output[i])) == NULL) {
perror("[nr_alloc_double_2D_array] Problem at 2D allocation");
nr_free_double_2D_array(output, xlen);
return NULL;
}
for (i = 0; i < xlen; i++)
for (j = 0; j < ylen; j++)
output[i][j] = 0;
return output;
}
void nr_free_double_3D_array(double ***input, uint16_t xlen, uint16_t ylen) {
int i, j;
for (i = 0; i < xlen; i++) {
for (j = 0; j < ylen; j++) {
free(input[i][j]);
}
free(input[i]);
}
free(input);
}
void nr_free_double_2D_array(double **input, uint16_t xlen) {
int i;
for (i = 0; i < xlen; i++) {
free(input[i]);
}
free(input);
}
void nr_free_uint8_3D_array(uint8_t ***input, uint16_t xlen, uint16_t ylen) {
int i, j;
for (i = 0; i < xlen; i++) {
for (j = 0; j < ylen; j++) {
free(input[i][j]);
}
free(input[i]);
}
free(input);
}
void nr_free_uint8_2D_array(uint8_t **input, uint16_t xlen) {
for (int i = 0; i < xlen; i++) free(input[i]);
free(input);
}
// Modified Bubble Sort.
void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len) {
int swaps;
+194 -161
View File
@@ -33,178 +33,236 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "PHY/NR_TRANSPORT/nr_dci.h"
#define PolarKey ((messageType<<24)|(messageLength<<8)|aggregation_level)
static t_nrPolar_params * PolarList=NULL;
pthread_mutex_t PolarListMutex=PTHREAD_MUTEX_INITIALIZER;
static int intcmp(const void *p1,const void *p2) {
return(*(int16_t *)p1 > *(int16_t *)p2);
}
static void nr_polar_init(t_nrPolar_params * *polarParams,
int8_t messageType,
static void nr_polar_delete_list(t_nrPolar_params * polarParams) {
if (!polarParams)
return;
if (polarParams->nextPtr)
nr_polar_delete_list(polarParams->nextPtr);
delete_decoder_tree(polarParams);
//From build_polar_tables()
for (int k=0; k < polarParams->K + polarParams->n_pc; k++)
if (polarParams->G_N_tab[k])
free(polarParams->G_N_tab[k]);
free(polarParams->G_N_tab);
free(polarParams->rm_tab);
if (polarParams->crc_generator_matrix)
free(polarParams->crc_generator_matrix);
//polar_encoder vectors:
free(polarParams->nr_polar_crc);
free(polarParams->nr_polar_aPrime);
free(polarParams->nr_polar_APrime);
free(polarParams->nr_polar_D);
free(polarParams->nr_polar_E);
//Polar Coding vectors
free(polarParams->nr_polar_U);
free(polarParams->nr_polar_CPrime);
free(polarParams->nr_polar_B);
free(polarParams->nr_polar_A);
free(polarParams->interleaving_pattern);
free(polarParams->deinterleaving_pattern);
free(polarParams->rate_matching_pattern);
free(polarParams->information_bit_pattern);
free(polarParams->Q_I_N);
free(polarParams->Q_F_N);
free(polarParams->Q_PC_N);
free(polarParams->channel_interleaver_pattern);
free(polarParams);
}
static void nr_polar_delete(void) {
pthread_mutex_lock(&PolarListMutex);
nr_polar_delete_list(PolarList);
PolarList=NULL;
pthread_mutex_unlock(&PolarListMutex);
}
t_nrPolar_params * nr_polar_params(int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level,
int decoder_flag) {
t_nrPolar_params *currentPtr = *polarParams;
uint16_t aggregation_prime = (messageType >= 2) ? aggregation_level : nr_polar_aggregation_prime(aggregation_level);
// The lock is weak, because we never delete in the list, only at exit time
// therefore, returning t_nrPolar_params * from the list is safe for future usage
pthread_mutex_lock(&PolarListMutex);
if(!PolarList)
atexit(nr_polar_delete);
t_nrPolar_params *currentPtr = PolarList;
//Parse the list. If the node is already created, return without initialization.
while (currentPtr != NULL) {
//printf("currentPtr->idx %d, (%d,%d)\n",currentPtr->idx,currentPtr->payloadBits,currentPtr->encoderLength);
//LOG_D(PHY,"Looking for index %d\n",(messageType * messageLength * aggregation_prime));
if (currentPtr->idx == (messageType * messageLength * aggregation_prime)) return;
else currentPtr = currentPtr->nextPtr;
if (currentPtr->busy == false && currentPtr->idx == PolarKey ) {
currentPtr->busy=true;
pthread_mutex_unlock(&PolarListMutex);
if (decoder_flag && !currentPtr->tree.root)
build_decoder_tree(currentPtr);
return currentPtr ;
}
else
currentPtr = currentPtr->nextPtr;
}
// printf("currentPtr %p (polarParams %p)\n",currentPtr,polarParams);
//Else, initialize and add node to the end of the linked list.
t_nrPolar_params *newPolarInitNode = calloc(sizeof(t_nrPolar_params),1);
if (newPolarInitNode != NULL) {
// LOG_D(PHY,"Setting new polarParams index %d, messageType %d, messageLength %d, aggregation_prime %d\n",(messageType * messageLength * aggregation_prime),messageType,messageLength,aggregation_prime);
newPolarInitNode->idx = (messageType * messageLength * aggregation_prime);
newPolarInitNode->nextPtr = NULL;
//printf("newPolarInitNode->idx %d, (%d,%d,%d:%d)\n",newPolarInitNode->idx,messageType,messageLength,aggregation_prime,aggregation_level);
newPolarInitNode->busy=true;
pthread_mutex_unlock(&PolarListMutex);
if (messageType == 0) { //PBCH
newPolarInitNode->n_max = NR_POLAR_PBCH_N_MAX;
newPolarInitNode->i_il = NR_POLAR_PBCH_I_IL;
newPolarInitNode->i_seg = NR_POLAR_PBCH_I_SEG;
newPolarInitNode->n_pc = NR_POLAR_PBCH_N_PC;
newPolarInitNode->n_pc_wm = NR_POLAR_PBCH_N_PC_WM;
newPolarInitNode->i_bil = NR_POLAR_PBCH_I_BIL;
newPolarInitNode->crcParityBits = NR_POLAR_PBCH_CRC_PARITY_BITS;
newPolarInitNode->payloadBits = NR_POLAR_PBCH_PAYLOAD_BITS;
newPolarInitNode->encoderLength = NR_POLAR_PBCH_E;
newPolarInitNode->crcCorrectionBits = NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits);//G_P
//printf("Initializing polar parameters for PBCH (K %d, E %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength);
} else if (messageType == 1) { //DCI
newPolarInitNode->n_max = NR_POLAR_DCI_N_MAX;
newPolarInitNode->i_il = NR_POLAR_DCI_I_IL;
newPolarInitNode->i_seg = NR_POLAR_DCI_I_SEG;
newPolarInitNode->n_pc = NR_POLAR_DCI_N_PC;
newPolarInitNode->n_pc_wm = NR_POLAR_DCI_N_PC_WM;
newPolarInitNode->i_bil = NR_POLAR_DCI_I_BIL;
newPolarInitNode->crcParityBits = NR_POLAR_DCI_CRC_PARITY_BITS;
newPolarInitNode->payloadBits = messageLength;
newPolarInitNode->encoderLength = aggregation_level*108;
newPolarInitNode->crcCorrectionBits = NR_POLAR_DCI_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->crc_generator_matrix=crc24c_generator_matrix(newPolarInitNode->payloadBits+newPolarInitNode->crcParityBits);//G_P
//printf("Initializing polar parameters for DCI (K %d, E %d, L %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength,aggregation_level);
} else if (messageType == 2) { //UCI PUCCH2
AssertFatal(aggregation_level>2,"Aggregation level (%d) for PUCCH 2 encoding is NPRB and should be > 2\n",aggregation_level);
AssertFatal(messageLength>11,"Message length %d is too short for polar encoding of UCI\n",messageLength);
newPolarInitNode->n_max = NR_POLAR_PUCCH_N_MAX;
newPolarInitNode->i_il = NR_POLAR_PUCCH_I_IL;
newPolarInitNode->encoderLength = aggregation_level * 16;
AssertFatal(newPolarInitNode != NULL, "[nr_polar_init] New t_nrPolar_params * could not be created");
// LOG_D(PHY,"Setting new polarParams index %d, messageType %d, messageLength %d, aggregation_prime %d\n",(messageType * messageLength * aggregation_prime),messageType,messageLength,aggregation_prime);
newPolarInitNode->idx = PolarKey;
newPolarInitNode->nextPtr = NULL;
//printf("newPolarInitNode->idx %d, (%d,%d,%d:%d)\n",newPolarInitNode->idx,messageType,messageLength,aggregation_prime,aggregation_level);
if (messageType == 0) { //PBCH
newPolarInitNode->n_max = NR_POLAR_PBCH_N_MAX;
newPolarInitNode->i_il = NR_POLAR_PBCH_I_IL;
newPolarInitNode->i_seg = NR_POLAR_PBCH_I_SEG;
newPolarInitNode->n_pc = NR_POLAR_PBCH_N_PC;
newPolarInitNode->n_pc_wm = NR_POLAR_PBCH_N_PC_WM;
newPolarInitNode->i_bil = NR_POLAR_PBCH_I_BIL;
newPolarInitNode->crcParityBits = NR_POLAR_PBCH_CRC_PARITY_BITS;
newPolarInitNode->payloadBits = NR_POLAR_PBCH_PAYLOAD_BITS;
newPolarInitNode->encoderLength = NR_POLAR_PBCH_E;
newPolarInitNode->crcCorrectionBits = NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits);//G_P
//printf("Initializing polar parameters for PBCH (K %d, E %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength);
} else if (messageType == 1) { //DCI
newPolarInitNode->n_max = NR_POLAR_DCI_N_MAX;
newPolarInitNode->i_il = NR_POLAR_DCI_I_IL;
newPolarInitNode->i_seg = NR_POLAR_DCI_I_SEG;
newPolarInitNode->n_pc = NR_POLAR_DCI_N_PC;
newPolarInitNode->n_pc_wm = NR_POLAR_DCI_N_PC_WM;
newPolarInitNode->i_bil = NR_POLAR_DCI_I_BIL;
newPolarInitNode->crcParityBits = NR_POLAR_DCI_CRC_PARITY_BITS;
newPolarInitNode->payloadBits = messageLength;
newPolarInitNode->encoderLength = aggregation_level*108;
newPolarInitNode->crcCorrectionBits = NR_POLAR_DCI_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->crc_generator_matrix=crc24c_generator_matrix(newPolarInitNode->payloadBits+newPolarInitNode->crcParityBits);//G_P
//printf("Initializing polar parameters for DCI (K %d, E %d, L %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength,aggregation_level);
} else if (messageType == 2) { //UCI PUCCH2
AssertFatal(aggregation_level>2,"Aggregation level (%d) for PUCCH 2 encoding is NPRB and should be > 2\n",aggregation_level);
AssertFatal(messageLength>11,"Message length %d is too short for polar encoding of UCI\n",messageLength);
newPolarInitNode->n_max = NR_POLAR_PUCCH_N_MAX;
newPolarInitNode->i_il = NR_POLAR_PUCCH_I_IL;
newPolarInitNode->encoderLength = aggregation_level * 16;
newPolarInitNode->i_seg = 0;
newPolarInitNode->i_seg = 0;
if ((messageLength >= 360 && newPolarInitNode->encoderLength >= 1088)||
(messageLength >= 1013)) newPolarInitNode->i_seg = 1;
if ((messageLength >= 360 && newPolarInitNode->encoderLength >= 1088)||
(messageLength >= 1013)) newPolarInitNode->i_seg = 1;
newPolarInitNode->crcParityBits = 11;
newPolarInitNode->n_pc = 0;
newPolarInitNode->n_pc_wm = 0;
newPolarInitNode->crcParityBits = 11;
newPolarInitNode->n_pc = 0;
newPolarInitNode->n_pc_wm = 0;
if (messageLength < 20) {
newPolarInitNode->crcParityBits = 6;
newPolarInitNode->n_pc = 3;
if ((newPolarInitNode->encoderLength - messageLength - 6 + 3) < 193) newPolarInitNode->n_pc_wm = 1;
}
newPolarInitNode->i_bil = NR_POLAR_PUCCH_I_BIL;
newPolarInitNode->payloadBits = messageLength;
newPolarInitNode->crcCorrectionBits = NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS;
//newPolarInitNode->crc_generator_matrix=crc24c_generator_matrix(newPolarInitNode->payloadBits+newPolarInitNode->crcParityBits);//G_P
//LOG_D(PHY,"New polar node, encoderLength %d, aggregation_level %d\n",newPolarInitNode->encoderLength,aggregation_level);
} else {
AssertFatal(1 == 0, "[nr_polar_init] Incorrect Message Type(%d)", messageType);
if (messageLength < 20) {
newPolarInitNode->crcParityBits = 6;
newPolarInitNode->n_pc = 3;
if ((newPolarInitNode->encoderLength - messageLength - 6 + 3) < 193) newPolarInitNode->n_pc_wm = 1;
}
newPolarInitNode->K = newPolarInitNode->payloadBits + newPolarInitNode->crcParityBits; // Number of bits to encode.
newPolarInitNode->N = nr_polar_output_length(newPolarInitNode->K,
newPolarInitNode->encoderLength,
newPolarInitNode->n_max);
newPolarInitNode->n = log2(newPolarInitNode->N);
newPolarInitNode->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++)
newPolarInitNode->deinterleaving_pattern[newPolarInitNode->interleaving_pattern[i]] = i;
newPolarInitNode->rate_matching_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength);
uint16_t *J = malloc(sizeof(uint16_t) * newPolarInitNode->N);
nr_polar_rate_matching_pattern(newPolarInitNode->rate_matching_pattern,
J,
nr_polar_subblock_interleaver_pattern,
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));
newPolarInitNode->i_bil = NR_POLAR_PUCCH_I_BIL;
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,
J,
newPolarInitNode->Q_0_Nminus1,
newPolarInitNode->K,
newPolarInitNode->N,
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);
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);
if (decoder_flag == 1) build_decoder_tree(newPolarInitNode);
build_polar_tables(newPolarInitNode);
init_polar_deinterleaver_table(newPolarInitNode);
//printf("decoder tree nodes %d\n",newPolarInitNode->tree.num_nodes);
newPolarInitNode->payloadBits = messageLength;
newPolarInitNode->crcCorrectionBits = NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS;
//newPolarInitNode->crc_generator_matrix=crc24c_generator_matrix(newPolarInitNode->payloadBits+newPolarInitNode->crcParityBits);//G_P
//LOG_D(PHY,"New polar node, encoderLength %d, aggregation_level %d\n",newPolarInitNode->encoderLength,aggregation_level);
} else {
AssertFatal(1 == 0, "[nr_polar_init] New t_nrPolar_params * could not be created");
AssertFatal(1 == 0, "[nr_polar_init] Incorrect Message Type(%d)", messageType);
}
//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;
newPolarInitNode->K = newPolarInitNode->payloadBits + newPolarInitNode->crcParityBits; // Number of bits to encode.
newPolarInitNode->N = nr_polar_output_length(newPolarInitNode->K,
newPolarInitNode->encoderLength,
newPolarInitNode->n_max);
newPolarInitNode->n = log2(newPolarInitNode->N);
newPolarInitNode->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++)
newPolarInitNode->deinterleaving_pattern[newPolarInitNode->interleaving_pattern[i]] = i;
newPolarInitNode->rate_matching_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength);
uint16_t J[newPolarInitNode->N];
nr_polar_rate_matching_pattern(newPolarInitNode->rate_matching_pattern,
J,
nr_polar_subblock_interleaver_pattern,
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,
J,
newPolarInitNode->Q_0_Nminus1,
newPolarInitNode->K,
newPolarInitNode->N,
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);
newPolarInitNode->channel_interleaver_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength);
nr_polar_channel_interleaver_pattern(newPolarInitNode->channel_interleaver_pattern,
newPolarInitNode->i_bil,
newPolarInitNode->encoderLength);
if (decoder_flag == 1)
build_decoder_tree(newPolarInitNode);
build_polar_tables(newPolarInitNode);
init_polar_deinterleaver_table(newPolarInitNode);
//printf("decoder tree nodes %d\n",newPolarInitNode->tree.num_nodes);
newPolarInitNode->nextPtr=PolarList;
PolarList=newPolarInitNode;
return newPolarInitNode;
}
void nr_polar_print_polarParams(t_nrPolar_params *polarParams) {
void nr_polar_print_polarParams() {
uint8_t i = 0;
if (polarParams == NULL) {
if (PolarList == NULL) {
printf("polarParams is empty.\n");
} else {
t_nrPolar_params * polarParams=PolarList;
while (polarParams != NULL) {
printf("polarParams[%d] = %d\n", i, polarParams->idx);
printf("polarParams[%d] = %d, %d, %d\n", i,
polarParams->idx>>24, (polarParams->idx>>8)&0xFFFF, polarParams->idx&0xFF);
polarParams = polarParams->nextPtr;
i++;
}
@@ -213,31 +271,6 @@ void nr_polar_print_polarParams(t_nrPolar_params *polarParams) {
return;
}
t_nrPolar_params *nr_polar_params (int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level,
int decoding_flag,
t_nrPolar_params **polarList_ext) {
static t_nrPolar_params *polarList = NULL;
nr_polar_init(polarList_ext != NULL ? polarList_ext : &polarList,
messageType,messageLength,aggregation_level,decoding_flag);
t_nrPolar_params *polarParams=polarList_ext != NULL ? *polarList_ext : polarList;
const int tag=messageType * messageLength * (messageType>=2 ? aggregation_level : nr_polar_aggregation_prime(aggregation_level));
while (polarParams != NULL) {
// LOG_D(PHY,"nr_polar_params : tag %d (from nr_polar_init %d)\n",tag,polarParams->idx);
if (polarParams->idx == tag)
return polarParams;
polarParams = polarParams->nextPtr;
}
AssertFatal(false,"Polar Init tables internal failure, no polarParams found\n");
return NULL;
}
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;
-2
View File
@@ -415,10 +415,8 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset
);
LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_eNB][MOD %02"PRIu8"][]\n", eNB->Mod_id);
LOG_I (PHY, "[eNB %" PRIu8 "] Initializing DL_FRAME_PARMS : N_RB_DL %" PRIu8 ", PHICH Resource %d, PHICH Duration %d\n",
eNB->Mod_id, fp->N_RB_DL, fp->phich_config_common.phich_resource, fp->phich_config_common.phich_duration);
LOG_D (PHY, "[MSC_NEW][FRAME 00000][PHY_eNB][MOD %02" PRIu8 "][]\n", eNB->Mod_id);
crcTableInit();
lte_gold (fp, eNB->lte_gold_table, fp->Nid_cell);
generate_pcfich_reg_mapping (fp);
+108 -69
View File
@@ -104,7 +104,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
load_dftslib();
LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_gNB][MOD %02"PRIu8"][]\n", gNB->Mod_id);
crcTableInit();
init_scrambling_luts();
init_pucch2_luts();
@@ -243,37 +242,9 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
common_vars->debugBuff = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t)*100);
common_vars->debugBuff_sample_offset = 0;
// 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 *) );
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 );
}
} //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));
}
*/
// PRACH
prach_vars->prachF = (int16_t *)malloc16_clear( 1024*2*sizeof(int16_t) );
prach_vars->rxsigF = (int16_t **)malloc16_clear(Prx*sizeof(int16_t*));
/*
for (i=0;i<Prx;i++){
prach_vars->rxsigF[i] = (int16_t *)malloc16_clear( 1024*2*sizeof(int16_t) );
}
*/
prach_vars->prach_ifft = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t));
init_prach_list(gNB);
@@ -329,51 +300,102 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
{
NR_DL_FRAME_PARMS* const fp = &gNB->frame_parms;
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
NR_gNB_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 Ptx=gNB->gNB_config.carrier_config.num_tx_ant.value;
const int Ptx = gNB->gNB_config.carrier_config.num_tx_ant.value;
const int Prx = gNB->gNB_config.carrier_config.num_rx_ant.value;
const int max_ul_mimo_layers = 4; // taken from phy_init_nr_gNB()
const int n_buf = Prx * max_ul_mimo_layers;
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
for (int symb = 0; symb < fp->symbols_per_slot; symb++)
free_and_zero(pdcch_dmrs[slot][symb]);
free_and_zero(pdcch_dmrs[slot]);
}
free_and_zero(pdcch_dmrs);
uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs;
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
for (int symb = 0; symb < fp->symbols_per_slot; symb++) {
for (int q = 0; q < NR_MAX_NB_CODEWORDS; q++)
free_and_zero(pdsch_dmrs[slot][symb][q]);
free_and_zero(pdsch_dmrs[slot][symb]);
}
free_and_zero(pdsch_dmrs[slot]);
}
free_and_zero(gNB->nr_gold_pdsch_dmrs);
uint32_t ****pusch_dmrs = gNB->nr_gold_pusch_dmrs;
for(int nscid = 0; nscid < 2; nscid++) {
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
for (int symb = 0; symb < fp->symbols_per_slot; symb++)
free_and_zero(pusch_dmrs[nscid][slot][symb]);
free_and_zero(pusch_dmrs[nscid][slot]);
}
free_and_zero(pusch_dmrs[nscid]);
}
free_and_zero(pusch_dmrs);
uint32_t ***csi_rs = gNB->nr_gold_csi_rs;
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
for (int symb = 0; symb < fp->symbols_per_slot; symb++)
free_and_zero(csi_rs[slot][symb]);
free_and_zero(csi_rs[slot]);
}
free_and_zero(csi_rs);
for (int id = 0; id < NUMBER_OF_NR_SRS_MAX; id++) {
for (int i = 0; i < Prx; i++){
free_and_zero(gNB->nr_srs_info[id]->srs_received_signal[i]);
free_and_zero(gNB->nr_srs_info[id]->srs_ls_estimated_channel[i]);
free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_freq[i]);
free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_time[i]);
free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_time_shifted[i]);
}
free_and_zero(gNB->nr_srs_info[id]->srs_generated_signal);
free_and_zero(gNB->nr_srs_info[id]->noise_power);
free_and_zero(gNB->nr_srs_info[id]->srs_received_signal);
free_and_zero(gNB->nr_srs_info[id]->srs_ls_estimated_channel);
free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_freq);
free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_time);
free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_time_shifted);
free_and_zero(gNB->nr_srs_info[id]);
}
free_ul_reference_signal_sequences();
free_gnb_lowpapr_sequences();
reset_nr_transport(gNB);
NR_gNB_COMMON * common_vars = &gNB->common_vars;
for (int i = 0; i < Ptx; i++) {
free_and_zero(common_vars->txdataF[i]);
/* rxdataF[i] is not allocated -> don't free */
free_and_zero(common_vars->beam_id[i]);
}
for (int i = 0; i < Prx; ++i) {
free_and_zero(common_vars->rxdataF[i]);
free_and_zero(common_vars->rxdata[i]);
}
free_and_zero(common_vars->txdataF);
free_and_zero(common_vars->rxdata);
free_and_zero(common_vars->rxdataF);
// PDCCH DMRS sequences
free_and_zero(pdcch_dmrs);
/*
// Channel estimates for SRS
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
for (i=0; i<64; i++) {
free_and_zero(srs_vars[UE_id].srs_ch_estimates[i]);
free_and_zero(srs_vars[UE_id].srs_ch_estimates_time[i]);
}
free_and_zero(common_vars->beam_id);
free_and_zero(srs_vars[UE_id].srs_ch_estimates);
free_and_zero(srs_vars[UE_id].srs_ch_estimates_time);
} //UE_id
//free_ul_ref_sigs();
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) free_and_zero(srs_vars[UE_id].srs);
free_and_zero(common_vars->debugBuff);
NR_gNB_PRACH* prach_vars = &gNB->prach_vars;
free_and_zero(prach_vars->prachF);
free_and_zero(prach_vars->rxsigF);
free_and_zero(prach_vars->prach_ifft);
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->rxsigF[0]);
*/
NR_gNB_PUSCH** pusch_vars = gNB->pusch_vars;
for (int ULSCH_id=0; ULSCH_id<gNB->number_of_nr_ulsch_max; ULSCH_id++) {
for (int i = 0; i < fp->nb_antennas_rx; i++) {
for (int i = 0; i < Prx; i++) {
free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext[i]);
free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2[i]);
}
for (int i = 0; i < 4*fp->nb_antennas_rx; i++) {
for (int i = 0; i < n_buf; i++) {
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates[i]);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_ext[i]);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_time[i]);
@@ -393,8 +415,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_ext);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_time);
free_and_zero(pusch_vars[ULSCH_id]->ptrs_phase_per_slot);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_time);
free_and_zero(pusch_vars[ULSCH_id]->ul_valid_re_per_slot);
free_and_zero(pusch_vars[ULSCH_id]->rxdataF_comp);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag0);
@@ -406,14 +428,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_and_zero(pusch_vars[ULSCH_id]->llr);
free_and_zero(pusch_vars[ULSCH_id]);
} //ULSCH_id
/*
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) gNB->UE_stats_ptr[UE_id] = NULL;
*/
free_gnb_lowpapr_sequences();
}
//Adding nr_schedule_handler
@@ -554,6 +568,16 @@ void init_DLSCH_struct(PHY_VARS_gNB *gNB, processingData_L1tx_t *msg) {
}
}
void reset_DLSCH_struct(const PHY_VARS_gNB *gNB, processingData_L1tx_t *msg)
{
const NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
const nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
const uint16_t grid_size = cfg->carrier_config.dl_grid_size[fp->numerology_index].value;
for (int i=0; i<gNB->number_of_nr_dlsch_max; i++)
for (int j=0; j<2; j++)
free_gNB_dlsch(&msg->dlsch[i][j], grid_size);
}
void init_nr_transport(PHY_VARS_gNB *gNB) {
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
LOG_I(PHY, "Initialise nr transport\n");
@@ -578,7 +602,7 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
for (int j=0; j<2; j++) {
// ULSCH for data
gNB->ulsch[i][j] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL, 0);
gNB->ulsch[i][j] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL);
if (!gNB->ulsch[i][j]) {
LOG_E(PHY,"Can't get gNB ulsch structures\n");
@@ -594,3 +618,18 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
//fp->pucch_config_common.deltaPUCCH_Shift = 1;
}
void reset_nr_transport(PHY_VARS_gNB *gNB)
{
const NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
for (int i = 0; i < NUMBER_OF_NR_PUCCH_MAX; i++)
free_gNB_pucch(gNB->pucch[i]);
for (int i = 0; i < NUMBER_OF_NR_SRS_MAX; i++)
free_gNB_srs(gNB->srs[i]);
for (int i=0; i<gNB->number_of_nr_ulsch_max; i++)
for (int j=0; j<2; j++)
free_gNB_ulsch(&gNB->ulsch[i][j], fp->N_RB_UL);
}
+34 -32
View File
@@ -124,32 +124,32 @@ int nr_phy_init_RU(RU_t *ru) {
ru->num_gNB,NUMBER_OF_gNB_MAX);
LOG_I(PHY,"[INIT] %s() ru->num_gNB:%d \n", __FUNCTION__, ru->num_gNB);
if (ru->do_precoding == 1) {
if (ru->do_precoding == 1) {
int beam_count = 0;
if (ru->nb_tx>1) {//Enable beamforming when nb_tx > 1
for (p=0;p<ru->nb_log_antennas;p++) {
//if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0
beam_count++;
}
AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx));
for (i=0; i<ru->num_gNB; i++) {
int l_ind = 0;
for (p=0;p<ru->nb_log_antennas;p++) {
for (i=0; i<ru->num_gNB; i++) {
int l_ind = 0;
for (p=0;p<ru->nb_log_antennas;p++) {
//if ((fp->L_ssb >> (63-p)) & 0x01) {
ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*));
for (j=0; j<ru->nb_tx; j++) {
ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t));
AssertFatal(ru->bw_list[i],"ru->bw_list[%d] is null\n",i);
for (re=0; re<fp->ofdm_symbol_size; re++)
ru->beam_weights[i][p][j][re] = ru->bw_list[i][l_ind];
//printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j);
l_ind++;
} // for j
ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*));
for (j=0; j<ru->nb_tx; j++) {
ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t));
AssertFatal(ru->bw_list[i],"ru->bw_list[%d] is null\n",i);
for (re=0; re<fp->ofdm_symbol_size; re++)
ru->beam_weights[i][p][j][re] = ru->bw_list[i][l_ind];
//printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j);
l_ind++;
} // for j
//}
} // for p
} //for i
} // for p
} //for i
}
ru->common.beam_id = (uint8_t**)malloc16_clear(ru->nb_tx*sizeof(uint8_t*));
@@ -174,17 +174,13 @@ void nr_phy_free_RU(RU_t *ru)
LOG_I(PHY, "Feeing RU signal buffers (if_south %s) nb_tx %d\n", ru_if_types[ru->if_south], ru->nb_tx);
free_and_zero(ru->nr_frame_parms);
free_and_zero(ru->frame_parms);
if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so free memory for time-domain signals
int32_t *ptr;
for (i = 0; i < ru->nb_tx; i++) {
ptr=&ru->common.txdata[i][-ru->sf_extension];
free_and_zero(ptr);
}
for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdata[i]);
for (i = 0; i < ru->nb_tx; i++)
free_and_zero(ru->common.txdata[i]);
free_and_zero(ru->common.txdata);
for (i = 0; i < ru->nb_rx; i++)
free_and_zero(ru->common.rxdata[i]);
free_and_zero(ru->common.rxdata);
} // else: IF5 or local RF -> nothing to free()
@@ -193,7 +189,7 @@ void nr_phy_free_RU(RU_t *ru)
free_and_zero(ru->common.rxdata_7_5kHz);
// free beamforming input buffers (TX)
for (i = 0; i < 15; i++) free_and_zero(ru->common.txdataF[i]);
for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdataF[i]);
free_and_zero(ru->common.txdataF);
// free IFFT input buffers (TX)
@@ -205,15 +201,21 @@ void nr_phy_free_RU(RU_t *ru)
free_and_zero(ru->common.rxdataF);
for (j=0;j<NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX;j++) {
for (i = 0; i < ru->nb_rx; i++) {
for (i = 0; i < ru->nb_rx; i++)
free_and_zero(ru->prach_rxsigF[j][i]);
}
free_and_zero(ru->prach_rxsigF[j]);
}
for (i = 0; i < ru->num_gNB; i++) {
for (p = 0; p < 15; p++) {
for (j=0; j<ru->nb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]);
free_and_zero(ru->beam_weights[i][p]);
if (ru->do_precoding == 1) {
for (i = 0; i < ru->num_gNB; i++) {
for (p = 0; p < ru->nb_log_antennas; p++) {
for (j=0; j<ru->nb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]);
free_and_zero(ru->beam_weights[i][p]);
}
}
for(i=0; i< ru->nb_tx; ++i)
free_and_zero(ru->common.beam_id[i]);
free_and_zero(ru->common.beam_id);
}
}
free_and_zero(ru->common.sync_corr);
+351 -144
View File
@@ -111,6 +111,49 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch,
}
}
void phy_term_nr_ue__PDSCH(NR_UE_PDSCH* pdsch, const NR_DL_FRAME_PARMS *const fp)
{
for (int i = 0; i < fp->nb_antennas_rx; i++) {
for (int j = 0; j < NR_MAX_NB_LAYERS; j++) {
const int idx = j * fp->nb_antennas_rx + i;
for (int k = 0; k < NR_MAX_NB_LAYERS; k++)
free_and_zero(pdsch->rho[i][j*NR_MAX_NB_LAYERS+k]);
free_and_zero(pdsch->rxdataF_comp0[idx]);
free_and_zero(pdsch->dl_ch_estimates[idx]);
free_and_zero(pdsch->dl_ch_estimates_ext[idx]);
free_and_zero(pdsch->dl_bf_ch_estimates[idx]);
free_and_zero(pdsch->dl_bf_ch_estimates_ext[idx]);
free_and_zero(pdsch->dl_ch_mag0[idx]);
free_and_zero(pdsch->dl_ch_magb0[idx]);
free_and_zero(pdsch->dl_ch_magr0[idx]);
}
free_and_zero(pdsch->rxdataF_ext[i]);
free_and_zero(pdsch->rxdataF_uespec_pilots[i]);
free_and_zero(pdsch->ptrs_phase_per_slot[i]);
free_and_zero(pdsch->ptrs_re_per_slot[i]);
free_and_zero(pdsch->dl_ch_ptrs_estimates_ext[i]);
free_and_zero(pdsch->rho[i]);
}
free_and_zero(pdsch->pmi_ext);
free_and_zero(pdsch->llr[0]);
free_and_zero(pdsch->layer_llr[0]);
free_and_zero(pdsch->llr128);
free_and_zero(pdsch->rxdataF_ext);
free_and_zero(pdsch->rxdataF_uespec_pilots);
free_and_zero(pdsch->rxdataF_comp0);
free_and_zero(pdsch->rho);
free_and_zero(pdsch->dl_ch_estimates);
free_and_zero(pdsch->dl_ch_estimates_ext);
free_and_zero(pdsch->dl_bf_ch_estimates);
free_and_zero(pdsch->dl_bf_ch_estimates_ext);
free_and_zero(pdsch->dl_ch_mag0);
free_and_zero(pdsch->dl_ch_magb0);
free_and_zero(pdsch->dl_ch_magr0);
free_and_zero(pdsch->ptrs_phase_per_slot);
free_and_zero(pdsch->ptrs_re_per_slot);
free_and_zero(pdsch->dl_ch_ptrs_estimates_ext);
}
void phy_init_nr_ue_PUSCH(NR_UE_PUSCH *const pusch,
const NR_DL_FRAME_PARMS *const fp) {
AssertFatal( pusch, "pusch==0" );
@@ -120,9 +163,14 @@ void phy_init_nr_ue_PUSCH(NR_UE_PUSCH *const pusch,
}
}
int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
int nb_connected_gNB,
uint8_t abstraction_flag) {
void phy_term_nr_ue_PUSCH(NR_UE_PUSCH *pusch)
{
for (int i = 0; i < NR_MAX_NB_LAYERS; i++)
free_and_zero(pusch->txdataF_layers[i]);
}
int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
{
// create shortcuts
NR_DL_FRAME_PARMS *const fp = &ue->frame_parms;
NR_UE_COMMON *const common_vars = &ue->common_vars;
@@ -134,11 +182,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
int gNB_id;
int th_id;
uint32_t ****pusch_dmrs;
uint16_t N_n_scid[2] = {0,1}; // [HOTFIX] This is a temporary implementation of scramblingID0 and scramblingID1 which are given by DMRS-UplinkConfig
int n_scid;
abstraction_flag = 0;
LOG_I(PHY, "Initializing UE vars (abstraction %u) for gNB TXant %u, UE RXant %u\n", abstraction_flag, fp->nb_antennas_tx, fp->nb_antennas_rx);
//LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_gNB_INST);
LOG_I(PHY, "Initializing UE vars for gNB TXant %u, UE RXant %u\n", fp->nb_antennas_tx, fp->nb_antennas_rx);
phy_init_nr_top(ue);
// many memory allocation sizes are hard coded
AssertFatal( fp->nb_antennas_rx <= 4, "hard coded allocation for ue_common_vars->dl_ch_estimates[gNB_id]" );
@@ -192,7 +236,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
///////////
ue->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
pusch_dmrs = ue->nr_gold_pusch_dmrs;
n_scid = 0; // This quantity is indicated by higher layer parameter dmrs-SeqInitialization
for (slot=0; slot<fp->slots_per_frame; slot++) {
pusch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t **));
@@ -209,7 +252,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
}
}
nr_init_pusch_dmrs(ue, N_n_scid, n_scid);
///////////
////////////////////////////////////////////////////////////////////////////////////////////
@@ -231,29 +273,27 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
for (i=0; i<10; i++)
ue->tx_power_dBm[i]=-127;
if (abstraction_flag == 0) {
// init TX buffers
common_vars->txdata = (int32_t **)malloc16( fp->nb_antennas_tx*sizeof(int32_t *) );
common_vars->txdataF = (int32_t **)malloc16( fp->nb_antennas_tx*sizeof(int32_t *) );
// init TX buffers
common_vars->txdata = (int32_t **)malloc16( fp->nb_antennas_tx*sizeof(int32_t *) );
common_vars->txdataF = (int32_t **)malloc16( fp->nb_antennas_tx*sizeof(int32_t *) );
for (i=0; i<fp->nb_antennas_tx; i++) {
common_vars->txdata[i] = (int32_t *)malloc16_clear( fp->samples_per_subframe*10*sizeof(int32_t) );
common_vars->txdataF[i] = (int32_t *)malloc16_clear( fp->samples_per_slot_wCP*sizeof(int32_t) );
}
for (i=0; i<fp->nb_antennas_tx; i++) {
common_vars->txdata[i] = (int32_t *)malloc16_clear( fp->samples_per_subframe*10*sizeof(int32_t) );
common_vars->txdataF[i] = (int32_t *)malloc16_clear( fp->samples_per_slot_wCP*sizeof(int32_t) );
}
// init RX buffers
common_vars->rxdata = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
// init RX buffers
common_vars->rxdata = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
common_vars->common_vars_rx_data_per_thread[th_id].rxdataF = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
}
for (i=0; i<fp->nb_antennas_rx; i++) {
common_vars->rxdata[i] = (int32_t *) malloc16_clear( (2*(fp->samples_per_frame)+2048)*sizeof(int32_t) );
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
common_vars->common_vars_rx_data_per_thread[th_id].rxdataF = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
}
for (i=0; i<fp->nb_antennas_rx; i++) {
common_vars->rxdata[i] = (int32_t *) malloc16_clear( (2*(fp->samples_per_frame)+2048)*sizeof(int32_t) );
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
common_vars->common_vars_rx_data_per_thread[th_id].rxdataF[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->samples_per_slot_wCP) );
}
common_vars->common_vars_rx_data_per_thread[th_id].rxdataF[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->samples_per_slot_wCP) );
}
}
@@ -272,9 +312,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
}
}
ue->scramblingID_pdcch = fp->Nid_cell;
nr_gold_pdcch(ue,fp->Nid_cell);
//PDSCH DMRS init (eNB offset = 0)
ue->nr_gold_pdsch[0] = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
uint32_t ****pdsch_dmrs = ue->nr_gold_pdsch[0];
@@ -294,12 +331,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
}
}
// initializing the scrambling IDs for PDSCH DMRS
for (int i=0; i<2; i++)
ue->scramblingID[i]=fp->Nid_cell;
nr_gold_pdsch(ue,ue->scramblingID);
// DLSCH
for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
@@ -331,110 +362,100 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
ue->nr_srs_info->srs_estimated_channel_time_shifted[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t));
}
if (abstraction_flag == 0) {
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
phy_init_nr_ue__PDSCH( ue->pdsch_vars[th_id][gNB_id], fp );
}
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][gNB_id]->llr_shifts = (uint8_t *)malloc16_clear(7*2*fp->N_RB_DL*12);
ue->pdsch_vars[th_id][gNB_id]->llr_shifts_p = ue->pdsch_vars[0][gNB_id]->llr_shifts;
ue->pdsch_vars[th_id][gNB_id]->llr[1] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
ue->pdsch_vars[th_id][gNB_id]->layer_llr[1] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
ue->pdsch_vars[th_id][gNB_id]->llr128_2ndstream = (int16_t **)malloc16_clear( sizeof(int16_t *) );
}
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
}
for (i=0; i<fp->nb_antennas_rx; i++)
for (j=0; j<4; j++) {
const int idx = (j*fp->nb_antennas_rx)+i;
const size_t num = 7*2*fp->N_RB_DL*12+4;
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
}
}
//const size_t num = 7*2*fp->N_RB_DL*12+4;
for (k=0; k<8; k++) { //harq_pid
for (l=0; l<8; l++) { //round
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
}
for (int i=0; i<fp->nb_antennas_rx; i++)
for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++)
const int idx = (j*fp->nb_antennas_rx)+i;
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l][idx] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l][idx] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l][idx] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
}
}
}
}
// 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdcch_vars[th_id][gNB_id]->llr = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
ue->pdcch_vars[th_id][gNB_id]->llr16 = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
ue->pdcch_vars[th_id][gNB_id]->wbar = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
ue->pdcch_vars[th_id][gNB_id]->e_rx = (int16_t *)malloc16_clear( 4*2*100*12 );
ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdcch_vars[th_id][gNB_id]->dl_ch_rho_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdcch_vars[th_id][gNB_id]->rho = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
// Channel estimates
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear(4*fp->nb_antennas_rx*sizeof(int32_t *));
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear(4*fp->nb_antennas_rx*sizeof(int32_t *));
for (i=0; i<fp->nb_antennas_rx; i++) {
ue->pdcch_vars[th_id][gNB_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(100*12*4));
for (j=0; j<4; j++) {
int idx = (j*fp->nb_antennas_rx)+i;
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) );
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
// size_t num = 7*2*fp->N_RB_DL*12;
size_t num = 4*273*12; // 4 symbols, 100 PRBs, 12 REs per PRB
ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num);
ue->pdcch_vars[th_id][gNB_id]->dl_ch_rho_ext[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num);
ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num);
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num);
}
}
}
// PBCH
prach_vars[gNB_id]->prachF = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
prach_vars[gNB_id]->prach = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
phy_init_nr_ue__PDSCH( ue->pdsch_vars[th_id][gNB_id], fp );
}
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][gNB_id]->llr_shifts = (uint8_t *)malloc16_clear(7*2*fp->N_RB_DL*12);
ue->pdsch_vars[th_id][gNB_id]->llr_shifts_p = ue->pdsch_vars[0][gNB_id]->llr_shifts;
ue->pdsch_vars[th_id][gNB_id]->llr[1] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
ue->pdsch_vars[th_id][gNB_id]->layer_llr[1] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
ue->pdsch_vars[th_id][gNB_id]->llr128_2ndstream = (int16_t **)malloc16_clear( sizeof(int16_t *) );
}
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
}
for (i=0; i<fp->nb_antennas_rx; i++)
for (j=0; j<4; j++) {
const int idx = (j*fp->nb_antennas_rx)+i;
const size_t num = 7*2*fp->N_RB_DL*12+4;
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
}
}
//const size_t num = 7*2*fp->N_RB_DL*12+4;
for (k=0; k<8; k++) { //harq_pid
for (l=0; l<8; l++) { //round
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
}
for (int i=0; i<fp->nb_antennas_rx; i++)
for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++)
const int idx = (j*fp->nb_antennas_rx)+i;
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l][idx] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l][idx] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l][idx] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12));
}
}
}
}
// PBCH
prach_vars[gNB_id]->prachF = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
prach_vars[gNB_id]->prach = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
// 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdcch_vars[th_id][gNB_id]->llr = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
ue->pdcch_vars[th_id][gNB_id]->llr16 = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
ue->pdcch_vars[th_id][gNB_id]->wbar = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
ue->pdcch_vars[th_id][gNB_id]->e_rx = (int16_t *)malloc16_clear( 4*2*100*12 );
ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdcch_vars[th_id][gNB_id]->dl_ch_rho_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdcch_vars[th_id][gNB_id]->rho = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
// Channel estimates
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear(4*fp->nb_antennas_rx*sizeof(int32_t *));
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear(4*fp->nb_antennas_rx*sizeof(int32_t *));
for (i=0; i<fp->nb_antennas_rx; i++) {
ue->pdcch_vars[th_id][gNB_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(100*12*4));
for (j=0; j<4; j++) {
int idx = (j*fp->nb_antennas_rx)+i;
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) );
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
// size_t num = 7*2*fp->N_RB_DL*12;
size_t num = 4*273*12; // 4 symbols, 100 PRBs, 12 REs per PRB
ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num);
ue->pdcch_vars[th_id][gNB_id]->dl_ch_rho_ext[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num);
ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num);
ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num);
}
}
}
}
// initialization for the last instance of pdsch_vars (used for MU-MIMO)
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
ue->pdsch_vars[th_id][gNB_id] = (NR_UE_PDSCH *)malloc16_clear(sizeof(NR_UE_PDSCH));
}
if (abstraction_flag == 0) {
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
//phy_init_lte_ue__PDSCH( ue->pdsch_vars[th_id][gNB_id], fp );
ue->pdsch_vars[th_id][gNB_id]->llr[1] = (int16_t *)malloc16_clear((8*(3*8*8448))*sizeof(int16_t));
ue->pdsch_vars[th_id][gNB_id]->layer_llr[1] = (int16_t *)malloc16_clear((8*(3*8*8448))*sizeof(int16_t));
}
} else { //abstraction == 1
ue->sinr_dB = (double *) malloc16_clear( fp->N_RB_DL*12*sizeof(double) );
ue->pdsch_vars[th_id][gNB_id] = malloc16_clear(sizeof(NR_UE_PDSCH));
ue->pdsch_vars[th_id][gNB_id]->llr[1] = malloc16_clear((8*(3*8*8448))*sizeof(int16_t));
ue->pdsch_vars[th_id][gNB_id]->layer_llr[1] = malloc16_clear((8*(3*8*8448))*sizeof(int16_t));
}
ue->sinr_CQI_dB = (double *) malloc16_clear( fp->N_RB_DL*12*sizeof(double) );
@@ -455,25 +476,205 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
return 0;
}
void init_nr_ue_transport(PHY_VARS_NR_UE *ue,
int abstraction_flag) {
void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
{
const NR_DL_FRAME_PARMS* fp = &ue->frame_parms;
phy_term_nr_top();
for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
phy_term_nr_ue_PUSCH(ue->pusch_vars[th_id][gNB_id]);
free_and_zero(ue->pusch_vars[th_id][gNB_id]);
free_and_zero(ue->pucch_vars[th_id][gNB_id]);
}
}
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
for (int symb = 0; symb < fp->symbols_per_slot; symb++) {
for (int q = 0; q < NR_MAX_NB_CODEWORDS; q++)
free_and_zero(ue->nr_gold_pusch_dmrs[slot][symb][q]);
free_and_zero(ue->nr_gold_pusch_dmrs[slot][symb]);
}
free_and_zero(ue->nr_gold_pusch_dmrs[slot]);
}
free_and_zero(ue->nr_gold_pusch_dmrs);
NR_UE_COMMON* common_vars = &ue->common_vars;
for (int i = 0; i < fp->nb_antennas_tx; i++) {
free_and_zero(common_vars->txdata[i]);
free_and_zero(common_vars->txdataF[i]);
}
free_and_zero(common_vars->txdata);
free_and_zero(common_vars->txdataF);
for (int i = 0; i < fp->nb_antennas_rx; i++) {
free_and_zero(common_vars->rxdata[i]);
for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++)
free_and_zero(common_vars->common_vars_rx_data_per_thread[th_id].rxdataF[i]);
}
for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
free_and_zero(common_vars->common_vars_rx_data_per_thread[th_id].rxdataF);
}
free_and_zero(common_vars->rxdata);
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
for (int symb = 0; symb < fp->symbols_per_slot; symb++)
free_and_zero(ue->nr_gold_pdcch[0][slot][symb]);
free_and_zero(ue->nr_gold_pdcch[0][slot]);
}
free_and_zero(ue->nr_gold_pdcch[0]);
for (int slot=0; slot<fp->slots_per_frame; slot++) {
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
for (int q=0; q<NR_MAX_NB_CODEWORDS; q++)
free_and_zero(ue->nr_gold_pdsch[0][slot][symb][q]);
free_and_zero(ue->nr_gold_pdsch[0][slot][symb]);
}
free_and_zero(ue->nr_gold_pdsch[0][slot]);
}
free_and_zero(ue->nr_gold_pdsch[0]);
for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
// PDSCH
for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
for (int k = 0; k < 8; k++) { //harq_pid
for (int l = 0; l < 8; l++) { //round
for (int i = 0; i < fp->nb_antennas_rx; i++) {
for (int j = 0; j < 4; j++) { //frame_parms->nb_antennas_tx; j++)
const int idx = j * fp->nb_antennas_rx + i;
free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l][idx]);
free_and_zero(ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l][idx]);
free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l][idx]);
free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l][idx]);
}
}
free_and_zero(ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l]);
free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l]);
free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l]);
free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l]);
}
}
for (int i = 0; i < fp->nb_antennas_rx; i++) {
for (int j = 0; j < 4; j++) {
const int idx = (j*fp->nb_antennas_rx)+i;
free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext[idx]);
}
}
free_and_zero(ue->pdsch_vars[th_id][gNB_id]->llr_shifts);
free_and_zero(ue->pdsch_vars[th_id][gNB_id]->llr[1]);
free_and_zero(ue->pdsch_vars[th_id][gNB_id]->layer_llr[1]);
free_and_zero(ue->pdsch_vars[th_id][gNB_id]->llr128_2ndstream);
free_and_zero(ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext);
phy_term_nr_ue__PDSCH(ue->pdsch_vars[th_id][gNB_id], fp);
free_and_zero(ue->pdsch_vars[th_id][gNB_id]);
}
for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
for (int i = 0; i < fp->nb_antennas_rx; i++) {
for (int j = 0; j < 4; j++) {
int idx = j * fp->nb_antennas_rx + i;
free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates[idx]);
free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time[idx]);
free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp[idx]);
free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_rho_ext[idx]);
free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext[idx]);
free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext[idx]);
}
free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rho[i]);
}
free_and_zero(ue->pdcch_vars[th_id][gNB_id]->llr);
free_and_zero(ue->pdcch_vars[th_id][gNB_id]->llr16);
free_and_zero(ue->pdcch_vars[th_id][gNB_id]->wbar);
free_and_zero(ue->pdcch_vars[th_id][gNB_id]->e_rx);
free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp);
free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_rho_ext);
free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rho);
free_and_zero(ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext);
free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext);
free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates);
free_and_zero(ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time);
free_and_zero(ue->pdcch_vars[th_id][gNB_id]);
}
for (int i = 0; i < fp->nb_antennas_rx; i++) {
free_and_zero(ue->nr_srs_info->srs_received_signal[i]);
free_and_zero(ue->nr_srs_info->srs_ls_estimated_channel[i]);
free_and_zero(ue->nr_srs_info->srs_estimated_channel_freq[i]);
free_and_zero(ue->nr_srs_info->srs_estimated_channel_time[i]);
free_and_zero(ue->nr_srs_info->srs_estimated_channel_time_shifted[i]);
}
free_and_zero(ue->nr_srs_info->srs_generated_signal);
free_and_zero(ue->nr_srs_info->noise_power);
free_and_zero(ue->nr_srs_info->srs_received_signal);
free_and_zero(ue->nr_srs_info->srs_ls_estimated_channel);
free_and_zero(ue->nr_srs_info->srs_estimated_channel_freq);
free_and_zero(ue->nr_srs_info->srs_estimated_channel_time);
free_and_zero(ue->nr_srs_info->srs_estimated_channel_time_shifted);
free_and_zero(ue->nr_srs_info);
free_and_zero(ue->srs_vars[gNB_id]);
free_and_zero(ue->pbch_vars[gNB_id]);
free_and_zero(ue->prach_vars[gNB_id]->prachF);
free_and_zero(ue->prach_vars[gNB_id]->prach);
free_and_zero(ue->prach_vars[gNB_id]);
}
const int gNB_id = ue->n_connected_gNB;
for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
free_and_zero(ue->pdsch_vars[th_id][gNB_id]->llr[1]);
free_and_zero(ue->pdsch_vars[th_id][gNB_id]->layer_llr[1]);
free_and_zero(ue->pdsch_vars[th_id][gNB_id]);
}
free_and_zero(ue->sinr_CQI_dB);
}
void term_nr_ue_transport(PHY_VARS_NR_UE *ue)
{
const int N_RB_DL = ue->frame_parms.N_RB_DL;
for (int i = 0; i < NUMBER_OF_CONNECTED_gNB_MAX; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < RX_NB_TH_MAX; k++) {
free_nr_ue_dlsch(&ue->dlsch[k][i][j], N_RB_DL);
free_nr_ue_ulsch(&ue->ulsch[k][i][j], N_RB_DL);
}
}
free_nr_ue_dlsch(&ue->dlsch_SI[i], N_RB_DL);
free_nr_ue_dlsch(&ue->dlsch_ra[i], N_RB_DL);
}
free_nr_ue_dlsch(&ue->dlsch_MCH[0], N_RB_DL);
}
void init_nr_ue_transport(PHY_VARS_NR_UE *ue)
{
for (int i = 0; i < NUMBER_OF_CONNECTED_gNB_MAX; i++) {
for (int j=0; j<2; j++) {
for (int k=0; k<RX_NB_TH_MAX; k++) {
AssertFatal((ue->dlsch[k][i][j] = new_nr_ue_dlsch(1,NR_MAX_DLSCH_HARQ_PROCESSES,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag))!=NULL,"Can't get ue dlsch structures\n");
AssertFatal((ue->dlsch[k][i][j] = new_nr_ue_dlsch(1,NR_MAX_DLSCH_HARQ_PROCESSES,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL))!=NULL,"Can't get ue dlsch structures\n");
LOG_D(PHY,"dlsch[%d][%d][%d] => %p\n",k,i,j,ue->dlsch[k][i][j]);
AssertFatal((ue->ulsch[k][i][j] = new_nr_ue_ulsch(ue->frame_parms.N_RB_UL, NR_MAX_ULSCH_HARQ_PROCESSES, abstraction_flag))!=NULL,"Can't get ue ulsch structures\n");
AssertFatal((ue->ulsch[k][i][j] = new_nr_ue_ulsch(ue->frame_parms.N_RB_UL, NR_MAX_ULSCH_HARQ_PROCESSES))!=NULL,"Can't get ue ulsch structures\n");
LOG_D(PHY,"ulsch[%d][%d][%d] => %p\n",k,i,j,ue->ulsch[k][i][j]);
}
}
ue->dlsch_SI[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag);
ue->dlsch_ra[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag);
ue->dlsch_SI[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL);
ue->dlsch_ra[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL);
ue->transmission_mode[i] = ue->frame_parms.nb_antenna_ports_gNB==1 ? 1 : 2;
}
//ue->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1;
ue->dlsch_MCH[0] = new_nr_ue_dlsch(1,NR_MAX_DLSCH_HARQ_PROCESSES,NSOFT,MAX_LDPC_ITERATIONS_MBSFN,ue->frame_parms.N_RB_DL,0);
ue->dlsch_MCH[0] = new_nr_ue_dlsch(1,NR_MAX_DLSCH_HARQ_PROCESSES,NSOFT,MAX_LDPC_ITERATIONS_MBSFN,ue->frame_parms.N_RB_DL);
for(int i=0; i<5; i++)
ue->dl_stats[i] = 0;
@@ -537,3 +738,9 @@ void phy_init_nr_top(PHY_VARS_NR_UE *ue) {
//init_unscrambling_lut();
//set_taus_seed(1328);
}
void phy_term_nr_top(void)
{
free_ul_reference_signal_sequences();
free_context_synchro_nr();
}
+6 -2
View File
@@ -57,6 +57,7 @@ int l1_north_init_eNB(void);
int phy_init_top(LTE_DL_FRAME_PARMS *frame_parms);
void phy_init_nr_top(PHY_VARS_NR_UE *ue);
void phy_term_nr_top(void);
/*!
@@ -395,8 +396,9 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb);
int nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms);
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band);
void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink_frequency, int32_t uplink_frequency_offset, uint8_t mu, uint16_t nr_band);
int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag);
void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag);
int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB);
void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB);
void init_nr_ue_transport(PHY_VARS_NR_UE *ue);
void init_N_TA_offset(PHY_VARS_NR_UE *ue);
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms);
int phy_init_nr_gNB(PHY_VARS_gNB *gNB, unsigned char is_secondary_gNB, unsigned char lowmem_flag);
@@ -405,11 +407,13 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu,
void phy_free_nr_gNB(PHY_VARS_gNB *gNB);
int l1_north_init_gNB(void);
void init_nr_transport(PHY_VARS_gNB *gNB);
void reset_nr_transport(PHY_VARS_gNB *gNB);
void init_dfts(void);
void fill_subframe_mask(PHY_VARS_eNB *eNB);
void init_DLSCH_struct(PHY_VARS_gNB *gNB, processingData_L1tx_t *msg);
void reset_DLSCH_struct(const PHY_VARS_gNB *gNB, processingData_L1tx_t *msg);
/** @} */
#endif
+2 -1
View File
@@ -601,7 +601,8 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,
G = G - Q_RI - Q_CQI;
ulsch_harq->G = G;
AssertFatal((int)G > 0,
"FATAL: ulsch_decoding.c G < 0 (%u) : Q_RI %u, Q_CQI %u\n",G,Q_RI,Q_CQI);
"FATAL: ulsch_decoding.c G < 0 (%u) : Q_RI %u, Q_CQI %u, nb_rb %u, Q_m %u, ulsch_harq->Nsymb_pusch %u, Qprime %u\n",
G, Q_RI, Q_CQI, nb_rb, Q_m, ulsch_harq->Nsymb_pusch, Qprime);
H = G + Q_CQI;
Hprime = H/Q_m;
// Demultiplexing/Deinterleaving of PUSCH/ACK/RI/CQI
@@ -6481,7 +6481,7 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,unsigned int *c
sprintf(fname,"dlsch%d_rxF_r%d_uespec0.m",eNB_id,round);
sprintf(vname,"dl%d_rxF_r%d_uespec0",eNB_id,round);
LOG_M(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->rxdataF_uespec_pilots[0],
12*(ue->frame_parms.N_RB_DL)*NSYMB,1,1);
12*(ue->frame_parms.N_RB_DL),1,1);
/*
LOG_M("dlsch%d_ch_ext01.m","dl01_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*NSYMB,1,1);
LOG_M("dlsch%d_ch_ext10.m","dl10_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*NSYMB,1,1);
+1
View File
@@ -65,6 +65,7 @@
/* SS/PBCH parameters */
#define N_RB_SS_PBCH_BLOCK (20)
#define NB_SYMBOLS_PBCH (3)
#define NR_N_SYMBOLS_SSB (4)
#define IQ_SIZE (sizeof(int16_t) * 2) /* I and Q are alternatively stored into buffers */
#define N_SYMB_SLOT (14)
+8 -4
View File
@@ -63,18 +63,22 @@
/************** VARIABLES *****************************************/
#define PHASE_HYPOTHESIS_NUMBER (7)
#define PHASE_HYPOTHESIS_NUMBER (16)
#define INDEX_NO_PHASE_DIFFERENCE (3) /* this is for no phase shift case */
EXTERN const int16_t phase_re_nr[PHASE_HYPOTHESIS_NUMBER]
#ifdef INIT_VARIABLES_SSS_NR_H
= {16383, 25101, 30791, 32767, 30791, 25101, 16383}
// -pi/3 ---- pi/3
= {16384,20173,23571,26509,28932,30791,32051,32687,32687,32051,30791,
28932,26509,23571,20173,16384}
#endif
;
EXTERN const int16_t phase_im_nr[PHASE_HYPOTHESIS_NUMBER]
#ifdef INIT_VARIABLES_SSS_NR_H
= {-28378, -21063, -11208, 0, 11207, 21062, 28377};
// -pi/3 ---- pi/3
= {-28377,-25821,-22762,-19260,-15383,-11207,-6813,-2286,2286,6813,11207,
15383,19260,22762,25821,28377}
#endif
;
@@ -92,7 +96,7 @@ int pss_ch_est_nr(PHY_VARS_NR_UE *ue,
int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR]);
int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max);
int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max, int *freq_offset_sss);
#undef INIT_VARIABLES_SSS_NR_H
#undef EXTERN
+19 -12
View File
@@ -122,23 +122,20 @@ int16_t *base_sequence_less_than_36(unsigned int M_ZC,
*********************************************************************/
int16_t get_index_for_dmrs_lowpapr_seq(int16_t num_dmrs_res) {
int16_t index = -1;
if (num_dmrs_res >= dmrs_ul_allocated_res[(MAX_INDEX_DMRS_UL_ALLOCATED_REs-1)])
int16_t index = num_dmrs_res/6 - 1;
if (index >= MAX_INDEX_DMRS_UL_ALLOCATED_REs)
index = MAX_INDEX_DMRS_UL_ALLOCATED_REs-1;
else
index = (num_dmrs_res/6) -1;
for (;index >= 0; index--) {
if (dmrs_ul_allocated_res[index] == num_dmrs_res)
break;
}
LOG_D(PHY, "num_dmrs_res: %d INDEX RETURNED: %d", num_dmrs_res, index);
return index;
LOG_D(PHY, "num_dmrs_res: %d INDEX RETURNED: %d", num_dmrs_res, index);
return index;
}
/*******************************************************************
@@ -204,6 +201,11 @@ int16_t *base_sequence_36_or_larger(unsigned int Msc_RS,
void generate_lowpapr_typ1_refsig_sequences(unsigned int scaling)
{
/* prevent multiple calls, relevant when both UE & gNB initialize this */
static bool already_called = false;
if (already_called) return;
already_called = true;
unsigned int u,Msc_RS;
unsigned int v = 0; // sequence hopping and group hopping are not supported yet
@@ -223,6 +225,11 @@ void generate_lowpapr_typ1_refsig_sequences(unsigned int scaling)
void generate_ul_reference_signal_sequences(unsigned int scaling)
{
/* prevent multiple calls, relevant when both UE & gNB initialize this */
static bool already_called = false;
if (already_called) return;
already_called = true;
unsigned int u,v,Msc_RS;
#if 0
@@ -295,10 +302,10 @@ void free_ul_reference_signal_sequences(void)
for (u=0; u < U_GROUP_NUMBER; u++) {
for (v=0; v < V_BASE_SEQUENCE_NUMBER; v++) {
if (rv_ul_ref_sig[u][v][Msc_RS])
free16(rv_ul_ref_sig[u][v][Msc_RS],2*sizeof(int16_t)*ul_allocated_re[Msc_RS]);
free_and_zero(rv_ul_ref_sig[u][v][Msc_RS]);
if ((v==0) && (Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs))
if (dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS])
free16(dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS],2*sizeof(int16_t)*dmrs_ul_allocated_res[Msc_RS]);
free_and_zero(dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS]);
}
}
}
@@ -321,7 +328,7 @@ void free_gnb_lowpapr_sequences(void)
v=0;
for (u=0; u < U_GROUP_NUMBER; u++) {
if (gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS])
free16(gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS],2*sizeof(int16_t)*dmrs_ul_allocated_res[Msc_RS]);
free_and_zero(gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS]);
}
}
}
+2 -5
View File
@@ -130,11 +130,8 @@ void nr_generate_dci(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
uint16_t Nid = dci_pdu->ScramblingId;
uint16_t scrambling_RNTI = dci_pdu->ScramblingRNTI;
t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE,
dci_pdu->PayloadSizeBits,
dci_pdu->AggregationLevel,
0,NULL);
polar_encoder_fast((uint64_t*)dci_pdu->Payload, (void*)encoder_output, n_RNTI,1,currentPtr);
polar_encoder_fast((uint64_t*)dci_pdu->Payload, (void*)encoder_output, n_RNTI, 1,
NR_POLAR_DCI_MESSAGE_TYPE, dci_pdu->PayloadSizeBits, dci_pdu->AggregationLevel);
#ifdef DEBUG_CHANNEL_CODING
printf("polar rnti %x,length %d, L %d\n",n_RNTI, dci_pdu->PayloadSizeBits,pdcch_pdu_rel15->dci_pdu->AggregationLevel);
printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n",
+42 -40
View File
@@ -224,21 +224,23 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n",
start_sc, rel15->StartSymbolIndex, rel15->rbSize, nb_re,rel15->nrOfLayers);
#endif
start_meas(&gNB->dlsch_resource_mapping_stats);
for (int ap=0; ap<rel15->nrOfLayers; ap++) {
// DMRS params for this ap
get_Wt(Wt, ap, dmrs_Type);
get_Wf(Wf, ap, dmrs_Type);
delta = get_delta(ap, dmrs_Type);
l_prime = 0; // single symbol ap 0
start_meas(&gNB->dlsch_resource_mapping_stats);
for (int nl=0; nl<rel15->nrOfLayers; nl++) {
int dmrs_port = get_dmrs_port(nl,rel15->dmrsPorts);
// DMRS params for this dmrs port
get_Wt(Wt, dmrs_port, dmrs_Type);
get_Wf(Wf, dmrs_port, dmrs_Type);
delta = get_delta(dmrs_port, dmrs_Type);
l_prime = 0; // single symbol nl 0
l0 = get_l0(rel15->dlDmrsSymbPos);
l_overline = l0;
#ifdef DEBUG_DLSCH_MAPPING
uint8_t dmrs_symbol = l0+l_prime;
printf("DMRS Type %d params for ap %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n",
1+dmrs_Type,ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime, l0, dmrs_symbol);
printf("DMRS Type %d params for nl %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n",
1+dmrs_Type,nl, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime, l0, dmrs_symbol);
#endif
uint16_t m=0, dmrs_idx=0;
@@ -307,7 +309,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
if (ptrs_symbol)
is_ptrs_re = is_ptrs_subcarrier(k,
rel15->rnti,
ap,
nl,
rel15->dmrsConfigType,
rel15->PTRSFreqDensity,
rel15->rbSize,
@@ -317,12 +319,12 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
/* Map DMRS Symbol */
if ( (dmrs_symbol_map & (1 << l)) &&
(k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) {
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 ] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15;
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 ] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
#ifdef DEBUG_DLSCH_MAPPING
printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n",
dmrs_idx, l, k, k_prime, n, txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1)],
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1]);
dmrs_idx, l, k, k_prime, n, txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1)],
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1]);
#endif
dmrs_idx++;
k_prime++;
@@ -330,30 +332,30 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
n+=(k_prime)?0:1;
}
else if(is_ptrs_re){
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = (beta_ptrs*amp*mod_ptrs[ptrs_idx<<1]) >> 15;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (beta_ptrs*amp*mod_ptrs[(ptrs_idx<<1) + 1])>> 15;
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = (beta_ptrs*amp*mod_ptrs[ptrs_idx<<1]) >> 15;
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (beta_ptrs*amp*mod_ptrs[(ptrs_idx<<1) + 1])>> 15;
#ifdef DEBUG_DLSCH_MAPPING
printf("ptrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d, mod_ptrs: %d %d\n",
ptrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)],mod_ptrs[ptrs_idx<<1],mod_ptrs[(ptrs_idx<<1)+1]);
ptrs_idx, l, k, k_prime, n, ((int16_t*)txdataF_precoding[nl])[((l*frame_parms->ofdm_symbol_size + k)<<1)],
((int16_t*)txdataF_precoding[nl])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1],mod_ptrs[ptrs_idx<<1],mod_ptrs[(ptrs_idx<<1)+1]);
#endif
ptrs_idx++;
}
/* Map DATA Symbol */
else if( ptrs_symbol || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,frame_parms->ofdm_symbol_size,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) {
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = (amp * tx_layers[ap][m<<1]) >> 15;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15;
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = (amp * tx_layers[nl][m<<1]) >> 15;
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * tx_layers[nl][(m<<1) + 1]) >> 15;
#ifdef DEBUG_DLSCH_MAPPING
printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
m, l, k, txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1)],
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1]);
m, l, k, txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1)],
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1]);
#endif
m++;
}
/* mute RE */
else {
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = 0;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = 0;
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = 0;
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = 0;
}
if (++k >= frame_parms->ofdm_symbol_size)
k -= frame_parms->ofdm_symbol_size;
@@ -369,26 +371,26 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
}
// fix the alignment issues later, use 64-bit SIMD below instead of 128.
if (0/*(frame_parms->N_RB_DL&1)==0*/) {
__m128i *txF=(__m128i*)&txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size+start_sc)<<1)];
__m128i *txF=(__m128i*)&txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size+start_sc)<<1)];
__m128i *txl = (__m128i*)&tx_layers[ap][m<<1];
__m128i *txl = (__m128i*)&tx_layers[nl][m<<1];
__m128i amp128=_mm_set1_epi16(amp);
for (int i=0; i<(upper_limit>>2); i++) {
txF[i] = _mm_mulhrs_epi16(amp128,txl[i]);
} //RE loop, first part
m+=upper_limit;
if (remaining_re > 0) {
txF = (__m128i*)&txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size)<<1)];
txl = (__m128i*)&tx_layers[ap][m<<1];
txF = (__m128i*)&txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size)<<1)];
txl = (__m128i*)&tx_layers[nl][m<<1];
for (int i=0; i<(remaining_re>>2); i++) {
txF[i] = _mm_mulhrs_epi16(amp128,txl[i]);
}
}
}
else {
__m64 *txF=(__m64*)&txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size+start_sc)<<1)];
__m64 *txF=(__m64*)&txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size+start_sc)<<1)];
__m64 *txl = (__m64*)&tx_layers[ap][m<<1];
__m64 *txl = (__m64*)&tx_layers[nl][m<<1];
__m64 amp64=_mm_set1_pi16(amp);
for (int i=0; i<(upper_limit>>1); i++) {
@@ -396,31 +398,31 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
#ifdef DEBUG_DLSCH_MAPPING
if ((i&1) > 0)
printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
m, l, start_sc+(i>>1), txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + start_sc+(i>>1))<<1)],
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + start_sc+(i>>1))<<1) + 1]);
m, l, start_sc+(i>>1), txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + start_sc+(i>>1))<<1)],
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + start_sc+(i>>1))<<1) + 1]);
#endif
/* handle this, mute RE */
/*else {
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = 0;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = 0;
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = 0;
txdataF_precoding[anl][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = 0;
}*/
} //RE loop, first part
m+=upper_limit;
if (remaining_re > 0) {
txF = (__m64*)&txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size)<<1)];
txl = (__m64*)&tx_layers[ap][m<<1];
txF = (__m64*)&txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size)<<1)];
txl = (__m64*)&tx_layers[nl][m<<1];
for (int i=0; i<(remaining_re>>1); i++) {
txF[i] = _mm_mulhrs_pi16(amp64,txl[i]);
#ifdef DEBUG_DLSCH_MAPPING
if ((i&1) > 0)
printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
m, l, i>>1, txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + (i>>1))<<1) ],
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + (i>>1))<<1) + 1]);
m, l, i>>1, txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + (i>>1))<<1) ],
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + (i>>1))<<1) + 1]);
#endif
/* handle this, mute RE */
/*else {
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = 0;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = 0;
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = 0;
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = 0;
}*/
} //RE loop, second part
} //
+32 -35
View File
@@ -55,42 +55,39 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB) {
NR_gNB_DLSCH_t *dlsch = *dlschptr;
uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated
if (dlsch) {
if (N_RB != 273) {
a_segments = a_segments*N_RB;
a_segments = a_segments/273 +1;
}
#ifdef DEBUG_DLSCH_FREE
LOG_D(PHY,"Freeing dlsch %p\n",dlsch);
#endif
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
if (harq->b) {
free16(harq->b, a_segments * 1056);
harq->b = NULL;
#ifdef DEBUG_DLSCH_FREE
LOG_D(PHY, "Freeing harq->b (%p)\n", harq->b);
#endif
}
#ifdef DEBUG_DLSCH_FREE
LOG_D(PHY, "Freeing dlsch process %d c (%p)\n", i, harq->c);
#endif
for (r = 0; r < a_segments; r++) {
#ifdef DEBUG_DLSCH_FREE
LOG_D(PHY, "Freeing dlsch process %d c[%d] (%p)\n", i, r, harq->c[r]);
#endif
if (harq->c[r]) {
free16(harq->c[r], 1056);
harq->c[r] = NULL;
}
}
free16(dlsch, sizeof(NR_gNB_DLSCH_t));
*dlschptr = NULL;
if (N_RB != 273) {
a_segments = a_segments*N_RB;
a_segments = a_segments/273 +1;
}
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
if (harq->b) {
free16(harq->b, a_segments * 1056);
harq->b = NULL;
}
for (r = 0; r < a_segments; r++) {
free(harq->c[r]);
harq->c[r] = NULL;
}
free(harq->pdu);
for (int aa = 0; aa < 64; aa++)
free(dlsch->calib_dl_ch_estimates[aa]);
free(dlsch->calib_dl_ch_estimates);
for (int q=0; q<NR_MAX_NB_CODEWORDS; q++)
free(dlsch->mod_symbs[q]);
for (int layer = 0; layer < NR_MAX_NB_LAYERS; layer++) {
free(dlsch->txdataF_precoding[layer]);
free(dlsch->txdataF[layer]);
for (int aa = 0; aa < 64; aa++)
free(dlsch->ue_spec_bf_weights[layer][aa]);
free(dlsch->ue_spec_bf_weights[layer]);
}
free(dlsch);
*dlschptr = NULL;
}
NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
+2 -2
View File
@@ -299,8 +299,8 @@ int nr_generate_pbch(nfapi_nr_dl_tti_ssb_pdu *ssb_pdu,
/// CRC, coding and rate matching
polar_encoder_fast (&a_reversed, (void*)pbch->pbch_e, 0, 0,
nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL,0,NULL)
);
NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL);
#ifdef DEBUG_PBCH_ENCODING
printf("Channel coding:\n");
@@ -106,6 +106,8 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
uint8_t abstraction_flag,
uint16_t N_RB);
void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB);
/** \brief This function is the top-level entry point to PUSCH demodulation, after frequency-domain transformation and channel estimation. It performs
- RB extraction (signal and channel estimates)
- channel compensation (matched filtering)
@@ -296,6 +298,7 @@ int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame,int slot, find_type_t type);
int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type);
NR_gNB_PUCCH_t *new_gNB_pucch(void);
void free_gNB_pucch(NR_gNB_PUCCH_t *pucch);
void nr_fill_pucch(PHY_VARS_gNB *gNB,
int frame,
@@ -308,6 +311,7 @@ int nr_find_pucch(uint16_t rnti,
PHY_VARS_gNB *gNB);
NR_gNB_SRS_t *new_gNB_srs(void);
void free_gNB_srs(NR_gNB_SRS_t *srs);
int nr_find_srs(uint16_t rnti,
int frame,
+2 -2
View File
@@ -33,9 +33,9 @@
#include "PHY/defs_gNB.h"
#include "common/utils/threadPool/thread-pool.h"
void free_gNB_ulsch(NR_gNB_ULSCH_t **ulsch,uint8_t N_RB_UL);
void free_gNB_ulsch(NR_gNB_ULSCH_t **ulsch, uint16_t N_RB_UL);
NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint16_t N_RB_UL, uint8_t abstraction_flag);
NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL);
/*! \brief Perform PUSCH decoding. TS 38.212 V15.4.0 subclause 6.2
+32 -54
View File
@@ -54,60 +54,40 @@
//extern double cpuf;
void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr,uint8_t N_RB_UL)
void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr, uint16_t N_RB_UL)
{
int i,r;
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated
NR_gNB_ULSCH_t *ulsch = *ulschptr;
if (ulsch) {
if (N_RB_UL != 273) {
a_segments = a_segments*N_RB_UL;
a_segments = a_segments/273 +1;
}
for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
if (ulsch->harq_processes[i]) {
if (ulsch->harq_processes[i]->b) {
free16(ulsch->harq_processes[i]->b,a_segments*1056);
ulsch->harq_processes[i]->b = NULL;
}
for (r=0; r<a_segments; r++) {
free16(ulsch->harq_processes[i]->c[r],(8448)*sizeof(uint8_t));
ulsch->harq_processes[i]->c[r] = NULL;
}
for (r=0; r<a_segments; r++) {
if (ulsch->harq_processes[i]->d[r]) {
free16(ulsch->harq_processes[i]->d[r],(68*384)*sizeof(int16_t));
ulsch->harq_processes[i]->d[r] = NULL;
}
}
for (r=0; r<a_segments; r++) {
if (ulsch->harq_processes[i]->w[r]) {
free16(ulsch->harq_processes[i]->w[r],(3*(6144+64))*sizeof(int16_t));
ulsch->harq_processes[i]->w[r] = NULL;
}
}
for (r=0; r<a_segments; r++) {
if (ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]){
nrLDPC_free_mem(ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]);
ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL;
}
}
free16(ulsch->harq_processes[i],sizeof(NR_UL_gNB_HARQ_t));
ulsch->harq_processes[i] = NULL;
}
}
free16(ulsch,sizeof(NR_gNB_ULSCH_t));
*ulschptr = NULL;
if (N_RB_UL != 273) {
a_segments = a_segments*N_RB_UL;
a_segments = a_segments/273 +1;
}
for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
if (ulsch->harq_processes[i]) {
if (ulsch->harq_processes[i]->b) {
free_and_zero(ulsch->harq_processes[i]->b);
ulsch->harq_processes[i]->b = NULL;
}
for (r=0; r<a_segments; r++) {
free_and_zero(ulsch->harq_processes[i]->c[r]);
free_and_zero(ulsch->harq_processes[i]->d[r]);
free_and_zero(ulsch->harq_processes[i]->w[r]);
nrLDPC_free_mem(ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]);
ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL;
}
free_and_zero(ulsch->harq_processes[i]);
ulsch->harq_processes[i] = NULL;
}
}
free_and_zero(*ulschptr);
}
NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint16_t N_RB_UL, uint8_t abstraction_flag)
NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL)
{
NR_gNB_ULSCH_t *ulsch;
@@ -129,13 +109,11 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint16_t N_RB_UL, uint
ulsch->harq_processes[i] = (NR_UL_gNB_HARQ_t *)malloc16_clear(sizeof(NR_UL_gNB_HARQ_t));
ulsch->harq_processes[i]->b = (uint8_t*)malloc16_clear(ulsch_bytes);
if (abstraction_flag == 0) {
for (r=0; r<a_segments; r++) {
ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem();
ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16_clear(8448*sizeof(uint8_t));
ulsch->harq_processes[i]->d[r] = (int16_t*)malloc16_clear((68*384)*sizeof(int16_t));
ulsch->harq_processes[i]->w[r] = (int16_t*)malloc16_clear((3*(6144+64))*sizeof(int16_t));
}
for (r=0; r<a_segments; r++) {
ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem();
ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16_clear(8448*sizeof(uint8_t));
ulsch->harq_processes[i]->d[r] = (int16_t*)malloc16_clear((68*384)*sizeof(int16_t));
ulsch->harq_processes[i]->w[r] = (int16_t*)malloc16_clear((3*(6144+64))*sizeof(int16_t));
}
}
@@ -328,8 +306,8 @@ void nr_processULSegment(void* arg) {
rv_index,
ulsch_harq->new_rx,
E,
ulsch_harq->F,
Kr-ulsch_harq->F-2*(p_decoderParms->Z))==-1) {
ulsch_harq->F,
Kr-ulsch_harq->F-2*(p_decoderParms->Z))==-1) {
stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
@@ -480,7 +458,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
A = (harq_process->TBS)<<3;
LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, n_layers %d, Coderate %d\n",harq_pid,A,G, mcs, n_layers, nb_rb, Qm, n_layers, R);
LOG_D(NR_PHY, "ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, n_layers %d, Coderate %d\n", harq_pid, A, G, mcs, n_layers, nb_rb, Qm, n_layers, R);
if (R<1024)
Coderate = (float) R /(float) 1024;
+6 -2
View File
@@ -62,6 +62,11 @@ NR_gNB_PUCCH_t *new_gNB_pucch(void){
return (pucch);
}
void free_gNB_pucch(NR_gNB_PUCCH_t *pucch)
{
free_and_zero(pucch);
}
int nr_find_pucch(uint16_t rnti,
int frame,
int slot,
@@ -1533,7 +1538,6 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
}
else { // polar coded case
t_nrPolar_params *currentPtr = nr_polar_params(2,nb_bit,pucch_pdu->prb_size,1,&gNB->uci_polarParams);
__m64 *rp_re[Prx2][2];
__m64 *rp2_re[Prx2][2];
__m64 *rp_im[Prx2][2];
@@ -1660,7 +1664,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
} // half_prb
} // symb
// run polar decoder on llrs
decoderState = polar_decoder_int16((int16_t*)llrs, decodedPayload, 0, currentPtr);
decoderState = polar_decoder_int16((int16_t*)llrs, decodedPayload, 0, 2,nb_bit,pucch_pdu->prb_size);
LOG_D(PHY,"UCI decoderState %d, payload[0] %llu\n",decoderState,(unsigned long long)decodedPayload[0]);
if (decoderState>0) decoderState=1;
corr_dB = dB_fixed64(corr);
+5
View File
@@ -49,6 +49,11 @@ NR_gNB_SRS_t *new_gNB_srs(void){
return (srs);
}
void free_gNB_srs(NR_gNB_SRS_t *srs)
{
free_and_zero(srs);
}
int nr_find_srs(uint16_t rnti,
int frame,
int slot,
@@ -116,12 +116,6 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
}
}
if (ue->rx_offset < 0)
ue->rx_offset += frame_parms->samples_per_frame;
if (ue->rx_offset >= frame_parms->samples_per_frame)
ue->rx_offset -= frame_parms->samples_per_frame;
#ifdef DEBUG_PHY
LOG_D(PHY,"AbsSubframe %d: diff = %i, rx_offset (final) = %i : clear = %d, max_pos = %d, max_pos_fil = %d, max_val = %d, sync_pos %d\n",
subframe,
+12 -10
View File
@@ -832,14 +832,18 @@ void nr_pdcch_unscrambling(int16_t *z,
/* This function compares the received DCI bits with
* re-encoded DCI bits and returns the number of mismatched bits
*/
uint16_t nr_dci_false_detection(uint64_t *dci,
int16_t *soft_in,
const t_nrPolar_params *polar_param,
int encoded_length,
int rnti) {
static uint16_t nr_dci_false_detection(uint64_t *dci,
int16_t *soft_in,
int encoded_length,
int rnti,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level
) {
uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD];
polar_encoder_fast(dci, (void*)encoder_output, rnti, 1, (t_nrPolar_params *)polar_param);
polar_encoder_fast(dci, (void*)encoder_output, rnti, 1,
messageType, messageLength, aggregation_level);
uint8_t *enout_p = (uint8_t*)encoder_output;
uint16_t x = 0;
@@ -886,7 +890,6 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
if (dci_found==1) continue;
int dci_length = rel15->dci_length_options[k];
uint64_t dci_estimation[2]= {0};
const t_nrPolar_params *currentPtrDCI = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L, 1, &ue->polarList);
LOG_D(PHY, "Trying DCI candidate %d of %d number of candidates, CCE %d (%d), L %d, length %d, format %s\n",
j, rel15->number_of_candidates, CCEind, CCEind*9*6*2, L, dci_length,nr_dci_format_string[rel15->dci_format_options[k]]);
@@ -901,11 +904,10 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
}
}
#endif
uint16_t crc = polar_decoder_int16(tmp_e,
dci_estimation,
1,
currentPtrDCI);
NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L);
n_rnti = rel15->rnti;
LOG_D(PHY, "(%i.%i) dci indication (rnti %x,dci format %s,n_CCE %d,payloadSize %d)\n",
@@ -913,7 +915,7 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
if (crc == n_rnti) {
LOG_D(PHY, "(%i.%i) Received dci indication (rnti %x,dci format %s,n_CCE %d,payloadSize %d,payload %llx)\n",
proc->frame_rx, proc->nr_slot_rx,n_rnti,nr_dci_format_string[rel15->dci_format_options[k]],CCEind,dci_length,*(unsigned long long*)dci_estimation);
uint16_t mb = nr_dci_false_detection(dci_estimation,tmp_e,currentPtrDCI,L*108,n_rnti);
uint16_t mb = nr_dci_false_detection(dci_estimation,tmp_e,L*108,n_rnti, NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L);
ue->dci_thres = (ue->dci_thres + mb) / 2;
if (mb > (ue->dci_thres+20)) {
LOG_W(PHY,"DCI false positive. Dropping DCI index %d. Mismatched bits: %d/%d. Current DCI threshold: %d\n",j,mb,L*108,ue->dci_thres);
@@ -79,7 +79,7 @@ void init_dlsch_tpool(uint8_t num_dlsch_threads) {
free(params);
}
void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL) {
void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr, uint16_t N_RB_DL) {
int i,r;
uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated
NR_UE_DLSCH_t *dlsch=*dlschptr;
@@ -131,7 +131,7 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL) {
}
}
NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_ldpc_iterations,uint16_t N_RB_DL, uint8_t abstraction_flag) {
NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_ldpc_iterations,uint16_t N_RB_DL) {
NR_UE_DLSCH_t *dlsch;
uint8_t exit_flag = 0,i,r;
uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated
@@ -167,30 +167,28 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
else
exit_flag=3;
if (abstraction_flag == 0) {
for (r=0; r<a_segments; r++) {
dlsch->harq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem();
dlsch->harq_processes[i]->c[r] = (uint8_t *)malloc16(1056);
for (r=0; r<a_segments; r++) {
dlsch->harq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem();
dlsch->harq_processes[i]->c[r] = (uint8_t *)malloc16(1056);
if (dlsch->harq_processes[i]->c[r])
memset(dlsch->harq_processes[i]->c[r],0,1056);
else
exit_flag=2;
if (dlsch->harq_processes[i]->c[r])
memset(dlsch->harq_processes[i]->c[r],0,1056);
else
exit_flag=2;
dlsch->harq_processes[i]->d[r] = (short *)malloc16((5*8448)*sizeof(short));
dlsch->harq_processes[i]->d[r] = (short *)malloc16((5*8448)*sizeof(short));
if (dlsch->harq_processes[i]->d[r])
memset(dlsch->harq_processes[i]->d[r],0,(5*8448)*sizeof(short));
else
exit_flag=2;
if (dlsch->harq_processes[i]->d[r])
memset(dlsch->harq_processes[i]->d[r],0,(5*8448)*sizeof(short));
else
exit_flag=2;
dlsch->harq_processes[i]->w[r] = (short *)malloc16((5*8448)*sizeof(short));
dlsch->harq_processes[i]->w[r] = (short *)malloc16((5*8448)*sizeof(short));
if (dlsch->harq_processes[i]->w[r])
memset(dlsch->harq_processes[i]->w[r],0,(5*8448)*sizeof(short));
else
exit_flag=2;
}
if (dlsch->harq_processes[i]->w[r])
memset(dlsch->harq_processes[i]->w[r],0,(5*8448)*sizeof(short));
else
exit_flag=2;
}
} else {
exit_flag=1;
@@ -931,12 +931,12 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
for (aatx=0; aatx<nb_aatx; aatx++) {
dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_rb*12];
for (atx=0; atx<nb_aatx; atx++) {
avg_rho_re[aarx][aatx*nb_aatx+atx] = 0;
avg_rho_im[aarx][aatx*nb_aatx+atx] = 0;
rho128 = (__m128i *)&rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12];
dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_rb*12];
dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[atx*frame_parms->nb_antennas_rx+aarx][symbol*nb_rb*12];
for (rb=0; rb<nb_rb_0; rb++) {
+68 -17
View File
@@ -31,8 +31,6 @@
*/
#include "PHY/types.h"
#include "PHY/defs_nr_UE.h"
#include "PHY/phy_extern_nr_ue.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "nr_transport_proto_ue.h"
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
@@ -46,7 +44,6 @@
#include "PHY/NR_REFSIG/pss_nr.h"
#include "PHY/NR_REFSIG/sss_nr.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "PHY/NR_TRANSPORT/nr_dci.h"
extern openair0_config_t openair0_cfg[];
//static nfapi_nr_config_request_t config_t;
@@ -206,6 +203,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
{
int32_t sync_pos, sync_pos_frame; // k_ssb, N_ssb_crb, sync_pos2,
int32_t accumulated_freq_offset = 0;
int32_t metric_tdd_ncp=0;
uint8_t phase_tdd_ncp;
double im, re;
@@ -254,22 +252,30 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
LOG_I(PHY,"sync_pos %d ssb_offset %d \n",sync_pos,ue->ssb_offset);
#endif
accumulated_freq_offset += ue->common_vars.freq_offset;
// digital compensation of FFO for SSB symbols
if (ue->UE_fo_compensation){
double s_time = 1/(1.0e3*fp->samples_per_subframe); // sampling time
double off_angle = -2*M_PI*s_time*(ue->common_vars.freq_offset); // offset rotation angle compensation per sample
if (ue->UE_fo_compensation){
double s_time = 1/(1.0e3*fp->samples_per_subframe); // sampling time
double off_angle = -2*M_PI*s_time*(ue->common_vars.freq_offset); // offset rotation angle compensation per sample
int start = is*fp->samples_per_frame+ue->ssb_offset; // start for offset correction is at ssb_offset (pss time position)
int end = start + 4*(fp->ofdm_symbol_size + fp->nb_prefix_samples); // loop over samples in 4 symbols (ssb size), including prefix
// In SA we need to perform frequency offset correction until the end of buffer because we need to decode SIB1
// and we do not know yet in which slot it goes.
for(int n=start; n<end; n++){
for (int ar=0; ar<fp->nb_antennas_rx; ar++) {
re = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n]);
im = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n+1]);
((short *)ue->common_vars.rxdata[ar])[2*n] = (short)(round(re*cos(n*off_angle) - im*sin(n*off_angle)));
((short *)ue->common_vars.rxdata[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle)));
}
}
// start for offset correction
int start = sa ? is*fp->samples_per_frame : is*fp->samples_per_frame + ue->ssb_offset;
// loop over samples
int end = sa ? n_frames*fp->samples_per_frame-1 : start + NR_N_SYMBOLS_SSB*(fp->ofdm_symbol_size + fp->nb_prefix_samples);
for(int n=start; n<end; n++){
for (int ar=0; ar<fp->nb_antennas_rx; ar++) {
re = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n]);
im = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n+1]);
((short *)ue->common_vars.rxdata[ar])[2*n] = (short)(round(re*cos(n*off_angle) - im*sin(n*off_angle)));
((short *)ue->common_vars.rxdata[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle)));
}
}
}
/* check that SSS/PBCH block is continuous inside the received buffer */
@@ -295,7 +301,34 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
LOG_I(PHY,"Calling sss detection (normal CP)\n");
#endif
rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp);
int freq_offset_sss = 0;
rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp, &freq_offset_sss);
accumulated_freq_offset += freq_offset_sss;
// digital compensation of FFO for SSB symbols
if (ue->UE_fo_compensation){
double s_time = 1/(1.0e3*fp->samples_per_subframe); // sampling time
double off_angle = -2*M_PI*s_time*freq_offset_sss; // offset rotation angle compensation per sample
// In SA we need to perform frequency offset correction until the end of buffer because we need to decode SIB1
// and we do not know yet in which slot it goes.
// start for offset correction
int start = sa ? is*fp->samples_per_frame : is*fp->samples_per_frame + ue->ssb_offset;
// loop over samples
int end = sa ? n_frames*fp->samples_per_frame-1 : start + NR_N_SYMBOLS_SSB*(fp->ofdm_symbol_size + fp->nb_prefix_samples);
for(int n=start; n<end; n++){
for (int ar=0; ar<fp->nb_antennas_rx; ar++) {
re = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n]);
im = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n+1]);
((short *)ue->common_vars.rxdata[ar])[2*n] = (short)(round(re*cos(n*off_angle) - im*sin(n*off_angle)));
((short *)ue->common_vars.rxdata[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle)));
}
}
}
nr_gold_pbch(ue);
ret = nr_pbch_detection(proc, ue, 1); // start pbch detection at first symbol after pss
@@ -310,6 +343,22 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
sync_pos_frame = n_symb_prefix0*(fp->ofdm_symbol_size + fp->nb_prefix_samples0)+(ue->symbol_offset-n_symb_prefix0)*(fp->ofdm_symbol_size + fp->nb_prefix_samples);
// for a correct computation of frame number to sync with the one decoded at MIB we need to take into account in which of the n_frames we got sync
ue->init_sync_frame = n_frames - 1 - is;
// compute the scramblingID_pdcch and the gold pdcch
ue->scramblingID_pdcch = fp->Nid_cell;
nr_gold_pdcch(ue,fp->Nid_cell);
// compute the scrambling IDs for PDSCH DMRS
for (int i=0; i<2; i++)
ue->scramblingID[i]=fp->Nid_cell;
nr_gold_pdsch(ue,ue->scramblingID);
// initialize the pusch dmrs
uint16_t N_n_scid[2] = {fp->Nid_cell,fp->Nid_cell};
int n_scid = 0; // This quantity is indicated by higher layer parameter dmrs-SeqInitialization
nr_init_pusch_dmrs(ue, N_n_scid, n_scid);
// we also need to take into account the shift by samples_per_frame in case the if is true
if (ue->ssb_offset < sync_pos_frame){
ue->rx_offset = fp->samples_per_frame - sync_pos_frame + ue->ssb_offset;
@@ -542,6 +591,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
}
if (dec == false) // sib1 not decoded
ret = -1;
ue->common_vars.freq_offset = accumulated_freq_offset;
}
// exit_fun("debug exit");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_OUT);
+7 -7
View File
@@ -504,11 +504,9 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
nr_pbch_unscrambling(nr_ue_pbch_vars, pbch_e_rx, frame_parms->Nid_cell, nushift, M, NR_POLAR_PBCH_E,
0, 0, pbch_a_prime, &pbch_a_interleaved);
//polar decoding de-rate matching
const t_nrPolar_params *currentPtr = nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS,
NR_POLAR_PBCH_AGGREGATION_LEVEL,1,&ue->polarList);
uint64_t tmp=pbch_a_prime;
decoderState = polar_decoder_int16(pbch_e_rx,&tmp,0,currentPtr);
pbch_a_prime=tmp;
decoderState = polar_decoder_int16(pbch_e_rx,(uint64_t *)&pbch_a_prime,0,
NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL);
if(decoderState)
return(decoderState);
@@ -577,13 +575,15 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
#endif
nr_downlink_indication_t dl_indication;
fapi_nr_rx_indication_t *rx_ind = calloc(1, sizeof(*rx_ind));
fapi_nr_rx_indication_t *rx_ind=calloc(sizeof(*rx_ind),1);
uint16_t number_pdus = 1;
nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id);
nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, gNB_id, ue, NULL, NULL, number_pdus, proc,(void *)result);
if (ue->if_inst && ue->if_inst->dl_indication)
ue->if_inst->dl_indication(&dl_indication, NULL);
ue->if_inst->dl_indication(&dl_indication, NULL);
else
free(rx_ind); // dl_indication would free(), so free() here if not called
return 0;
}
@@ -50,24 +50,23 @@
\brief This function frees memory allocated for a particular DLSCH at UE
@param dlsch Pointer to DLSCH to be removed
*/
void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlsch,uint8_t N_RB_DL);
void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlsch, uint16_t N_RB_DL);
/** \fn new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t abstraction_flag)
/** \fn new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft)
\brief This function allocates structures for a particular DLSCH at UE
@returns Pointer to DLSCH to be removed
@param Kmimo Kmimo factor from 36-212/36-213
@param Mdlharq Maximum number of HARQ rounds (36-212/36-213)
@param Nsoft Soft-LLR buffer size from UE-Category
@params N_RB_DL total number of resource blocks (determine the operating BW)
@param abstraction_flag Flag to indicate abstracted interface
*/
NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint16_t N_RB_DL, uint8_t abstraction_flag);
NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint16_t N_RB_DL);
void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulsch,unsigned char N_RB_UL);
void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulsch, uint16_t N_RB_UL);
NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag);
NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, int number_of_harq_pids);
/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/QPSK reception.
@param stream0_in Input from channel compensated (MR combined) stream 0
@@ -272,6 +272,8 @@ typedef struct {
uint8_t dmrsConfigType;
// Number of DMRS CDM groups with no data
uint8_t n_dmrs_cdm_groups;
/// DMRS ports bitmap
uint16_t dmrs_ports;
/// Starting Symbol number
uint16_t start_symbol;
/// Current subband PMI allocation
+41 -88
View File
@@ -43,7 +43,7 @@
//#define DEBUG_ULSCH_CODING
void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulschptr,unsigned char N_RB_UL)
void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulschptr, uint16_t N_RB_UL)
{
int i, r;
@@ -105,12 +105,8 @@ void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulschptr,unsigned char N_RB_UL)
}
NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL,
int number_of_harq_pids,
uint8_t abstraction_flag)
NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, int number_of_harq_pids)
{
NR_UE_ULSCH_t *ulsch;
unsigned char exit_flag = 0,i,r;
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated
if (N_RB_UL != 273) {
@@ -120,97 +116,54 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL,
uint32_t ulsch_bytes = a_segments*1056; // allocated bytes per segment
ulsch = (NR_UE_ULSCH_t *)malloc16(sizeof(NR_UE_ULSCH_t));
NR_UE_ULSCH_t *ulsch = malloc16(sizeof(NR_UE_ULSCH_t));
DevAssert(ulsch);
memset(ulsch, 0, sizeof(*ulsch));
if (ulsch) {
memset(ulsch,0,sizeof(NR_UE_ULSCH_t));
ulsch->number_harq_processes_for_pusch = NR_MAX_ULSCH_HARQ_PROCESSES;
ulsch->Mlimit = 4; // maximum harq retransmissions
ulsch->number_harq_processes_for_pusch = NR_MAX_ULSCH_HARQ_PROCESSES;
ulsch->Mlimit = 4; // maximum harq retransmissions
//for (i=0; i<10; i++)
//ulsch->harq_ids[i] = 0;
//for (i=0; i<10; i++)
//ulsch->harq_ids[i] = 0;
for (int i = 0; i < number_of_harq_pids; i++) {
for (i=0; i<number_of_harq_pids; i++) {
ulsch->harq_processes[i] = malloc16(sizeof(NR_UL_UE_HARQ_t));
DevAssert(ulsch->harq_processes[i]);
memset(ulsch->harq_processes[i], 0, sizeof(NR_UL_UE_HARQ_t));
ulsch->harq_processes[i] = (NR_UL_UE_HARQ_t *)malloc16(sizeof(NR_UL_UE_HARQ_t));
ulsch->harq_processes[i]->a = malloc16(ulsch_bytes);
DevAssert(ulsch->harq_processes[i]->a);
bzero(ulsch->harq_processes[i]->a,ulsch_bytes);
// printf("ulsch->harq_processes[%d] %p\n",i,ulsch->harq_processes[i]);
if (ulsch->harq_processes[i]) {
memset(ulsch->harq_processes[i], 0, sizeof(NR_UL_UE_HARQ_t));
ulsch->harq_processes[i]->b = (uint8_t*)malloc16(ulsch_bytes);
ulsch->harq_processes[i]->a = (unsigned char*)malloc16(ulsch_bytes);
ulsch->harq_processes[i]->b = malloc16(ulsch_bytes);
DevAssert(ulsch->harq_processes[i]->b);
bzero(ulsch->harq_processes[i]->b,ulsch_bytes);
if (ulsch->harq_processes[i]->a) {
bzero(ulsch->harq_processes[i]->a,ulsch_bytes);
} else {
printf("Can't allocate PDU\n");
exit_flag=1;
}
for (int r = 0; r < a_segments; r++) {
// account for filler in first segment and CRCs for multiple segment case
ulsch->harq_processes[i]->c[r] = malloc16(8448);
DevAssert(ulsch->harq_processes[i]->c[r]);
bzero(ulsch->harq_processes[i]->c[r],8448);
if (ulsch->harq_processes[i]->b)
bzero(ulsch->harq_processes[i]->b,ulsch_bytes);
else {
LOG_E(PHY,"Can't get b\n");
exit_flag=1;
}
if (abstraction_flag==0) {
for (r=0; r<a_segments; r++) {
// account for filler in first segment and CRCs for multiple segment case
ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(8448);
ulsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384); //max size for coded output
if (ulsch->harq_processes[i]->c[r]) {
bzero(ulsch->harq_processes[i]->c[r],8448);
} else {
printf("Can't get c\n");
exit_flag=2;
}
if (ulsch->harq_processes[i]->d[r]) {
bzero(ulsch->harq_processes[i]->d[r],(68*384));
} else {
printf("Can't get d\n");
exit_flag=2;
}
}
ulsch->harq_processes[i]->e = (uint8_t*)malloc16(14*N_RB_UL*12*8);
if (ulsch->harq_processes[i]->e) {
bzero(ulsch->harq_processes[i]->e,14*N_RB_UL*12*8);
} else {
printf("Can't get e\n");
exit_flag=1;
}
ulsch->harq_processes[i]->f = (uint8_t*)malloc16(14*N_RB_UL*12*8);
if (ulsch->harq_processes[i]->f) {
bzero(ulsch->harq_processes[i]->f,14*N_RB_UL*12*8);
} else {
printf("Can't get f\n");
exit_flag=1;
}
}
ulsch->harq_processes[i]->subframe_scheduling_flag = 0;
ulsch->harq_processes[i]->first_tx = 1;
} else {
LOG_E(PHY,"Can't get harq_p %d\n",i);
exit_flag=3;
}
ulsch->harq_processes[i]->d[r] = malloc16(68*384); //max size for coded output
DevAssert(ulsch->harq_processes[i]->d[r]);
bzero(ulsch->harq_processes[i]->d[r],(68*384));
}
if (exit_flag==0) {
for (i=0; i<number_of_harq_pids; i++) {
ulsch->harq_processes[i]->round=0;
}
return(ulsch);
}
ulsch->harq_processes[i]->e = malloc16(14*N_RB_UL*12*8);
DevAssert(ulsch->harq_processes[i]->e);
bzero(ulsch->harq_processes[i]->e,14*N_RB_UL*12*8);
ulsch->harq_processes[i]->f = malloc16(14*N_RB_UL*12*8);
DevAssert(ulsch->harq_processes[i]->f);
bzero(ulsch->harq_processes[i]->f,14*N_RB_UL*12*8);
ulsch->harq_processes[i]->subframe_scheduling_flag = 0;
ulsch->harq_processes[i]->first_tx = 1;
}
LOG_E(PHY,"new_ue_ulsch exit flag, size of %d , %zu\n",exit_flag, sizeof(LTE_UE_ULSCH_t));
free_nr_ue_ulsch(&ulsch,N_RB_UL);
return(NULL);
return(ulsch);
}
@@ -263,9 +216,9 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_UE_ULSCH_ENCODING, VCD_FUNCTION_IN);
LOG_D(PHY,"ulsch coding nb_rb %d, Nl = %d\n", nb_rb, harq_process->pusch_pdu.nrOfLayers);
LOG_D(PHY,"ulsch coding A %d G %d mod_order %d\n", A,G, mod_order);
LOG_D(PHY,"harq_pid %d harq_process->ndi %d, pusch_data.new_data_indicator %d\n",
LOG_D(NR_PHY, "ulsch coding nb_rb %d, Nl = %d\n", nb_rb, harq_process->pusch_pdu.nrOfLayers);
LOG_D(NR_PHY, "ulsch coding A %d G %d mod_order %d\n", A, G, mod_order);
LOG_D(NR_PHY, "harq_pid %d harq_process->ndi %d, pusch_data.new_data_indicator %d\n",
harq_pid,harq_process->ndi,harq_process->pusch_pdu.pusch_data.new_data_indicator);
if (harq_process->first_tx == 1 ||
+2 -3
View File
@@ -128,7 +128,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id];
uint8_t num_of_codewords = 1; // tmp assumption
int Nid_cell = 0;
int N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig
uint16_t number_dmrs_symbols = 0;
@@ -153,7 +152,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
if (start_sc >= frame_parms->ofdm_symbol_size)
start_sc -= frame_parms->ofdm_symbol_size;
ulsch_ue->Nid_cell = Nid_cell;
ulsch_ue->Nid_cell = frame_parms->Nid_cell;
for (int i = start_symbol; i < start_symbol + number_of_symbols; i++) {
if((ul_dmrs_symb_pos >> i) & 0x01)
@@ -391,7 +390,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
// Perform this on gold sequence, not required when SC FDMA operation is done,
LOG_D(PHY,"DMRS in symbol %d\n",l);
nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
} else {
dmrs_idx = 0;
}
+5 -27
View File
@@ -34,6 +34,7 @@
#include <assert.h>
#include <errno.h>
#include <math.h>
#include <nr-uesoftmodem.h>
#include "PHY/defs_nr_UE.h"
@@ -439,33 +440,10 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
void free_context_pss_nr(void)
{
for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) {
if (primary_synchro_time_nr[i] != NULL) {
free(primary_synchro_time_nr[i]);
primary_synchro_time_nr[i] = NULL;
}
else {
LOG_E(PHY,"Fatal memory deallocation problem \n");
assert(0);
}
if (primary_synchro_nr[i] != NULL) {
free(primary_synchro_nr[i]);
primary_synchro_nr[i] = NULL;
}
else {
LOG_E(PHY,"Fatal memory deallocation problem \n");
assert(0);
}
if (pss_corr_ue[i] != NULL) {
free(pss_corr_ue[i]);
pss_corr_ue[i] = NULL;
}
else {
LOG_E(PHY,"Fatal memory deallocation problem \n");
assert(0);
}
free_and_zero(primary_synchro_nr[i]);
free_and_zero(primary_synchro_nr2[i]);
free_and_zero(primary_synchro_time_nr[i]);
free_and_zero(pss_corr_ue[i]);
}
}
+5 -7
View File
@@ -850,7 +850,7 @@ static inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_
printf("\t\t [nr_pucch2_3_4_scrambling] scrambling M_bit=%d bits\n", M_bit);
#endif
}
void nr_uci_encoding(uint64_t payload,
static void nr_uci_encoding(uint64_t payload,
uint8_t nr_bit,
int fmt,
uint8_t is_pi_over_2_bpsk_enabled,
@@ -946,12 +946,10 @@ void nr_uci_encoding(uint64_t payload,
AssertFatal(nrofPRB<=16,"Number of PRB >16\n");
} else if (A>=12) {
AssertFatal(A<65,"Polar encoding not supported yet for UCI with more than 64 bits\n");
t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_UCI_PUCCH_MESSAGE_TYPE,
A,
nrofPRB,
1,
NULL);
polar_encoder_fast(&payload, b, 0,0,currentPtr);
polar_encoder_fast(&payload, b, 0,0,
NR_POLAR_UCI_PUCCH_MESSAGE_TYPE,
A,
nrofPRB);
}
}
+15 -1
View File
@@ -420,7 +420,7 @@ int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue,
*
*********************************************************************/
int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max)
int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max, int *freq_offset_sss)
{
uint8_t i;
int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR];
@@ -558,5 +558,19 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric,
}
//#endif
int re = 0;
int im = 0;
d = (int16_t *)&d_sss[Nid2][Nid1];
for(i = 0; i<LENGTH_SSS_NR; i++) {
re += d[i]*sss[2*i];
im += d[i]*sss[2*i+1];
}
double ffo_sss = atan2(im,re)/M_PI/4.3;
*freq_offset_sss = (int)(ffo_sss*frame_parms->subcarrier_spacing);
double ffo_pss = ((double)ue->common_vars.freq_offset)/frame_parms->subcarrier_spacing;
LOG_I(NR_PHY, "ffo_pss %f (%i Hz), ffo_sss %f (%i Hz), ffo_pss+ffo_sss %f (%i Hz)\n",
ffo_pss, (int)(ffo_pss*frame_parms->subcarrier_spacing), ffo_sss, *freq_offset_sss, ffo_pss+ffo_sss, (int)((ffo_pss+ffo_sss)*frame_parms->subcarrier_spacing));
return(0);
}
-6
View File
@@ -49,12 +49,6 @@ void reset_stats(FL_OBJECT *button, long arg) {
int i,j,k;
PHY_VARS_eNB *phy_vars_eNB = RC.eNB[0][0];
printf("XXX %d %d %d\n",
sizeofArray(phy_vars_eNB->UE_stats),
sizeofArray( phy_vars_eNB->UE_stats[i].dlsch_NAK),
sizeofArray( *phy_vars_eNB->UE_stats[i].dlsch_NAK)
);
for (i=0; i<sizeofArray(phy_vars_eNB->UE_stats); i++) {
for (k=0; k<sizeofArray(phy_vars_eNB->UE_stats[i].dlsch_NAK); k++) { //harq_processes
for (j=0; j<sizeofArray(*phy_vars_eNB->UE_stats[i].dlsch_NAK); j++) {
-1
View File
@@ -55,7 +55,6 @@
#include <string.h>
#include <math.h>
#include "common_lib.h"
#include "msc.h"
#include "defs_common.h"
#include "impl_defs_top.h"
-1
View File
@@ -54,7 +54,6 @@
#include <string.h>
#include <math.h>
#include "common_lib.h"
#include "msc.h"
#include <common/utils/LOG/log.h>
#include "assertions.h"
-1
View File
@@ -55,7 +55,6 @@
#include <unistd.h>
#include "common_lib.h"
#include "msc.h"
#include "defs_common.h"
#include "defs_RU.h"
#include "impl_defs_top.h"
+1 -1
View File
@@ -779,7 +779,7 @@ typedef struct PHY_VARS_gNB_s {
/// statistics for ULSCH measurement collection
NR_gNB_SCH_STATS_t ulsch_stats[NUMBER_OF_NR_SCH_STATS_MAX];
NR_gNB_UCI_STATS_t uci_stats[NUMBER_OF_NR_UCI_STATS_MAX];
t_nrPolar_params *uci_polarParams;
t_nrPolar_params **polarParams;
/// SRS variables
nr_srs_info_t *nr_srs_info[NUMBER_OF_NR_SRS_MAX];
-2
View File
@@ -44,7 +44,6 @@
#include <string.h>
#include <math.h>
#include "common_lib.h"
#include "msc.h"
#include "fapi_nr_ue_interface.h"
#include "assertions.h"
@@ -781,7 +780,6 @@ typedef struct {
fapi_nr_config_request_t nrUE_config;
t_nrPolar_params *polarList;
NR_UE_PDSCH *pdsch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX+1]; // two RxTx Threads
NR_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_gNB_MAX];
NR_UE_PDCCH *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX];
-2
View File
@@ -387,8 +387,6 @@ struct NR_DL_FRAME_PARMS {
uint8_t N_ssb;
/// SSB index
uint8_t ssb_index;
/// PBCH polar encoder params
t_nrPolar_params pbch_polar_params;
/// OFDM symbol offset divisor for UL
uint32_t ofdm_offset_divisor;
};