Commit 457ab9f7 authored by Matthieu Kanj's avatar Matthieu Kanj

Adding NPUSH related functions (vincent savaux code)

parent c343f5ef
...@@ -1062,6 +1062,7 @@ set(PHY_SRC ...@@ -1062,6 +1062,7 @@ set(PHY_SRC
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_gold_mbsfn.c ${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_gold_mbsfn.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_dl_mbsfn.c ${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_dl_mbsfn.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_ul_ref.c ${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_ul_ref.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_ul_ref_NB_IoT.c
${OPENAIR1_DIR}/PHY/CODING/lte_segmentation.c ${OPENAIR1_DIR}/PHY/CODING/lte_segmentation.c
${OPENAIR1_DIR}/PHY/CODING/lte_segmentation_NB_IoT.c ${OPENAIR1_DIR}/PHY/CODING/lte_segmentation_NB_IoT.c
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte.c ${OPENAIR1_DIR}/PHY/CODING/ccoding_byte.c
......
...@@ -317,19 +317,19 @@ void freq_equalization_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms, ...@@ -317,19 +317,19 @@ void freq_equalization_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
if (Qm==4) if (Qm==4)
ul_ch_mag128[re] = _mm_set1_epi16(324); // this is 512*2/sqrt(10) ul_ch_mag128[re] = _mm_set1_epi16(324); // this is 512*2/sqrt(10)
else { // else {
ul_ch_mag128[re] = _mm_set1_epi16(316); // this is 512*4/sqrt(42) // ul_ch_mag128[re] = _mm_set1_epi16(316); // this is 512*4/sqrt(42)
ul_ch_magb128[re] = _mm_set1_epi16(158); // this is 512*2/sqrt(42) // ul_ch_magb128[re] = _mm_set1_epi16(158); // this is 512*2/sqrt(42)
} // }
#elif defined(__arm__) #elif defined(__arm__)
rxdataF_comp128[re] = vmulq_s16(rxdataF_comp128[re],*((int16x8_t *)&inv_ch_NB_IoT[8*amp])); rxdataF_comp128[re] = vmulq_s16(rxdataF_comp128[re],*((int16x8_t *)&inv_ch_NB_IoT[8*amp]));
if (Qm==4) if (Qm==4)
ul_ch_mag128[re] = vdupq_n_s16(324); // this is 512*2/sqrt(10) ul_ch_mag128[re] = vdupq_n_s16(324); // this is 512*2/sqrt(10)
else { //else {
ul_ch_mag128[re] = vdupq_n_s16(316); // this is 512*4/sqrt(42) // ul_ch_mag128[re] = vdupq_n_s16(316); // this is 512*4/sqrt(42)
ul_ch_magb128[re] = vdupq_n_s16(158); // this is 512*2/sqrt(42) // ul_ch_magb128[re] = vdupq_n_s16(158); // this is 512*2/sqrt(42)
} //}
#endif #endif
// printf("(%d,%d)\n",*(int16_t*)&(rxdataF_comp128[re]),*(1+(int16_t*)&(rxdataF_comp128[re]))); // printf("(%d,%d)\n",*(int16_t*)&(rxdataF_comp128[re]),*(1+(int16_t*)&(rxdataF_comp128[re])));
......
...@@ -31,15 +31,16 @@ ...@@ -31,15 +31,16 @@
// For Channel Estimation in Distributed Alamouti Scheme // For Channel Estimation in Distributed Alamouti Scheme
//static int16_t temp_out_ifft[2048*4] __attribute__((aligned(16))); //static int16_t temp_out_ifft[2048*4] __attribute__((aligned(16)));
/*
static int16_t temp_out_fft_0[2048*4] __attribute__((aligned(16))); static int16_t temp_out_fft_0[2048*4] __attribute__((aligned(16)));
static int16_t temp_out_fft_1[2048*4] __attribute__((aligned(16))); static int16_t temp_out_fft_1[2048*4] __attribute__((aligned(16)));
static int16_t temp_out_ifft_0[2048*4] __attribute__((aligned(16))); static int16_t temp_out_ifft_0[2048*4] __attribute__((aligned(16)));
static int16_t temp_out_ifft_1[2048*4] __attribute__((aligned(16))); static int16_t temp_out_ifft_1[2048*4] __attribute__((aligned(16)));
*/
static int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32))); static int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32)));
static int32_t temp_in_ifft_1[2048*2] __attribute__((aligned(32))); //static int32_t temp_in_ifft_1[2048*2] __attribute__((aligned(32)));
static int32_t temp_in_fft_0[2048*2] __attribute__((aligned(16))); //static int32_t temp_in_fft_0[2048*2] __attribute__((aligned(16)));
static int32_t temp_in_fft_1[2048*2] __attribute__((aligned(16))); static int32_t temp_in_fft_1[2048*2] __attribute__((aligned(16)));
// round(exp(sqrt(-1)*(pi/2)*[0:1:N-1]/N)*pow2(15)) // round(exp(sqrt(-1)*(pi/2)*[0:1:N-1]/N)*pow2(15))
...@@ -62,8 +63,8 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -62,8 +63,8 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_eNB_PUSCH *pusch_vars = eNB->pusch_vars[UE_id]; NB_IoT_eNB_PUSCH *pusch_vars = eNB->pusch_vars[UE_id];
int32_t **ul_ch_estimates=pusch_vars->drs_ch_estimates[eNB_id]; int32_t **ul_ch_estimates=pusch_vars->drs_ch_estimates[eNB_id];
int32_t **ul_ch_estimates_time= pusch_vars->drs_ch_estimates_time[eNB_id]; int32_t **ul_ch_estimates_time= pusch_vars->drs_ch_estimates_time[eNB_id];
int32_t **ul_ch_estimates_0= pusch_vars->drs_ch_estimates_0[eNB_id]; //int32_t **ul_ch_estimates_0= pusch_vars->drs_ch_estimates_0[eNB_id];
int32_t **ul_ch_estimates_1= pusch_vars->drs_ch_estimates_1[eNB_id]; //int32_t **ul_ch_estimates_1= pusch_vars->drs_ch_estimates_1[eNB_id];
int32_t **rxdataF_ext= pusch_vars->rxdataF_ext[eNB_id]; int32_t **rxdataF_ext= pusch_vars->rxdataF_ext[eNB_id];
int subframe = proc->subframe_rx; int subframe = proc->subframe_rx;
//uint8_t harq_pid = subframe2harq_pid_NB_IoT(frame_parms,proc->frame_rx,subframe); //uint8_t harq_pid = subframe2harq_pid_NB_IoT(frame_parms,proc->frame_rx,subframe);
...@@ -77,7 +78,7 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -77,7 +78,7 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
int k,pilot_pos1 = 3 - frame_parms->Ncp, pilot_pos2 = 10 - 2*frame_parms->Ncp; int k,pilot_pos1 = 3 - frame_parms->Ncp, pilot_pos2 = 10 - 2*frame_parms->Ncp;
int16_t alpha, beta; int16_t alpha, beta;
int32_t *ul_ch1=NULL, *ul_ch2=NULL; int32_t *ul_ch1=NULL, *ul_ch2=NULL;
int32_t *ul_ch1_0=NULL,*ul_ch2_0=NULL,*ul_ch1_1=NULL,*ul_ch2_1=NULL; //int32_t *ul_ch1_0=NULL,*ul_ch2_0=NULL,*ul_ch1_1=NULL,*ul_ch2_1=NULL;
int16_t ul_ch_estimates_re,ul_ch_estimates_im; int16_t ul_ch_estimates_re,ul_ch_estimates_im;
int32_t rx_power_correction; int32_t rx_power_correction;
...@@ -87,10 +88,11 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -87,10 +88,11 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
uint32_t alpha_ind; uint32_t alpha_ind;
uint32_t u=frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.grouphop[Ns+(subframe<<1)]; uint32_t u=frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.grouphop[Ns+(subframe<<1)];
uint32_t v=frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.seqhop[Ns+(subframe<<1)]; //uint32_t v=frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.seqhop[Ns+(subframe<<1)];
int32_t tmp_estimates[N_rb_alloc*12] __attribute__((aligned(16))); int32_t tmp_estimates[N_rb_alloc*12] __attribute__((aligned(16)));
int symbol_offset,i,j; int symbol_offset,i;
//int j;
//debug_msg("lte_ul_channel_estimation: cyclic shift %d\n",cyclicShift); //debug_msg("lte_ul_channel_estimation: cyclic shift %d\n",cyclicShift);
...@@ -98,10 +100,12 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -98,10 +100,12 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
int16_t alpha_re[12] = {32767, 28377, 16383, 0,-16384, -28378,-32768,-28378,-16384, -1, 16383, 28377}; int16_t alpha_re[12] = {32767, 28377, 16383, 0,-16384, -28378,-32768,-28378,-16384, -1, 16383, 28377};
int16_t alpha_im[12] = {0, 16383, 28377, 32767, 28377, 16383, 0,-16384,-28378,-32768,-28378,-16384}; int16_t alpha_im[12] = {0, 16383, 28377, 32767, 28377, 16383, 0,-16384,-28378,-32768,-28378,-16384};
/*
int32_t *in_fft_ptr_0 = (int32_t*)0,*in_fft_ptr_1 = (int32_t*)0, int32_t *in_fft_ptr_0 = (int32_t*)0,*in_fft_ptr_1 = (int32_t*)0,
*temp_out_fft_0_ptr = (int32_t*)0,*out_fft_ptr_0 = (int32_t*)0, *temp_out_fft_0_ptr = (int32_t*)0,*out_fft_ptr_0 = (int32_t*)0,
*temp_out_fft_1_ptr = (int32_t*)0,*out_fft_ptr_1 = (int32_t*)0, *temp_out_fft_1_ptr = (int32_t*)0,*out_fft_ptr_1 = (int32_t*)0,
*temp_in_ifft_ptr = (int32_t*)0; *temp_in_ifft_ptr = (int32_t*)0;
*/
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
__m128i *rxdataF128,*ul_ref128,*ul_ch128; __m128i *rxdataF128,*ul_ref128,*ul_ch128;
...@@ -160,11 +164,11 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -160,11 +164,11 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
rxdataF128 = (__m128i *)&rxdataF_ext[aa][symbol_offset]; rxdataF128 = (__m128i *)&rxdataF_ext[aa][symbol_offset];
ul_ch128 = (__m128i *)&ul_ch_estimates[aa][symbol_offset]; ul_ch128 = (__m128i *)&ul_ch_estimates[aa][symbol_offset];
ul_ref128 = (__m128i *)ul_ref_sigs_rx[u][v][Msc_RS_idx]; ul_ref128 = (__m128i *)ul_ref_sigs_rx[u][Msc_RS_idx];
#elif defined(__arm__) #elif defined(__arm__)
rxdataF128 = (int16x8_t *)&rxdataF_ext[aa][symbol_offset]; rxdataF128 = (int16x8_t *)&rxdataF_ext[aa][symbol_offset];
ul_ch128 = (int16x8_t *)&ul_ch_estimates[aa][symbol_offset]; ul_ch128 = (int16x8_t *)&ul_ch_estimates[aa][symbol_offset];
ul_ref128 = (int16x8_t *)ul_ref_sigs_rx[u][v][Msc_RS_idx]; ul_ref128 = (int16x8_t *)ul_ref_sigs_rx[u][Msc_RS_idx];
#endif #endif
for (i=0; i<Msc_RS/12; i++) { for (i=0; i<Msc_RS/12; i++) {
...@@ -263,8 +267,9 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -263,8 +267,9 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
alpha_ind = 0; alpha_ind = 0;
if((cyclic_shift != 0)) { if((cyclic_shift != 0) && Msc_RS != 12) {
// Compensating for the phase shift introduced at the transmitte // Compensating for the phase shift introduced at the transmitter
// In NB-IoT, phase alpha is zero when 12 subcarriers are allocated
#ifdef DEBUG_CH #ifdef DEBUG_CH
write_output("drs_est_pre.m","drsest_pre",ul_ch_estimates[0],300*12,1,1); write_output("drs_est_pre.m","drsest_pre",ul_ch_estimates[0],300*12,1,1);
#endif #endif
...@@ -349,192 +354,192 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -349,192 +354,192 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
#endif #endif
if(cooperation_flag == 2) { // if(cooperation_flag == 2) {
memset(temp_in_ifft_0,0,frame_parms->ofdm_symbol_size*sizeof(int32_t*)*2); // memset(temp_in_ifft_0,0,frame_parms->ofdm_symbol_size*sizeof(int32_t*)*2);
memset(temp_in_ifft_1,0,frame_parms->ofdm_symbol_size*sizeof(int32_t*)*2); // memset(temp_in_ifft_1,0,frame_parms->ofdm_symbol_size*sizeof(int32_t*)*2);
memset(temp_in_fft_0,0,frame_parms->ofdm_symbol_size*sizeof(int32_t*)*2); // memset(temp_in_fft_0,0,frame_parms->ofdm_symbol_size*sizeof(int32_t*)*2);
memset(temp_in_fft_1,0,frame_parms->ofdm_symbol_size*sizeof(int32_t*)*2); // memset(temp_in_fft_1,0,frame_parms->ofdm_symbol_size*sizeof(int32_t*)*2);
temp_in_ifft_ptr = &temp_in_ifft_0[0]; // temp_in_ifft_ptr = &temp_in_ifft_0[0];
i = symbol_offset; // i = symbol_offset;
for(j=0; j<(frame_parms->N_RB_UL*12); j++) { // for(j=0; j<(frame_parms->N_RB_UL*12); j++) {
temp_in_ifft_ptr[j] = ul_ch_estimates[aa][i]; // temp_in_ifft_ptr[j] = ul_ch_estimates[aa][i];
i++; // i++;
} // }
alpha_ind = 0; // alpha_ind = 0;
// Compensating for the phase shift introduced at the transmitter // // Compensating for the phase shift introduced at the transmitter
for(i=symbol_offset; i<symbol_offset+Msc_RS; i++) { // for(i=symbol_offset; i<symbol_offset+Msc_RS; i++) {
ul_ch_estimates_re = ((int16_t*) ul_ch_estimates[aa])[i<<1]; // ul_ch_estimates_re = ((int16_t*) ul_ch_estimates[aa])[i<<1];
ul_ch_estimates_im = ((int16_t*) ul_ch_estimates[aa])[(i<<1)+1]; // ul_ch_estimates_im = ((int16_t*) ul_ch_estimates[aa])[(i<<1)+1];
// ((int16_t*) ul_ch_estimates[aa])[i<<1] = (i%2 == 1? 1:-1) * ul_ch_estimates_re; // // ((int16_t*) ul_ch_estimates[aa])[i<<1] = (i%2 == 1? 1:-1) * ul_ch_estimates_re;
((int16_t*) ul_ch_estimates[aa])[i<<1] = // ((int16_t*) ul_ch_estimates[aa])[i<<1] =
(int16_t) (((int32_t) (alpha_re[alpha_ind]) * (int32_t) (ul_ch_estimates_re) + // (int16_t) (((int32_t) (alpha_re[alpha_ind]) * (int32_t) (ul_ch_estimates_re) +
(int32_t) (alpha_im[alpha_ind]) * (int32_t) (ul_ch_estimates_im))>>15); // (int32_t) (alpha_im[alpha_ind]) * (int32_t) (ul_ch_estimates_im))>>15);
//((int16_t*) ul_ch_estimates[aa])[(i<<1)+1] = (i%2 == 1? 1:-1) * ul_ch_estimates_im; // //((int16_t*) ul_ch_estimates[aa])[(i<<1)+1] = (i%2 == 1? 1:-1) * ul_ch_estimates_im;
((int16_t*) ul_ch_estimates[aa])[(i<<1)+1] = // ((int16_t*) ul_ch_estimates[aa])[(i<<1)+1] =
(int16_t) (((int32_t) (alpha_re[alpha_ind]) * (int32_t) (ul_ch_estimates_im) - // (int16_t) (((int32_t) (alpha_re[alpha_ind]) * (int32_t) (ul_ch_estimates_im) -
(int32_t) (alpha_im[alpha_ind]) * (int32_t) (ul_ch_estimates_re))>>15); // (int32_t) (alpha_im[alpha_ind]) * (int32_t) (ul_ch_estimates_re))>>15);
alpha_ind+=10; // alpha_ind+=10;
if (alpha_ind>11) // if (alpha_ind>11)
alpha_ind-=12; // alpha_ind-=12;
} // }
//Extracting Channel Estimates for Distributed Alamouti Receiver Combining // //Extracting Channel Estimates for Distributed Alamouti Receiver Combining
temp_in_ifft_ptr = &temp_in_ifft_1[0]; // temp_in_ifft_ptr = &temp_in_ifft_1[0];
i = symbol_offset; // i = symbol_offset;
for(j=0; j<(frame_parms->N_RB_UL*12); j++) { // for(j=0; j<(frame_parms->N_RB_UL*12); j++) {
temp_in_ifft_ptr[j] = ul_ch_estimates[aa][i]; // temp_in_ifft_ptr[j] = ul_ch_estimates[aa][i];
i++; // i++;
} // }
switch (frame_parms->N_RB_DL) { // switch (frame_parms->N_RB_DL) {
case 6: // case 6:
idft128((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates // idft128((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates
temp_out_ifft_0, // temp_out_ifft_0,
1); // 1);
idft128((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates // idft128((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates
temp_out_ifft_1, // temp_out_ifft_1,
1); // 1);
break; // break;
case 25: // case 25:
idft512((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates // idft512((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates
temp_out_ifft_0, // temp_out_ifft_0,
1); // 1);
idft512((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates // idft512((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates
temp_out_ifft_1, // temp_out_ifft_1,
1); // 1);
break; // break;
case 50: // case 50:
idft1024((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates // idft1024((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates
temp_out_ifft_0, // temp_out_ifft_0,
1); // 1);
idft1024((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates // idft1024((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates
temp_out_ifft_1, // temp_out_ifft_1,
1); // 1);
break; // break;
case 100: // case 100:
idft2048((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates // idft2048((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates
temp_out_ifft_0, // temp_out_ifft_0,
1); // 1);
idft2048((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates // idft2048((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates
temp_out_ifft_1, // temp_out_ifft_1,
1); // 1);
break; // break;
} // }
// because the ifft is not power preserving, we should apply the factor sqrt(power_correction) here, but we rather apply power_correction here and nothing after the next fft // // because the ifft is not power preserving, we should apply the factor sqrt(power_correction) here, but we rather apply power_correction here and nothing after the next fft
in_fft_ptr_0 = &temp_in_fft_0[0]; // in_fft_ptr_0 = &temp_in_fft_0[0];
in_fft_ptr_1 = &temp_in_fft_1[0]; // in_fft_ptr_1 = &temp_in_fft_1[0];
for(j=0; j<(frame_parms->ofdm_symbol_size)/12; j++) { // for(j=0; j<(frame_parms->ofdm_symbol_size)/12; j++) {
if (j>19) { // if (j>19) {
((int16_t*)in_fft_ptr_0)[-40+(2*j)] = ((int16_t*)temp_out_ifft_0)[-80+(2*j)]*rx_power_correction; // ((int16_t*)in_fft_ptr_0)[-40+(2*j)] = ((int16_t*)temp_out_ifft_0)[-80+(2*j)]*rx_power_correction;
((int16_t*)in_fft_ptr_0)[-40+(2*j)+1] = ((int16_t*)temp_out_ifft_0)[-80+(2*j+1)]*rx_power_correction; // ((int16_t*)in_fft_ptr_0)[-40+(2*j)+1] = ((int16_t*)temp_out_ifft_0)[-80+(2*j+1)]*rx_power_correction;
((int16_t*)in_fft_ptr_1)[-40+(2*j)] = ((int16_t*)temp_out_ifft_1)[-80+(2*j)]*rx_power_correction; // ((int16_t*)in_fft_ptr_1)[-40+(2*j)] = ((int16_t*)temp_out_ifft_1)[-80+(2*j)]*rx_power_correction;
((int16_t*)in_fft_ptr_1)[-40+(2*j)+1] = ((int16_t*)temp_out_ifft_1)[-80+(2*j)+1]*rx_power_correction; // ((int16_t*)in_fft_ptr_1)[-40+(2*j)+1] = ((int16_t*)temp_out_ifft_1)[-80+(2*j)+1]*rx_power_correction;
} else { // } else {
((int16_t*)in_fft_ptr_0)[2*(frame_parms->ofdm_symbol_size-20+j)] = ((int16_t*)temp_out_ifft_0)[2*(frame_parms->ofdm_symbol_size-20+j)]*rx_power_correction; // ((int16_t*)in_fft_ptr_0)[2*(frame_parms->ofdm_symbol_size-20+j)] = ((int16_t*)temp_out_ifft_0)[2*(frame_parms->ofdm_symbol_size-20+j)]*rx_power_correction;
((int16_t*)in_fft_ptr_0)[2*(frame_parms->ofdm_symbol_size-20+j)+1] = ((int16_t*)temp_out_ifft_0)[2*(frame_parms->ofdm_symbol_size-20+j)+1]*rx_power_correction; // ((int16_t*)in_fft_ptr_0)[2*(frame_parms->ofdm_symbol_size-20+j)+1] = ((int16_t*)temp_out_ifft_0)[2*(frame_parms->ofdm_symbol_size-20+j)+1]*rx_power_correction;
((int16_t*)in_fft_ptr_1)[2*(frame_parms->ofdm_symbol_size-20+j)] = ((int16_t*)temp_out_ifft_1)[2*(frame_parms->ofdm_symbol_size-20+j)]*rx_power_correction; // ((int16_t*)in_fft_ptr_1)[2*(frame_parms->ofdm_symbol_size-20+j)] = ((int16_t*)temp_out_ifft_1)[2*(frame_parms->ofdm_symbol_size-20+j)]*rx_power_correction;
((int16_t*)in_fft_ptr_1)[2*(frame_parms->ofdm_symbol_size-20+j)+1] = ((int16_t*)temp_out_ifft_1)[2*(frame_parms->ofdm_symbol_size-20+j)+1]*rx_power_correction; // ((int16_t*)in_fft_ptr_1)[2*(frame_parms->ofdm_symbol_size-20+j)+1] = ((int16_t*)temp_out_ifft_1)[2*(frame_parms->ofdm_symbol_size-20+j)+1]*rx_power_correction;
} // }
} // }
switch (frame_parms->N_RB_DL) { // switch (frame_parms->N_RB_DL) {
case 6: // case 6:
dft128((int16_t*) &temp_in_fft_0[0], // dft128((int16_t*) &temp_in_fft_0[0],
// Performing FFT to obtain the Channel Estimates for UE0 to eNB1 // // Performing FFT to obtain the Channel Estimates for UE0 to eNB1
temp_out_fft_0, // temp_out_fft_0,
1); // 1);
break; // break;
case 25: // case 25:
dft512((int16_t*) &temp_in_fft_0[0], // dft512((int16_t*) &temp_in_fft_0[0],
// Performing FFT to obtain the Channel Estimates for UE0 to eNB1 // // Performing FFT to obtain the Channel Estimates for UE0 to eNB1
temp_out_fft_0, // temp_out_fft_0,
1); // 1);
break; // break;
case 50: // case 50:
dft1024((int16_t*) &temp_in_fft_0[0], // dft1024((int16_t*) &temp_in_fft_0[0],
// Performing FFT to obtain the Channel Estimates for UE0 to eNB1 // // Performing FFT to obtain the Channel Estimates for UE0 to eNB1
temp_out_fft_0, // temp_out_fft_0,
1); // 1);
break; // break;
case 100: // case 100:
dft2048((int16_t*) &temp_in_fft_0[0], // dft2048((int16_t*) &temp_in_fft_0[0],
// Performing FFT to obtain the Channel Estimates for UE0 to eNB1 // // Performing FFT to obtain the Channel Estimates for UE0 to eNB1
temp_out_fft_0, // temp_out_fft_0,
1); // 1);
break; // break;
} // }
out_fft_ptr_0 = &ul_ch_estimates_0[aa][symbol_offset]; // CHANNEL ESTIMATES FOR UE0 TO eNB1 // out_fft_ptr_0 = &ul_ch_estimates_0[aa][symbol_offset]; // CHANNEL ESTIMATES FOR UE0 TO eNB1
temp_out_fft_0_ptr = (int32_t*) temp_out_fft_0; // temp_out_fft_0_ptr = (int32_t*) temp_out_fft_0;
i=0; // i=0;
for(j=0; j<frame_parms->N_RB_UL*12; j++) { // for(j=0; j<frame_parms->N_RB_UL*12; j++) {
out_fft_ptr_0[i] = temp_out_fft_0_ptr[j]; // out_fft_ptr_0[i] = temp_out_fft_0_ptr[j];
i++; // i++;
} // }
switch (frame_parms->N_RB_DL) { // switch (frame_parms->N_RB_DL) {
case 6: // case 6:
dft128((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1 // dft128((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1
temp_out_fft_1, // temp_out_fft_1,
1); // 1);
break; // break;
case 25: // case 25:
dft512((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1 // dft512((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1
temp_out_fft_1, // temp_out_fft_1,
1); // 1);
break; // break;
case 50: // case 50:
dft1024((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1 // dft1024((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1
temp_out_fft_1, // temp_out_fft_1,
1); // 1);
break; // break;
case 100: // case 100:
dft2048((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1 // dft2048((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1
temp_out_fft_1, // temp_out_fft_1,
1); // 1);
break; // break;
} // }
out_fft_ptr_1 = &ul_ch_estimates_1[aa][symbol_offset]; // CHANNEL ESTIMATES FOR UE1 TO eNB1 // out_fft_ptr_1 = &ul_ch_estimates_1[aa][symbol_offset]; // CHANNEL ESTIMATES FOR UE1 TO eNB1
temp_out_fft_1_ptr = (int32_t*) temp_out_fft_1; // temp_out_fft_1_ptr = (int32_t*) temp_out_fft_1;
i=0; // i=0;
for(j=0; j<frame_parms->N_RB_UL*12; j++) { // for(j=0; j<frame_parms->N_RB_UL*12; j++) {
out_fft_ptr_1[i] = temp_out_fft_1_ptr[j]; // out_fft_ptr_1[i] = temp_out_fft_1_ptr[j];
i++; // i++;
} // }
#ifdef DEBUG_CH // #ifdef DEBUG_CH
#ifdef USER_MODE // #ifdef USER_MODE
if((aa == 0)&& (cooperation_flag == 2)) { // if((aa == 0)&& (cooperation_flag == 2)) {
write_output("test1.m","t1",temp_in_ifft_0,512,1,1); // write_output("test1.m","t1",temp_in_ifft_0,512,1,1);
write_output("test2.m","t2",temp_out_ifft_0,512*2,2,1); // write_output("test2.m","t2",temp_out_ifft_0,512*2,2,1);
write_output("test3.m","t3",temp_in_fft_0,512,1,1); // write_output("test3.m","t3",temp_in_fft_0,512,1,1);
write_output("test4.m","t4",temp_out_fft_0,512,1,1); // write_output("test4.m","t4",temp_out_fft_0,512,1,1);
write_output("test5.m","t5",temp_in_fft_1,512,1,1); // write_output("test5.m","t5",temp_in_fft_1,512,1,1);
write_output("test6.m","t6",temp_out_fft_1,512,1,1); // write_output("test6.m","t6",temp_out_fft_1,512,1,1);
} // }
#endif // #endif
#endif // #endif
}//cooperation_flag == 2 // }//cooperation_flag == 2
if (Ns&1) {//we are in the second slot of the sub-frame, so do the interpolation if (Ns&1) {//we are in the second slot of the sub-frame, so do the interpolation
...@@ -542,13 +547,13 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -542,13 +547,13 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
ul_ch2 = &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos2]; ul_ch2 = &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos2];
if(cooperation_flag == 2) { // For Distributed Alamouti // if(cooperation_flag == 2) { // For Distributed Alamouti
ul_ch1_0 = &ul_ch_estimates_0[aa][frame_parms->N_RB_UL*12*pilot_pos1]; // ul_ch1_0 = &ul_ch_estimates_0[aa][frame_parms->N_RB_UL*12*pilot_pos1];
ul_ch2_0 = &ul_ch_estimates_0[aa][frame_parms->N_RB_UL*12*pilot_pos2]; // ul_ch2_0 = &ul_ch_estimates_0[aa][frame_parms->N_RB_UL*12*pilot_pos2];
ul_ch1_1 = &ul_ch_estimates_1[aa][frame_parms->N_RB_UL*12*pilot_pos1]; // ul_ch1_1 = &ul_ch_estimates_1[aa][frame_parms->N_RB_UL*12*pilot_pos1];
ul_ch2_1 = &ul_ch_estimates_1[aa][frame_parms->N_RB_UL*12*pilot_pos2]; // ul_ch2_1 = &ul_ch_estimates_1[aa][frame_parms->N_RB_UL*12*pilot_pos2];
} // }
// Estimation of phase difference between the 2 channel estimates // Estimation of phase difference between the 2 channel estimates
delta_phase = lte_ul_freq_offset_estimation_NB_IoT(frame_parms, delta_phase = lte_ul_freq_offset_estimation_NB_IoT(frame_parms,
...@@ -633,13 +638,13 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -633,13 +638,13 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
*/ */
// memcpy(&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],ul_ch1,Msc_RS*sizeof(int32_t)); // memcpy(&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],ul_ch1,Msc_RS*sizeof(int32_t));
if(cooperation_flag == 2) { // For Distributed Alamouti // if(cooperation_flag == 2) { // For Distributed Alamouti
multadd_complex_vector_real_scalar((int16_t*) ul_ch1_0,beta ,(int16_t*) &ul_ch_estimates_0[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS); // multadd_complex_vector_real_scalar((int16_t*) ul_ch1_0,beta ,(int16_t*) &ul_ch_estimates_0[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
multadd_complex_vector_real_scalar((int16_t*) ul_ch2_0,alpha,(int16_t*) &ul_ch_estimates_0[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS); // multadd_complex_vector_real_scalar((int16_t*) ul_ch2_0,alpha,(int16_t*) &ul_ch_estimates_0[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
multadd_complex_vector_real_scalar((int16_t*) ul_ch1_1,beta ,(int16_t*) &ul_ch_estimates_1[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS); // multadd_complex_vector_real_scalar((int16_t*) ul_ch1_1,beta ,(int16_t*) &ul_ch_estimates_1[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
multadd_complex_vector_real_scalar((int16_t*) ul_ch2_1,alpha,(int16_t*) &ul_ch_estimates_1[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS); // multadd_complex_vector_real_scalar((int16_t*) ul_ch2_1,alpha,(int16_t*) &ul_ch_estimates_1[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
} // }
} }
} //for(k=... } //for(k=...
...@@ -649,13 +654,13 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -649,13 +654,13 @@ int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
// multadd_complex_vector_real_scalar((int16_t*) ul_ch1,SCALE,(int16_t*) ul_ch1,1,Msc_RS); // multadd_complex_vector_real_scalar((int16_t*) ul_ch1,SCALE,(int16_t*) ul_ch1,1,Msc_RS);
// multadd_complex_vector_real_scalar((int16_t*) ul_ch2,SCALE,(int16_t*) ul_ch2,1,Msc_RS); // multadd_complex_vector_real_scalar((int16_t*) ul_ch2,SCALE,(int16_t*) ul_ch2,1,Msc_RS);
if(cooperation_flag == 2) { // For Distributed Alamouti // if(cooperation_flag == 2) { // For Distributed Alamouti
multadd_complex_vector_real_scalar((int16_t*) ul_ch1_0,SCALE,(int16_t*) ul_ch1_0,1,Msc_RS); // multadd_complex_vector_real_scalar((int16_t*) ul_ch1_0,SCALE,(int16_t*) ul_ch1_0,1,Msc_RS);
multadd_complex_vector_real_scalar((int16_t*) ul_ch2_0,SCALE,(int16_t*) ul_ch2_0,1,Msc_RS); // multadd_complex_vector_real_scalar((int16_t*) ul_ch2_0,SCALE,(int16_t*) ul_ch2_0,1,Msc_RS);
multadd_complex_vector_real_scalar((int16_t*) ul_ch1_1,SCALE,(int16_t*) ul_ch1_1,1,Msc_RS); // multadd_complex_vector_real_scalar((int16_t*) ul_ch1_1,SCALE,(int16_t*) ul_ch1_1,1,Msc_RS);
multadd_complex_vector_real_scalar((int16_t*) ul_ch2_1,SCALE,(int16_t*) ul_ch2_1,1,Msc_RS); // multadd_complex_vector_real_scalar((int16_t*) ul_ch2_1,SCALE,(int16_t*) ul_ch2_1,1,Msc_RS);
} // }
} //if (Ns&1) } //if (Ns&1)
......
...@@ -53,4 +53,8 @@ unsigned int lte_gold_generic_NB_IoT(unsigned int *x1, ...@@ -53,4 +53,8 @@ unsigned int lte_gold_generic_NB_IoT(unsigned int *x1,
unsigned int *x2, unsigned int *x2,
unsigned char reset); unsigned char reset);
void generate_ul_ref_sigs_rx(void);
void free_ul_ref_sigs(void);
#endif #endif
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifdef MAIN
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#endif
#include "defs.h"
uint16_t dftsizes[33] = {12,24,36,48,60,72,96,108,120,144,180,192,216,240,288,300,324,360,384,432,480,540,576,600,648,720,864,900,960,972,1080,1152,1200};
uint16_t ref_primes[33] = {11,23,31,47,59,71,89,107,113,139,179,191,211,239,283,293,317,359,383,431,479,523,571,599,647,719,863,887,953,971,1069,1151,1193};
uint16_t sequence_length[4] = {1,3,6,12}; //the "1" value should be
// int16_t *ul_ref_sigs[30][33];
int16_t *ul_ref_sigs_rx[30][4]; //these contain the sequences in repeated format and quantized to QPSK ifdef IFFT_FPGA
/* 36.211 table 5.5.1.2-1 */
char ref12[360] = {-1,1,3,-3,3,3,1,1,3,1,-3,3,1,1,3,3,3,-1,1,-3,-3,1,-3,3,1,1,-3,-3,-3,-1,-3,-3,1,-3,1,-1,-1,1,1,1,1,-1,-3,-3,1,-3,3,-1,-1,3,1,-1,1,-1,-3,-1,1,-1,1,3,1,-3,3,-1,-1,1,1,-1,-1,3,-3,1,-1,3,-3,-3,-3,3,1,-1,3,3,-3,1,-3,-1,-1,-1,1,-3,3,-1,1,-3,3,1,1,-3,3,1,-1,-1,-1,1,1,3,-1,1,1,-3,-1,3,3,-1,-3,1,1,1,1,1,-1,3,-1,1,1,-3,-3,-1,-3,-3,3,-1,3,1,-1,-1,3,3,-3,1,3,1,3,3,1,-3,1,1,-3,1,1,1,-3,-3,-3,1,3,3,-3,3,-3,1,1,3,-1,-3,3,3,-3,1,-1,-3,-1,3,1,3,3,3,-1,1,3,-1,1,-3,-1,-1,1,1,3,1,-1,-3,1,3,1,-1,1,3,3,3,-1,-1,3,-1,-3,1,1,3,-3,3,-3,-3,3,1,3,-1,-3,3,1,1,-3,1,-3,-3,-1,-1,1,-3,-1,3,1,3,1,-1,-1,3,-3,-1,-3,-1,-1,-3,1,1,1,1,3,1,-1,1,-3,-1,-1,3,-1,1,-3,-3,-3,-3,-3,1,-1,-3,1,1,-3,-3,-3,-3,-1,3,-3,1,-3,3,1,1,-1,-3,-1,-3,1,-1,1,3,-1,1,1,1,3,1,3,3,-1,1,-1,-3,-3,1,1,-3,3,3,1,3,3,1,-3,-1,-1,3,1,3,-3,-3,3,-3,1,-1,-1,3,-1,-3,-3,-1,-3,-1,-3,3,1,-1,1,3,-3,-3,-1,3,-3,3,-1,3,3,-3,3,3,-1,-1,3,-3,-3,-1,-1,-3,-1,3,-3,3,1,-1};
/* 36.211 table 5.5.1.2-2 */
// char ref24[720] = {
// -1,3,1,-3,3,-1,1,3,-3,3,1,3,-3,3,1,1,-1,1,3,-3,3,-3,-1,-3,-3,3,-3,-3,-3,1,-3,-3,3,-1,1,1,1,3,1,-1,3,-3,-3,1,3,1,1,-3,3,-1,3,3,1,1,-3,3,3,3,3,1,-1,3,-1,1,1,-1,-3,-1,-1,1,3,3,-1,-3,1,1,3,-3,1,1,-3,-1,-1,1,3,1,3,1,-1,3,1,1,-3,-1,-3,-1,-1,-1,-1,-3,-3,-1,1,1,3,3,-1,3,-1,1,-1,-3,1,-1,-3,-3,1,-3,-1,-1,-3,1,1,3,-1,1,3,1,-3,1,-3,1,1,-1,-1,3,-1,-3,3,-3,-3,-3,1,1,1,1,-1,-1,3,-3,-3,3,-3,1,-1,-1,1,-1,1,1,-1,-3,-1,1,-1,3,-1,-3,-3,3,3,-1,-1,-3,-1,3,1,3,1,3,1,1,-1,3,1,-1,1,3,-3,-1,-1,1,-3,1,3,-3,1,-1,-3,3,-3,3,-1,-1,-1,-1,1,-3,-3,-3,1,-3,-3,-3,1,-3,1,1,-3,3,3,-1,-3,-1,3,-3,3,3,3,-1,1,1,-3,1,-1,1,1,-3,1,1,-1,1,-3,-3,3,-1,3,-1,-1,-3,-3,-3,-1,-3,-3,1,-1,1,3,3,-1,1,-1,3,1,3,3,-3,-3,1,3,1,-1,-3,-3,-3,3,3,-3,3,3,-1,-3,3,-1,1,-3,1,1,3,3,1,1,1,-1,-1,1,-3,3,-1,1,1,-3,3,3,-1,-3,3,-3,-1,-3,-1,3,-1,-1,-1,-1,-3,-1,3,3,1,-1,1,3,3,3,-1,1,1,-3,1,3,-1,-3,3,-3,-3,3,1,3,1,-3,3,1,3,1,1,3,3,-1,-1,-3,1,-3,-1,3,1,1,3,-1,-1,1,-3,1,3,-3,1,-1,-3,-1,3,1,3,1,-1,-3,-3,-1,-1,-3,-3,-3,-1,-1,-3,3,-1,-1,-1,-1,1,1,-3,3,1,3,3,1,-1,1,-3,1,-3,1,1,-3,-1,1,3,-1,3,3,-1,-3,1,-1,-3,3,3,3,-1,1,1,3,-1,-3,-1,3,-1,-1,-1,1,1,1,1,1,-1,3,-1,-3,1,1,3,-3,1,-3,-1,1,1,-3,-3,3,1,1,-3,1,3,3,1,-1,-3,3,-1,3,3,3,-3,1,-1,1,-1,-3,-1,1,3,-1,3,-3,-3,-1,-3,3,-3,-3,-3,-1,-1,-3,-1,-3,3,1,3,-3,-1,3,-1,1,-1,3,-3,1,-1,-3,-3,1,1,-1,1,-1,1,-1,3,1,-3,-1,1,-1,1,-1,-1,3,3,-3,-1,1,-3,-3,-1,-3,3,1,-1,-3,-1,-3,-3,3,-3,3,-3,-1,1,3,1,-3,1,3,3,-1,-3,-1,-1,-1,-1,3,3,3,1,3,3,-3,1,3,-1,3,-1,3,3,-3,3,1,-1,3,3,1,-1,3,3,-1,-3,3,-3,-1,-1,3,-1,3,-1,-1,1,1,1,1,-1,-1,-3,-1,3,1,-1,1,-1,3,-1,3,1,1,-1,-1,-3,1,1,-3,1,3,-3,1,1,-3,-3,-1,-1,-3,-1,1,3,1,1,-3,-1,-1,-3,3,-3,3,1,-3,3,-3,1,-1,1,-3,1,1,1,-1,-3,3,3,1,1,3,-1,-3,-1,-1,-1,3,1,-3,-3,-1,3,-3,-1,-3,-1,-3,-1,-1,-3,-1,-1,1,-3,-1,-1,1,-1,-3,1,1,-3,1,-3,-3,3,1,1,-1,3,-1,-1,1,1,-1,-1,-3,-1,3,-1,3,-1,1,3,1,-1,3,1,3,-3,-3,1,-1,-1,1,3
// };
// 36.211, Section 10.1.4.1.2, Table 10.1.4.1.2-1
char ref3[36] = {1, -3, -3, 1, -3, -1, 1, -3, 3, 1, -1, -1, 1, -1, 1, 1, -1, 3, 1, 1, -3, 1, 1, -1, 1, 1, 3, 1, 3, -1, 1, 3, 1, 1, 3, 3 };
// 36.211, Section 10.1.4.1.2, Table 10.1.4.1.2-2
char ref6[84] = {1, 1, 1, 1, 3, -3, 1, 1, 3, 1, -3, 3, 1, -1, -1, -1, 1, -3, 1, -1, 3, -3, -1, -1, 1, 3, 1, -1, -1, 3, 1, -3, -3, 1, 3, 1, -1, -1, 1, -3, -3, -1,
-1, -1, -1, 3, -3, -1, 3, -1, 1, -3, -3, 3, 3, -1, 3, -3, -1, 1, 3, -3, 3, -1, 3, 3, -3, 1, 3, 1, -3, -1, -3, 1, -3, 3, -3, -1, -3, 3, -3, 1, 1, -3};
// 36.211, Section 10.1.4.1.2, Table 10.1.4.1.2-3
double alpha3[3] = {0 , M_PI*2/3, M_PI*4/3};
double alpha6[4] = {0 , M_PI*2/6, M_PI*4/6, M_PI*8/6};
// NB-IoT: 36.211, Section 10.1.4.1.1, Table 10.1.4.1.1-1
char w_n[256] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
1, 1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1,
1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1, 1,
1, 1, 1, 1,-1,-1,-1,-1, 1, 1, 1, 1,-1,-1,-1,-1,
1,-1, 1,-1,-1, 1,-1, 1, 1,-1, 1,-1,-1, 1,-1, 1,
1, 1,-1,-1,-1,-1, 1, 1, 1, 1,-1,-1,-1,-1, 1, 1,
1,-1,-1, 1,-1, 1, 1,-1, 1,-1,-1, 1,-1, 1, 1,-1,
1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1,-1,
1,-1, 1,-1, 1,-1, 1,-1,-1, 1,-1, 1,-1, 1,-1, 1,
1, 1,-1,-1, 1, 1,-1,-1,-1,-1, 1, 1,-1,-1, 1, 1,
1,-1,-1, 1, 1,-1,-1, 1,-1, 1, 1,-1,-1, 1, 1,-1,
1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1, 1,
1,-1, 1,-1,-1, 1,-1, 1,-1, 1,-1, 1, 1,-1, 1,-1,
1, 1,-1,-1,-1,-1, 1, 1,-1,-1, 1, 1, 1, 1,-1,-1,
1,-1,-1, 1,-1, 1, 1,-1,-1, 1, 1,-1, 1,-1,-1, 1
};
// void generate_ul_ref_sigs(void)
// {
// double qbar,phase;
// unsigned int u,v,Msc_RS,q,m,n;
// // These are the Zadoff-Chu sequences (for RB 3-100)
// for (Msc_RS=2; Msc_RS<33; Msc_RS++) {
// for (u=0; u<30; u++) {
// for (v=0; v<2; v++) {
// qbar = ref_primes[Msc_RS] * (u+1)/(double)31;
// ul_ref_sigs[u][v][Msc_RS] = (int16_t*)malloc16(2*sizeof(int16_t)*dftsizes[Msc_RS]);
// if ((((int)floor(2*qbar))&1) == 0)
// q = (int)(floor(qbar+.5)) - v;
// else
// q = (int)(floor(qbar+.5)) + v;
// #ifdef MAIN
// printf("Msc_RS %d (%d), u %d, v %d -> q %d (qbar %f)\n",Msc_RS,dftsizes[Msc_RS],u,v,q,qbar);
// #endif
// for (n=0; n<dftsizes[Msc_RS]; n++) {
// m=n%ref_primes[Msc_RS];
// phase = (double)q*m*(m+1)/ref_primes[Msc_RS];
// ul_ref_sigs[u][v][Msc_RS][n<<1] =(int16_t)(floor(32767*cos(M_PI*phase)));
// ul_ref_sigs[u][v][Msc_RS][1+(n<<1)] =-(int16_t)(floor(32767*sin(M_PI*phase)));
// #ifdef MAIN
// if (Msc_RS<5)
// printf("(%d,%d) ",ul_ref_sigs[u][v][Msc_RS][n<<1],ul_ref_sigs[u][v][Msc_RS][1+(n<<1)]);
// #endif
// }
// #ifdef MAIN
// if (Msc_RS<5)
// printf("\n");
// #endif
// }
// }
// }
// // These are the sequences for RB 1
// for (u=0; u<30; u++) {
// ul_ref_sigs[u][0][0] = (int16_t*)malloc16(2*sizeof(int16_t)*dftsizes[0]);
// for (n=0; n<dftsizes[0]; n++) {
// ul_ref_sigs[u][0][0][n<<1] =(int16_t)(floor(32767*cos(M_PI*ref12[(u*12) + n]/4)));
// ul_ref_sigs[u][0][0][1+(n<<1)]=(int16_t)(floor(32767*sin(M_PI*ref12[(u*12) + n]/4)));
// }
// }
// // These are the sequences for RB 2
// for (u=0; u<30; u++) {
// ul_ref_sigs[u][0][1] = (int16_t*)malloc16(2*sizeof(int16_t)*dftsizes[1]);
// for (n=0; n<dftsizes[1]; n++) {
// ul_ref_sigs[u][0][1][n<<1] =(int16_t)(floor(32767*cos(M_PI*ref24[(u*24) + n]/4)));
// ul_ref_sigs[u][0][1][1+(n<<1)]=(int16_t)(floor(32767*sin(M_PI*ref24[(u*24) + n]/4)));
// }
// }
// }
void generate_ul_ref_sigs_rx_NB_IoT(void)
{
unsigned int u,Msc_RS,n;
uint8_t threetnecyclicshift=0, sixtonecyclichift=0;// NB-IoT: to be defined from higher layer, see 36.211 Section 10.1.4.1.2
for (Msc_RS=0; Msc_RS<4; Msc_RS++) {
for (u=0; u<30; u++) {
ul_ref_sigs_rx[u][Msc_RS] = (int16_t*)malloc16(2*sizeof(int16_t)*sequence_length[Msc_RS]);
switch (Msc_RS){
case 0:
printf("Not coded yet\n");
break;
case 1:
for (n=0; n<sequence_length[Msc_RS]; n++) {
ul_ref_sigs_rx[u][Msc_RS][n<<1] = (int16_t)(floor(32767*cos(M_PI*ref3[(u*3) + n]/4 + alpha3[threetnecyclicshift])));
ul_ref_sigs_rx[u][Msc_RS][1+(n<<1)]= (int16_t)(floor(32767*sin(M_PI*ref3[(u*3) + n]/4 + alpha3[threetnecyclicshift])));
}
break;
case 2:
for (n=0; n<sequence_length[Msc_RS]; n++) {
ul_ref_sigs_rx[u][Msc_RS][n<<1] = (int16_t)(floor(32767*cos(M_PI*ref6[(u*6) + n]/4 + alpha6[sixtonecyclichift])));
ul_ref_sigs_rx[u][Msc_RS][1+(n<<1)]= (int16_t)(floor(32767*sin(M_PI*ref6[(u*6) + n]/4 + alpha6[sixtonecyclichift])));
}
break;
case 3:
for (n=0; n<sequence_length[Msc_RS]; n++) {
ul_ref_sigs_rx[u][Msc_RS][n<<1] = (int16_t)(floor(32767*cos(M_PI*ref12[(u*12) + n]/4)));
ul_ref_sigs_rx[u][Msc_RS][1+(n<<1)]= (int16_t)(floor(32767*sin(M_PI*ref12[(u*12) + n]/4)));
}
break;
}
}
}
}
void free_ul_ref_sigs(void)
{
unsigned int u,Msc_RS;
for (Msc_RS=0; Msc_RS<4; Msc_RS++) {
for (u=0; u<30; u++) {
if (ul_ref_sigs_rx[u][Msc_RS])
free16(ul_ref_sigs_rx[u][Msc_RS],4*sizeof(int16_t)*sequence_length[Msc_RS]);
}
}
}
#ifdef MAIN
main()
{
//generate_ul_ref_sigs();
generate_ul_ref_sigs_rx();
free_ul_ref_sigs();
}
#endif
...@@ -690,6 +690,15 @@ typedef struct { ...@@ -690,6 +690,15 @@ typedef struct {
// int calibration_flag; // int calibration_flag;
/// delta_TF for power control /// delta_TF for power control
int32_t delta_TF; int32_t delta_TF;
///////////////////////////////////////////// 3 parameter added by vincent ///////////////////////////////////////////////
// NB_IoT: Nsymb_UL and Nslot_UL are defined in 36.211, Section 10.1.2.3, Table 10.1.2.3-1
// The number of symbol in a resource unit is given by Nsymb_UL*Nslot_UL
uint8_t Nsymb_UL;
// Number of NPUSCH slots
uint8_t Nslot_UL;
// Number of subcarrier for NPUSH
uint8_t N_sc_RU;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
} NB_IoT_UL_eNB_HARQ_t; } NB_IoT_UL_eNB_HARQ_t;
......
...@@ -19,13 +19,13 @@ ...@@ -19,13 +19,13 @@
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*! \file PHY/LTE_TRANSPORT/lte_mcs.c /*! \file PHY/LTE_TRANSPORT/lte_mcs_NB_IoT.c
* \brief Some support routines for MCS computations * \brief Some support routines for MCS computations
* \author R. Knopp * \author V. Savaux
* \date 2011 * \date 2017
* \version 0.1 * \version 0.1
* \company Eurecom * \company b<>com
* \email: knopp@eurecom.fr * \email:
* \note * \note
* \warning * \warning
*/ */
...@@ -34,16 +34,24 @@ ...@@ -34,16 +34,24 @@
//#include "PHY/extern.h" //#include "PHY/extern.h"
#include "PHY/LTE_TRANSPORT/proto_NB_IoT.h" #include "PHY/LTE_TRANSPORT/proto_NB_IoT.h"
// 36213 Section 16.5.1.2, Table
unsigned char get_Qm_ul_NB_IoT(unsigned char I_MCS) unsigned char get_Qm_ul_NB_IoT(unsigned char I_MCS, uint8_t N_sc_RU)
{ {
if (I_MCS < 11) if (N_sc_RU)
return(2); return(2);
else if (I_MCS < 21)
return(4);
else else
return(6); if (I_MCS<2)
return(1);
else
return(2);
// if (I_MCS < 11)
// return(2);
// else if (I_MCS < 21)
// return(4);
// else
// return(6);
} }
...@@ -172,7 +172,9 @@ uint8_t subframe2harq_pid_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t fra ...@@ -172,7 +172,9 @@ uint8_t subframe2harq_pid_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t fra
/** \brief Compute Q (modulation order) based on I_MCS for PUSCH. Implements table 8.6.1-1 from 36.213. /** \brief Compute Q (modulation order) based on I_MCS for PUSCH. Implements table 8.6.1-1 from 36.213.
@param I_MCS */ @param I_MCS */
uint8_t get_Qm_ul_NB_IoT(uint8_t I_MCS);
//uint8_t get_Qm_ul_NB_IoT(uint8_t I_MCS);
unsigned char get_Qm_ul_NB_IoT(unsigned char I_MCS, uint8_t N_sc_RU);
/** \fn dlsch_encoding(PHY_VARS_eNB *eNB, /** \fn dlsch_encoding(PHY_VARS_eNB *eNB,
uint8_t *input_buffer, uint8_t *input_buffer,
......
...@@ -732,6 +732,9 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr ...@@ -732,6 +732,9 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
return( (ret>proc->tdp.ret) ? ret : proc->tdp.ret ); return( (ret>proc->tdp.ret) ? ret : proc->tdp.ret );
} }
*/
/*
// NB_IoT: functions in ulsch_decoding_data_NB_IoT must be defined
int ulsch_decoding_data_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,int UE_id,int harq_pid,int llr8_flag) { int ulsch_decoding_data_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,int UE_id,int harq_pid,int llr8_flag) {
...@@ -897,6 +900,9 @@ int ulsch_decoding_data_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,int UE_id,int harq_pid,i ...@@ -897,6 +900,9 @@ int ulsch_decoding_data_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,int UE_id,int harq_pid,i
} }
*/ */
// NB_IoT: functions in ulsch_decoding_data_NB_IoT must be defined :ulsch_decoding_data_NB_IoT (defined in this file)
static inline unsigned int lte_gold_unscram_NB_IoT(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline)); static inline unsigned int lte_gold_unscram_NB_IoT(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline));
static inline unsigned int lte_gold_unscram_NB_IoT(unsigned int *x1, unsigned int *x2, unsigned char reset) static inline unsigned int lte_gold_unscram_NB_IoT(unsigned int *x1, unsigned int *x2, unsigned char reset)
{ {
...@@ -944,26 +950,30 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -944,26 +950,30 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
unsigned short nb_rb; unsigned short nb_rb;
unsigned int A; unsigned int A;
uint8_t Q_m; uint8_t Q_m;
unsigned int i,i2,q,j,j2; unsigned int i,i2,j,j2;
// unsigned int q;
int iprime; int iprime;
unsigned int ret = 0; unsigned int ret = 0;
int r,Kr; int r,Kr;
uint8_t *columnset; // uint8_t *columnset;
unsigned int sumKr=0; unsigned int sumKr=0;
unsigned int Qprime,L,G,Q_CQI,Q_RI,H,Hprime,Hpp,Cmux,Rmux_prime,O_RCC; //unsigned int Qprime,L,O_RCC;
unsigned int Qprime_ACK,Qprime_RI,len_ACK=0,len_RI=0; unsigned int G,Q_CQI,Q_RI,H,Hprime,Hpp,Cmux,Rmux_prime;
//unsigned int Qprime_ACK,Qprime_RI,len_ACK=0,len_RI=0;
int metric,metric_new; // int metric,metric_new;
uint8_t o_flip[8]; //uint8_t o_flip[8];
uint32_t x1, x2, s=0; uint32_t x1, x2, s=0;
int16_t ys,c; //int16_t ys;
uint32_t wACK_idx; int16_t c;
uint8_t dummy_w_cc[3*(MAX_CQI_BITS+8+32)]; //uint32_t wACK_idx;
//uint8_t dummy_w_cc[3*(MAX_CQI_BITS+8+32)];
int16_t y[6*14*1200] __attribute__((aligned(32))); int16_t y[6*14*1200] __attribute__((aligned(32)));
uint8_t ytag[14*1200]; uint8_t ytag[14*1200];
int16_t cseq[6*14*1200]; int16_t cseq[6*14*1200];
int off; //int off;
int subframe = proc->subframe_rx; int subframe = proc->subframe_rx;
harq_pid = subframe2harq_pid_NB_IoT(frame_parms,proc->frame_rx,subframe); harq_pid = subframe2harq_pid_NB_IoT(frame_parms,proc->frame_rx,subframe);
...@@ -971,7 +981,9 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -971,7 +981,9 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,1);
// x1 is set in lte_gold_generic // x1 is set in lte_gold_generic
x2 = ((uint32_t)ulsch->rnti<<14) + ((uint32_t)subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.3.1 // x2 should not reinitialized each subframe
// x2 should be reinitialized according to 36.211 Sections 10.1.3.1 and 10.1.3.6
x2 = ((uint32_t)ulsch->rnti<<14) + ((uint32_t)subframe<<9) + (((uint32_t)proc->frame_rx%2)<<13) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.3.1
ulsch_harq = ulsch->harq_process; ulsch_harq = ulsch->harq_process;
if (harq_pid==255) { if (harq_pid==255) {
...@@ -986,12 +998,13 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -986,12 +998,13 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
return 1+ulsch->max_turbo_iterations; return 1+ulsch->max_turbo_iterations;
} }
/* ----------------------- Segmentation */
nb_rb = ulsch_harq->nb_rb; nb_rb = ulsch_harq->nb_rb; // nb_rb set but not used ??
A = ulsch_harq->TBS; A = ulsch_harq->TBS;
Q_m = get_Qm_ul_NB_IoT(ulsch_harq->mcs); Q_m = get_Qm_ul_NB_IoT(ulsch_harq->mcs,ulsch_harq->N_sc_RU);
G = nb_rb * (12 * Q_m) * ulsch_harq->Nsymb_pusch; //G = nb_rb * (12 * Q_m) * ulsch_harq->Nsymb_pusch;
G = (ulsch_harq->N_sc_RU * Q_m) * ulsch_harq->Nsymb_UL * ulsch_harq->Nslot_UL;
#ifdef DEBUG_ULSCH_DECODING #ifdef DEBUG_ULSCH_DECODING
printf("ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d, subframe %d\n", printf("ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d, subframe %d\n",
...@@ -1048,69 +1061,71 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1048,69 +1061,71 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
//mac_xface_NB_IoT->macphy_exit("ulsch_decoding.c: FATAL sumKr is 0!"); //mac_xface_NB_IoT->macphy_exit("ulsch_decoding.c: FATAL sumKr is 0!");
return(-1); return(-1);
} }
// Compute Q_ri
Qprime = ulsch_harq->O_RI*ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_ri_times8;
if (Qprime > 0 ) {
if ((Qprime % (8*sumKr)) > 0)
Qprime = 1+(Qprime/(8*sumKr));
else
Qprime = Qprime/(8*sumKr);
if (Qprime > 4*nb_rb * 12)
Qprime = 4*nb_rb * 12;
}
Q_RI = Q_m*Qprime; // No control information in NB-IoT
Qprime_RI = Qprime; // Compute Q_ri
// Compute Q_ack // Qprime = ulsch_harq->O_RI*ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_ri_times8;
Qprime = ulsch_harq->O_ACK*ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_harqack_times8;
if (Qprime > 0) { // if (Qprime > 0 ) {
if ((Qprime % (8*sumKr)) > 0) // if ((Qprime % (8*sumKr)) > 0)
Qprime = 1+(Qprime/(8*sumKr)); // Qprime = 1+(Qprime/(8*sumKr));
else // else
Qprime = Qprime/(8*sumKr); // Qprime = Qprime/(8*sumKr);
if (Qprime > (4*nb_rb * 12)) // if (Qprime > 4*nb_rb * 12)
Qprime = 4*nb_rb * 12; // Qprime = 4*nb_rb * 12;
} // }
// Q_ACK = Qprime * Q_m;
Qprime_ACK = Qprime;
#ifdef DEBUG_ULSCH_DECODING
printf("ulsch_decoding.c: Qprime_ACK %d, Msc_initial %d, Nsymb_initial %d, sumKr %d\n",
Qprime_ACK,ulsch_harq->Msc_initial,ulsch_harq->Nsymb_initial,sumKr);
#endif
// Compute Q_cqi // Q_RI = Q_m*Qprime;
if (ulsch_harq->Or1 < 12) // Qprime_RI = Qprime;
L=0; // // Compute Q_ack
else // Qprime = ulsch_harq->O_ACK*ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_harqack_times8;
L=8;
// NOTE: we have to handle the case where we have a very small number of bits (condition on pg. 26 36.212) // if (Qprime > 0) {
if (ulsch_harq->Or1 > 0) // if ((Qprime % (8*sumKr)) > 0)
Qprime = (ulsch_harq->Or1 + L) * ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_cqi_times8; // Qprime = 1+(Qprime/(8*sumKr));
else // else
Qprime=0; // Qprime = Qprime/(8*sumKr);
if (Qprime > 0) { // check if ceiling is larger than floor in Q' expression // if (Qprime > (4*nb_rb * 12))
if ((Qprime % (8*sumKr)) > 0) // Qprime = 4*nb_rb * 12;
Qprime = 1+(Qprime/(8*sumKr)); // }
else // // Q_ACK = Qprime * Q_m;
Qprime = Qprime/(8*sumKr); // Qprime_ACK = Qprime;
} // #ifdef DEBUG_ULSCH_DECODING
// printf("ulsch_decoding.c: Qprime_ACK %d, Msc_initial %d, Nsymb_initial %d, sumKr %d\n",
// Qprime_ACK,ulsch_harq->Msc_initial,ulsch_harq->Nsymb_initial,sumKr);
// #endif
// // Compute Q_cqi
// if (ulsch_harq->Or1 < 12)
// L=0;
// else
// L=8;
// // NOTE: we have to handle the case where we have a very small number of bits (condition on pg. 26 36.212)
// if (ulsch_harq->Or1 > 0)
// Qprime = (ulsch_harq->Or1 + L) * ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_cqi_times8;
// else
// Qprime=0;
// if (Qprime > 0) { // check if ceiling is larger than floor in Q' expression
// if ((Qprime % (8*sumKr)) > 0)
// Qprime = 1+(Qprime/(8*sumKr));
// else
// Qprime = Qprime/(8*sumKr);
// }
G = nb_rb * (12 * Q_m) * (ulsch_harq->Nsymb_pusch); // G = nb_rb * (12 * Q_m) * (ulsch_harq->Nsymb_pusch);
Q_CQI = Q_m * Qprime; // Q_CQI = Q_m * Qprime;
#ifdef DEBUG_ULSCH_DECODING // #ifdef DEBUG_ULSCH_DECODING
printf("ulsch_decoding: G %d, Q_RI %d, Q_CQI %d (L %d, Or1 %d) O_ACK %d\n",G,Q_RI,Q_CQI,L,ulsch_harq->Or1,ulsch_harq->O_ACK); // printf("ulsch_decoding: G %d, Q_RI %d, Q_CQI %d (L %d, Or1 %d) O_ACK %d\n",G,Q_RI,Q_CQI,L,ulsch_harq->Or1,ulsch_harq->O_ACK);
#endif // #endif
G = G - Q_RI - Q_CQI; // G = G - Q_RI - Q_CQI;
ulsch_harq->G = G; ulsch_harq->G = G;
if ((int)G < 0) { if ((int)G < 0) {
...@@ -1118,12 +1133,18 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1118,12 +1133,18 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
return(-1); return(-1);
} }
H = G + Q_CQI; //H = G + Q_CQI;
H = G ;
Hprime = H/Q_m; Hprime = H/Q_m;
// Demultiplexing/Deinterleaving of PUSCH/ACK/RI/CQI // Demultiplexing/Deinterleaving of PUSCH/ACK/RI/CQI
//start_meas_NB_IoT(&eNB->ulsch_demultiplexing_stats); //start_meas_NB_IoT(&eNB->ulsch_demultiplexing_stats);
Hpp = Hprime + Qprime_RI; //Hpp = Hprime + Qprime_RI;
Cmux = ulsch_harq->Nsymb_pusch; Hpp = Hprime;
// Cmux = ulsch_harq->Nsymb_pusch;
// unsigned int Nsymb_UL, Nslot_UL; // NB_IoT: these parameters should included in ulsch_harq
// Cmux = (Nsymb_UL-1)*Nslot_UL;
Cmux = (ulsch_harq->Nsymb_UL-1)*ulsch_harq->Nslot_UL;
Rmux_prime = Hpp/Cmux; Rmux_prime = Hpp/Cmux;
// Clear "tag" interleaving matrix to allow for CQI/DATA identification // Clear "tag" interleaving matrix to allow for CQI/DATA identification
...@@ -1165,64 +1186,68 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1165,64 +1186,68 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
// printf("after unscrambling c[%d] = %p\n",0,ulsch_harq->c[0]); // printf("after unscrambling c[%d] = %p\n",0,ulsch_harq->c[0]);
if (frame_parms->Ncp == 0) // if (frame_parms->Ncp == 0)
columnset = cs_ri_normal_NB_IoT; // columnset = cs_ri_normal_NB_IoT;
else // else
columnset = cs_ri_extended_NB_IoT; // columnset = cs_ri_extended_NB_IoT;
j = 0; // j = 0;
for (i=0; i<Qprime_RI; i++) { // for (i=0; i<Qprime_RI; i++) {
r = Rmux_prime - 1 - (i>>2); // r = Rmux_prime - 1 - (i>>2);
/* // /*
for (q=0;q<Q_m;q++) // for (q=0;q<Q_m;q++)
ytag2[q+(Q_m*((r*Cmux) + columnset[j]))] = q_RI[(q+(Q_m*i))%len_RI]; // ytag2[q+(Q_m*((r*Cmux) + columnset[j]))] = q_RI[(q+(Q_m*i))%len_RI];
*/ // */
off =((Rmux_prime*Q_m*columnset[j])+(r*Q_m)); // off =((Rmux_prime*Q_m*columnset[j])+(r*Q_m));
cseq[off+1] = cseq[off]; // PUSCH_y // cseq[off+1] = cseq[off]; // PUSCH_y
for (q=2; q<Q_m; q++) // for (q=2; q<Q_m; q++)
cseq[off+q] = -1; // PUSCH_x // cseq[off+q] = -1; // PUSCH_x
j = (j+3)&3; // j = (j+3)&3;
} // }
// printf("after RI c[%d] = %p\n",0,ulsch_harq->c[0]); // // printf("after RI c[%d] = %p\n",0,ulsch_harq->c[0]);
// HARQ-ACK Bits (Note these overwrite some bits) // // HARQ-ACK Bits (Note these overwrite some bits)
if (frame_parms->Ncp == 0) // if (frame_parms->Ncp == 0)
columnset = cs_ack_normal_NB_IoT; // columnset = cs_ack_normal_NB_IoT;
else // else
columnset = cs_ack_extended_NB_IoT; // columnset = cs_ack_extended_NB_IoT;
j = 0; // j = 0;
for (i=0; i<Qprime_ACK; i++) { // for (i=0; i<Qprime_ACK; i++) {
r = Rmux_prime - 1 - (i>>2); // r = Rmux_prime - 1 - (i>>2);
off =((Rmux_prime*Q_m*columnset[j])+(r*Q_m)); // off =((Rmux_prime*Q_m*columnset[j])+(r*Q_m));
if (ulsch_harq->O_ACK == 1) { // if (ulsch_harq->O_ACK == 1) {
if (ulsch->bundling==0) // if (ulsch->bundling==0)
cseq[off+1] = cseq[off]; // PUSCH_y // cseq[off+1] = cseq[off]; // PUSCH_y
for (q=2; q<Q_m; q++) // for (q=2; q<Q_m; q++)
cseq[off+q] = -1; // PUSCH_x // cseq[off+q] = -1; // PUSCH_x
} else if (ulsch_harq->O_ACK == 2) { // } else if (ulsch_harq->O_ACK == 2) {
for (q=2; q<Q_m; q++) // for (q=2; q<Q_m; q++)
cseq[off+q] = -1; // PUSCH_x // cseq[off+q] = -1; // PUSCH_x
} // }
#ifdef DEBUG_ULSCH_DECODING // #ifdef DEBUG_ULSCH_DECODING
printf("ulsch_decoding.c: ACK i %d, r %d, j %d, ColumnSet[j] %d\n",i,r,j,columnset[j]); // printf("ulsch_decoding.c: ACK i %d, r %d, j %d, ColumnSet[j] %d\n",i,r,j,columnset[j]);
#endif // #endif
j=(j+3)&3; // j=(j+3)&3;
} // }
i = 0; i = 0;
switch (Q_m) { switch (Q_m) {
// why the case 1 ??????????????????
case 1:
break;
case 2: case 2:
for (j=0; j<Cmux; j++) { for (j=0; j<Cmux; j++) {
...@@ -1244,170 +1269,171 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1244,170 +1269,171 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
break; break;
case 4: // case 4:
for (j=0; j<Cmux; j++) { // for (j=0; j<Cmux; j++) {
i2 = j<<2; // i2 = j<<2;
for (r=0; r<Rmux_prime; r++) { // for (r=0; r<Rmux_prime; r++) {
/* // /*
c = cseq[i]; // c = cseq[i];
y[i2++] = c*ulsch_llr[i++]; // y[i2++] = c*ulsch_llr[i++];
c = cseq[i]; // c = cseq[i];
y[i2++] = c*ulsch_llr[i++]; // y[i2++] = c*ulsch_llr[i++];
c = cseq[i]; // c = cseq[i];
y[i2++] = c*ulsch_llr[i++]; // y[i2++] = c*ulsch_llr[i++];
c = cseq[i]; // c = cseq[i];
y[i2] = c*ulsch_llr[i++]; // y[i2] = c*ulsch_llr[i++];
i2=(i2+(Cmux<<2)-3); // i2=(i2+(Cmux<<2)-3);
*/ // */
// slightly more optimized version (equivalent to above) for 16QAM to improve computational performance // // slightly more optimized version (equivalent to above) for 16QAM to improve computational performance
*(__m64 *)&y[i2] = _mm_sign_pi16(*(__m64*)&ulsch_llr[i],*(__m64*)&cseq[i]);i+=4;i2+=(Cmux<<2); // *(__m64 *)&y[i2] = _mm_sign_pi16(*(__m64*)&ulsch_llr[i],*(__m64*)&cseq[i]);i+=4;i2+=(Cmux<<2);
}
}
break;
case 6:
for (j=0; j<Cmux; j++) {
i2 = j*6; // }
// }
for (r=0; r<Rmux_prime; r++) { // break;
c = cseq[i];
y[i2++] = c*ulsch_llr[i++]; // case 6:
c = cseq[i]; // for (j=0; j<Cmux; j++) {
y[i2++] = c*ulsch_llr[i++];
c = cseq[i]; // i2 = j*6;
y[i2++] = c*ulsch_llr[i++];
c = cseq[i]; // for (r=0; r<Rmux_prime; r++) {
y[i2++] = c*ulsch_llr[i++]; // c = cseq[i];
c = cseq[i]; // y[i2++] = c*ulsch_llr[i++];
y[i2++] = c*ulsch_llr[i++]; // c = cseq[i];
c = cseq[i]; // y[i2++] = c*ulsch_llr[i++];
y[i2] = c*ulsch_llr[i++]; // c = cseq[i];
i2 =(i2+(Cmux*6)-5); // y[i2++] = c*ulsch_llr[i++];
} // c = cseq[i];
} // y[i2++] = c*ulsch_llr[i++];
// c = cseq[i];
// y[i2++] = c*ulsch_llr[i++];
// c = cseq[i];
// y[i2] = c*ulsch_llr[i++];
// i2 =(i2+(Cmux*6)-5);
// }
// }
break; // break;
} }
if (i!=(H+Q_RI)) // if (i!=(H+Q_RI))
if (i!=(H))
LOG_D(PHY,"ulsch_decoding.c: Error in input buffer length (j %d, H+Q_RI %d)\n",i,H+Q_RI); LOG_D(PHY,"ulsch_decoding.c: Error in input buffer length (j %d, H+Q_RI %d)\n",i,H+Q_RI);
// HARQ-ACK Bits (LLRs are nulled in overwritten bits after copying HARQ-ACK LLR) // HARQ-ACK Bits (LLRs are nulled in overwritten bits after copying HARQ-ACK LLR)
if (frame_parms->Ncp == 0) // if (frame_parms->Ncp == 0)
columnset = cs_ack_normal_NB_IoT; // columnset = cs_ack_normal_NB_IoT;
else // else
columnset = cs_ack_extended_NB_IoT; // columnset = cs_ack_extended_NB_IoT;
j=0; // j=0;
if (ulsch_harq->O_ACK == 1) { // if (ulsch_harq->O_ACK == 1) {
switch (Q_m) { // switch (Q_m) {
case 2: // case 2:
len_ACK = 2; // len_ACK = 2;
break; // break;
case 4: // case 4:
len_ACK = 4; // len_ACK = 4;
break; // break;
case 6: // case 6:
len_ACK = 6; // len_ACK = 6;
break; // break;
} // }
} // }
if (ulsch_harq->O_ACK == 2) { // if (ulsch_harq->O_ACK == 2) {
switch (Q_m) { // switch (Q_m) {
case 2: // case 2:
len_ACK = 6; // len_ACK = 6;
break; // break;
case 4: // case 4:
len_ACK = 12; // len_ACK = 12;
break; // break;
case 6: // case 6:
len_ACK = 18; // len_ACK = 18;
break; // break;
} // }
} // }
if (ulsch_harq->O_ACK > 2) { // if (ulsch_harq->O_ACK > 2) {
LOG_E(PHY,"ulsch_decoding: FATAL, ACK cannot be more than 2 bits yet\n"); // LOG_E(PHY,"ulsch_decoding: FATAL, ACK cannot be more than 2 bits yet\n");
return(-1); // return(-1);
} // }
for (i=0; i<len_ACK; i++) // for (i=0; i<len_ACK; i++)
ulsch_harq->q_ACK[i] = 0; // ulsch_harq->q_ACK[i] = 0;
for (i=0; i<Qprime_ACK; i++) { // for (i=0; i<Qprime_ACK; i++) {
r = Rmux_prime -1 - (i>>2); // r = Rmux_prime -1 - (i>>2);
for (q=0; q<Q_m; q++) { // for (q=0; q<Q_m; q++) {
if (y[q+(Q_m*((r*Cmux) + columnset[j]))]!=0) // if (y[q+(Q_m*((r*Cmux) + columnset[j]))]!=0)
ulsch_harq->q_ACK[(q+(Q_m*i))%len_ACK] += y[q+(Q_m*((r*Cmux) + columnset[j]))]; // ulsch_harq->q_ACK[(q+(Q_m*i))%len_ACK] += y[q+(Q_m*((r*Cmux) + columnset[j]))];
y[q+(Q_m*((r*Cmux) + columnset[j]))] = 0; // NULL LLRs in ACK positions // y[q+(Q_m*((r*Cmux) + columnset[j]))] = 0; // NULL LLRs in ACK positions
} // }
j = (j+3)&3; // j = (j+3)&3;
} // }
// printf("after ACKNAK c[%d] = %p\n",0,ulsch_harq->c[0]); // // printf("after ACKNAK c[%d] = %p\n",0,ulsch_harq->c[0]);
// RI BITS // // RI BITS
if (ulsch_harq->O_RI == 1) { // if (ulsch_harq->O_RI == 1) {
switch (Q_m) { // switch (Q_m) {
case 2: // case 2:
len_RI = 2; // len_RI = 2;
break; // break;
case 4: // case 4:
len_RI = 4; // len_RI = 4;
break; // break;
case 6: // case 6:
len_RI = 6; // len_RI = 6;
break; // break;
} // }
} // }
if (ulsch_harq->O_RI > 1) { // if (ulsch_harq->O_RI > 1) {
LOG_E(PHY,"ulsch_decoding: FATAL, RI cannot be more than 1 bit yet\n"); // LOG_E(PHY,"ulsch_decoding: FATAL, RI cannot be more than 1 bit yet\n");
return(-1); // return(-1);
} // }
for (i=0; i<len_RI; i++) // for (i=0; i<len_RI; i++)
ulsch_harq->q_RI[i] = 0; // ulsch_harq->q_RI[i] = 0;
if (frame_parms->Ncp == 0) // if (frame_parms->Ncp == 0)
columnset = cs_ri_normal_NB_IoT; // columnset = cs_ri_normal_NB_IoT;
else // else
columnset = cs_ri_extended_NB_IoT; // columnset = cs_ri_extended_NB_IoT;
j=0; // j=0;
for (i=0; i<Qprime_RI; i++) { // for (i=0; i<Qprime_RI; i++) {
r = Rmux_prime -1 - (i>>2); // r = Rmux_prime -1 - (i>>2);
for (q=0; q<Q_m; q++) // for (q=0; q<Q_m; q++)
ulsch_harq->q_RI[(q+(Q_m*i))%len_RI] += y[q+(Q_m*((r*Cmux) + columnset[j]))]; // ulsch_harq->q_RI[(q+(Q_m*i))%len_RI] += y[q+(Q_m*((r*Cmux) + columnset[j]))];
ytag[(r*Cmux) + columnset[j]] = LTE_NULL_NB_IoT; // ytag[(r*Cmux) + columnset[j]] = LTE_NULL_NB_IoT;
j = (j+3)&3; // j = (j+3)&3;
} // }
// printf("after RI2 c[%d] = %p\n",0,ulsch_harq->c[0]); // printf("after RI2 c[%d] = %p\n",0,ulsch_harq->c[0]);
...@@ -1416,85 +1442,85 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1416,85 +1442,85 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
j2 = 0; j2 = 0;
// r=0; // r=0;
if (Q_RI>0) { // if (Q_RI>0) {
for (i=0; i<(Q_CQI/Q_m); i++) { // for (i=0; i<(Q_CQI/Q_m); i++) {
while (ytag[j]==LTE_NULL_NB_IoT) {
j++;
j2+=Q_m;
}
for (q=0; q<Q_m; q++) {
ys = y[q+j2]; // while (ytag[j]==LTE_NULL_NB_IoT) {
// j++;
// j2+=Q_m;
// }
if (ys>127) // for (q=0; q<Q_m; q++) {
ulsch_harq->q[q+(Q_m*i)] = 127;
else if (ys<-128)
ulsch_harq->q[q+(Q_m*i)] = -128;
else
ulsch_harq->q[q+(Q_m*i)] = ys;
}
j2+=Q_m;
}
// ys = y[q+j2];
switch (Q_m) { // if (ys>127)
case 2: // ulsch_harq->q[q+(Q_m*i)] = 127;
for (iprime=0; iprime<G;) { // else if (ys<-128)
while (ytag[j]==LTE_NULL_NB_IoT) { // ulsch_harq->q[q+(Q_m*i)] = -128;
j++; // else
j2+=2; // ulsch_harq->q[q+(Q_m*i)] = ys;
} // }
ulsch_harq->e[iprime++] = y[j2++]; // j2+=Q_m;
ulsch_harq->e[iprime++] = y[j2++]; // }
}
break;
case 4:
for (iprime=0; iprime<G;) {
while (ytag[j]==LTE_NULL_NB_IoT) {
j++;
j2+=4;
}
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
}
break;
case 6: // switch (Q_m) {
for (iprime=0; iprime<G;) { // case 2:
while (ytag[j]==LTE_NULL_NB_IoT) { // for (iprime=0; iprime<G;) {
j++; // while (ytag[j]==LTE_NULL_NB_IoT) {
j2+=6; // j++;
} // j2+=2;
ulsch_harq->e[iprime++] = y[j2++]; // }
ulsch_harq->e[iprime++] = y[j2++]; // ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++]; // ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++]; // }
ulsch_harq->e[iprime++] = y[j2++]; // break;
ulsch_harq->e[iprime++] = y[j2++];
}
break;
}
} // Q_RI>0
else {
for (i=0; i<(Q_CQI/Q_m); i++) { // case 4:
// for (iprime=0; iprime<G;) {
// while (ytag[j]==LTE_NULL_NB_IoT) {
// j++;
// j2+=4;
// }
// ulsch_harq->e[iprime++] = y[j2++];
// ulsch_harq->e[iprime++] = y[j2++];
// ulsch_harq->e[iprime++] = y[j2++];
// ulsch_harq->e[iprime++] = y[j2++];
// }
// break;
for (q=0; q<Q_m; q++) { // case 6:
ys = y[q+j2]; // for (iprime=0; iprime<G;) {
if (ys>127) // while (ytag[j]==LTE_NULL_NB_IoT) {
ulsch_harq->q[q+(Q_m*i)] = 127; // j++;
else if (ys<-128) // j2+=6;
ulsch_harq->q[q+(Q_m*i)] = -128; // }
else // ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->q[q+(Q_m*i)] = ys; // ulsch_harq->e[iprime++] = y[j2++];
} // ulsch_harq->e[iprime++] = y[j2++];
j2+=Q_m; // ulsch_harq->e[iprime++] = y[j2++];
} // ulsch_harq->e[iprime++] = y[j2++];
// ulsch_harq->e[iprime++] = y[j2++];
// }
// break;
// }
// } // Q_RI>0
// else {
// for (i=0; i<(Q_CQI/Q_m); i++) {
// for (q=0; q<Q_m; q++) {
// ys = y[q+j2];
// if (ys>127)
// ulsch_harq->q[q+(Q_m*i)] = 127;
// else if (ys<-128)
// ulsch_harq->q[q+(Q_m*i)] = -128;
// else
// ulsch_harq->q[q+(Q_m*i)] = ys;
// }
// j2+=Q_m;
// }
/* To be improved according to alignment of j2 /* To be improved according to alignment of j2
#if defined(__x86_64__)||defined(__i386__) #if defined(__x86_64__)||defined(__i386__)
#ifndef __AVX2__ #ifndef __AVX2__
...@@ -1523,7 +1549,7 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1523,7 +1549,7 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
ep[6] = yp[6]; ep[6] = yp[6];
ep[7] = yp[7]; ep[7] = yp[7];
} }
}
//stop_meas_NB_IoT(&eNB->ulsch_demultiplexing_stats); //stop_meas_NB_IoT(&eNB->ulsch_demultiplexing_stats);
...@@ -1531,7 +1557,7 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1531,7 +1557,7 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
// printf("after ACKNAK2 c[%d] = %p (iprime %d, G %d)\n",0,ulsch_harq->c[0],iprime,G); // printf("after ACKNAK2 c[%d] = %p (iprime %d, G %d)\n",0,ulsch_harq->c[0],iprime,G);
// Do CQI/RI/HARQ-ACK Decoding first and pass to MAC // Do CQI/RI/HARQ-ACK Decoding first and pass to MAC
/*
// HARQ-ACK // HARQ-ACK
wACK_idx = (ulsch->bundling==0) ? 4 : ((Nbundled-1)&3); wACK_idx = (ulsch->bundling==0) ? 4 : ((Nbundled-1)&3);
...@@ -1553,16 +1579,16 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1553,16 +1579,16 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[4]*wACK_RX_NB_IoT[wACK_idx][1]; ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[4]*wACK_RX_NB_IoT[wACK_idx][1];
ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[2]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[5]*wACK_RX_NB_IoT[wACK_idx][1]; ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[2]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[5]*wACK_RX_NB_IoT[wACK_idx][1];
break; break;
case 4: // case 4:
ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[5]*wACK_RX_NB_IoT[wACK_idx][1]; // ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[5]*wACK_RX_NB_IoT[wACK_idx][1];
ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[8]*wACK_RX_NB_IoT[wACK_idx][1]; // ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[8]*wACK_RX_NB_IoT[wACK_idx][1];
ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[4]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[9]*wACK_RX_NB_IoT[wACK_idx][1]; // ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[4]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[9]*wACK_RX_NB_IoT[wACK_idx][1];
break; // break;
case 6: // case 6:
ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[7]*wACK_RX_NB_IoT[wACK_idx][1]; // ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[7]*wACK_RX_NB_IoT[wACK_idx][1];
ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[12]*wACK_RX_NB_IoT[wACK_idx][1]; // ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[12]*wACK_RX_NB_IoT[wACK_idx][1];
ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[6]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[13]*wACK_RX_NB_IoT[wACK_idx][1]; // ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[6]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[13]*wACK_RX_NB_IoT[wACK_idx][1];
break; // break;
} }
ulsch_harq->o_ACK[0] = 1; ulsch_harq->o_ACK[0] = 1;
...@@ -1659,7 +1685,7 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1659,7 +1685,7 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
#endif #endif
} }
*/
// Do ULSCH Decoding for data portion // Do ULSCH Decoding for data portion
ret = eNB->td(eNB,UE_id,harq_pid,llr8_flag); ret = eNB->td(eNB,UE_id,harq_pid,llr8_flag);
...@@ -1668,6 +1694,8 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1668,6 +1694,8 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
return(ret); return(ret);
} }
/* /*
#ifdef PHY_ABSTRACTION #ifdef PHY_ABSTRACTION
......
...@@ -68,7 +68,7 @@ void lte_idft_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Ms ...@@ -68,7 +68,7 @@ void lte_idft_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Ms
// printf("Doing lte_idft for Msc_PUSCH %d\n",Msc_PUSCH); // printf("Doing lte_idft for Msc_PUSCH %d\n",Msc_PUSCH);
if (frame_parms->Ncp == 0) { // Normal prefix // Normal prefix
z0 = z; z0 = z;
z1 = z0+(frame_parms->N_RB_DL*12); z1 = z0+(frame_parms->N_RB_DL*12);
z2 = z1+(frame_parms->N_RB_DL*12); z2 = z1+(frame_parms->N_RB_DL*12);
...@@ -85,22 +85,6 @@ void lte_idft_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Ms ...@@ -85,22 +85,6 @@ void lte_idft_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Ms
z10 = z9+(frame_parms->N_RB_DL*12); z10 = z9+(frame_parms->N_RB_DL*12);
// srs // srs
z11 = z10+(frame_parms->N_RB_DL*12); z11 = z10+(frame_parms->N_RB_DL*12);
} else { // extended prefix
z0 = z;
z1 = z0+(frame_parms->N_RB_DL*12);
//pilot
z2 = z1+(2*frame_parms->N_RB_DL*12);
z3 = z2+(frame_parms->N_RB_DL*12);
z4 = z3+(frame_parms->N_RB_DL*12);
z5 = z4+(frame_parms->N_RB_DL*12);
z6 = z5+(frame_parms->N_RB_DL*12);
//pilot
z7 = z6+(2*frame_parms->N_RB_DL*12);
z8 = z7+(frame_parms->N_RB_DL*12);
// srs
z9 = z8+(frame_parms->N_RB_DL*12);
}
// conjugate input // conjugate input
for (i=0; i<(Msc_PUSCH>>2); i++) { for (i=0; i<(Msc_PUSCH>>2); i++) {
...@@ -185,197 +169,197 @@ void lte_idft_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Ms ...@@ -185,197 +169,197 @@ void lte_idft_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Ms
break; break;
case 24: // case 24:
dft24(idft_in0,idft_out0,1); // dft24(idft_in0,idft_out0,1);
dft24(idft_in1,idft_out1,1); // dft24(idft_in1,idft_out1,1);
dft24(idft_in2,idft_out2,1); // dft24(idft_in2,idft_out2,1);
break; // break;
case 36: // case 36:
dft36(idft_in0,idft_out0,1); // dft36(idft_in0,idft_out0,1);
dft36(idft_in1,idft_out1,1); // dft36(idft_in1,idft_out1,1);
dft36(idft_in2,idft_out2,1); // dft36(idft_in2,idft_out2,1);
break; // break;
case 48: // case 48:
dft48(idft_in0,idft_out0,1); // dft48(idft_in0,idft_out0,1);
dft48(idft_in1,idft_out1,1); // dft48(idft_in1,idft_out1,1);
dft48(idft_in2,idft_out2,1); // dft48(idft_in2,idft_out2,1);
break; // break;
case 60: // case 60:
dft60(idft_in0,idft_out0,1); // dft60(idft_in0,idft_out0,1);
dft60(idft_in1,idft_out1,1); // dft60(idft_in1,idft_out1,1);
dft60(idft_in2,idft_out2,1); // dft60(idft_in2,idft_out2,1);
break; // break;
case 72: // case 72:
dft72(idft_in0,idft_out0,1); // dft72(idft_in0,idft_out0,1);
dft72(idft_in1,idft_out1,1); // dft72(idft_in1,idft_out1,1);
dft72(idft_in2,idft_out2,1); // dft72(idft_in2,idft_out2,1);
break; // break;
case 96: // case 96:
dft96(idft_in0,idft_out0,1); // dft96(idft_in0,idft_out0,1);
dft96(idft_in1,idft_out1,1); // dft96(idft_in1,idft_out1,1);
dft96(idft_in2,idft_out2,1); // dft96(idft_in2,idft_out2,1);
break; // break;
case 108: // case 108:
dft108(idft_in0,idft_out0,1); // dft108(idft_in0,idft_out0,1);
dft108(idft_in1,idft_out1,1); // dft108(idft_in1,idft_out1,1);
dft108(idft_in2,idft_out2,1); // dft108(idft_in2,idft_out2,1);
break; // break;
case 120: // case 120:
dft120(idft_in0,idft_out0,1); // dft120(idft_in0,idft_out0,1);
dft120(idft_in1,idft_out1,1); // dft120(idft_in1,idft_out1,1);
dft120(idft_in2,idft_out2,1); // dft120(idft_in2,idft_out2,1);
break; // break;
case 144: // case 144:
dft144(idft_in0,idft_out0,1); // dft144(idft_in0,idft_out0,1);
dft144(idft_in1,idft_out1,1); // dft144(idft_in1,idft_out1,1);
dft144(idft_in2,idft_out2,1); // dft144(idft_in2,idft_out2,1);
break; // break;
case 180: // case 180:
dft180(idft_in0,idft_out0,1); // dft180(idft_in0,idft_out0,1);
dft180(idft_in1,idft_out1,1); // dft180(idft_in1,idft_out1,1);
dft180(idft_in2,idft_out2,1); // dft180(idft_in2,idft_out2,1);
break; // break;
case 192: // case 192:
dft192(idft_in0,idft_out0,1); // dft192(idft_in0,idft_out0,1);
dft192(idft_in1,idft_out1,1); // dft192(idft_in1,idft_out1,1);
dft192(idft_in2,idft_out2,1); // dft192(idft_in2,idft_out2,1);
break; // break;
case 216: // case 216:
dft216(idft_in0,idft_out0,1); // dft216(idft_in0,idft_out0,1);
dft216(idft_in1,idft_out1,1); // dft216(idft_in1,idft_out1,1);
dft216(idft_in2,idft_out2,1); // dft216(idft_in2,idft_out2,1);
break; // break;
case 240: // case 240:
dft240(idft_in0,idft_out0,1); // dft240(idft_in0,idft_out0,1);
dft240(idft_in1,idft_out1,1); // dft240(idft_in1,idft_out1,1);
dft240(idft_in2,idft_out2,1); // dft240(idft_in2,idft_out2,1);
break; // break;
case 288: // case 288:
dft288(idft_in0,idft_out0,1); // dft288(idft_in0,idft_out0,1);
dft288(idft_in1,idft_out1,1); // dft288(idft_in1,idft_out1,1);
dft288(idft_in2,idft_out2,1); // dft288(idft_in2,idft_out2,1);
break; // break;
case 300: // case 300:
dft300(idft_in0,idft_out0,1); // dft300(idft_in0,idft_out0,1);
dft300(idft_in1,idft_out1,1); // dft300(idft_in1,idft_out1,1);
dft300(idft_in2,idft_out2,1); // dft300(idft_in2,idft_out2,1);
break; // break;
case 324: // case 324:
dft324((int16_t*)idft_in0,(int16_t*)idft_out0,1); // dft324((int16_t*)idft_in0,(int16_t*)idft_out0,1);
dft324((int16_t*)idft_in1,(int16_t*)idft_out1,1); // dft324((int16_t*)idft_in1,(int16_t*)idft_out1,1);
dft324((int16_t*)idft_in2,(int16_t*)idft_out2,1); // dft324((int16_t*)idft_in2,(int16_t*)idft_out2,1);
break; // break;
case 360: // case 360:
dft360((int16_t*)idft_in0,(int16_t*)idft_out0,1); // dft360((int16_t*)idft_in0,(int16_t*)idft_out0,1);
dft360((int16_t*)idft_in1,(int16_t*)idft_out1,1); // dft360((int16_t*)idft_in1,(int16_t*)idft_out1,1);
dft360((int16_t*)idft_in2,(int16_t*)idft_out2,1); // dft360((int16_t*)idft_in2,(int16_t*)idft_out2,1);
break; // break;
case 384: // case 384:
dft384((int16_t*)idft_in0,(int16_t*)idft_out0,1); // dft384((int16_t*)idft_in0,(int16_t*)idft_out0,1);
dft384((int16_t*)idft_in1,(int16_t*)idft_out1,1); // dft384((int16_t*)idft_in1,(int16_t*)idft_out1,1);
dft384((int16_t*)idft_in2,(int16_t*)idft_out2,1); // dft384((int16_t*)idft_in2,(int16_t*)idft_out2,1);
break; // break;
case 432: // case 432:
dft432((int16_t*)idft_in0,(int16_t*)idft_out0,1); // dft432((int16_t*)idft_in0,(int16_t*)idft_out0,1);
dft432((int16_t*)idft_in1,(int16_t*)idft_out1,1); // dft432((int16_t*)idft_in1,(int16_t*)idft_out1,1);
dft432((int16_t*)idft_in2,(int16_t*)idft_out2,1); // dft432((int16_t*)idft_in2,(int16_t*)idft_out2,1);
break; // break;
case 480: // case 480:
dft480((int16_t*)idft_in0,(int16_t*)idft_out0,1); // dft480((int16_t*)idft_in0,(int16_t*)idft_out0,1);
dft480((int16_t*)idft_in1,(int16_t*)idft_out1,1); // dft480((int16_t*)idft_in1,(int16_t*)idft_out1,1);
dft480((int16_t*)idft_in2,(int16_t*)idft_out2,1); // dft480((int16_t*)idft_in2,(int16_t*)idft_out2,1);
break; // break;
case 540: // case 540:
dft540((int16_t*)idft_in0,(int16_t*)idft_out0,1); // dft540((int16_t*)idft_in0,(int16_t*)idft_out0,1);
dft540((int16_t*)idft_in1,(int16_t*)idft_out1,1); // dft540((int16_t*)idft_in1,(int16_t*)idft_out1,1);
dft540((int16_t*)idft_in2,(int16_t*)idft_out2,1); // dft540((int16_t*)idft_in2,(int16_t*)idft_out2,1);
break; // break;
case 576: // case 576:
dft576((int16_t*)idft_in0,(int16_t*)idft_out0,1); // dft576((int16_t*)idft_in0,(int16_t*)idft_out0,1);
dft576((int16_t*)idft_in1,(int16_t*)idft_out1,1); // dft576((int16_t*)idft_in1,(int16_t*)idft_out1,1);
dft576((int16_t*)idft_in2,(int16_t*)idft_out2,1); // dft576((int16_t*)idft_in2,(int16_t*)idft_out2,1);
break; // break;
case 600: // case 600:
dft600((int16_t*)idft_in0,(int16_t*)idft_out0,1); // dft600((int16_t*)idft_in0,(int16_t*)idft_out0,1);
dft600((int16_t*)idft_in1,(int16_t*)idft_out1,1); // dft600((int16_t*)idft_in1,(int16_t*)idft_out1,1);
dft600((int16_t*)idft_in2,(int16_t*)idft_out2,1); // dft600((int16_t*)idft_in2,(int16_t*)idft_out2,1);
break; // break;
case 648: // case 648:
dft648((int16_t*)idft_in0,(int16_t*)idft_out0,1); // dft648((int16_t*)idft_in0,(int16_t*)idft_out0,1);
dft648((int16_t*)idft_in1,(int16_t*)idft_out1,1); // dft648((int16_t*)idft_in1,(int16_t*)idft_out1,1);
dft648((int16_t*)idft_in2,(int16_t*)idft_out2,1); // dft648((int16_t*)idft_in2,(int16_t*)idft_out2,1);
break; // break;
case 720: // case 720:
dft720((int16_t*)idft_in0,(int16_t*)idft_out0,1); // dft720((int16_t*)idft_in0,(int16_t*)idft_out0,1);
dft720((int16_t*)idft_in1,(int16_t*)idft_out1,1); // dft720((int16_t*)idft_in1,(int16_t*)idft_out1,1);
dft720((int16_t*)idft_in2,(int16_t*)idft_out2,1); // dft720((int16_t*)idft_in2,(int16_t*)idft_out2,1);
break; // break;
case 864: // case 864:
dft864((int16_t*)idft_in0,(int16_t*)idft_out0,1); // dft864((int16_t*)idft_in0,(int16_t*)idft_out0,1);
dft864((int16_t*)idft_in1,(int16_t*)idft_out1,1); // dft864((int16_t*)idft_in1,(int16_t*)idft_out1,1);
dft864((int16_t*)idft_in2,(int16_t*)idft_out2,1); // dft864((int16_t*)idft_in2,(int16_t*)idft_out2,1);
break; // break;
case 900: // case 900:
dft900((int16_t*)idft_in0,(int16_t*)idft_out0,1); // dft900((int16_t*)idft_in0,(int16_t*)idft_out0,1);
dft900((int16_t*)idft_in1,(int16_t*)idft_out1,1); // dft900((int16_t*)idft_in1,(int16_t*)idft_out1,1);
dft900((int16_t*)idft_in2,(int16_t*)idft_out2,1); // dft900((int16_t*)idft_in2,(int16_t*)idft_out2,1);
break; // break;
case 960: // case 960:
dft960((int16_t*)idft_in0,(int16_t*)idft_out0,1); // dft960((int16_t*)idft_in0,(int16_t*)idft_out0,1);
dft960((int16_t*)idft_in1,(int16_t*)idft_out1,1); // dft960((int16_t*)idft_in1,(int16_t*)idft_out1,1);
dft960((int16_t*)idft_in2,(int16_t*)idft_out2,1); // dft960((int16_t*)idft_in2,(int16_t*)idft_out2,1);
break; // break;
case 972: // case 972:
dft972((int16_t*)idft_in0,(int16_t*)idft_out0,1); // dft972((int16_t*)idft_in0,(int16_t*)idft_out0,1);
dft972((int16_t*)idft_in1,(int16_t*)idft_out1,1); // dft972((int16_t*)idft_in1,(int16_t*)idft_out1,1);
dft972((int16_t*)idft_in2,(int16_t*)idft_out2,1); // dft972((int16_t*)idft_in2,(int16_t*)idft_out2,1);
break; // break;
case 1080: // case 1080:
dft1080((int16_t*)idft_in0,(int16_t*)idft_out0,1); // dft1080((int16_t*)idft_in0,(int16_t*)idft_out0,1);
dft1080((int16_t*)idft_in1,(int16_t*)idft_out1,1); // dft1080((int16_t*)idft_in1,(int16_t*)idft_out1,1);
dft1080((int16_t*)idft_in2,(int16_t*)idft_out2,1); // dft1080((int16_t*)idft_in2,(int16_t*)idft_out2,1);
break; // break;
case 1152: // case 1152:
dft1152((int16_t*)idft_in0,(int16_t*)idft_out0,1); // dft1152((int16_t*)idft_in0,(int16_t*)idft_out0,1);
dft1152((int16_t*)idft_in1,(int16_t*)idft_out1,1); // dft1152((int16_t*)idft_in1,(int16_t*)idft_out1,1);
dft1152((int16_t*)idft_in2,(int16_t*)idft_out2,1); // dft1152((int16_t*)idft_in2,(int16_t*)idft_out2,1);
break; // break;
case 1200: // case 1200:
dft1200(idft_in0,idft_out0,1); // dft1200(idft_in0,idft_out0,1);
dft1200(idft_in1,idft_out1,1); // dft1200(idft_in1,idft_out1,1);
dft1200(idft_in2,idft_out2,1); // dft1200(idft_in2,idft_out2,1);
break; // break;
default: default:
// should not be reached // should not be reached
...@@ -952,299 +936,299 @@ void ulsch_channel_compensation_NB_IoT(int32_t **rxdataF_ext, ...@@ -952,299 +936,299 @@ void ulsch_channel_compensation_NB_IoT(int32_t **rxdataF_ext,
#if defined(__x86_64__) || defined(__i386__) // #if defined(__x86_64__) || defined(__i386__)
__m128i QAM_amp128U_0,QAM_amp128bU_0,QAM_amp128U_1,QAM_amp128bU_1; // __m128i QAM_amp128U_0,QAM_amp128bU_0,QAM_amp128U_1,QAM_amp128bU_1;
#endif // #endif
void ulsch_channel_compensation_alamouti_NB_IoT(int32_t **rxdataF_ext, // For Distributed Alamouti Combining
int32_t **ul_ch_estimates_ext_0,
int32_t **ul_ch_estimates_ext_1,
int32_t **ul_ch_mag_0,
int32_t **ul_ch_magb_0,
int32_t **ul_ch_mag_1,
int32_t **ul_ch_magb_1,
int32_t **rxdataF_comp_0,
int32_t **rxdataF_comp_1,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t symbol,
uint8_t Qm,
uint16_t nb_rb,
uint8_t output_shift)
{
#if defined(__x86_64__) || defined(__i386__)
uint16_t rb;
__m128i *ul_ch128_0,*ul_ch128_1,*ul_ch_mag128_0,*ul_ch_mag128_1,*ul_ch_mag128b_0,*ul_ch_mag128b_1,*rxdataF128,*rxdataF_comp128_0,*rxdataF_comp128_1;
uint8_t aarx;//,symbol_mod;
__m128i mmtmpU0,mmtmpU1,mmtmpU2,mmtmpU3;
// symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
// printf("comp: symbol %d\n",symbol);
if (Qm == 4) {
QAM_amp128U_0 = _mm_set1_epi16(QAM16_n1);
QAM_amp128U_1 = _mm_set1_epi16(QAM16_n1);
} else if (Qm == 6) {
QAM_amp128U_0 = _mm_set1_epi16(QAM64_n1);
QAM_amp128bU_0 = _mm_set1_epi16(QAM64_n2);
QAM_amp128U_1 = _mm_set1_epi16(QAM64_n1); // void ulsch_channel_compensation_alamouti_NB_IoT(int32_t **rxdataF_ext, // For Distributed Alamouti Combining
QAM_amp128bU_1 = _mm_set1_epi16(QAM64_n2); // int32_t **ul_ch_estimates_ext_0,
} // int32_t **ul_ch_estimates_ext_1,
// int32_t **ul_ch_mag_0,
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { // int32_t **ul_ch_magb_0,
// int32_t **ul_ch_mag_1,
ul_ch128_0 = (__m128i *)&ul_ch_estimates_ext_0[aarx][symbol*frame_parms->N_RB_DL*12]; // int32_t **ul_ch_magb_1,
ul_ch_mag128_0 = (__m128i *)&ul_ch_mag_0[aarx][symbol*frame_parms->N_RB_DL*12]; // int32_t **rxdataF_comp_0,
ul_ch_mag128b_0 = (__m128i *)&ul_ch_magb_0[aarx][symbol*frame_parms->N_RB_DL*12]; // int32_t **rxdataF_comp_1,
ul_ch128_1 = (__m128i *)&ul_ch_estimates_ext_1[aarx][symbol*frame_parms->N_RB_DL*12]; // NB_IoT_DL_FRAME_PARMS *frame_parms,
ul_ch_mag128_1 = (__m128i *)&ul_ch_mag_1[aarx][symbol*frame_parms->N_RB_DL*12]; // uint8_t symbol,
ul_ch_mag128b_1 = (__m128i *)&ul_ch_magb_1[aarx][symbol*frame_parms->N_RB_DL*12]; // uint8_t Qm,
rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; // uint16_t nb_rb,
rxdataF_comp128_0 = (__m128i *)&rxdataF_comp_0[aarx][symbol*frame_parms->N_RB_DL*12]; // uint8_t output_shift)
rxdataF_comp128_1 = (__m128i *)&rxdataF_comp_1[aarx][symbol*frame_parms->N_RB_DL*12]; // {
// #if defined(__x86_64__) || defined(__i386__)
// uint16_t rb;
for (rb=0; rb<nb_rb; rb++) { // __m128i *ul_ch128_0,*ul_ch128_1,*ul_ch_mag128_0,*ul_ch_mag128_1,*ul_ch_mag128b_0,*ul_ch_mag128b_1,*rxdataF128,*rxdataF_comp128_0,*rxdataF_comp128_1;
// printf("comp: symbol %d rb %d\n",symbol,rb); // uint8_t aarx;//,symbol_mod;
if (Qm>2) { // __m128i mmtmpU0,mmtmpU1,mmtmpU2,mmtmpU3;
// get channel amplitude if not QPSK
mmtmpU0 = _mm_madd_epi16(ul_ch128_0[0],ul_ch128_0[0]);
mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
mmtmpU1 = _mm_madd_epi16(ul_ch128_0[1],ul_ch128_0[1]);
mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
mmtmpU0 = _mm_packs_epi32(mmtmpU0,mmtmpU1);
ul_ch_mag128_0[0] = _mm_unpacklo_epi16(mmtmpU0,mmtmpU0);
ul_ch_mag128b_0[0] = ul_ch_mag128_0[0];
ul_ch_mag128_0[0] = _mm_mulhi_epi16(ul_ch_mag128_0[0],QAM_amp128U_0);
ul_ch_mag128_0[0] = _mm_slli_epi16(ul_ch_mag128_0[0],2); // 2 to compensate the scale channel estimate
ul_ch_mag128_0[1] = _mm_unpackhi_epi16(mmtmpU0,mmtmpU0); // // symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
ul_ch_mag128b_0[1] = ul_ch_mag128_0[1];
ul_ch_mag128_0[1] = _mm_mulhi_epi16(ul_ch_mag128_0[1],QAM_amp128U_0);
ul_ch_mag128_0[1] = _mm_slli_epi16(ul_ch_mag128_0[1],2); // 2 to scale compensate the scale channel estimate
mmtmpU0 = _mm_madd_epi16(ul_ch128_0[2],ul_ch128_0[2]);
mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
mmtmpU1 = _mm_packs_epi32(mmtmpU0,mmtmpU0);
ul_ch_mag128_0[2] = _mm_unpacklo_epi16(mmtmpU1,mmtmpU1); // // printf("comp: symbol %d\n",symbol);
ul_ch_mag128b_0[2] = ul_ch_mag128_0[2];
ul_ch_mag128_0[2] = _mm_mulhi_epi16(ul_ch_mag128_0[2],QAM_amp128U_0);
ul_ch_mag128_0[2] = _mm_slli_epi16(ul_ch_mag128_0[2],2); // 2 to scale compensate the scale channel estimat
// if (Qm == 4) {
// QAM_amp128U_0 = _mm_set1_epi16(QAM16_n1);
// QAM_amp128U_1 = _mm_set1_epi16(QAM16_n1);
// } else if (Qm == 6) {
// QAM_amp128U_0 = _mm_set1_epi16(QAM64_n1);
// QAM_amp128bU_0 = _mm_set1_epi16(QAM64_n2);
ul_ch_mag128b_0[0] = _mm_mulhi_epi16(ul_ch_mag128b_0[0],QAM_amp128bU_0); // QAM_amp128U_1 = _mm_set1_epi16(QAM64_n1);
ul_ch_mag128b_0[0] = _mm_slli_epi16(ul_ch_mag128b_0[0],2); // 2 to scale compensate the scale channel estima // QAM_amp128bU_1 = _mm_set1_epi16(QAM64_n2);
// }
// for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
ul_ch_mag128b_0[1] = _mm_mulhi_epi16(ul_ch_mag128b_0[1],QAM_amp128bU_0); // ul_ch128_0 = (__m128i *)&ul_ch_estimates_ext_0[aarx][symbol*frame_parms->N_RB_DL*12];
ul_ch_mag128b_0[1] = _mm_slli_epi16(ul_ch_mag128b_0[1],2); // 2 to scale compensate the scale channel estima // ul_ch_mag128_0 = (__m128i *)&ul_ch_mag_0[aarx][symbol*frame_parms->N_RB_DL*12];
// ul_ch_mag128b_0 = (__m128i *)&ul_ch_magb_0[aarx][symbol*frame_parms->N_RB_DL*12];
// ul_ch128_1 = (__m128i *)&ul_ch_estimates_ext_1[aarx][symbol*frame_parms->N_RB_DL*12];
// ul_ch_mag128_1 = (__m128i *)&ul_ch_mag_1[aarx][symbol*frame_parms->N_RB_DL*12];
// ul_ch_mag128b_1 = (__m128i *)&ul_ch_magb_1[aarx][symbol*frame_parms->N_RB_DL*12];
// rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
// rxdataF_comp128_0 = (__m128i *)&rxdataF_comp_0[aarx][symbol*frame_parms->N_RB_DL*12];
// rxdataF_comp128_1 = (__m128i *)&rxdataF_comp_1[aarx][symbol*frame_parms->N_RB_DL*12];
ul_ch_mag128b_0[2] = _mm_mulhi_epi16(ul_ch_mag128b_0[2],QAM_amp128bU_0);
ul_ch_mag128b_0[2] = _mm_slli_epi16(ul_ch_mag128b_0[2],2); // 2 to scale compensate the scale channel estima
// for (rb=0; rb<nb_rb; rb++) {
// // printf("comp: symbol %d rb %d\n",symbol,rb);
// if (Qm>2) {
// // get channel amplitude if not QPSK
// mmtmpU0 = _mm_madd_epi16(ul_ch128_0[0],ul_ch128_0[0]);
// mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
mmtmpU0 = _mm_madd_epi16(ul_ch128_1[0],ul_ch128_1[0]); // mmtmpU1 = _mm_madd_epi16(ul_ch128_0[1],ul_ch128_0[1]);
// mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
// mmtmpU0 = _mm_packs_epi32(mmtmpU0,mmtmpU1);
mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift); // ul_ch_mag128_0[0] = _mm_unpacklo_epi16(mmtmpU0,mmtmpU0);
// ul_ch_mag128b_0[0] = ul_ch_mag128_0[0];
// ul_ch_mag128_0[0] = _mm_mulhi_epi16(ul_ch_mag128_0[0],QAM_amp128U_0);
// ul_ch_mag128_0[0] = _mm_slli_epi16(ul_ch_mag128_0[0],2); // 2 to compensate the scale channel estimate
mmtmpU1 = _mm_madd_epi16(ul_ch128_1[1],ul_ch128_1[1]); // ul_ch_mag128_0[1] = _mm_unpackhi_epi16(mmtmpU0,mmtmpU0);
mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift); // ul_ch_mag128b_0[1] = ul_ch_mag128_0[1];
mmtmpU0 = _mm_packs_epi32(mmtmpU0,mmtmpU1); // ul_ch_mag128_0[1] = _mm_mulhi_epi16(ul_ch_mag128_0[1],QAM_amp128U_0);
// ul_ch_mag128_0[1] = _mm_slli_epi16(ul_ch_mag128_0[1],2); // 2 to scale compensate the scale channel estimate
ul_ch_mag128_1[0] = _mm_unpacklo_epi16(mmtmpU0,mmtmpU0); // mmtmpU0 = _mm_madd_epi16(ul_ch128_0[2],ul_ch128_0[2]);
ul_ch_mag128b_1[0] = ul_ch_mag128_1[0]; // mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
ul_ch_mag128_1[0] = _mm_mulhi_epi16(ul_ch_mag128_1[0],QAM_amp128U_1); // mmtmpU1 = _mm_packs_epi32(mmtmpU0,mmtmpU0);
ul_ch_mag128_1[0] = _mm_slli_epi16(ul_ch_mag128_1[0],2); // 2 to compensate the scale channel estimate
ul_ch_mag128_1[1] = _mm_unpackhi_epi16(mmtmpU0,mmtmpU0); // ul_ch_mag128_0[2] = _mm_unpacklo_epi16(mmtmpU1,mmtmpU1);
ul_ch_mag128b_1[1] = ul_ch_mag128_1[1]; // ul_ch_mag128b_0[2] = ul_ch_mag128_0[2];
ul_ch_mag128_1[1] = _mm_mulhi_epi16(ul_ch_mag128_1[1],QAM_amp128U_1);
ul_ch_mag128_1[1] = _mm_slli_epi16(ul_ch_mag128_1[1],2); // 2 to scale compensate the scale channel estimate
mmtmpU0 = _mm_madd_epi16(ul_ch128_1[2],ul_ch128_1[2]); // ul_ch_mag128_0[2] = _mm_mulhi_epi16(ul_ch_mag128_0[2],QAM_amp128U_0);
mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift); // ul_ch_mag128_0[2] = _mm_slli_epi16(ul_ch_mag128_0[2],2); // 2 to scale compensate the scale channel estimat
mmtmpU1 = _mm_packs_epi32(mmtmpU0,mmtmpU0);
ul_ch_mag128_1[2] = _mm_unpacklo_epi16(mmtmpU1,mmtmpU1);
ul_ch_mag128b_1[2] = ul_ch_mag128_1[2];
ul_ch_mag128_1[2] = _mm_mulhi_epi16(ul_ch_mag128_1[2],QAM_amp128U_0); // ul_ch_mag128b_0[0] = _mm_mulhi_epi16(ul_ch_mag128b_0[0],QAM_amp128bU_0);
ul_ch_mag128_1[2] = _mm_slli_epi16(ul_ch_mag128_1[2],2); // 2 to scale compensate the scale channel estimat // ul_ch_mag128b_0[0] = _mm_slli_epi16(ul_ch_mag128b_0[0],2); // 2 to scale compensate the scale channel estima
ul_ch_mag128b_1[0] = _mm_mulhi_epi16(ul_ch_mag128b_1[0],QAM_amp128bU_1); // ul_ch_mag128b_0[1] = _mm_mulhi_epi16(ul_ch_mag128b_0[1],QAM_amp128bU_0);
ul_ch_mag128b_1[0] = _mm_slli_epi16(ul_ch_mag128b_1[0],2); // 2 to scale compensate the scale channel estima // ul_ch_mag128b_0[1] = _mm_slli_epi16(ul_ch_mag128b_0[1],2); // 2 to scale compensate the scale channel estima
// ul_ch_mag128b_0[2] = _mm_mulhi_epi16(ul_ch_mag128b_0[2],QAM_amp128bU_0);
// ul_ch_mag128b_0[2] = _mm_slli_epi16(ul_ch_mag128b_0[2],2); // 2 to scale compensate the scale channel estima
// mmtmpU0 = _mm_madd_epi16(ul_ch128_1[0],ul_ch128_1[0]);
// mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
// mmtmpU1 = _mm_madd_epi16(ul_ch128_1[1],ul_ch128_1[1]);
// mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
// mmtmpU0 = _mm_packs_epi32(mmtmpU0,mmtmpU1);
// ul_ch_mag128_1[0] = _mm_unpacklo_epi16(mmtmpU0,mmtmpU0);
// ul_ch_mag128b_1[0] = ul_ch_mag128_1[0];
// ul_ch_mag128_1[0] = _mm_mulhi_epi16(ul_ch_mag128_1[0],QAM_amp128U_1);
// ul_ch_mag128_1[0] = _mm_slli_epi16(ul_ch_mag128_1[0],2); // 2 to compensate the scale channel estimate
ul_ch_mag128b_1[1] = _mm_mulhi_epi16(ul_ch_mag128b_1[1],QAM_amp128bU_1); // ul_ch_mag128_1[1] = _mm_unpackhi_epi16(mmtmpU0,mmtmpU0);
ul_ch_mag128b_1[1] = _mm_slli_epi16(ul_ch_mag128b_1[1],2); // 2 to scale compensate the scale channel estima // ul_ch_mag128b_1[1] = ul_ch_mag128_1[1];
// ul_ch_mag128_1[1] = _mm_mulhi_epi16(ul_ch_mag128_1[1],QAM_amp128U_1);
// ul_ch_mag128_1[1] = _mm_slli_epi16(ul_ch_mag128_1[1],2); // 2 to scale compensate the scale channel estimate
ul_ch_mag128b_1[2] = _mm_mulhi_epi16(ul_ch_mag128b_1[2],QAM_amp128bU_1); // mmtmpU0 = _mm_madd_epi16(ul_ch128_1[2],ul_ch128_1[2]);
ul_ch_mag128b_1[2] = _mm_slli_epi16(ul_ch_mag128b_1[2],2); // 2 to scale compensate the scale channel estima // mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
} // mmtmpU1 = _mm_packs_epi32(mmtmpU0,mmtmpU0);
/************************For Computing (y)*(h0*)********************************************/
// multiply by conjugated channel
mmtmpU0 = _mm_madd_epi16(ul_ch128_0[0],rxdataF128[0]);
// print_ints("re",&mmtmpU0);
// mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
mmtmpU1 = _mm_shufflelo_epi16(ul_ch128_0[0],_MM_SHUFFLE(2,3,0,1));
mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)&conjugate[0]);
// print_ints("im",&mmtmpU1);
mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[0]);
// mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
// print_ints("re(shift)",&mmtmpU0);
mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
// print_ints("im(shift)",&mmtmpU1);
mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
// print_ints("c0",&mmtmpU2);
// print_ints("c1",&mmtmpU3);
rxdataF_comp128_0[0] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// print_shorts("rx:",rxdataF128[0]);
// print_shorts("ch:",ul_ch128_0[0]);
// print_shorts("pack:",rxdataF_comp128_0[0]);
// multiply by conjugated channel
mmtmpU0 = _mm_madd_epi16(ul_ch128_0[1],rxdataF128[1]);
// mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
mmtmpU1 = _mm_shufflelo_epi16(ul_ch128_0[1],_MM_SHUFFLE(2,3,0,1));
mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate);
mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[1]);
// mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
rxdataF_comp128_0[1] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// print_shorts("rx:",rxdataF128[1]);
// print_shorts("ch:",ul_ch128_0[1]);
// print_shorts("pack:",rxdataF_comp128_0[1]);
// multiply by conjugated channel
mmtmpU0 = _mm_madd_epi16(ul_ch128_0[2],rxdataF128[2]);
// mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
mmtmpU1 = _mm_shufflelo_epi16(ul_ch128_0[2],_MM_SHUFFLE(2,3,0,1));
mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate);
mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[2]);
// mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
rxdataF_comp128_0[2] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// print_shorts("rx:",rxdataF128[2]);
// print_shorts("ch:",ul_ch128_0[2]);
// print_shorts("pack:",rxdataF_comp128_0[2]);
/*************************For Computing (y*)*(h1)************************************/
// multiply by conjugated signal
mmtmpU0 = _mm_madd_epi16(ul_ch128_1[0],rxdataF128[0]);
// print_ints("re",&mmtmpU0);
// mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
mmtmpU1 = _mm_shufflelo_epi16(rxdataF128[0],_MM_SHUFFLE(2,3,0,1));
mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)&conjugate[0]);
// print_ints("im",&mmtmpU1);
mmtmpU1 = _mm_madd_epi16(mmtmpU1,ul_ch128_1[0]);
// mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
// print_ints("re(shift)",&mmtmpU0);
mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
// print_ints("im(shift)",&mmtmpU1);
mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
// print_ints("c0",&mmtmpU2);
// print_ints("c1",&mmtmpU3);
rxdataF_comp128_1[0] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// print_shorts("rx:",rxdataF128[0]);
// print_shorts("ch_conjugate:",ul_ch128_1[0]);
// print_shorts("pack:",rxdataF_comp128_1[0]);
// multiply by conjugated signal
mmtmpU0 = _mm_madd_epi16(ul_ch128_1[1],rxdataF128[1]);
// mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
mmtmpU1 = _mm_shufflelo_epi16(rxdataF128[1],_MM_SHUFFLE(2,3,0,1));
mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate);
mmtmpU1 = _mm_madd_epi16(mmtmpU1,ul_ch128_1[1]);
// mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
rxdataF_comp128_1[1] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// print_shorts("rx:",rxdataF128[1]);
// print_shorts("ch_conjugate:",ul_ch128_1[1]);
// print_shorts("pack:",rxdataF_comp128_1[1]);
// multiply by conjugated signal
mmtmpU0 = _mm_madd_epi16(ul_ch128_1[2],rxdataF128[2]);
// mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
mmtmpU1 = _mm_shufflelo_epi16(rxdataF128[2],_MM_SHUFFLE(2,3,0,1));
mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate);
mmtmpU1 = _mm_madd_epi16(mmtmpU1,ul_ch128_1[2]);
// mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
rxdataF_comp128_1[2] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// print_shorts("rx:",rxdataF128[2]);
// print_shorts("ch_conjugate:",ul_ch128_0[2]);
// print_shorts("pack:",rxdataF_comp128_1[2]);
ul_ch128_0+=3;
ul_ch_mag128_0+=3;
ul_ch_mag128b_0+=3;
ul_ch128_1+=3;
ul_ch_mag128_1+=3;
ul_ch_mag128b_1+=3;
rxdataF128+=3;
rxdataF_comp128_0+=3;
rxdataF_comp128_1+=3;
}
}
_mm_empty();
_m_empty();
#endif
}
// ul_ch_mag128_1[2] = _mm_unpacklo_epi16(mmtmpU1,mmtmpU1);
// ul_ch_mag128b_1[2] = ul_ch_mag128_1[2];
// ul_ch_mag128_1[2] = _mm_mulhi_epi16(ul_ch_mag128_1[2],QAM_amp128U_0);
// ul_ch_mag128_1[2] = _mm_slli_epi16(ul_ch_mag128_1[2],2); // 2 to scale compensate the scale channel estimat
// ul_ch_mag128b_1[0] = _mm_mulhi_epi16(ul_ch_mag128b_1[0],QAM_amp128bU_1);
// ul_ch_mag128b_1[0] = _mm_slli_epi16(ul_ch_mag128b_1[0],2); // 2 to scale compensate the scale channel estima
// ul_ch_mag128b_1[1] = _mm_mulhi_epi16(ul_ch_mag128b_1[1],QAM_amp128bU_1);
// ul_ch_mag128b_1[1] = _mm_slli_epi16(ul_ch_mag128b_1[1],2); // 2 to scale compensate the scale channel estima
// ul_ch_mag128b_1[2] = _mm_mulhi_epi16(ul_ch_mag128b_1[2],QAM_amp128bU_1);
// ul_ch_mag128b_1[2] = _mm_slli_epi16(ul_ch_mag128b_1[2],2); // 2 to scale compensate the scale channel estima
// }
// /************************For Computing (y)*(h0*)********************************************/
// // multiply by conjugated channel
// mmtmpU0 = _mm_madd_epi16(ul_ch128_0[0],rxdataF128[0]);
// // print_ints("re",&mmtmpU0);
// // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
// mmtmpU1 = _mm_shufflelo_epi16(ul_ch128_0[0],_MM_SHUFFLE(2,3,0,1));
// mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
// mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)&conjugate[0]);
// // print_ints("im",&mmtmpU1);
// mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[0]);
// // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
// mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
// // print_ints("re(shift)",&mmtmpU0);
// mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
// // print_ints("im(shift)",&mmtmpU1);
// mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
// mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
// // print_ints("c0",&mmtmpU2);
// // print_ints("c1",&mmtmpU3);
// rxdataF_comp128_0[0] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// // print_shorts("rx:",rxdataF128[0]);
// // print_shorts("ch:",ul_ch128_0[0]);
// // print_shorts("pack:",rxdataF_comp128_0[0]);
// // multiply by conjugated channel
// mmtmpU0 = _mm_madd_epi16(ul_ch128_0[1],rxdataF128[1]);
// // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
// mmtmpU1 = _mm_shufflelo_epi16(ul_ch128_0[1],_MM_SHUFFLE(2,3,0,1));
// mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
// mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate);
// mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[1]);
// // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
// mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
// mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
// mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
// mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
// rxdataF_comp128_0[1] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// // print_shorts("rx:",rxdataF128[1]);
// // print_shorts("ch:",ul_ch128_0[1]);
// // print_shorts("pack:",rxdataF_comp128_0[1]);
// // multiply by conjugated channel
// mmtmpU0 = _mm_madd_epi16(ul_ch128_0[2],rxdataF128[2]);
// // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
// mmtmpU1 = _mm_shufflelo_epi16(ul_ch128_0[2],_MM_SHUFFLE(2,3,0,1));
// mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
// mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate);
// mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[2]);
// // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
// mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
// mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
// mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
// mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
// rxdataF_comp128_0[2] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// // print_shorts("rx:",rxdataF128[2]);
// // print_shorts("ch:",ul_ch128_0[2]);
// // print_shorts("pack:",rxdataF_comp128_0[2]);
// /*************************For Computing (y*)*(h1)************************************/
// // multiply by conjugated signal
// mmtmpU0 = _mm_madd_epi16(ul_ch128_1[0],rxdataF128[0]);
// // print_ints("re",&mmtmpU0);
// // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
// mmtmpU1 = _mm_shufflelo_epi16(rxdataF128[0],_MM_SHUFFLE(2,3,0,1));
// mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
// mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)&conjugate[0]);
// // print_ints("im",&mmtmpU1);
// mmtmpU1 = _mm_madd_epi16(mmtmpU1,ul_ch128_1[0]);
// // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
// mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
// // print_ints("re(shift)",&mmtmpU0);
// mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
// // print_ints("im(shift)",&mmtmpU1);
// mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
// mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
// // print_ints("c0",&mmtmpU2);
// // print_ints("c1",&mmtmpU3);
// rxdataF_comp128_1[0] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// // print_shorts("rx:",rxdataF128[0]);
// // print_shorts("ch_conjugate:",ul_ch128_1[0]);
// // print_shorts("pack:",rxdataF_comp128_1[0]);
// // multiply by conjugated signal
// mmtmpU0 = _mm_madd_epi16(ul_ch128_1[1],rxdataF128[1]);
// // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
// mmtmpU1 = _mm_shufflelo_epi16(rxdataF128[1],_MM_SHUFFLE(2,3,0,1));
// mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
// mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate);
// mmtmpU1 = _mm_madd_epi16(mmtmpU1,ul_ch128_1[1]);
// // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
// mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
// mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
// mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
// mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
// rxdataF_comp128_1[1] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// // print_shorts("rx:",rxdataF128[1]);
// // print_shorts("ch_conjugate:",ul_ch128_1[1]);
// // print_shorts("pack:",rxdataF_comp128_1[1]);
// // multiply by conjugated signal
// mmtmpU0 = _mm_madd_epi16(ul_ch128_1[2],rxdataF128[2]);
// // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
// mmtmpU1 = _mm_shufflelo_epi16(rxdataF128[2],_MM_SHUFFLE(2,3,0,1));
// mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
// mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate);
// mmtmpU1 = _mm_madd_epi16(mmtmpU1,ul_ch128_1[2]);
// // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
// mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
// mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
// mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
// mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
// rxdataF_comp128_1[2] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// // print_shorts("rx:",rxdataF128[2]);
// // print_shorts("ch_conjugate:",ul_ch128_0[2]);
// // print_shorts("pack:",rxdataF_comp128_1[2]);
// ul_ch128_0+=3;
// ul_ch_mag128_0+=3;
// ul_ch_mag128b_0+=3;
// ul_ch128_1+=3;
// ul_ch_mag128_1+=3;
// ul_ch_mag128b_1+=3;
// rxdataF128+=3;
// rxdataF_comp128_0+=3;
// rxdataF_comp128_1+=3;
// }
// }
// _mm_empty();
// _m_empty();
// #endif
// }
/*
void ulsch_alamouti_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,// For Distributed Alamouti Receiver Combining void ulsch_alamouti_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,// For Distributed Alamouti Receiver Combining
int32_t **rxdataF_comp, int32_t **rxdataF_comp,
int32_t **rxdataF_comp_0, int32_t **rxdataF_comp_0,
...@@ -1318,7 +1302,7 @@ void ulsch_alamouti_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,// For Distributed ...@@ -1318,7 +1302,7 @@ void ulsch_alamouti_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,// For Distributed
#endif #endif
} }
*/
...@@ -1410,8 +1394,8 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1410,8 +1394,8 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
int32_t avgs; int32_t avgs;
uint8_t log2_maxh = 0,aarx; uint8_t log2_maxh = 0,aarx;
int32_t avgs_0,avgs_1; // int32_t avgs_0,avgs_1;
uint32_t log2_maxh_0 = 0,log2_maxh_1 = 0; // uint32_t log2_maxh_0 = 0,log2_maxh_1 = 0;
uint8_t harq_pid; uint8_t harq_pid;
uint8_t Qm; uint8_t Qm;
...@@ -1420,7 +1404,7 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1420,7 +1404,7 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
int subframe = proc->subframe_rx; int subframe = proc->subframe_rx;
harq_pid = subframe2harq_pid_NB_IoT(frame_parms,proc->frame_rx,subframe); harq_pid = subframe2harq_pid_NB_IoT(frame_parms,proc->frame_rx,subframe);
Qm = get_Qm_ul_NB_IoT(ulsch[UE_id]->harq_process->mcs); Qm = get_Qm_ul_NB_IoT(ulsch[UE_id]->harq_process->mcs,ulsch[UE_id]->harq_process->N_sc_RU);
rx_power_correction = 1; rx_power_correction = 1;
...@@ -1429,7 +1413,7 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1429,7 +1413,7 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
return; return;
} }
for (l=0; l<(frame_parms->symbols_per_tti-ulsch[UE_id]->harq_process->srs_active); l++) { for (l=0; l<frame_parms->symbols_per_tti; l++) {
ulsch_extract_rbs_single_NB_IoT(common_vars->rxdataF[eNB_id], ulsch_extract_rbs_single_NB_IoT(common_vars->rxdataF[eNB_id],
pusch_vars->rxdataF_ext[eNB_id], pusch_vars->rxdataF_ext[eNB_id],
...@@ -1447,21 +1431,21 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1447,21 +1431,21 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
cooperation_flag); cooperation_flag);
} }
if(cooperation_flag == 2) { // if(cooperation_flag == 2) {
for (i=0; i<frame_parms->nb_antennas_rx; i++) { // for (i=0; i<frame_parms->nb_antennas_rx; i++) {
pusch_vars->ulsch_power_0[i] = signal_energy(pusch_vars->drs_ch_estimates_0[eNB_id][i], // pusch_vars->ulsch_power_0[i] = signal_energy(pusch_vars->drs_ch_estimates_0[eNB_id][i],
ulsch[UE_id]->harq_process->nb_rb*12)*rx_power_correction; // ulsch[UE_id]->harq_process->nb_rb*12)*rx_power_correction;
pusch_vars->ulsch_power_1[i] = signal_energy(pusch_vars->drs_ch_estimates_1[eNB_id][i], // pusch_vars->ulsch_power_1[i] = signal_energy(pusch_vars->drs_ch_estimates_1[eNB_id][i],
ulsch[UE_id]->harq_process->nb_rb*12)*rx_power_correction; // ulsch[UE_id]->harq_process->nb_rb*12)*rx_power_correction;
} // }
} else { // } else {
for (i=0; i<frame_parms->nb_antennas_rx; i++) { for (i=0; i<frame_parms->nb_antennas_rx; i++) {
/* /*
pusch_vars->ulsch_power[i] = signal_energy_nodc(pusch_vars->drs_ch_estimates[eNB_id][i], pusch_vars->ulsch_power[i] = signal_energy_nodc(pusch_vars->drs_ch_estimates[eNB_id][i],
ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12)*rx_power_correction; ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12)*rx_power_correction;
*/ */
//////////////////////// NB_IoT: maybe, should be defined for NB-IoT
pusch_vars->ulsch_power[i] = signal_energy_nodc(pusch_vars->drs_ch_estimates[eNB_id][i], pusch_vars->ulsch_power[i] = signal_energy_nodc(pusch_vars->drs_ch_estimates[eNB_id][i],
ulsch[UE_id]->harq_process->nb_rb*12); ulsch[UE_id]->harq_process->nb_rb*12);
...@@ -1471,50 +1455,50 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1471,50 +1455,50 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
ulsch[UE_id]->harq_process->nb_rb*12, pusch_vars->subcarrier_power, rx_power_correction); ulsch[UE_id]->harq_process->nb_rb*12, pusch_vars->subcarrier_power, rx_power_correction);
#endif #endif
} }
} // }
//write_output("rxdataF_ext.m","rxF_ext",pusch_vars->rxdataF_ext[eNB_id][0],300*(frame_parms->symbols_per_tti-ulsch[UE_id]->srs_active),1,1); //write_output("rxdataF_ext.m","rxF_ext",pusch_vars->rxdataF_ext[eNB_id][0],300*(frame_parms->symbols_per_tti-ulsch[UE_id]->srs_active),1,1);
//write_output("ulsch_chest.m","drs_est",pusch_vars->drs_ch_estimates[eNB_id][0],300*(frame_parms->symbols_per_tti-ulsch[UE_id]->srs_active),1,1); //write_output("ulsch_chest.m","drs_est",pusch_vars->drs_ch_estimates[eNB_id][0],300*(frame_parms->symbols_per_tti-ulsch[UE_id]->srs_active),1,1);
if(cooperation_flag == 2) { // if(cooperation_flag == 2) {
ulsch_channel_level_NB_IoT(pusch_vars->drs_ch_estimates_0[eNB_id], // ulsch_channel_level_NB_IoT(pusch_vars->drs_ch_estimates_0[eNB_id],
frame_parms, // frame_parms,
avgU_0, // avgU_0,
ulsch[UE_id]->harq_process->nb_rb); // ulsch[UE_id]->harq_process->nb_rb);
// printf("[ULSCH] avg_0[0] %d\n",avgU_0[0]); // // printf("[ULSCH] avg_0[0] %d\n",avgU_0[0]);
avgs_0 = 0; // avgs_0 = 0;
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) // for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
avgs_0 = cmax(avgs_0,avgU_0[(aarx<<1)]); // avgs_0 = cmax(avgs_0,avgU_0[(aarx<<1)]);
log2_maxh_0 = (log2_approx(avgs_0)/2)+ log2_approx(frame_parms->nb_antennas_rx-1)+3; // log2_maxh_0 = (log2_approx(avgs_0)/2)+ log2_approx(frame_parms->nb_antennas_rx-1)+3;
#ifdef DEBUG_ULSCH // #ifdef DEBUG_ULSCH
printf("[ULSCH] log2_maxh_0 = %d (%d,%d)\n",log2_maxh_0,avgU_0[0],avgs_0); // printf("[ULSCH] log2_maxh_0 = %d (%d,%d)\n",log2_maxh_0,avgU_0[0],avgs_0);
#endif // #endif
ulsch_channel_level_NB_IoT(pusch_vars->drs_ch_estimates_1[eNB_id], // ulsch_channel_level_NB_IoT(pusch_vars->drs_ch_estimates_1[eNB_id],
frame_parms, // frame_parms,
avgU_1, // avgU_1,
ulsch[UE_id]->harq_process->nb_rb); // ulsch[UE_id]->harq_process->nb_rb);
// printf("[ULSCH] avg_1[0] %d\n",avgU_1[0]); // // printf("[ULSCH] avg_1[0] %d\n",avgU_1[0]);
avgs_1 = 0; // avgs_1 = 0;
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) // for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
avgs_1 = cmax(avgs_1,avgU_1[(aarx<<1)]); // avgs_1 = cmax(avgs_1,avgU_1[(aarx<<1)]);
log2_maxh_1 = (log2_approx(avgs_1)/2) + log2_approx(frame_parms->nb_antennas_rx-1)+3; // log2_maxh_1 = (log2_approx(avgs_1)/2) + log2_approx(frame_parms->nb_antennas_rx-1)+3;
#ifdef DEBUG_ULSCH // #ifdef DEBUG_ULSCH
printf("[ULSCH] log2_maxh_1 = %d (%d,%d)\n",log2_maxh_1,avgU_1[0],avgs_1); // printf("[ULSCH] log2_maxh_1 = %d (%d,%d)\n",log2_maxh_1,avgU_1[0],avgs_1);
#endif // #endif
log2_maxh = max(log2_maxh_0,log2_maxh_1); // log2_maxh = max(log2_maxh_0,log2_maxh_1);
} else { // } else {
ulsch_channel_level_NB_IoT(pusch_vars->drs_ch_estimates[eNB_id], ulsch_channel_level_NB_IoT(pusch_vars->drs_ch_estimates[eNB_id],
frame_parms, frame_parms,
avgU, avgU,
...@@ -1535,46 +1519,46 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1535,46 +1519,46 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
#ifdef DEBUG_ULSCH #ifdef DEBUG_ULSCH
printf("[ULSCH] log2_maxh = %d (%d,%d)\n",log2_maxh,avgU[0],avgs); printf("[ULSCH] log2_maxh = %d (%d,%d)\n",log2_maxh,avgU[0],avgs);
#endif #endif
} //}
for (l=0; l<frame_parms->symbols_per_tti-ulsch[UE_id]->harq_process->srs_active; l++) { for (l=0; l<frame_parms->symbols_per_tti; l++) {
if (((frame_parms->Ncp == 0) && ((l==3) || (l==10)))|| // skip pilots if (((frame_parms->Ncp == 0) && ((l==3) || (l==10)))|| // skip pilots
((frame_parms->Ncp == 1) && ((l==2) || (l==8)))) { ((frame_parms->Ncp == 1) && ((l==2) || (l==8)))) {
l++; l++;
} }
if(cooperation_flag == 2) { // if(cooperation_flag == 2) {
ulsch_channel_compensation_alamouti_NB_IoT( // ulsch_channel_compensation_alamouti_NB_IoT(
pusch_vars->rxdataF_ext[eNB_id], // pusch_vars->rxdataF_ext[eNB_id],
pusch_vars->drs_ch_estimates_0[eNB_id], // pusch_vars->drs_ch_estimates_0[eNB_id],
pusch_vars->drs_ch_estimates_1[eNB_id], // pusch_vars->drs_ch_estimates_1[eNB_id],
pusch_vars->ul_ch_mag_0[eNB_id], // pusch_vars->ul_ch_mag_0[eNB_id],
pusch_vars->ul_ch_magb_0[eNB_id], // pusch_vars->ul_ch_magb_0[eNB_id],
pusch_vars->ul_ch_mag_1[eNB_id], // pusch_vars->ul_ch_mag_1[eNB_id],
pusch_vars->ul_ch_magb_1[eNB_id], // pusch_vars->ul_ch_magb_1[eNB_id],
pusch_vars->rxdataF_comp_0[eNB_id], // pusch_vars->rxdataF_comp_0[eNB_id],
pusch_vars->rxdataF_comp_1[eNB_id], // pusch_vars->rxdataF_comp_1[eNB_id],
frame_parms, // frame_parms,
l, // l,
Qm, // Qm,
ulsch[UE_id]->harq_process->nb_rb, // ulsch[UE_id]->harq_process->nb_rb,
log2_maxh); // log2_maxh);
ulsch_alamouti_NB_IoT(frame_parms, // ulsch_alamouti_NB_IoT(frame_parms,
pusch_vars->rxdataF_comp[eNB_id], // pusch_vars->rxdataF_comp[eNB_id],
pusch_vars->rxdataF_comp_0[eNB_id], // pusch_vars->rxdataF_comp_0[eNB_id],
pusch_vars->rxdataF_comp_1[eNB_id], // pusch_vars->rxdataF_comp_1[eNB_id],
pusch_vars->ul_ch_mag[eNB_id], // pusch_vars->ul_ch_mag[eNB_id],
pusch_vars->ul_ch_magb[eNB_id], // pusch_vars->ul_ch_magb[eNB_id],
pusch_vars->ul_ch_mag_0[eNB_id], // pusch_vars->ul_ch_mag_0[eNB_id],
pusch_vars->ul_ch_magb_0[eNB_id], // pusch_vars->ul_ch_magb_0[eNB_id],
pusch_vars->ul_ch_mag_1[eNB_id], // pusch_vars->ul_ch_mag_1[eNB_id],
pusch_vars->ul_ch_magb_1[eNB_id], // pusch_vars->ul_ch_magb_1[eNB_id],
l, // l,
ulsch[UE_id]->harq_process->nb_rb); // ulsch[UE_id]->harq_process->nb_rb);
} else { // } else {
ulsch_channel_compensation_NB_IoT( ulsch_channel_compensation_NB_IoT(
pusch_vars->rxdataF_ext[eNB_id], pusch_vars->rxdataF_ext[eNB_id],
pusch_vars->drs_ch_estimates[eNB_id], pusch_vars->drs_ch_estimates[eNB_id],
...@@ -1587,7 +1571,7 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1587,7 +1571,7 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
ulsch[UE_id]->harq_process->nb_rb, ulsch[UE_id]->harq_process->nb_rb,
log2_maxh); // log2_maxh+I0_shift log2_maxh); // log2_maxh+I0_shift
} // }
//eren //eren
...@@ -1648,7 +1632,7 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1648,7 +1632,7 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
T_BUFFER(pusch_vars->rxdataF_comp[eNB_id][0], T_BUFFER(pusch_vars->rxdataF_comp[eNB_id][0],
2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_tti*2)); 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_tti*2));
for (l=0; l<frame_parms->symbols_per_tti-ulsch[UE_id]->harq_process->srs_active; l++) { for (l=0; l<frame_parms->symbols_per_tti; l++) {
if (((frame_parms->Ncp == 0) && ((l==3) || (l==10)))|| // skip pilots if (((frame_parms->Ncp == 0) && ((l==3) || (l==10)))|| // skip pilots
((frame_parms->Ncp == 1) && ((l==2) || (l==8)))) { ((frame_parms->Ncp == 1) && ((l==2) || (l==8)))) {
...@@ -1656,6 +1640,9 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1656,6 +1640,9 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
} }
switch (Qm) { switch (Qm) {
case 1:
printf("To be developped\n");
break;
case 2 : case 2 :
ulsch_qpsk_llr_NB_IoT(frame_parms, ulsch_qpsk_llr_NB_IoT(frame_parms,
pusch_vars->rxdataF_comp[eNB_id], pusch_vars->rxdataF_comp[eNB_id],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment