Commit d8fcc7c3 authored by Vincent Savaux's avatar Vincent Savaux

Adapt function demod to modulation configs

parent e860b674
......@@ -315,8 +315,8 @@ void freq_equalization_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
#if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128[re] = _mm_mullo_epi16(rxdataF_comp128[re],*((__m128i *)&inv_ch_NB_IoT[8*amp]));
if (Qm==4)
ul_ch_mag128[re] = _mm_set1_epi16(324); // this is 512*2/sqrt(10)
// if (Qm==4)
// ul_ch_mag128[re] = _mm_set1_epi16(324); // this is 512*2/sqrt(10)
// else {
// 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)
......@@ -324,8 +324,8 @@ void freq_equalization_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
#elif defined(__arm__)
rxdataF_comp128[re] = vmulq_s16(rxdataF_comp128[re],*((int16x8_t *)&inv_ch_NB_IoT[8*amp]));
if (Qm==4)
ul_ch_mag128[re] = vdupq_n_s16(324); // this is 512*2/sqrt(10)
// if (Qm==4)
// ul_ch_mag128[re] = vdupq_n_s16(324); // this is 512*2/sqrt(10)
//else {
// 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)
......
......@@ -143,7 +143,7 @@ int32_t ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
int16_t *p_alpha_re, *p_alpha_im; // pointers to tables alpha above;
uint8_t threetnecyclicshift=0, sixtonecyclichift=0; // NB-IoT: to be defined from higher layer, see 36.211 Section 10.1.4.1.2
uint8_t actual_cyclicshift;
uint16_t Nsc_RU; // Vincent: number of sc 1,3,6,12
uint8_t Nsc_RU = eNB->ulsch[UE_id]->harq_process->N_sc_RU; // Vincent: number of sc 1,3,6,12
unsigned int index_Nsc_RU; // Vincent: index_Nsc_RU 0,1,2,3 ---> number of sc 1,3,6,12
int16_t *received_data, *estimated_channel, *pilot_sig; // pointers to
uint8_t npusch_format = 1; // NB-IoT: format 1 (data), or 2: ack. Should be defined in higher layer
......@@ -163,6 +163,24 @@ int32_t ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
///////////////////////////////////////////////////////////////////////////////////////
switch (Nsc_RU){
case 1:
index_Nsc_RU = 0;
break;
case 3:
index_Nsc_RU = 1;
break;
case 6:
index_Nsc_RU = 2;
break;
case 12:
index_Nsc_RU = 3;
break;
default:
printf("Error in number of subcarrier in channel estimation\n");
break;
}
ul_sc_start = get_UL_sc_start_NB_IoT(I_sc); // NB-IoT: get the used subcarrier in RB
u=frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.grouphop[n_s][index_Nsc_RU]; // Vincent: may be adapted for Nsc_RU, see 36.211, Section 10.1.4.1.3
switch (npusch_format){
......@@ -183,10 +201,10 @@ int32_t ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
for (k=0;k<12;k++){
// Multiplication by the complex conjugate of the pilot
estimated_channel[k<<1] = (int16_t)((int32_t)received_data[k<<1]*(int32_t)pilot_sig[k<<1] +
(int32_t)received_data[(k<<1)+1]*(int32_t)pilot_sig[(k<<1)+1]); //real part of estimated channel
estimated_channel[(k<<1)+1] = (int16_t)((int32_t)received_data[(k<<1)+1]*(int32_t)pilot_sig[k<<1] -
(int32_t)received_data[k<<1]*(int32_t)pilot_sig[(k<<1)+1]); //imaginary part of estimated channel
estimated_channel[k<<1] = (int16_t)(((int32_t)received_data[k<<1]*(int32_t)pilot_sig[k<<1] +
(int32_t)received_data[(k<<1)+1]*(int32_t)pilot_sig[(k<<1)+1])>>15); //real part of estimated channel
estimated_channel[(k<<1)+1] = (int16_t)(((int32_t)received_data[(k<<1)+1]*(int32_t)pilot_sig[k<<1] -
(int32_t)received_data[k<<1]*(int32_t)pilot_sig[(k<<1)+1])>>15); //imaginary part of estimated channel
}
if(Nsc_RU != 1 && Nsc_RU != 12) {
......@@ -268,10 +286,10 @@ int32_t ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
for (k=0;k<12;k++){
// Multiplication by the complex conjugate of the pilot
estimated_channel[k<<1] = (int16_t)((int32_t)received_data[k<<1]*(int32_t)pilot_sig[k<<1] +
(int32_t)received_data[(k<<1)+1]*(int32_t)pilot_sig[(k<<1)+1]); //real part of estimated channel
estimated_channel[(k<<1)+1] = (int16_t)((int32_t)received_data[(k<<1)+1]*(int32_t)pilot_sig[k<<1] -
(int32_t)received_data[k<<1]*(int32_t)pilot_sig[(k<<1)+1]); //imaginary part of estimated channel
estimated_channel[k<<1] = (int16_t)(((int32_t)received_data[k<<1]*(int32_t)pilot_sig[k<<1] +
(int32_t)received_data[(k<<1)+1]*(int32_t)pilot_sig[(k<<1)+1])>>15); //real part of estimated channel
estimated_channel[(k<<1)+1] = (int16_t)(((int32_t)received_data[(k<<1)+1]*(int32_t)pilot_sig[k<<1] -
(int32_t)received_data[k<<1]*(int32_t)pilot_sig[(k<<1)+1])>>15); //imaginary part of estimated channel
}
// Compensating for the phase shift introduced at the transmitter
......@@ -345,860 +363,860 @@ int32_t ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
eNB_rxtx_proc_NB_IoT_t *proc,
uint8_t eNB_id,
uint8_t UE_id,
unsigned char l,
unsigned char Ns,
uint8_t cooperation_flag)
{
NB_IoT_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
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_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_1= pusch_vars->drs_ch_estimates_1[eNB_id];
int32_t **rxdataF_ext= pusch_vars->rxdataF_ext[eNB_id];
int subframe = proc->subframe_rx;
//uint8_t harq_pid = subframe2harq_pid_NB_IoT(frame_parms,proc->frame_rx,subframe);
int16_t delta_phase = 0;
int16_t *ru1 = ru_90;
int16_t *ru2 = ru_90;
int16_t current_phase1,current_phase2;
uint16_t N_rb_alloc = eNB->ulsch[UE_id]->harq_process->nb_rb;
uint16_t aa,Msc_RS,Msc_RS_idx;
uint16_t * Msc_idx_ptr;
int32_t rx_power_correction;
// int k,pilot_pos1 = 3 - frame_parms->Ncp, pilot_pos2 = 10 - 2*frame_parms->Ncp;
int k,pilot_pos1 = 3, pilot_pos2 = 10;
int16_t alpha, beta;
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;
int16_t ul_ch_estimates_re,ul_ch_estimates_im;
//uint8_t nb_antennas_rx = frame_parms->nb_antenna_ports_eNB;
uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
uint8_t cyclic_shift;
uint32_t alpha_ind;
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)];
int32_t tmp_estimates[N_rb_alloc*12] __attribute__((aligned(16)));
int symbol_offset,i;
//int j;
//debug_msg("lte_ul_channel_estimation: cyclic shift %d\n",cyclicShift);
// 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};
////// NB-IoT specific ///////////////////////////////////////////////////////////////////////////////////////
uint32_t I_sc = eNB->ulsch[UE_id]->harq_process->I_sc; // NB_IoT: subcarrier indication field: must be defined in higher layer
uint16_t ul_sc_start; // subcarrier start index into UL RB
// 36.211, Section 10.1.4.1.2, Table 10.1.4.1.2-3
int16_t alpha3_re[9] = {32767 , 32767, 32767,
32767, -16384, -16384,
32767, -16384, -16384};
int16_t alpha3_im[9] = {0 , 0, 0,
0, 28377, -28378,
0, -28378, 28377};
int16_t alpha6_re[24] = {32767 , 32767, 32767, 32767, 32767, 32767,
32767, 16383, -16384, -32768, -16384, 16383,
32767, -16384, -16384, 32767, -16384, -16384,
32767, -16384, -16384, 32767, -16384, -16384};
int16_t alpha6_im[24] = {0 , 0, 0, 0, 0, 0,
0, 28377, 28377, 0, -28378, -28378,
0, 28377, -28378, 0, 28377, -28378,
0, -28378, 28377, 0, -28378, 28377};
int16_t *p_alpha_re, *p_alpha_im; // pointers to tables above;
uint8_t threetnecyclicshift=0, sixtonecyclichift=0; // NB-IoT: to be defined from higher layer, see 36.211 Section 10.1.4.1.2
uint8_t actual_cyclicshift;
uint16_t Nsc_RU; // Vincent: number of sc 1,3,6,12
unsigned int index_Nsc_RU; // Vincent: index_Nsc_RU 0,1,2,3 ---> number of sc 1,3,6,12
///////////////////////////////////////////////////////////////////////////////////////
// int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
// eNB_rxtx_proc_NB_IoT_t *proc,
// uint8_t eNB_id,
// uint8_t UE_id,
// unsigned char l,
// unsigned char Ns,
// uint8_t cooperation_flag)
// {
// NB_IoT_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
// 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_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_1= pusch_vars->drs_ch_estimates_1[eNB_id];
// int32_t **rxdataF_ext= pusch_vars->rxdataF_ext[eNB_id];
// int subframe = proc->subframe_rx;
// //uint8_t harq_pid = subframe2harq_pid_NB_IoT(frame_parms,proc->frame_rx,subframe);
// int16_t delta_phase = 0;
// int16_t *ru1 = ru_90;
// int16_t *ru2 = ru_90;
// int16_t current_phase1,current_phase2;
// uint16_t N_rb_alloc = eNB->ulsch[UE_id]->harq_process->nb_rb;
// uint16_t aa,Msc_RS,Msc_RS_idx;
// uint16_t * Msc_idx_ptr;
// int32_t rx_power_correction;
// // int k,pilot_pos1 = 3 - frame_parms->Ncp, pilot_pos2 = 10 - 2*frame_parms->Ncp;
// int k,pilot_pos1 = 3, pilot_pos2 = 10;
// int16_t alpha, beta;
// 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;
// int16_t ul_ch_estimates_re,ul_ch_estimates_im;
// //uint8_t nb_antennas_rx = frame_parms->nb_antenna_ports_eNB;
// uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
// uint8_t cyclic_shift;
// uint32_t alpha_ind;
// 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)];
// int32_t tmp_estimates[N_rb_alloc*12] __attribute__((aligned(16)));
// int symbol_offset,i;
// //int j;
// //debug_msg("lte_ul_channel_estimation: cyclic shift %d\n",cyclicShift);
// // 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};
// ////// NB-IoT specific ///////////////////////////////////////////////////////////////////////////////////////
// uint32_t I_sc = eNB->ulsch[UE_id]->harq_process->I_sc; // NB_IoT: subcarrier indication field: must be defined in higher layer
// uint16_t ul_sc_start; // subcarrier start index into UL RB
// // 36.211, Section 10.1.4.1.2, Table 10.1.4.1.2-3
// int16_t alpha3_re[9] = {32767 , 32767, 32767,
// 32767, -16384, -16384,
// 32767, -16384, -16384};
// int16_t alpha3_im[9] = {0 , 0, 0,
// 0, 28377, -28378,
// 0, -28378, 28377};
// int16_t alpha6_re[24] = {32767 , 32767, 32767, 32767, 32767, 32767,
// 32767, 16383, -16384, -32768, -16384, 16383,
// 32767, -16384, -16384, 32767, -16384, -16384,
// 32767, -16384, -16384, 32767, -16384, -16384};
// int16_t alpha6_im[24] = {0 , 0, 0, 0, 0, 0,
// 0, 28377, 28377, 0, -28378, -28378,
// 0, 28377, -28378, 0, 28377, -28378,
// 0, -28378, 28377, 0, -28378, 28377};
// int16_t *p_alpha_re, *p_alpha_im; // pointers to tables above;
// uint8_t threetnecyclicshift=0, sixtonecyclichift=0; // NB-IoT: to be defined from higher layer, see 36.211 Section 10.1.4.1.2
// uint8_t actual_cyclicshift;
// uint16_t Nsc_RU; // Vincent: number of sc 1,3,6,12
// unsigned int index_Nsc_RU; // Vincent: index_Nsc_RU 0,1,2,3 ---> number of sc 1,3,6,12
// ///////////////////////////////////////////////////////////////////////////////////////
// /*
// 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_1_ptr = (int32_t*)0,*out_fft_ptr_1 = (int32_t*)0,
// *temp_in_ifft_ptr = (int32_t*)0;
// */
// #if defined(__x86_64__) || defined(__i386__)
// __m128i *rxdataF128,*ul_ref128,*ul_ch128;
// __m128i mmtmpU0,mmtmpU1,mmtmpU2,mmtmpU3;
// #elif defined(__arm__)
// int16x8_t *rxdataF128,*ul_ref128,*ul_ch128;
// int32x4_t mmtmp0,mmtmp1,mmtmp_re,mmtmp_im;
// #endif
// Msc_RS = N_rb_alloc*12;
/*
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_1_ptr = (int32_t*)0,*out_fft_ptr_1 = (int32_t*)0,
*temp_in_ifft_ptr = (int32_t*)0;
*/
// cyclic_shift = (frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.cyclicShift +
// eNB->ulsch[UE_id]->harq_process->n_DMRS2 +
// frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.nPRS[(subframe<<1)+Ns]) % 12;
#if defined(__x86_64__) || defined(__i386__)
__m128i *rxdataF128,*ul_ref128,*ul_ch128;
__m128i mmtmpU0,mmtmpU1,mmtmpU2,mmtmpU3;
#elif defined(__arm__)
int16x8_t *rxdataF128,*ul_ref128,*ul_ch128;
int32x4_t mmtmp0,mmtmp1,mmtmp_re,mmtmp_im;
#endif
Msc_RS = N_rb_alloc*12;
cyclic_shift = (frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.cyclicShift +
eNB->ulsch[UE_id]->harq_process->n_DMRS2 +
frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.nPRS[(subframe<<1)+Ns]) % 12;
#if defined(USER_MODE)
Msc_idx_ptr = (uint16_t*) bsearch(&Msc_RS, dftsizes, 33, sizeof(uint16_t), compareints);
if (Msc_idx_ptr)
Msc_RS_idx = Msc_idx_ptr - dftsizes;
else {
msg("lte_ul_channel_estimation: index for Msc_RS=%d not found\n",Msc_RS);
return(-1);
}
// #if defined(USER_MODE)
// Msc_idx_ptr = (uint16_t*) bsearch(&Msc_RS, dftsizes, 33, sizeof(uint16_t), compareints);
#else
uint8_t b;
// if (Msc_idx_ptr)
// Msc_RS_idx = Msc_idx_ptr - dftsizes;
// else {
// msg("lte_ul_channel_estimation: index for Msc_RS=%d not found\n",Msc_RS);
// return(-1);
// }
for (b=0; b<33; b++)
if (Msc_RS==dftsizes[b])
Msc_RS_idx = b;
// #else
// uint8_t b;
#endif
// for (b=0; b<33; b++)
// if (Msc_RS==dftsizes[b])
// Msc_RS_idx = b;
// LOG_I(PHY,"subframe %d, Ns %d, l %d, Msc_RS = %d, Msc_RS_idx = %d, u %d, v %d, cyclic_shift %d\n",subframe,Ns,l,Msc_RS, Msc_RS_idx,u,v,cyclic_shift);
#ifdef DEBUG_CH
// #endif
#ifdef USER_MODE
// // LOG_I(PHY,"subframe %d, Ns %d, l %d, Msc_RS = %d, Msc_RS_idx = %d, u %d, v %d, cyclic_shift %d\n",subframe,Ns,l,Msc_RS, Msc_RS_idx,u,v,cyclic_shift);
// #ifdef DEBUG_CH
if (Ns==0)
write_output("drs_seq0.m","drsseq0",ul_ref_sigs_rx[u][Msc_RS_idx],2*Msc_RS,2,1);
else
write_output("drs_seq1.m","drsseq1",ul_ref_sigs_rx[u][Msc_RS_idx],2*Msc_RS,2,1);
// #ifdef USER_MODE
#endif
#endif
// if (Ns==0)
// write_output("drs_seq0.m","drsseq0",ul_ref_sigs_rx[u][Msc_RS_idx],2*Msc_RS,2,1);
// else
// write_output("drs_seq1.m","drsseq1",ul_ref_sigs_rx[u][Msc_RS_idx],2*Msc_RS,2,1);
rx_power_correction = 1;
ul_sc_start = get_UL_sc_start_NB_IoT(I_sc); // NB-IoT: get the used subcarrier in RB
u=frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.grouphop[Ns+(subframe<<1)][index_Nsc_RU]; // Vincent: may be adapted for Nsc_RU, see 36.211, Section 10.1.4.1.3
// #endif
// #endif
// if (l == (3 - frame_parms->Ncp)) {
if (l == 3) { // NB-IoT: no extended CP
// rx_power_correction = 1;
// ul_sc_start = get_UL_sc_start_NB_IoT(I_sc); // NB-IoT: get the used subcarrier in RB
// u=frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.grouphop[Ns+(subframe<<1)][index_Nsc_RU]; // Vincent: may be adapted for Nsc_RU, see 36.211, Section 10.1.4.1.3
// // if (l == (3 - frame_parms->Ncp)) {
// if (l == 3) { // NB-IoT: no extended CP
// // symbol_offset = frame_parms->N_RB_UL*12*(l+((7-frame_parms->Ncp)*(Ns&1)));
// symbol_offset = frame_parms->N_RB_UL*12*(l+(7*(Ns&1)));
// for (aa=0; aa<nb_antennas_rx; aa++) {
// // msg("Componentwise prod aa %d, symbol_offset %d,ul_ch_estimates %p,ul_ch_estimates[aa] %p,ul_ref_sigs_rx[0][0][Msc_RS_idx] %p\n",aa,symbol_offset,ul_ch_estimates,ul_ch_estimates[aa],ul_ref_sigs_rx[0][0][Msc_RS_idx]);
// #if defined(__x86_64__) || defined(__i386__)
// rxdataF128 = (__m128i *)&rxdataF_ext[aa][symbol_offset];
// ul_ch128 = (__m128i *)&ul_ch_estimates[aa][symbol_offset];
// if (index_Nsc_RU){ // NB-IoT: a shift ul_sc_start is added in order to get the same position of the first pilot in rxdataF_ext and ul_ref_sigs_rx
// ul_ref128 = (__m128i *)ul_ref_sigs_rx[u][index_Nsc_RU][24-(ul_sc_start<<1)]; // pilot values are the same every slots
// }else{
// ul_ref128 = (__m128i *)ul_ref_sigs_rx[u][index_Nsc_RU][24 + 12*(subframe<<1)-(ul_sc_start<<1)]; // pilot values depends on the slots
// }
// #elif defined(__arm__)
// rxdataF128 = (int16x8_t *)&rxdataF_ext[aa][symbol_offset];
// ul_ch128 = (int16x8_t *)&ul_ch_estimates[aa][symbol_offset];
// if (index_Nsc_RU){
// ul_ref128 = (int16x8_t *)ul_ref_sigs_rx[u][index_Nsc_RU][24-(ul_sc_start<<1)];
// }else{
// ul_ref128 = (int16x8_t *)ul_ref_sigs_rx[u][index_Nsc_RU][24 + 12*(subframe<<1)-(ul_sc_start<<1)];
// }
// #endif
// symbol_offset = frame_parms->N_RB_UL*12*(l+((7-frame_parms->Ncp)*(Ns&1)));
symbol_offset = frame_parms->N_RB_UL*12*(l+(7*(Ns&1)));
// // for (i=0; i<Msc_RS/12; i++) {
// #if defined(__x86_64__) || defined(__i386__)
// // multiply by conjugated channel
// mmtmpU0 = _mm_madd_epi16(ul_ref128[0],rxdataF128[0]);
// // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
// mmtmpU1 = _mm_shufflelo_epi16(ul_ref128[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]);
// mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[0]);
// // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
// mmtmpU0 = _mm_srai_epi32(mmtmpU0,15);
// mmtmpU1 = _mm_srai_epi32(mmtmpU1,15);
// mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
// mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
// ul_ch128[0] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// // printf("rb %d ch: %d %d\n",i,((int16_t*)ul_ch128)[0],((int16_t*)ul_ch128)[1]);
// // multiply by conjugated channel
// mmtmpU0 = _mm_madd_epi16(ul_ref128[1],rxdataF128[1]);
// // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
// mmtmpU1 = _mm_shufflelo_epi16(ul_ref128[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,15);
// mmtmpU1 = _mm_srai_epi32(mmtmpU1,15);
// mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
// mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
// ul_ch128[1] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// mmtmpU0 = _mm_madd_epi16(ul_ref128[2],rxdataF128[2]);
// // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
// mmtmpU1 = _mm_shufflelo_epi16(ul_ref128[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,15);
// mmtmpU1 = _mm_srai_epi32(mmtmpU1,15);
// mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
// mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
// ul_ch128[2] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// #elif defined(__arm__)
// mmtmp0 = vmull_s16(((int16x4_t*)ul_ref128)[0],((int16x4_t*)rxdataF128)[0]);
// mmtmp1 = vmull_s16(((int16x4_t*)ul_ref128)[1],((int16x4_t*)rxdataF128)[1]);
// mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
// vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
// mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[0]);
// mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[1]);
// mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
// vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
// ul_ch128[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im));
// ul_ch128++;
// ul_ref128++;
// rxdataF128++;
// mmtmp0 = vmull_s16(((int16x4_t*)ul_ref128)[0],((int16x4_t*)rxdataF128)[0]);
// mmtmp1 = vmull_s16(((int16x4_t*)ul_ref128)[1],((int16x4_t*)rxdataF128)[1]);
// mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
// vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
// mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[0]);
// mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[1]);
// mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
// vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
// ul_ch128[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im));
// ul_ch128++;
// ul_ref128++;
// rxdataF128++;
// mmtmp0 = vmull_s16(((int16x4_t*)ul_ref128)[0],((int16x4_t*)rxdataF128)[0]);
// mmtmp1 = vmull_s16(((int16x4_t*)ul_ref128)[1],((int16x4_t*)rxdataF128)[1]);
// mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
// vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
// mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[0]);
// mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[1]);
// mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
// vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
// ul_ch128[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im));
// ul_ch128++;
// ul_ref128++;
// rxdataF128++;
for (aa=0; aa<nb_antennas_rx; aa++) {
// msg("Componentwise prod aa %d, symbol_offset %d,ul_ch_estimates %p,ul_ch_estimates[aa] %p,ul_ref_sigs_rx[0][0][Msc_RS_idx] %p\n",aa,symbol_offset,ul_ch_estimates,ul_ch_estimates[aa],ul_ref_sigs_rx[0][0][Msc_RS_idx]);
#if defined(__x86_64__) || defined(__i386__)
rxdataF128 = (__m128i *)&rxdataF_ext[aa][symbol_offset];
ul_ch128 = (__m128i *)&ul_ch_estimates[aa][symbol_offset];
if (index_Nsc_RU){ // NB-IoT: a shift ul_sc_start is added in order to get the same position of the first pilot in rxdataF_ext and ul_ref_sigs_rx
ul_ref128 = (__m128i *)ul_ref_sigs_rx[u][index_Nsc_RU][24-(ul_sc_start<<1)]; // pilot values are the same every slots
}else{
ul_ref128 = (__m128i *)ul_ref_sigs_rx[u][index_Nsc_RU][24 + 12*(subframe<<1)-(ul_sc_start<<1)]; // pilot values depends on the slots
}
#elif defined(__arm__)
rxdataF128 = (int16x8_t *)&rxdataF_ext[aa][symbol_offset];
ul_ch128 = (int16x8_t *)&ul_ch_estimates[aa][symbol_offset];
if (index_Nsc_RU){
ul_ref128 = (int16x8_t *)ul_ref_sigs_rx[u][index_Nsc_RU][24-(ul_sc_start<<1)];
}else{
ul_ref128 = (int16x8_t *)ul_ref_sigs_rx[u][index_Nsc_RU][24 + 12*(subframe<<1)-(ul_sc_start<<1)];
}
#endif
// for (i=0; i<Msc_RS/12; i++) {
#if defined(__x86_64__) || defined(__i386__)
// multiply by conjugated channel
mmtmpU0 = _mm_madd_epi16(ul_ref128[0],rxdataF128[0]);
// mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
mmtmpU1 = _mm_shufflelo_epi16(ul_ref128[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]);
mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[0]);
// mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpU0 = _mm_srai_epi32(mmtmpU0,15);
mmtmpU1 = _mm_srai_epi32(mmtmpU1,15);
mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
ul_ch128[0] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// printf("rb %d ch: %d %d\n",i,((int16_t*)ul_ch128)[0],((int16_t*)ul_ch128)[1]);
// multiply by conjugated channel
mmtmpU0 = _mm_madd_epi16(ul_ref128[1],rxdataF128[1]);
// mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
mmtmpU1 = _mm_shufflelo_epi16(ul_ref128[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,15);
mmtmpU1 = _mm_srai_epi32(mmtmpU1,15);
mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
ul_ch128[1] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
mmtmpU0 = _mm_madd_epi16(ul_ref128[2],rxdataF128[2]);
// mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
mmtmpU1 = _mm_shufflelo_epi16(ul_ref128[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,15);
mmtmpU1 = _mm_srai_epi32(mmtmpU1,15);
mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
ul_ch128[2] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
#elif defined(__arm__)
mmtmp0 = vmull_s16(((int16x4_t*)ul_ref128)[0],((int16x4_t*)rxdataF128)[0]);
mmtmp1 = vmull_s16(((int16x4_t*)ul_ref128)[1],((int16x4_t*)rxdataF128)[1]);
mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[0]);
mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[1]);
mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
ul_ch128[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im));
ul_ch128++;
ul_ref128++;
rxdataF128++;
mmtmp0 = vmull_s16(((int16x4_t*)ul_ref128)[0],((int16x4_t*)rxdataF128)[0]);
mmtmp1 = vmull_s16(((int16x4_t*)ul_ref128)[1],((int16x4_t*)rxdataF128)[1]);
mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[0]);
mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[1]);
mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
ul_ch128[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im));
ul_ch128++;
ul_ref128++;
rxdataF128++;
mmtmp0 = vmull_s16(((int16x4_t*)ul_ref128)[0],((int16x4_t*)rxdataF128)[0]);
mmtmp1 = vmull_s16(((int16x4_t*)ul_ref128)[1],((int16x4_t*)rxdataF128)[1]);
mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[0]);
mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[1]);
mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
ul_ch128[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im));
ul_ch128++;
ul_ref128++;
rxdataF128++;
#endif
// ul_ch128+=3;
// ul_ref128+=3;
// rxdataF128+=3;
// }
// #endif
// // ul_ch128+=3;
// // ul_ref128+=3;
// // rxdataF128+=3;
// // }
// // alpha_ind = 0;
// // if((cyclic_shift != 0) && Msc_RS != 12) {
// // // if(Nsc_RU != 1 && Nsc_RU != 12) {
// // // Compensating for the phase shift introduced at the transmitter
// // // In NB-IoT, phase alpha is zero when 12 subcarriers are allocated
// // #ifdef DEBUG_CH
// // write_output("drs_est_pre.m","drsest_pre",ul_ch_estimates[0],300*12,1,1);
// // #endif
// // 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_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] =
// // (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);
// // //((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) (((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);
// // alpha_ind+=cyclic_shift;
// // if (alpha_ind>11)
// // alpha_ind-=12;
// // }
// // #ifdef DEBUG_CH
// // write_output("drs_est_post.m","drsest_post",ul_ch_estimates[0],300*12,1,1);
// // #endif
// // }
// alpha_ind = 0;
// if((cyclic_shift != 0) && Msc_RS != 12) {
// // if(Nsc_RU != 1 && Nsc_RU != 12) {
// if(Nsc_RU != 1 && Nsc_RU != 12) {
// // Compensating for the phase shift introduced at the transmitter
// // In NB-IoT, phase alpha is zero when 12 subcarriers are allocated
// // In NB-IoT, phase alpha is zero when 1 and 12 subcarriers are allocated
// #ifdef DEBUG_CH
// write_output("drs_est_pre.m","drsest_pre",ul_ch_estimates[0],300*12,1,1);
// #endif
// if (Nsc_RU == 3){
// p_alpha_re = alpha3_re;
// p_alpha_im = alpha3_im;
// actual_cyclicshift = threetnecyclicshift;
// }else if (Nsc_RU == 6){
// p_alpha_re = alpha6_re;
// p_alpha_im = alpha6_im;
// actual_cyclicshift= sixtonecyclichift;
// }else{
// msg("lte_ul_channel_estimation_NB-IoT: wrong Nsc_RU value, Nsc_RU=%d\n",Nsc_RU);
// return(-1);
// }
// for(i=symbol_offset; i<symbol_offset+Msc_RS; i++) {
// for(i=symbol_offset+ul_sc_start; i<symbol_offset+ul_sc_start+Nsc_RU; i++) {
// 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];
// // ((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) (((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);
// (int16_t) (((int32_t) (p_alpha_re[actual_cyclicshift*Nsc_RU+i]) * (int32_t) (ul_ch_estimates_re) +
// (int32_t) (p_alpha_im[actual_cyclicshift*Nsc_RU+i]) * (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] =
// (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);
// (int16_t) (((int32_t) (p_alpha_re[actual_cyclicshift*Nsc_RU+i]) * (int32_t) (ul_ch_estimates_im) -
// (int32_t) (p_alpha_im[actual_cyclicshift*Nsc_RU+i]) * (int32_t) (ul_ch_estimates_re))>>15);
// alpha_ind+=cyclic_shift;
// if (alpha_ind>11)
// alpha_ind-=12;
// }
// #ifdef DEBUG_CH
// write_output("drs_est_post.m","drsest_post",ul_ch_estimates[0],300*12,1,1);
// #endif
// }
alpha_ind = 0;
// }
if(Nsc_RU != 1 && Nsc_RU != 12) {
// Compensating for the phase shift introduced at the transmitter
// In NB-IoT, phase alpha is zero when 1 and 12 subcarriers are allocated
#ifdef DEBUG_CH
write_output("drs_est_pre.m","drsest_pre",ul_ch_estimates[0],300*12,1,1);
#endif
if (Nsc_RU == 3){
p_alpha_re = alpha3_re;
p_alpha_im = alpha3_im;
actual_cyclicshift = threetnecyclicshift;
}else if (Nsc_RU == 6){
p_alpha_re = alpha6_re;
p_alpha_im = alpha6_im;
actual_cyclicshift= sixtonecyclichift;
}else{
msg("lte_ul_channel_estimation_NB-IoT: wrong Nsc_RU value, Nsc_RU=%d\n",Nsc_RU);
return(-1);
}
for(i=symbol_offset+ul_sc_start; i<symbol_offset+ul_sc_start+Nsc_RU; i++) {
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];
// ((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) (((int32_t) (p_alpha_re[actual_cyclicshift*Nsc_RU+i]) * (int32_t) (ul_ch_estimates_re) +
(int32_t) (p_alpha_im[actual_cyclicshift*Nsc_RU+i]) * (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] =
(int16_t) (((int32_t) (p_alpha_re[actual_cyclicshift*Nsc_RU+i]) * (int32_t) (ul_ch_estimates_im) -
(int32_t) (p_alpha_im[actual_cyclicshift*Nsc_RU+i]) * (int32_t) (ul_ch_estimates_re))>>15);
}
#ifdef DEBUG_CH
write_output("drs_est_post.m","drsest_post",ul_ch_estimates[0],300*12,1,1);
#endif
}
// //copy MIMO channel estimates to temporary buffer for EMOS
// //memcpy(&ul_ch_estimates_0[aa][symbol_offset],&ul_ch_estimates[aa][symbol_offset],frame_parms->ofdm_symbol_size*sizeof(int32_t)*2);
//copy MIMO channel estimates to temporary buffer for EMOS
//memcpy(&ul_ch_estimates_0[aa][symbol_offset],&ul_ch_estimates[aa][symbol_offset],frame_parms->ofdm_symbol_size*sizeof(int32_t)*2);
// memset(temp_in_ifft_0,0,frame_parms->ofdm_symbol_size*sizeof(int32_t));
memset(temp_in_ifft_0,0,frame_parms->ofdm_symbol_size*sizeof(int32_t));
// Convert to time domain for visualization
for(i=0; i<Msc_RS; i++)
((int32_t*)temp_in_ifft_0)[i] = ul_ch_estimates[aa][symbol_offset+i];
switch(frame_parms->N_RB_DL) {
case 6:
// // Convert to time domain for visualization
// for(i=0; i<Msc_RS; i++)
// ((int32_t*)temp_in_ifft_0)[i] = ul_ch_estimates[aa][symbol_offset+i];
// switch(frame_parms->N_RB_DL) {
// case 6:
idft128((int16_t*) temp_in_ifft_0,
(int16_t*) ul_ch_estimates_time[aa],
1);
break;
case 25:
// idft128((int16_t*) temp_in_ifft_0,
// (int16_t*) ul_ch_estimates_time[aa],
// 1);
// break;
// case 25:
idft512((int16_t*) temp_in_ifft_0,
(int16_t*) ul_ch_estimates_time[aa],
1);
break;
case 50:
// idft512((int16_t*) temp_in_ifft_0,
// (int16_t*) ul_ch_estimates_time[aa],
// 1);
// break;
// case 50:
idft1024((int16_t*) temp_in_ifft_0,
(int16_t*) ul_ch_estimates_time[aa],
1);
break;
case 100:
// idft1024((int16_t*) temp_in_ifft_0,
// (int16_t*) ul_ch_estimates_time[aa],
// 1);
// break;
// case 100:
idft2048((int16_t*) temp_in_ifft_0,
(int16_t*) ul_ch_estimates_time[aa],
1);
break;
}
#if T_TRACER
if (aa == 0)
T(T_ENB_PHY_UL_CHANNEL_ESTIMATE, T_INT(eNB_id), T_INT(UE_id),
T_INT(proc->frame_rx), T_INT(subframe),
T_INT(0), T_BUFFER(ul_ch_estimates_time[0], 512 * 4));
#endif
#ifdef DEBUG_CH
if (aa==0) {
if (Ns == 0) {
write_output("rxdataF_ext.m","rxF_ext",&rxdataF_ext[aa][symbol_offset],512*2,2,1);
write_output("tmpin_ifft.m","drs_in",temp_in_ifft_0,512,1,1);
write_output("drs_est0.m","drs0",ul_ch_estimates_time[aa],512,1,1);
} else
write_output("drs_est1.m","drs1",ul_ch_estimates_time[aa],512,1,1);
}
#endif
// if(cooperation_flag == 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_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);
// temp_in_ifft_ptr = &temp_in_ifft_0[0];
// i = symbol_offset;
// for(j=0; j<(frame_parms->N_RB_UL*12); j++) {
// temp_in_ifft_ptr[j] = ul_ch_estimates[aa][i];
// i++;
// }
// alpha_ind = 0;
// // Compensating for the phase shift introduced at the transmitter
// 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_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] =
// (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);
// //((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) (((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);
// alpha_ind+=10;
// if (alpha_ind>11)
// alpha_ind-=12;
// }
// //Extracting Channel Estimates for Distributed Alamouti Receiver Combining
// temp_in_ifft_ptr = &temp_in_ifft_1[0];
// i = symbol_offset;
// for(j=0; j<(frame_parms->N_RB_UL*12); j++) {
// temp_in_ifft_ptr[j] = ul_ch_estimates[aa][i];
// i++;
// }
// switch (frame_parms->N_RB_DL) {
// case 6:
// idft128((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates
// temp_out_ifft_0,
// 1);
// idft128((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates
// temp_out_ifft_1,
// 1);
// break;
// case 25:
// idft512((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates
// temp_out_ifft_0,
// 1);
// idft512((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates
// temp_out_ifft_1,
// 1);
// break;
// case 50:
// idft1024((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates
// temp_out_ifft_0,
// 1);
// idft1024((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates
// temp_out_ifft_1,
// 1);
// break;
// case 100:
// idft2048((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates
// temp_out_ifft_0,
// 1);
// idft2048((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates
// temp_out_ifft_1,
// 1);
// 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
// in_fft_ptr_0 = &temp_in_fft_0[0];
// in_fft_ptr_1 = &temp_in_fft_1[0];
// for(j=0; j<(frame_parms->ofdm_symbol_size)/12; j++) {
// 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)+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)+1] = ((int16_t*)temp_out_ifft_1)[-80+(2*j)+1]*rx_power_correction;
// } 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)+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)+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) {
// case 6:
// dft128((int16_t*) &temp_in_fft_0[0],
// // Performing FFT to obtain the Channel Estimates for UE0 to eNB1
// temp_out_fft_0,
// 1);
// break;
// case 25:
// dft512((int16_t*) &temp_in_fft_0[0],
// // Performing FFT to obtain the Channel Estimates for UE0 to eNB1
// temp_out_fft_0,
// 1);
// break;
// case 50:
// dft1024((int16_t*) &temp_in_fft_0[0],
// // Performing FFT to obtain the Channel Estimates for UE0 to eNB1
// temp_out_fft_0,
// 1);
// break;
// case 100:
// dft2048((int16_t*) &temp_in_fft_0[0],
// // Performing FFT to obtain the Channel Estimates for UE0 to eNB1
// temp_out_fft_0,
// 1);
// break;
// }
// 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;
// i=0;
// for(j=0; j<frame_parms->N_RB_UL*12; j++) {
// out_fft_ptr_0[i] = temp_out_fft_0_ptr[j];
// i++;
// }
// switch (frame_parms->N_RB_DL) {
// case 6:
// dft128((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1
// temp_out_fft_1,
// 1);
// break;
// case 25:
// dft512((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1
// temp_out_fft_1,
// 1);
// break;
// case 50:
// dft1024((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1
// temp_out_fft_1,
// 1);
// break;
// case 100:
// dft2048((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1
// temp_out_fft_1,
// 1);
// break;
// }
// 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;
// i=0;
// for(j=0; j<frame_parms->N_RB_UL*12; j++) {
// out_fft_ptr_1[i] = temp_out_fft_1_ptr[j];
// i++;
// }
// idft2048((int16_t*) temp_in_ifft_0,
// (int16_t*) ul_ch_estimates_time[aa],
// 1);
// break;
// }
// #if T_TRACER
// if (aa == 0)
// T(T_ENB_PHY_UL_CHANNEL_ESTIMATE, T_INT(eNB_id), T_INT(UE_id),
// T_INT(proc->frame_rx), T_INT(subframe),
// T_INT(0), T_BUFFER(ul_ch_estimates_time[0], 512 * 4));
// #endif
// #ifdef DEBUG_CH
// #ifdef USER_MODE
// if((aa == 0)&& (cooperation_flag == 2)) {
// 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("test3.m","t3",temp_in_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("test6.m","t6",temp_out_fft_1,512,1,1);
// }
// if (aa==0) {
// if (Ns == 0) {
// write_output("rxdataF_ext.m","rxF_ext",&rxdataF_ext[aa][symbol_offset],512*2,2,1);
// write_output("tmpin_ifft.m","drs_in",temp_in_ifft_0,512,1,1);
// write_output("drs_est0.m","drs0",ul_ch_estimates_time[aa],512,1,1);
// } else
// write_output("drs_est1.m","drs1",ul_ch_estimates_time[aa],512,1,1);
// }
// #endif
// #endif
// }//cooperation_flag == 2
if (Ns&1) {//we are in the second slot of the sub-frame, so do the interpolation
ul_ch1 = &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos1];
ul_ch2 = &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos2];
// if(cooperation_flag == 2) { // For Distributed Alamouti
// 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];
// // if(cooperation_flag == 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_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);
// // temp_in_ifft_ptr = &temp_in_ifft_0[0];
// // i = symbol_offset;
// // for(j=0; j<(frame_parms->N_RB_UL*12); j++) {
// // temp_in_ifft_ptr[j] = ul_ch_estimates[aa][i];
// // i++;
// // }
// // alpha_ind = 0;
// // // Compensating for the phase shift introduced at the transmitter
// // 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_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] =
// // (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);
// // //((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) (((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);
// // alpha_ind+=10;
// // if (alpha_ind>11)
// // alpha_ind-=12;
// // }
// // //Extracting Channel Estimates for Distributed Alamouti Receiver Combining
// // temp_in_ifft_ptr = &temp_in_ifft_1[0];
// // i = symbol_offset;
// // for(j=0; j<(frame_parms->N_RB_UL*12); j++) {
// // temp_in_ifft_ptr[j] = ul_ch_estimates[aa][i];
// // i++;
// // }
// // switch (frame_parms->N_RB_DL) {
// // case 6:
// // idft128((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates
// // temp_out_ifft_0,
// // 1);
// // idft128((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates
// // temp_out_ifft_1,
// // 1);
// // break;
// // case 25:
// // idft512((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates
// // temp_out_ifft_0,
// // 1);
// // idft512((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates
// // temp_out_ifft_1,
// // 1);
// // break;
// // case 50:
// // idft1024((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates
// // temp_out_ifft_0,
// // 1);
// // idft1024((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates
// // temp_out_ifft_1,
// // 1);
// // break;
// // case 100:
// // idft2048((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates
// // temp_out_ifft_0,
// // 1);
// // idft2048((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates
// // temp_out_ifft_1,
// // 1);
// // 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
// // in_fft_ptr_0 = &temp_in_fft_0[0];
// // in_fft_ptr_1 = &temp_in_fft_1[0];
// // for(j=0; j<(frame_parms->ofdm_symbol_size)/12; j++) {
// // 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)+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)+1] = ((int16_t*)temp_out_ifft_1)[-80+(2*j)+1]*rx_power_correction;
// // } 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)+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)+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) {
// // case 6:
// // dft128((int16_t*) &temp_in_fft_0[0],
// // // Performing FFT to obtain the Channel Estimates for UE0 to eNB1
// // temp_out_fft_0,
// // 1);
// // break;
// // case 25:
// // dft512((int16_t*) &temp_in_fft_0[0],
// // // Performing FFT to obtain the Channel Estimates for UE0 to eNB1
// // temp_out_fft_0,
// // 1);
// // break;
// // case 50:
// // dft1024((int16_t*) &temp_in_fft_0[0],
// // // Performing FFT to obtain the Channel Estimates for UE0 to eNB1
// // temp_out_fft_0,
// // 1);
// // break;
// // case 100:
// // dft2048((int16_t*) &temp_in_fft_0[0],
// // // Performing FFT to obtain the Channel Estimates for UE0 to eNB1
// // temp_out_fft_0,
// // 1);
// // break;
// // }
// // 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;
// // i=0;
// // for(j=0; j<frame_parms->N_RB_UL*12; j++) {
// // out_fft_ptr_0[i] = temp_out_fft_0_ptr[j];
// // i++;
// // }
// // switch (frame_parms->N_RB_DL) {
// // case 6:
// // dft128((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1
// // temp_out_fft_1,
// // 1);
// // break;
// // case 25:
// // dft512((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1
// // temp_out_fft_1,
// // 1);
// // break;
// // case 50:
// // dft1024((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1
// // temp_out_fft_1,
// // 1);
// // break;
// // case 100:
// // dft2048((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1
// // temp_out_fft_1,
// // 1);
// // break;
// // }
// // 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;
// // i=0;
// // for(j=0; j<frame_parms->N_RB_UL*12; j++) {
// // out_fft_ptr_1[i] = temp_out_fft_1_ptr[j];
// // i++;
// // }
// // #ifdef DEBUG_CH
// // #ifdef USER_MODE
// // if((aa == 0)&& (cooperation_flag == 2)) {
// // 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("test3.m","t3",temp_in_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("test6.m","t6",temp_out_fft_1,512,1,1);
// // }
// // #endif
// // #endif
// // }//cooperation_flag == 2
// if (Ns&1) {//we are in the second slot of the sub-frame, so do the interpolation
// ul_ch1 = &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos1];
// ul_ch2 = &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos2];
// // if(cooperation_flag == 2) { // For Distributed Alamouti
// // 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_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];
// // }
// // Estimation of phase difference between the 2 channel estimates
// // delta_phase = lte_ul_freq_offset_estimation_NB_IoT(frame_parms,
// // ul_ch_estimates[aa],
// // N_rb_alloc);
// delta_phase = lte_ul_freq_offset_estimation_NB_IoT(frame_parms,
// ul_ch_estimates[aa],
// 1); // NB-IoT: only 1 RB
// // negative phase index indicates negative Im of ru
// // msg("delta_phase: %d\n",delta_phase);
// 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];
// }
// Estimation of phase difference between the 2 channel estimates
// delta_phase = lte_ul_freq_offset_estimation_NB_IoT(frame_parms,
// ul_ch_estimates[aa],
// N_rb_alloc);
delta_phase = lte_ul_freq_offset_estimation_NB_IoT(frame_parms,
ul_ch_estimates[aa],
1); // NB-IoT: only 1 RB
// negative phase index indicates negative Im of ru
// msg("delta_phase: %d\n",delta_phase);
#ifdef DEBUG_CH
msg("lte_ul_channel_estimation: ul_ch1 = %p, ul_ch2 = %p, pilot_pos1=%d, pilot_pos2=%d\n",ul_ch1, ul_ch2, pilot_pos1,pilot_pos2);
#endif
for (k=0; k<frame_parms->symbols_per_tti; k++) {
// we scale alpha and beta by SCALE (instead of 0x7FFF) to avoid overflows
alpha = (int16_t) (((int32_t) SCALE * (int32_t) (pilot_pos2-k))/(pilot_pos2-pilot_pos1));
beta = (int16_t) (((int32_t) SCALE * (int32_t) (k-pilot_pos1))/(pilot_pos2-pilot_pos1));
#ifdef DEBUG_CH
msg("lte_ul_channel_estimation: k=%d, alpha = %d, beta = %d\n",k,alpha,beta);
#endif
//symbol_offset_subframe = frame_parms->N_RB_UL*12*k;
// interpolate between estimates
if ((k != pilot_pos1) && (k != pilot_pos2)) {
// multadd_complex_vector_real_scalar((int16_t*) ul_ch1,alpha,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
// multadd_complex_vector_real_scalar((int16_t*) ul_ch2,beta ,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
// multadd_complex_vector_real_scalar((int16_t*) ul_ch1,SCALE,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
// multadd_complex_vector_real_scalar((int16_t*) ul_ch2,SCALE,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
// msg("phase = %d\n",ru[2*cmax(((delta_phase/7)*(k-3)),0)]);
// the phase is linearly interpolated
current_phase1 = (delta_phase/7)*(k-pilot_pos1);
current_phase2 = (delta_phase/7)*(k-pilot_pos2);
// msg("sym: %d, current_phase1: %d, current_phase2: %d\n",k,current_phase1,current_phase2);
// set the right quadrant
(current_phase1 > 0) ? (ru1 = ru_90) : (ru1 = ru_90c);
(current_phase2 > 0) ? (ru2 = ru_90) : (ru2 = ru_90c);
// take absolute value and clip
current_phase1 = cmin(abs(current_phase1),127);
current_phase2 = cmin(abs(current_phase2),127);
// msg("sym: %d, current_phase1: %d, ru: %d + j%d, current_phase2: %d, ru: %d + j%d\n",k,current_phase1,ru1[2*current_phase1],ru1[2*current_phase1+1],current_phase2,ru2[2*current_phase2],ru2[2*current_phase2+1]);
// rotate channel estimates by estimated phase
rotate_cpx_vector((int16_t*) ul_ch1,
&ru1[2*current_phase1],
(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],
Msc_RS,
15);
rotate_cpx_vector((int16_t*) ul_ch2,
&ru2[2*current_phase2],
(int16_t*) &tmp_estimates[0],
Msc_RS,
15);
// Combine the two rotated estimates
multadd_complex_vector_real_scalar((int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],SCALE,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
multadd_complex_vector_real_scalar((int16_t*) &tmp_estimates[0],SCALE,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
/*
if ((k<pilot_pos1) || ((k>pilot_pos2))) {
multadd_complex_vector_real_scalar((int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],SCALE>>1,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
multadd_complex_vector_real_scalar((int16_t*) &tmp_estimates[0],SCALE>>1,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
} else {
multadd_complex_vector_real_scalar((int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],SCALE>>1,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
multadd_complex_vector_real_scalar((int16_t*) &tmp_estimates[0],SCALE>>1,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
// multadd_complex_vector_real_scalar((int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],alpha,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
// multadd_complex_vector_real_scalar((int16_t*) &tmp_estimates[0],beta ,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
}
*/
// 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
// 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_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);
// }
}
} //for(k=...
// #ifdef DEBUG_CH
// msg("lte_ul_channel_estimation: ul_ch1 = %p, ul_ch2 = %p, pilot_pos1=%d, pilot_pos2=%d\n",ul_ch1, ul_ch2, pilot_pos1,pilot_pos2);
// #endif
// because of the scaling of alpha and beta we also need to scale the final channel estimate at the pilot positions
// for (k=0; k<frame_parms->symbols_per_tti; k++) {
// 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);
// // we scale alpha and beta by SCALE (instead of 0x7FFF) to avoid overflows
// alpha = (int16_t) (((int32_t) SCALE * (int32_t) (pilot_pos2-k))/(pilot_pos2-pilot_pos1));
// beta = (int16_t) (((int32_t) SCALE * (int32_t) (k-pilot_pos1))/(pilot_pos2-pilot_pos1));
// 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_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_ch2_1,SCALE,(int16_t*) ul_ch2_1,1,Msc_RS);
// }
// #ifdef DEBUG_CH
// msg("lte_ul_channel_estimation: k=%d, alpha = %d, beta = %d\n",k,alpha,beta);
// #endif
// //symbol_offset_subframe = frame_parms->N_RB_UL*12*k;
// // interpolate between estimates
// if ((k != pilot_pos1) && (k != pilot_pos2)) {
// // multadd_complex_vector_real_scalar((int16_t*) ul_ch1,alpha,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
// // multadd_complex_vector_real_scalar((int16_t*) ul_ch2,beta ,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
} //if (Ns&1)
// // multadd_complex_vector_real_scalar((int16_t*) ul_ch1,SCALE,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
// // multadd_complex_vector_real_scalar((int16_t*) ul_ch2,SCALE,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
// // msg("phase = %d\n",ru[2*cmax(((delta_phase/7)*(k-3)),0)]);
} //for(aa=...
// // the phase is linearly interpolated
// current_phase1 = (delta_phase/7)*(k-pilot_pos1);
// current_phase2 = (delta_phase/7)*(k-pilot_pos2);
// // msg("sym: %d, current_phase1: %d, current_phase2: %d\n",k,current_phase1,current_phase2);
// // set the right quadrant
// (current_phase1 > 0) ? (ru1 = ru_90) : (ru1 = ru_90c);
// (current_phase2 > 0) ? (ru2 = ru_90) : (ru2 = ru_90c);
// // take absolute value and clip
// current_phase1 = cmin(abs(current_phase1),127);
// current_phase2 = cmin(abs(current_phase2),127);
} //if(l==...
// // msg("sym: %d, current_phase1: %d, ru: %d + j%d, current_phase2: %d, ru: %d + j%d\n",k,current_phase1,ru1[2*current_phase1],ru1[2*current_phase1+1],current_phase2,ru2[2*current_phase2],ru2[2*current_phase2+1]);
// // rotate channel estimates by estimated phase
// rotate_cpx_vector((int16_t*) ul_ch1,
// &ru1[2*current_phase1],
// (int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],
// Msc_RS,
// 15);
// rotate_cpx_vector((int16_t*) ul_ch2,
// &ru2[2*current_phase2],
// (int16_t*) &tmp_estimates[0],
// Msc_RS,
// 15);
return(0);
}
// // Combine the two rotated estimates
// multadd_complex_vector_real_scalar((int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],SCALE,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
// multadd_complex_vector_real_scalar((int16_t*) &tmp_estimates[0],SCALE,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
// /*
// if ((k<pilot_pos1) || ((k>pilot_pos2))) {
int16_t lte_ul_freq_offset_estimation_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t *ul_ch_estimates,
uint16_t nb_rb)
{
// multadd_complex_vector_real_scalar((int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],SCALE>>1,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
#if defined(__x86_64__) || defined(__i386__)
int k, rb;
int a_idx = 64;
uint8_t conj_flag = 0;
uint8_t output_shift;
// int pilot_pos1 = 3 - frame_parms->Ncp;
// int pilot_pos2 = 10 - 2*frame_parms->Ncp;
int pilot_pos1 = 3;
int pilot_pos2 = 10;
__m128i *ul_ch1 = (__m128i*)&ul_ch_estimates[pilot_pos1*frame_parms->N_RB_UL*12];
__m128i *ul_ch2 = (__m128i*)&ul_ch_estimates[pilot_pos2*frame_parms->N_RB_UL*12];
int32_t avg[2];
int16_t Ravg[2];
Ravg[0]=0;
Ravg[1]=0;
int16_t iv, rv, phase_idx;
__m128i avg128U1, avg128U2, R[3], mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
// round(tan((pi/4)*[1:1:N]/N)*pow2(15))
int16_t alpha[128] = {201, 402, 603, 804, 1006, 1207, 1408, 1610, 1811, 2013, 2215, 2417, 2619, 2822, 3024, 3227, 3431, 3634, 3838, 4042, 4246, 4450, 4655, 4861, 5066, 5272, 5479, 5686, 5893, 6101, 6309, 6518, 6727, 6937, 7147, 7358, 7570, 7782, 7995, 8208, 8422, 8637, 8852, 9068, 9285, 9503, 9721, 9940, 10160, 10381, 10603, 10825, 11049, 11273, 11498, 11725, 11952, 12180, 12410, 12640, 12872, 13104, 13338, 13573, 13809, 14046, 14285, 14525, 14766, 15009, 15253, 15498, 15745, 15993, 16243, 16494, 16747, 17001, 17257, 17515, 17774, 18035, 18298, 18563, 18829, 19098, 19368, 19640, 19915, 20191, 20470, 20750, 21033, 21318, 21605, 21895, 22187, 22481, 22778, 23078, 23380, 23685, 23992, 24302, 24615, 24931, 25250, 25572, 25897, 26226, 26557, 26892, 27230, 27572, 27917, 28266, 28618, 28975, 29335, 29699, 30067, 30440, 30817, 31198, 31583, 31973, 32368, 32767};
// compute log2_maxh (output_shift)
avg128U1 = _mm_setzero_si128();
avg128U2 = _mm_setzero_si128();
for (rb=0; rb<nb_rb; rb++) {
avg128U1 = _mm_add_epi32(avg128U1,_mm_madd_epi16(ul_ch1[0],ul_ch1[0]));
avg128U1 = _mm_add_epi32(avg128U1,_mm_madd_epi16(ul_ch1[1],ul_ch1[1]));
avg128U1 = _mm_add_epi32(avg128U1,_mm_madd_epi16(ul_ch1[2],ul_ch1[2]));
avg128U2 = _mm_add_epi32(avg128U2,_mm_madd_epi16(ul_ch2[0],ul_ch2[0]));
avg128U2 = _mm_add_epi32(avg128U2,_mm_madd_epi16(ul_ch2[1],ul_ch2[1]));
avg128U2 = _mm_add_epi32(avg128U2,_mm_madd_epi16(ul_ch2[2],ul_ch2[2]));
ul_ch1+=3;
ul_ch2+=3;
}
// multadd_complex_vector_real_scalar((int16_t*) &tmp_estimates[0],SCALE>>1,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
avg[0] = (((int*)&avg128U1)[0] +
((int*)&avg128U1)[1] +
((int*)&avg128U1)[2] +
((int*)&avg128U1)[3])/(nb_rb*12);
avg[1] = (((int*)&avg128U2)[0] +
((int*)&avg128U2)[1] +
((int*)&avg128U2)[2] +
((int*)&avg128U2)[3])/(nb_rb*12);
// msg("avg0 = %d, avg1 = %d\n",avg[0],avg[1]);
avg[0] = cmax(avg[0],avg[1]);
avg[1] = log2_approx(avg[0]);
output_shift = cmax(0,avg[1]-10);
//output_shift = (log2_approx(avg[0])/2)+ log2_approx(frame_parms->nb_antennas_rx-1)+1;
// msg("avg= %d, shift = %d\n",avg[0],output_shift);
ul_ch1 = (__m128i*)&ul_ch_estimates[pilot_pos1*frame_parms->N_RB_UL*12];
ul_ch2 = (__m128i*)&ul_ch_estimates[pilot_pos2*frame_parms->N_RB_UL*12];
// correlate and average the 2 channel estimates ul_ch1*ul_ch2
for (rb=0; rb<nb_rb; rb++) {
mmtmpD0 = _mm_madd_epi16(ul_ch1[0],ul_ch2[0]);
mmtmpD1 = _mm_shufflelo_epi16(ul_ch1[0],_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate);
mmtmpD1 = _mm_madd_epi16(mmtmpD1,ul_ch2[0]);
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
R[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
mmtmpD0 = _mm_madd_epi16(ul_ch1[1],ul_ch2[1]);
mmtmpD1 = _mm_shufflelo_epi16(ul_ch1[1],_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate);
mmtmpD1 = _mm_madd_epi16(mmtmpD1,ul_ch2[1]);
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
R[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
mmtmpD0 = _mm_madd_epi16(ul_ch1[2],ul_ch2[2]);
mmtmpD1 = _mm_shufflelo_epi16(ul_ch1[2],_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate);
mmtmpD1 = _mm_madd_epi16(mmtmpD1,ul_ch2[2]);
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
R[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
R[0] = _mm_add_epi16(_mm_srai_epi16(R[0],1),_mm_srai_epi16(R[1],1));
R[0] = _mm_add_epi16(_mm_srai_epi16(R[0],1),_mm_srai_epi16(R[2],1));
Ravg[0] += (((short*)&R)[0] +
((short*)&R)[2] +
((short*)&R)[4] +
((short*)&R)[6])/(nb_rb*4);
Ravg[1] += (((short*)&R)[1] +
((short*)&R)[3] +
((short*)&R)[5] +
((short*)&R)[7])/(nb_rb*4);
ul_ch1+=3;
ul_ch2+=3;
}
// } else {
// phase estimation on Ravg
// Ravg[0] = 56;
// Ravg[1] = 0;
rv = Ravg[0];
iv = Ravg[1];
// multadd_complex_vector_real_scalar((int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],SCALE>>1,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
if (iv<0)
iv = -Ravg[1];
// multadd_complex_vector_real_scalar((int16_t*) &tmp_estimates[0],SCALE>>1,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
if (rv<iv) {
rv = iv;
iv = Ravg[0];
conj_flag = 1;
}
// // multadd_complex_vector_real_scalar((int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],alpha,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
// msg("rv = %d, iv = %d\n",rv,iv);
// msg("max_avg = %d, log2_approx = %d, shift = %d\n",avg[0], avg[1], output_shift);
// // multadd_complex_vector_real_scalar((int16_t*) &tmp_estimates[0],beta ,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
for (k=0; k<6; k++) {
(iv<(((int32_t)(alpha[a_idx]*rv))>>15)) ? (a_idx -= 32>>k) : (a_idx += 32>>k);
}
// }
// */
(conj_flag==1) ? (phase_idx = 127-(a_idx>>1)) : (phase_idx = (a_idx>>1));
// // 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
// // 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);
if (Ravg[1]<0)
phase_idx = -phase_idx;
// // 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);
// // }
return(phase_idx);
#elif defined(__arm__)
return(0);
#endif
}
// }
// } //for(k=...
// // because of the scaling of alpha and beta we also need to scale the final channel estimate at the pilot positions
// // 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);
// // 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_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_ch2_1,SCALE,(int16_t*) ul_ch2_1,1,Msc_RS);
// // }
// } //if (Ns&1)
// } //for(aa=...
// } //if(l==...
// return(0);
// }
// int16_t lte_ul_freq_offset_estimation_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
// int32_t *ul_ch_estimates,
// uint16_t nb_rb)
// {
// #if defined(__x86_64__) || defined(__i386__)
// int k, rb;
// int a_idx = 64;
// uint8_t conj_flag = 0;
// uint8_t output_shift;
// // int pilot_pos1 = 3 - frame_parms->Ncp;
// // int pilot_pos2 = 10 - 2*frame_parms->Ncp;
// int pilot_pos1 = 3;
// int pilot_pos2 = 10;
// __m128i *ul_ch1 = (__m128i*)&ul_ch_estimates[pilot_pos1*frame_parms->N_RB_UL*12];
// __m128i *ul_ch2 = (__m128i*)&ul_ch_estimates[pilot_pos2*frame_parms->N_RB_UL*12];
// int32_t avg[2];
// int16_t Ravg[2];
// Ravg[0]=0;
// Ravg[1]=0;
// int16_t iv, rv, phase_idx;
// __m128i avg128U1, avg128U2, R[3], mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
// // round(tan((pi/4)*[1:1:N]/N)*pow2(15))
// int16_t alpha[128] = {201, 402, 603, 804, 1006, 1207, 1408, 1610, 1811, 2013, 2215, 2417, 2619, 2822, 3024, 3227, 3431, 3634, 3838, 4042, 4246, 4450, 4655, 4861, 5066, 5272, 5479, 5686, 5893, 6101, 6309, 6518, 6727, 6937, 7147, 7358, 7570, 7782, 7995, 8208, 8422, 8637, 8852, 9068, 9285, 9503, 9721, 9940, 10160, 10381, 10603, 10825, 11049, 11273, 11498, 11725, 11952, 12180, 12410, 12640, 12872, 13104, 13338, 13573, 13809, 14046, 14285, 14525, 14766, 15009, 15253, 15498, 15745, 15993, 16243, 16494, 16747, 17001, 17257, 17515, 17774, 18035, 18298, 18563, 18829, 19098, 19368, 19640, 19915, 20191, 20470, 20750, 21033, 21318, 21605, 21895, 22187, 22481, 22778, 23078, 23380, 23685, 23992, 24302, 24615, 24931, 25250, 25572, 25897, 26226, 26557, 26892, 27230, 27572, 27917, 28266, 28618, 28975, 29335, 29699, 30067, 30440, 30817, 31198, 31583, 31973, 32368, 32767};
// // compute log2_maxh (output_shift)
// avg128U1 = _mm_setzero_si128();
// avg128U2 = _mm_setzero_si128();
// for (rb=0; rb<nb_rb; rb++) {
// avg128U1 = _mm_add_epi32(avg128U1,_mm_madd_epi16(ul_ch1[0],ul_ch1[0]));
// avg128U1 = _mm_add_epi32(avg128U1,_mm_madd_epi16(ul_ch1[1],ul_ch1[1]));
// avg128U1 = _mm_add_epi32(avg128U1,_mm_madd_epi16(ul_ch1[2],ul_ch1[2]));
// avg128U2 = _mm_add_epi32(avg128U2,_mm_madd_epi16(ul_ch2[0],ul_ch2[0]));
// avg128U2 = _mm_add_epi32(avg128U2,_mm_madd_epi16(ul_ch2[1],ul_ch2[1]));
// avg128U2 = _mm_add_epi32(avg128U2,_mm_madd_epi16(ul_ch2[2],ul_ch2[2]));
// ul_ch1+=3;
// ul_ch2+=3;
// }
// avg[0] = (((int*)&avg128U1)[0] +
// ((int*)&avg128U1)[1] +
// ((int*)&avg128U1)[2] +
// ((int*)&avg128U1)[3])/(nb_rb*12);
// avg[1] = (((int*)&avg128U2)[0] +
// ((int*)&avg128U2)[1] +
// ((int*)&avg128U2)[2] +
// ((int*)&avg128U2)[3])/(nb_rb*12);
// // msg("avg0 = %d, avg1 = %d\n",avg[0],avg[1]);
// avg[0] = cmax(avg[0],avg[1]);
// avg[1] = log2_approx(avg[0]);
// output_shift = cmax(0,avg[1]-10);
// //output_shift = (log2_approx(avg[0])/2)+ log2_approx(frame_parms->nb_antennas_rx-1)+1;
// // msg("avg= %d, shift = %d\n",avg[0],output_shift);
// ul_ch1 = (__m128i*)&ul_ch_estimates[pilot_pos1*frame_parms->N_RB_UL*12];
// ul_ch2 = (__m128i*)&ul_ch_estimates[pilot_pos2*frame_parms->N_RB_UL*12];
// // correlate and average the 2 channel estimates ul_ch1*ul_ch2
// for (rb=0; rb<nb_rb; rb++) {
// mmtmpD0 = _mm_madd_epi16(ul_ch1[0],ul_ch2[0]);
// mmtmpD1 = _mm_shufflelo_epi16(ul_ch1[0],_MM_SHUFFLE(2,3,0,1));
// mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
// mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate);
// mmtmpD1 = _mm_madd_epi16(mmtmpD1,ul_ch2[0]);
// mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
// mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
// mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
// mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
// R[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
// mmtmpD0 = _mm_madd_epi16(ul_ch1[1],ul_ch2[1]);
// mmtmpD1 = _mm_shufflelo_epi16(ul_ch1[1],_MM_SHUFFLE(2,3,0,1));
// mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
// mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate);
// mmtmpD1 = _mm_madd_epi16(mmtmpD1,ul_ch2[1]);
// mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
// mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
// mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
// mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
// R[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
// mmtmpD0 = _mm_madd_epi16(ul_ch1[2],ul_ch2[2]);
// mmtmpD1 = _mm_shufflelo_epi16(ul_ch1[2],_MM_SHUFFLE(2,3,0,1));
// mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
// mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate);
// mmtmpD1 = _mm_madd_epi16(mmtmpD1,ul_ch2[2]);
// mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
// mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
// mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
// mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
// R[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
// R[0] = _mm_add_epi16(_mm_srai_epi16(R[0],1),_mm_srai_epi16(R[1],1));
// R[0] = _mm_add_epi16(_mm_srai_epi16(R[0],1),_mm_srai_epi16(R[2],1));
// Ravg[0] += (((short*)&R)[0] +
// ((short*)&R)[2] +
// ((short*)&R)[4] +
// ((short*)&R)[6])/(nb_rb*4);
// Ravg[1] += (((short*)&R)[1] +
// ((short*)&R)[3] +
// ((short*)&R)[5] +
// ((short*)&R)[7])/(nb_rb*4);
// ul_ch1+=3;
// ul_ch2+=3;
// }
// // phase estimation on Ravg
// // Ravg[0] = 56;
// // Ravg[1] = 0;
// rv = Ravg[0];
// iv = Ravg[1];
// if (iv<0)
// iv = -Ravg[1];
// if (rv<iv) {
// rv = iv;
// iv = Ravg[0];
// conj_flag = 1;
// }
// // msg("rv = %d, iv = %d\n",rv,iv);
// // msg("max_avg = %d, log2_approx = %d, shift = %d\n",avg[0], avg[1], output_shift);
// for (k=0; k<6; k++) {
// (iv<(((int32_t)(alpha[a_idx]*rv))>>15)) ? (a_idx -= 32>>k) : (a_idx += 32>>k);
// }
// (conj_flag==1) ? (phase_idx = 127-(a_idx>>1)) : (phase_idx = (a_idx>>1));
// if (Ravg[1]<0)
// phase_idx = -phase_idx;
// return(phase_idx);
// #elif defined(__arm__)
// return(0);
// #endif
// }
......@@ -251,5 +251,40 @@ uint16_t get_UL_sc_start_NB_IoT(uint16_t I_sc);
void generate_grouphop_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms);
void init_ul_hopping_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms);
void rotate_single_carrier_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
uint8_t UE_id,
uint8_t symbol,
uint8_t Qm);
void fill_rbs_zeros_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
uint8_t UE_id,
uint8_t symbol);
int32_t ulsch_bpsk_llr_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int16_t *ulsch_llr,
uint8_t symbol,
uint8_t uint8_t,
int16_t **llrp);
int32_t ulsch_qpsk_llr_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int16_t *ulsch_llr,
uint8_t symbol,
uint8_t UE_id,
int16_t **llrp);
void rotate_bpsk_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
uint8_t UE_id,
uint8_t symbol);
//************************************************************//
#endif
......@@ -733,6 +733,7 @@ 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 );
}
*/
/*
// NB_IoT: functions in ulsch_decoding_data_NB_IoT must be defined
......@@ -983,7 +984,7 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
// x1 is set in lte_gold_generic
// 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
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 10.1.3.1
ulsch_harq = ulsch->harq_process;
if (harq_pid==255) {
......@@ -1000,7 +1001,8 @@ unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
/* ----------------------- Segmentation */
nb_rb = ulsch_harq->nb_rb; // nb_rb set but not used ??
// nb_rb = ulsch_harq->nb_rb; // nb_rb set but not used ??
nb_rb = 1; // nb_rb set but not used ??
A = ulsch_harq->TBS;
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;
......
......@@ -64,8 +64,6 @@ void lte_idft_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Ms
uint32_t *z0,*z1,*z2,*z3,*z4,*z5,*z6,*z7,*z8,*z9,*z10=NULL,*z11=NULL;
int i,ip;
// printf("Doing lte_idft for Msc_PUSCH %d\n",Msc_PUSCH);
// Normal prefix
......@@ -100,10 +98,10 @@ void lte_idft_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Ms
*&(((__m128i*)z8)[i])=_mm_sign_epi16(*&(((__m128i*)z8)[i]),*(__m128i*)&conjugate2[0]);
*&(((__m128i*)z9)[i])=_mm_sign_epi16(*&(((__m128i*)z9)[i]),*(__m128i*)&conjugate2[0]);
if (frame_parms->Ncp==NORMAL_NB_IoT) {
// if (frame_parms->Ncp==NORMAL_NB_IoT) {
*&(((__m128i*)z10)[i])=_mm_sign_epi16(*&(((__m128i*)z10)[i]),*(__m128i*)&conjugate2[0]);
*&(((__m128i*)z11)[i])=_mm_sign_epi16(*&(((__m128i*)z11)[i]),*(__m128i*)&conjugate2[0]);
}
// }
#elif defined(__arm__)
*&(((int16x8_t*)z0)[i])=vmulq_s16(*&(((int16x8_t*)z0)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z1)[i])=vmulq_s16(*&(((int16x8_t*)z1)[i]),*(int16x8_t*)&conjugate2[0]);
......@@ -117,10 +115,10 @@ void lte_idft_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Ms
*&(((int16x8_t*)z9)[i])=vmulq_s16(*&(((int16x8_t*)z9)[i]),*(int16x8_t*)&conjugate2[0]);
if (frame_parms->Ncp==NORMAL_NB_IoT) {
// if (frame_parms->Ncp==NORMAL_NB_IoT) {
*&(((int16x8_t*)z10)[i])=vmulq_s16(*&(((int16x8_t*)z10)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z11)[i])=vmulq_s16(*&(((int16x8_t*)z11)[i]),*(int16x8_t*)&conjugate2[0]);
}
// }
#endif
}
......@@ -137,10 +135,10 @@ void lte_idft_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Ms
((uint32_t*)idft_in2)[ip+0] = z8[i];
((uint32_t*)idft_in2)[ip+1] = z9[i];
if (frame_parms->Ncp==0) {
// if (frame_parms->Ncp==0) {
((uint32_t*)idft_in2)[ip+2] = z10[i];
((uint32_t*)idft_in2)[ip+3] = z11[i];
}
// }
}
......@@ -388,10 +386,10 @@ void lte_idft_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Ms
z8[i] = ((uint32_t*)idft_out2)[ip];
z9[i] = ((uint32_t*)idft_out2)[ip+1];
if (frame_parms->Ncp==0) {
// if (frame_parms->Ncp==0) {
z10[i] = ((uint32_t*)idft_out2)[ip+2];
z11[i] = ((uint32_t*)idft_out2)[ip+3];
}
// }
}
// conjugate output
......@@ -408,10 +406,10 @@ void lte_idft_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Ms
((__m128i*)z8)[i]=_mm_sign_epi16(((__m128i*)z8)[i],*(__m128i*)&conjugate2[0]);
((__m128i*)z9)[i]=_mm_sign_epi16(((__m128i*)z9)[i],*(__m128i*)&conjugate2[0]);
if (frame_parms->Ncp==NORMAL_NB_IoT) {
// if (frame_parms->Ncp==NORMAL_NB_IoT) {
((__m128i*)z10)[i]=_mm_sign_epi16(((__m128i*)z10)[i],*(__m128i*)&conjugate2[0]);
((__m128i*)z11)[i]=_mm_sign_epi16(((__m128i*)z11)[i],*(__m128i*)&conjugate2[0]);
}
// }
#elif defined(__arm__)
*&(((int16x8_t*)z0)[i])=vmulq_s16(*&(((int16x8_t*)z0)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z1)[i])=vmulq_s16(*&(((int16x8_t*)z1)[i]),*(int16x8_t*)&conjugate2[0]);
......@@ -425,10 +423,10 @@ void lte_idft_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Ms
*&(((int16x8_t*)z9)[i])=vmulq_s16(*&(((int16x8_t*)z9)[i]),*(int16x8_t*)&conjugate2[0]);
if (frame_parms->Ncp==NORMAL_NB_IoT) {
// if (frame_parms->Ncp==NORMAL_NB_IoT) {
*&(((int16x8_t*)z10)[i])=vmulq_s16(*&(((int16x8_t*)z10)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z11)[i])=vmulq_s16(*&(((int16x8_t*)z11)[i]),*(int16x8_t*)&conjugate2[0]);
}
// }
#endif
}
......@@ -442,40 +440,98 @@ void lte_idft_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Ms
#endif
int32_t ulsch_bpsk_llr_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int16_t *ulsch_llr,
uint8_t symbol,
uint8_t UE_id,
int16_t **llrp)
{
int16_t *rxF;
uint32_t I_sc = eNB->ulsch[UE_id]->harq_process->I_sc; // NB_IoT: subcarrier indication field: must be defined in higher layer
uint16_t ul_sc_start; // subcarrier start index into UL RB
// int i;
ul_sc_start = get_UL_sc_start_NB_IoT(I_sc); // NB-IoT: get the used subcarrier in RB
rxF = (int16_t *)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12) + ul_sc_start];
// printf("qpsk llr for symbol %d (pos %d), llr offset %d\n",symbol,(symbol*frame_parms->N_RB_DL*12),llr128U-(__m128i*)ulsch_llr);
//printf("%d,%d,%d,%d,%d,%d,%d,%d\n",((int16_t *)rxF)[0],((int16_t *)rxF)[1],((int16_t *)rxF)[2],((int16_t *)rxF)[3],((int16_t *)rxF)[4],((int16_t *)rxF)[5],((int16_t *)rxF)[6],((int16_t *)rxF)[7]);
*(*llrp) = *rxF;
//rxF++;
(*llrp)++;
return(0);
}
// int32_t ulsch_qpsk_llr_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
// int32_t **rxdataF_comp,
// int16_t *ulsch_llr,
// uint8_t symbol,
// uint16_t nb_rb,
// int16_t **llrp)
// {
// #if defined(__x86_64__) || defined(__i386__)
// __m128i *rxF=(__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
// __m128i **llrp128 = (__m128i **)llrp;
// #elif defined(__arm__)
// int16x8_t *rxF= (int16x8_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
// int16x8_t **llrp128 = (int16x8_t **)llrp;
// #endif
// int i;
// // printf("qpsk llr for symbol %d (pos %d), llr offset %d\n",symbol,(symbol*frame_parms->N_RB_DL*12),llr128U-(__m128i*)ulsch_llr);
// for (i=0; i<(nb_rb*3); i++) {
// //printf("%d,%d,%d,%d,%d,%d,%d,%d\n",((int16_t *)rxF)[0],((int16_t *)rxF)[1],((int16_t *)rxF)[2],((int16_t *)rxF)[3],((int16_t *)rxF)[4],((int16_t *)rxF)[5],((int16_t *)rxF)[6],((int16_t *)rxF)[7]);
// *(*llrp128) = *rxF;
// rxF++;
// (*llrp128)++;
// }
// #if defined(__x86_64__) || defined(__i386__)
// _mm_empty();
// _m_empty();
// #endif
// return(0);
// }
int32_t ulsch_qpsk_llr_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t ulsch_qpsk_llr_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int16_t *ulsch_llr,
uint8_t symbol,
uint16_t nb_rb,
int16_t *ulsch_llr,
uint8_t symbol,
uint8_t UE_id,
int16_t **llrp)
{
#if defined(__x86_64__) || defined(__i386__)
__m128i *rxF=(__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
__m128i **llrp128 = (__m128i **)llrp;
#elif defined(__arm__)
int16x8_t *rxF= (int16x8_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
int16x8_t **llrp128 = (int16x8_t **)llrp;
#endif
int i;
int32_t *rxF;
int32_t **llrp32 = (int32_t **)llrp;
uint32_t I_sc = eNB->ulsch[UE_id]->harq_process->I_sc; // NB_IoT: subcarrier indication field: must be defined in higher layer
uint16_t ul_sc_start; // subcarrier start index into UL RB
uint8_t Nsc_RU = eNB->ulsch[UE_id]->harq_process->N_sc_RU; // Vincent: number of sc 1,3,6,12
int i;
ul_sc_start = get_UL_sc_start_NB_IoT(I_sc); // NB-IoT: get the used subcarrier in RB
rxF = (int32_t *)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12) + ul_sc_start];
// printf("qpsk llr for symbol %d (pos %d), llr offset %d\n",symbol,(symbol*frame_parms->N_RB_DL*12),llr128U-(__m128i*)ulsch_llr);
for (i=0; i<(nb_rb*3); i++) {
for (i=0; i<Nsc_RU; i++) {
//printf("%d,%d,%d,%d,%d,%d,%d,%d\n",((int16_t *)rxF)[0],((int16_t *)rxF)[1],((int16_t *)rxF)[2],((int16_t *)rxF)[3],((int16_t *)rxF)[4],((int16_t *)rxF)[5],((int16_t *)rxF)[6],((int16_t *)rxF)[7]);
*(*llrp128) = *rxF;
*(*llrp32) = *rxF;
rxF++;
(*llrp128)++;
(*llrp32)++;
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
return(0);
}
......@@ -489,7 +545,6 @@ void ulsch_detection_mrc_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
uint16_t nb_rb)
{
#if defined(__x86_64__) || defined(__i386__)
__m128i *rxdataF_comp128_0,*ul_ch_mag128_0,*ul_ch_mag128_0b;
......@@ -517,6 +572,7 @@ void ulsch_detection_mrc_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
ul_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(ul_ch_mag128_0[i],1),_mm_srai_epi16(ul_ch_mag128_1[i],1));
ul_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(ul_ch_mag128_0b[i],1),_mm_srai_epi16(ul_ch_mag128_1b[i],1));
rxdataF_comp128_0[i] = _mm_add_epi16(rxdataF_comp128_0[i],(*(__m128i*)&jitterc[0]));
}
#elif defined(__arm__)
rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12];
......@@ -532,10 +588,11 @@ void ulsch_detection_mrc_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
ul_ch_mag128_0[i] = vhaddq_s16(ul_ch_mag128_0[i],ul_ch_mag128_1[i]);
ul_ch_mag128_0b[i] = vhaddq_s16(ul_ch_mag128_0b[i],ul_ch_mag128_1b[i]);
rxdataF_comp128_0[i] = vqaddq_s16(rxdataF_comp128_0[i],(*(int16x8_t*)&jitterc[0]));
}
#endif
}
}
#if defined(__x86_64__) || defined(__i386__)
......@@ -629,7 +686,7 @@ void ulsch_channel_compensation_NB_IoT(int32_t **rxdataF_ext,
uint8_t output_shift)
{
uint16_t rb;
// uint16_t rb;
#if defined(__x86_64__) || defined(__i386__)
......@@ -658,25 +715,25 @@ void ulsch_channel_compensation_NB_IoT(int32_t **rxdataF_ext,
#endif
#ifdef OFDMA_ULSCH
// #ifdef OFDMA_ULSCH
#if defined(__x86_64__) || defined(__i386__)
if (Qm == 4)
QAM_amp128U = _mm_set1_epi16(QAM16_n1);
else if (Qm == 6) {
QAM_amp128U = _mm_set1_epi16(QAM64_n1);
QAM_amp128bU = _mm_set1_epi16(QAM64_n2);
}
#elif defined(__arm__)
if (Qm == 4)
QAM_amp128U = vdupq_n_s16(QAM16_n1);
else if (Qm == 6) {
QAM_amp128U = vdupq_n_s16(QAM64_n1);
QAM_amp128bU = vdupq_n_s16(QAM64_n2);
}
// #if defined(__x86_64__) || defined(__i386__)
// if (Qm == 4)
// QAM_amp128U = _mm_set1_epi16(QAM16_n1);
// else if (Qm == 6) {
// QAM_amp128U = _mm_set1_epi16(QAM64_n1);
// QAM_amp128bU = _mm_set1_epi16(QAM64_n2);
// }
// #elif defined(__arm__)
// if (Qm == 4)
// QAM_amp128U = vdupq_n_s16(QAM16_n1);
// else if (Qm == 6) {
// QAM_amp128U = vdupq_n_s16(QAM64_n1);
// QAM_amp128bU = vdupq_n_s16(QAM64_n2);
// }
#endif
#endif
// #endif
// #endif
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
......@@ -698,78 +755,78 @@ void ulsch_channel_compensation_NB_IoT(int32_t **rxdataF_ext,
rxdataF_comp128 = (int16x8_t *)&rxdataF_comp[aarx][symbol*frame_parms->N_RB_DL*12];
#endif
for (rb=0; rb<nb_rb; rb++) {
// for (rb=0; rb<nb_rb; rb++) {
// printf("comp: symbol %d rb %d\n",symbol,rb);
#ifdef OFDMA_ULSCH
if (Qm>2) {
// get channel amplitude if not QPSK
#if defined(__x86_64__) || defined(__i386__)
mmtmpU0 = _mm_madd_epi16(ul_ch128[0],ul_ch128[0]);
mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
mmtmpU1 = _mm_madd_epi16(ul_ch128[1],ul_ch128[1]);
mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
mmtmpU0 = _mm_packs_epi32(mmtmpU0,mmtmpU1);
ul_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpU0,mmtmpU0);
ul_ch_mag128b[0] = ul_ch_mag128[0];
ul_ch_mag128[0] = _mm_mulhi_epi16(ul_ch_mag128[0],QAM_amp128U);
ul_ch_mag128[0] = _mm_slli_epi16(ul_ch_mag128[0],2); // 2 to compensate the scale channel estimate
ul_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpU0,mmtmpU0);
ul_ch_mag128b[1] = ul_ch_mag128[1];
ul_ch_mag128[1] = _mm_mulhi_epi16(ul_ch_mag128[1],QAM_amp128U);
ul_ch_mag128[1] = _mm_slli_epi16(ul_ch_mag128[1],2); // 2 to compensate the scale channel estimate
mmtmpU0 = _mm_madd_epi16(ul_ch128[2],ul_ch128[2]);
mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
mmtmpU1 = _mm_packs_epi32(mmtmpU0,mmtmpU0);
ul_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpU1,mmtmpU1);
ul_ch_mag128b[2] = ul_ch_mag128[2];
ul_ch_mag128[2] = _mm_mulhi_epi16(ul_ch_mag128[2],QAM_amp128U);
ul_ch_mag128[2] = _mm_slli_epi16(ul_ch_mag128[2],2); // 2 to compensate the scale channel estimate
// #ifdef OFDMA_ULSCH
// if (Qm>2) {
// // get channel amplitude if not QPSK
// #if defined(__x86_64__) || defined(__i386__)
// mmtmpU0 = _mm_madd_epi16(ul_ch128[0],ul_ch128[0]);
ul_ch_mag128b[0] = _mm_mulhi_epi16(ul_ch_mag128b[0],QAM_amp128bU);
ul_ch_mag128b[0] = _mm_slli_epi16(ul_ch_mag128b[0],2); // 2 to compensate the scale channel estimate
// mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
// mmtmpU1 = _mm_madd_epi16(ul_ch128[1],ul_ch128[1]);
// mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
// mmtmpU0 = _mm_packs_epi32(mmtmpU0,mmtmpU1);
ul_ch_mag128b[1] = _mm_mulhi_epi16(ul_ch_mag128b[1],QAM_amp128bU);
ul_ch_mag128b[1] = _mm_slli_epi16(ul_ch_mag128b[1],2); // 2 to compensate the scale channel estimate
// ul_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpU0,mmtmpU0);
// ul_ch_mag128b[0] = ul_ch_mag128[0];
// ul_ch_mag128[0] = _mm_mulhi_epi16(ul_ch_mag128[0],QAM_amp128U);
// ul_ch_mag128[0] = _mm_slli_epi16(ul_ch_mag128[0],2); // 2 to compensate the scale channel estimate
// ul_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpU0,mmtmpU0);
// ul_ch_mag128b[1] = ul_ch_mag128[1];
// ul_ch_mag128[1] = _mm_mulhi_epi16(ul_ch_mag128[1],QAM_amp128U);
// ul_ch_mag128[1] = _mm_slli_epi16(ul_ch_mag128[1],2); // 2 to compensate the scale channel estimate
ul_ch_mag128b[2] = _mm_mulhi_epi16(ul_ch_mag128b[2],QAM_amp128bU);
ul_ch_mag128b[2] = _mm_slli_epi16(ul_ch_mag128b[2],2);// 2 to compensate the scale channel estimate
// mmtmpU0 = _mm_madd_epi16(ul_ch128[2],ul_ch128[2]);
// mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
// mmtmpU1 = _mm_packs_epi32(mmtmpU0,mmtmpU0);
#elif defined(__arm__)
mmtmpU0 = vmull_s16(ul_ch128[0], ul_ch128[0]);
mmtmpU0 = vqshlq_s32(vqaddq_s32(mmtmpU0,vrev64q_s32(mmtmpU0)),-output_shift128);
mmtmpU1 = vmull_s16(ul_ch128[1], ul_ch128[1]);
mmtmpU1 = vqshlq_s32(vqaddq_s32(mmtmpU1,vrev64q_s32(mmtmpU1)),-output_shift128);
mmtmpU2 = vcombine_s16(vmovn_s32(mmtmpU0),vmovn_s32(mmtmpU1));
mmtmpU0 = vmull_s16(ul_ch128[2], ul_ch128[2]);
mmtmpU0 = vqshlq_s32(vqaddq_s32(mmtmpU0,vrev64q_s32(mmtmpU0)),-output_shift128);
mmtmpU1 = vmull_s16(ul_ch128[3], ul_ch128[3]);
mmtmpU1 = vqshlq_s32(vqaddq_s32(mmtmpU1,vrev64q_s32(mmtmpU1)),-output_shift128);
mmtmpU3 = vcombine_s16(vmovn_s32(mmtmpU0),vmovn_s32(mmtmpU1));
mmtmpU0 = vmull_s16(ul_ch128[4], ul_ch128[4]);
mmtmpU0 = vqshlq_s32(vqaddq_s32(mmtmpU0,vrev64q_s32(mmtmpU0)),-output_shift128);
mmtmpU1 = vmull_s16(ul_ch128[5], ul_ch128[5]);
mmtmpU1 = vqshlq_s32(vqaddq_s32(mmtmpU1,vrev64q_s32(mmtmpU1)),-output_shift128);
mmtmpU4 = vcombine_s16(vmovn_s32(mmtmpU0),vmovn_s32(mmtmpU1));
ul_ch_mag128b[0] = vqdmulhq_s16(mmtmpU2,QAM_amp128b);
ul_ch_mag128b[1] = vqdmulhq_s16(mmtmpU3,QAM_amp128b);
ul_ch_mag128[0] = vqdmulhq_s16(mmtmpU2,QAM_amp128);
ul_ch_mag128[1] = vqdmulhq_s16(mmtmpU3,QAM_amp128);
ul_ch_mag128b[2] = vqdmulhq_s16(mmtmpU4,QAM_amp128b);
ul_ch_mag128[2] = vqdmulhq_s16(mmtmpU4,QAM_amp128);
#endif
}
// ul_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpU1,mmtmpU1);
// ul_ch_mag128b[2] = ul_ch_mag128[2];
// ul_ch_mag128[2] = _mm_mulhi_epi16(ul_ch_mag128[2],QAM_amp128U);
// ul_ch_mag128[2] = _mm_slli_epi16(ul_ch_mag128[2],2); // 2 to compensate the scale channel estimate
// ul_ch_mag128b[0] = _mm_mulhi_epi16(ul_ch_mag128b[0],QAM_amp128bU);
// ul_ch_mag128b[0] = _mm_slli_epi16(ul_ch_mag128b[0],2); // 2 to compensate the scale channel estimate
// ul_ch_mag128b[1] = _mm_mulhi_epi16(ul_ch_mag128b[1],QAM_amp128bU);
// ul_ch_mag128b[1] = _mm_slli_epi16(ul_ch_mag128b[1],2); // 2 to compensate the scale channel estimate
// ul_ch_mag128b[2] = _mm_mulhi_epi16(ul_ch_mag128b[2],QAM_amp128bU);
// ul_ch_mag128b[2] = _mm_slli_epi16(ul_ch_mag128b[2],2);// 2 to compensate the scale channel estimate
// #elif defined(__arm__)
// mmtmpU0 = vmull_s16(ul_ch128[0], ul_ch128[0]);
// mmtmpU0 = vqshlq_s32(vqaddq_s32(mmtmpU0,vrev64q_s32(mmtmpU0)),-output_shift128);
// mmtmpU1 = vmull_s16(ul_ch128[1], ul_ch128[1]);
// mmtmpU1 = vqshlq_s32(vqaddq_s32(mmtmpU1,vrev64q_s32(mmtmpU1)),-output_shift128);
// mmtmpU2 = vcombine_s16(vmovn_s32(mmtmpU0),vmovn_s32(mmtmpU1));
// mmtmpU0 = vmull_s16(ul_ch128[2], ul_ch128[2]);
// mmtmpU0 = vqshlq_s32(vqaddq_s32(mmtmpU0,vrev64q_s32(mmtmpU0)),-output_shift128);
// mmtmpU1 = vmull_s16(ul_ch128[3], ul_ch128[3]);
// mmtmpU1 = vqshlq_s32(vqaddq_s32(mmtmpU1,vrev64q_s32(mmtmpU1)),-output_shift128);
// mmtmpU3 = vcombine_s16(vmovn_s32(mmtmpU0),vmovn_s32(mmtmpU1));
// mmtmpU0 = vmull_s16(ul_ch128[4], ul_ch128[4]);
// mmtmpU0 = vqshlq_s32(vqaddq_s32(mmtmpU0,vrev64q_s32(mmtmpU0)),-output_shift128);
// mmtmpU1 = vmull_s16(ul_ch128[5], ul_ch128[5]);
// mmtmpU1 = vqshlq_s32(vqaddq_s32(mmtmpU1,vrev64q_s32(mmtmpU1)),-output_shift128);
// mmtmpU4 = vcombine_s16(vmovn_s32(mmtmpU0),vmovn_s32(mmtmpU1));
// ul_ch_mag128b[0] = vqdmulhq_s16(mmtmpU2,QAM_amp128b);
// ul_ch_mag128b[1] = vqdmulhq_s16(mmtmpU3,QAM_amp128b);
// ul_ch_mag128[0] = vqdmulhq_s16(mmtmpU2,QAM_amp128);
// ul_ch_mag128[1] = vqdmulhq_s16(mmtmpU3,QAM_amp128);
// ul_ch_mag128b[2] = vqdmulhq_s16(mmtmpU4,QAM_amp128b);
// ul_ch_mag128[2] = vqdmulhq_s16(mmtmpU4,QAM_amp128);
// #endif
// }
#else // SC-FDMA
// #else // SC-FDMA
// just compute channel magnitude without scaling, this is done after equalization for SC-FDMA
#if defined(__x86_64__) || defined(__i386__)
......@@ -812,7 +869,7 @@ void ulsch_channel_compensation_NB_IoT(int32_t **rxdataF_ext,
ul_ch_mag128[2] = vcombine_s16(vmovn_s32(mmtmpU0),vmovn_s32(mmtmpU1));
#endif
#endif
// #endif
#if defined(__x86_64__) || defined(__i386__)
// multiply by conjugated channel
......@@ -946,7 +1003,7 @@ void ulsch_channel_compensation_NB_IoT(int32_t **rxdataF_ext,
rxdataF_comp128+=3;
#endif
}
// }
}
#if defined(__x86_64__) || defined(__i386__)
......@@ -1248,8 +1305,98 @@ void ulsch_channel_compensation_NB_IoT(int32_t **rxdataF_ext,
// #endif
// }
void fill_rbs_zeros_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
uint8_t UE_id,
uint8_t symbol)
{
uint32_t I_sc = eNB->ulsch[UE_id]->harq_process->I_sc; // NB_IoT: subcarrier indication field: must be defined in higher layer
uint8_t Nsc_RU = eNB->ulsch[UE_id]->harq_process->N_sc_RU; // Vincent: number of sc 1,3,6,12
uint16_t ul_sc_start; // subcarrier start index into UL RB
int32_t *rxdataF_comp32;
uint8_t m; // index of subcarrier
ul_sc_start = get_UL_sc_start_NB_IoT(I_sc); // NB-IoT: get the used subcarrier in RB
rxdataF_comp32 = (int32_t *)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12];
if (Nsc_RU != 12){
for (m=0;m<12;m++){ // 12 is the number of subcarriers per RB
if (m == ul_sc_start){
m = m + Nsc_RU; // skip non-zeros subcarriers
}
rxdataF_comp32[m] = 0;
}
}
}
void rotate_single_carrier_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
uint8_t UE_id,
uint8_t symbol,
uint8_t Qm)
{
uint32_t I_sc = eNB->ulsch[UE_id]->harq_process->I_sc; // NB_IoT: subcarrier indication field: must be defined in higher layer
uint16_t ul_sc_start; // subcarrier start index into UL RB
int16_t pi_2_re[2] = {32767 , 0};
int16_t pi_2_im[2] = {0 , 32768};
int16_t pi_4_re[2] = {32767 , 25735};
int16_t pi_4_im[2] = {0 , 25736};
int16_t *rxdataF_comp16;
int16_t rxdataF_comp16_re, rxdataF_comp16_im;
ul_sc_start = get_UL_sc_start_NB_IoT(I_sc); // NB-IoT: get the used subcarrier in RB
rxdataF_comp16 = (int16_t *)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12 + ul_sc_start];
rxdataF_comp16_re = rxdataF_comp16[0];
rxdataF_comp16_im = rxdataF_comp16[1];
if (Qm == 1){
rxdataF_comp16[0] = (int16_t)(((int32_t)pi_2_re[symbol%2] * (int32_t)rxdataF_comp16_re +
(int32_t)pi_2_im[symbol%2] * (int32_t)rxdataF_comp16_im)>>15);
rxdataF_comp16[1] = (int16_t)(((int32_t)pi_2_re[symbol%1] * (int32_t)rxdataF_comp16_im -
(int32_t)pi_2_im[symbol%2] * (int32_t)rxdataF_comp16_re)>>15);
}
if(Qm == 2){
rxdataF_comp16[0] = (int16_t)(((int32_t)pi_4_re[symbol%2] * (int32_t)rxdataF_comp16_re +
(int32_t)pi_4_im[symbol%2] * (int32_t)rxdataF_comp16_im)>>15);
rxdataF_comp16[1] = (int16_t)(((int32_t)pi_4_re[symbol%1] * (int32_t)rxdataF_comp16_im -
(int32_t)pi_4_im[symbol%2] * (int32_t)rxdataF_comp16_re)>>15);
}
}
void rotate_bpsk_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
uint8_t UE_id,
uint8_t symbol)
{
uint32_t I_sc = eNB->ulsch[UE_id]->harq_process->I_sc; // NB_IoT: subcarrier indication field: must be defined in higher layer
uint16_t ul_sc_start; // subcarrier start index into UL RB
int16_t m_pi_4_re = 25735; // cos(pi/4)
int16_t m_pi_4_im = 25736; // sin(pi/4)
int16_t *rxdataF_comp16;
int16_t rxdataF_comp16_re, rxdataF_comp16_im;
ul_sc_start = get_UL_sc_start_NB_IoT(I_sc); // NB-IoT: get the used subcarrier in RB
rxdataF_comp16 = (int16_t *)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12 + ul_sc_start];
rxdataF_comp16_re = rxdataF_comp16[0];
rxdataF_comp16_im = rxdataF_comp16[1];
rxdataF_comp16[0] = (int16_t)(((int32_t)m_pi_4_re * (int32_t)rxdataF_comp16_re +
(int32_t)m_pi_4_im * (int32_t)rxdataF_comp16_im)>>15);
rxdataF_comp16[1] = (int16_t)(((int32_t)m_pi_4_re * (int32_t)rxdataF_comp16_im -
(int32_t)m_pi_4_im * (int32_t)rxdataF_comp16_re)>>15);
}
/*
void ulsch_alamouti_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,// For Distributed Alamouti Receiver Combining
int32_t **rxdataF_comp,
......@@ -1340,7 +1487,7 @@ void ulsch_channel_level_NB_IoT(int32_t **drs_ch_estimates_ext,
uint16_t nb_rb)
{
int16_t rb;
// int16_t rb;
uint8_t aarx;
#if defined(__x86_64__) || defined(__i386__)
__m128i *ul_ch128;
......@@ -1423,7 +1570,10 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
uint8_t Qm;
uint16_t rx_power_correction;
int16_t *llrp;
int subframe = proc->subframe_rx;
int subframe = proc->subframe_rx;
uint8_t npusch_format = 1; // NB-IoT: format 1 (data), or 2: ack. Should be defined in higher layer
uint8_t Nsc_RU = eNB->ulsch[UE_id]->harq_process->N_sc_RU; // Vincent: number of sc 1,3,6,12
harq_pid = subframe2harq_pid_NB_IoT(frame_parms,proc->frame_rx,subframe);
Qm = get_Qm_ul_NB_IoT(ulsch[UE_id]->harq_process->mcs,ulsch[UE_id]->harq_process->N_sc_RU);
......@@ -1448,12 +1598,19 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
l/(frame_parms->symbols_per_tti/2),
frame_parms);
lte_ul_channel_estimation_NB_IoT(eNB,proc,
// lte_ul_channel_estimation_NB_IoT(eNB,proc,
// eNB_id,
// UE_id,
// l%(frame_parms->symbols_per_tti/2),
// l/(frame_parms->symbols_per_tti/2),
// cooperation_flag);
ul_channel_estimation_NB_IoT(eNB,proc,
eNB_id,
UE_id,
l%(frame_parms->symbols_per_tti/2),
l/(frame_parms->symbols_per_tti/2),
cooperation_flag);
cooperation_flag);
}
// if(cooperation_flag == 2) {
......@@ -1548,12 +1705,18 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
//}
for (l=0; l<frame_parms->symbols_per_tti; l++) {
if (((frame_parms->Ncp == 0) && ((l==3) || (l==10)))|| // skip pilots
((frame_parms->Ncp == 1) && ((l==2) || (l==8)))) {
l++;
if (npusch_format == 1){
if (l==3 || l==10) // skip pilots
{
l++;
}
}
if (npusch_format == 2){
if (l == 2 || l == 9) // skip 3 pilots
{
l = l + 3;
}
}
// if(cooperation_flag == 2) {
// ulsch_channel_compensation_alamouti_NB_IoT(
......@@ -1619,23 +1782,38 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
l,
ulsch[UE_id]->harq_process->nb_rb);
#ifndef OFDMA_ULSCH
// #ifndef OFDMA_ULSCH
if ((eNB->measurements->n0_power_dB[0]+3)<pusch_vars->ulsch_power[0]) {
// if ((eNB->measurements->n0_power_dB[0]+3)<pusch_vars->ulsch_power[0]) {
// freq_equalization_NB_IoT(frame_parms,
// pusch_vars->rxdataF_comp[eNB_id],
// pusch_vars->ul_ch_mag[eNB_id],
// pusch_vars->ul_ch_magb[eNB_id],
// l,
// ulsch[UE_id]->harq_process->nb_rb*12,
// Qm);
freq_equalization_NB_IoT(frame_parms,
pusch_vars->rxdataF_comp[eNB_id],
pusch_vars->ul_ch_mag[eNB_id],
pusch_vars->ul_ch_magb[eNB_id],
l,
ulsch[UE_id]->harq_process->nb_rb*12,
12,
Qm);
}
// }
// #endif
// this function is added in to fill the RB resource elements with zeros
// before processing the IFDT, in order to avoid absurd values
fill_rbs_zeros_NB_IoT(eNB,
frame_parms,
pusch_vars->rxdataF_comp[eNB_id],
UE_id,
l);
#endif
}
#ifndef OFDMA_ULSCH
// #ifndef OFDMA_ULSCH
//#ifdef DEBUG_ULSCH
// Inverse-Transform equalized outputs
......@@ -1652,7 +1830,7 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
// printf("Done\n");
//#endif //DEBUG_ULSCH
#endif
// #endif
......@@ -1666,21 +1844,73 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
for (l=0; l<frame_parms->symbols_per_tti; l++) {
if (((frame_parms->Ncp == 0) && ((l==3) || (l==10)))|| // skip pilots
((frame_parms->Ncp == 1) && ((l==2) || (l==8)))) {
l++;
// if (((frame_parms->Ncp == 0) && ((l==3) || (l==10)))|| // skip pilots
// ((frame_parms->Ncp == 1) && ((l==2) || (l==8)))) {
// l++;
// }
if (npusch_format == 1){
if (l==3 || l==10) // skip pilots
{
l++;
}
// In case of 1 subcarrier: BPSK and QPSK should be rotated by pi/2 and pi/4, respectively
if (Nsc_RU == 1){
rotate_single_carrier_NB_IoT(eNB,
frame_parms,
pusch_vars->rxdataF_comp[eNB_id],
UE_id,
l,
Qm);
}
}
if (npusch_format == 2){
if (l == 2 || l == 9) // skip 3 pilots
{
l = l + 3;
}
// In case of 1 subcarrier: BPSK and QPSK must be rotated by pi/2 and pi/4, respectively
rotate_single_carrier_NB_IoT(eNB,
frame_parms,
pusch_vars->rxdataF_comp[eNB_id],
UE_id,
l,
Qm);
}
switch (Qm) {
case 1:
printf("To be developped\n");
// In case of BPSK, apply a phase rotation of pi/4 before llr, see 36.211, Table 7.1.1-1
rotate_bpsk_NB_IoT(eNB,
frame_parms,
pusch_vars->rxdataF_comp[eNB_id],
UE_id,
l);
// BPSK always corresponds to single-carrier
ulsch_bpsk_llr_NB_IoT(eNB,
frame_parms,
pusch_vars->rxdataF_comp[eNB_id],
pusch_vars->llr,
l,
UE_id,
&llrp);
break;
case 2:
ulsch_qpsk_llr_NB_IoT(frame_parms,
ulsch_qpsk_llr_NB_IoT(eNB,
frame_parms,
pusch_vars->rxdataF_comp[eNB_id],
pusch_vars->llr,
l,
ulsch[UE_id]->harq_process->nb_rb,
UE_id,
&llrp);
break;
......
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