Commit e860b674 authored by Vincent Savaux's avatar Vincent Savaux

Adapt channel estimation to 1,3,6,12 subcarriers

parent aef1e0d5
......@@ -45,6 +45,17 @@ int lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB,
uint8_t Ns,
uint8_t cooperation_flag);
////////// Vincent: NB-IoT specific adapted function for channel estimation ////////////////////
int 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);
////////////////////////////////////////////////////////////////////////////////////////////////
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);
......
......@@ -42,7 +42,7 @@ uint16_t dftsizes[33] = {12,24,36,48,60,72,96,108,120,144,180,192,216,240,288,30
uint16_t ref_primes[33] = {11,23,31,47,59,71,89,107,113,139,179,191,211,239,283,293,317,359,383,431,479,523,571,599,647,719,863,887,953,971,1069,1151,1193};
uint16_t sequence_length[4] = {2048,3,6,12}; //the "32" value corresponds to the max gold sequence length
uint16_t sequence_length[4] = {32,3,6,12}; //the "32" value corresponds to the max gold sequence length
// int16_t *ul_ref_sigs[30][33];
int16_t *ul_ref_sigs_rx[30][4]; //these contain the sequences in repeated format and quantized to QPSK ifdef IFFT_FPGA
......@@ -83,6 +83,8 @@ int16_t w_n[256] = {
1,-1,-1, 1,-1, 1, 1,-1,-1, 1, 1,-1, 1,-1,-1, 1
};
// void generate_ul_ref_sigs(void)
// {
// double qbar,phase;
......@@ -181,7 +183,7 @@ void generate_ul_ref_sigs_rx_NB_IoT(void)
for (n=0; n<sequence_length[index_Nsc_RU]; n++) {
// ul_ref_sigs_rx[u][index_Nsc_RU][n<<1] = ref_sigs_sc1[n<<1];
// ul_ref_sigs_rx[u][index_Nsc_RU][1+(n<<1)]= ref_sigs_sc1[1+(n<<1)];
ul_ref_sigs_rx[u][index_Nsc_RU][12*n<<1+24] = ref_sigs_sc1[n<<1]; // ul_ref_sigs_rx is filled every 12 RE, real part
ul_ref_sigs_rx[u][index_Nsc_RU][12*(n<<1)+24] = ref_sigs_sc1[n<<1]; // ul_ref_sigs_rx is filled every 12 RE, real part
ul_ref_sigs_rx[u][index_Nsc_RU][1+12*(n<<1)+24]= ref_sigs_sc1[1+(n<<1)]; // ul_ref_sigs_rx is filled every 12 RE, imaginary part
}
}
......@@ -194,7 +196,7 @@ void generate_ul_ref_sigs_rx_NB_IoT(void)
for (n=0; n<sequence_length[index_Nsc_RU]; n++) {
// ul_ref_sigs_rx[u][index_Nsc_RU][n<<1] = (int16_t)(floor(32767*cos(M_PI*ref3[(u*3) + n]/4 + alpha3[threetnecyclicshift])));
// ul_ref_sigs_rx[u][index_Nsc_RU][1+(n<<1)]= (int16_t)(floor(32767*sin(M_PI*ref3[(u*3) + n]/4 + alpha3[threetnecyclicshift])));
ul_ref_sigs_rx[u][index_Nsc_RU][n<<1+24] = (int16_t)(floor(32767*cos(M_PI*ref3[(u*3) + n]/4 )));
ul_ref_sigs_rx[u][index_Nsc_RU][(n<<1)+24] = (int16_t)(floor(32767*cos(M_PI*ref3[(u*3) + n]/4 )));
ul_ref_sigs_rx[u][index_Nsc_RU][1+(n<<1)+24]= (int16_t)(floor(32767*sin(M_PI*ref3[(u*3) + n]/4 )));
}
break;
......@@ -203,7 +205,7 @@ void generate_ul_ref_sigs_rx_NB_IoT(void)
for (n=0; n<sequence_length[index_Nsc_RU]; n++) {
// ul_ref_sigs_rx[u][index_Nsc_RU][n<<1] = (int16_t)(floor(32767*cos(M_PI*ref6[(u*6) + n]/4 + alpha6[sixtonecyclichift])));
// ul_ref_sigs_rx[u][index_Nsc_RU][1+(n<<1)]= (int16_t)(floor(32767*sin(M_PI*ref6[(u*6) + n]/4 + alpha6[sixtonecyclichift])));
ul_ref_sigs_rx[u][index_Nsc_RU][n<<1+24] = (int16_t)(floor(32767*cos(M_PI*ref6[(u*6) + n]/4 )));
ul_ref_sigs_rx[u][index_Nsc_RU][(n<<1)+24] = (int16_t)(floor(32767*cos(M_PI*ref6[(u*6) + n]/4 )));
ul_ref_sigs_rx[u][index_Nsc_RU][1+(n<<1)+24]= (int16_t)(floor(32767*sin(M_PI*ref6[(u*6) + n]/4 )));
}
break;
......
......@@ -223,7 +223,7 @@ void ulsch_extract_rbs_single_NB_IoT(int32_t **rxdataF,
// uint32_t first_rb,
uint32_t UL_RB_ID_NB_IoT, // index of UL NB_IoT resource block
uint8_t N_sc_RU, // number of subcarriers in UL
uint32_t I_sc, // subcarrier indication field
// uint32_t I_sc, // subcarrier indication field
uint32_t nb_rb,
uint8_t l,
uint8_t Ns,
......
......@@ -549,7 +549,7 @@ void ulsch_extract_rbs_single_NB_IoT(int32_t **rxdataF,
// uint32_t first_rb,
uint32_t UL_RB_ID_NB_IoT, // index of UL NB_IoT resource block
uint8_t N_sc_RU, // number of subcarriers in UL
uint32_t I_sc, // NB_IoT: subcarrier indication field: must be defined in higher layer
// uint32_t I_sc, // NB_IoT: subcarrier indication field: must be defined in higher layer
uint32_t nb_rb,
uint8_t l,
uint8_t Ns,
......@@ -560,10 +560,10 @@ void ulsch_extract_rbs_single_NB_IoT(int32_t **rxdataF,
uint8_t aarx,n;
// int32_t *rxF,*rxF_ext;
//uint8_t symbol = l+Ns*frame_parms->symbols_per_tti/2;
uint8_t symbol = l+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame
uint16_t ul_sc_start; // subcarrier start index into UL RB
uint8_t symbol = l+(7*(Ns&1)); ///symbol within sub-frame
// uint16_t ul_sc_start; // subcarrier start index into UL RB
ul_sc_start = get_UL_sc_start_NB_IoT(I_sc);
// ul_sc_start = get_UL_sc_start_NB_IoT(I_sc);
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
......@@ -574,9 +574,10 @@ void ulsch_extract_rbs_single_NB_IoT(int32_t **rxdataF,
if (nb_rb1) { // RB NB-IoT is in the first half
for (n=0;n<N_sc_RU;n++){
for (n=0;n<12;n++){ // extract whole RB of 12 subcarriers
// Note that FFT splits the RBs
rxdataF_ext[aarx][symbol*frame_parms->N_RB_UL*12 + n] = rxdataF[aarx][UL_RB_ID_NB_IoT*12 + ul_sc_start + frame_parms->first_carrier_offset + symbol*frame_parms->ofdm_symbol_size + n];
// rxdataF_ext[aarx][symbol*frame_parms->N_RB_UL*12 + n] = rxdataF[aarx][UL_RB_ID_NB_IoT*12 + ul_sc_start + frame_parms->first_carrier_offset + symbol*frame_parms->ofdm_symbol_size + n];
rxdataF_ext[aarx][symbol*frame_parms->N_RB_UL*12 + n] = rxdataF[aarx][UL_RB_ID_NB_IoT*12 + frame_parms->first_carrier_offset + symbol*frame_parms->ofdm_symbol_size + n];
}
......@@ -595,9 +596,11 @@ void ulsch_extract_rbs_single_NB_IoT(int32_t **rxdataF,
// }
} else { // RB NB-IoT is in the second half
for (n=0;n<N_sc_RU;n++){
for (n=0;n<12;n++){ // extract whole RB of 12 subcarriers
// Note that FFT splits the RBs
rxdataF_ext[aarx][symbol*frame_parms->N_RB_UL*12 + n] = rxdataF[aarx][6*(2*UL_RB_ID_NB_IoT - frame_parms->N_RB_UL) + ul_sc_start + symbol*frame_parms->ofdm_symbol_size + n];
// rxdataF_ext[aarx][symbol*frame_parms->N_RB_UL*12 + n] = rxdataF[aarx][6*(2*UL_RB_ID_NB_IoT - frame_parms->N_RB_UL) + ul_sc_start + symbol*frame_parms->ofdm_symbol_size + n];
rxdataF_ext[aarx][symbol*frame_parms->N_RB_UL*12 + n] = rxdataF[aarx][6*(2*UL_RB_ID_NB_IoT - frame_parms->N_RB_UL) + symbol*frame_parms->ofdm_symbol_size + n];
}
......@@ -1350,7 +1353,7 @@ void ulsch_channel_level_NB_IoT(int32_t **drs_ch_estimates_ext,
avg128U = _mm_setzero_si128();
ul_ch128=(__m128i *)drs_ch_estimates_ext[aarx];
for (rb=0; rb<nb_rb; rb++) {
// for (rb=0; rb<nb_rb; rb++) {
avg128U = _mm_add_epi32(avg128U,_mm_madd_epi16(ul_ch128[0],ul_ch128[0]));
avg128U = _mm_add_epi32(avg128U,_mm_madd_epi16(ul_ch128[1],ul_ch128[1]));
......@@ -1359,13 +1362,13 @@ void ulsch_channel_level_NB_IoT(int32_t **drs_ch_estimates_ext,
ul_ch128+=3;
}
// }
#elif defined(__arm__)
avg128U = vdupq_n_s32(0);
ul_ch128=(int16x4_t *)drs_ch_estimates_ext[aarx];
for (rb=0; rb<nb_rb; rb++) {
// for (rb=0; rb<nb_rb; rb++) {
avg128U = vqaddq_s32(avg128U,vmull_s16(ul_ch128[0],ul_ch128[0]));
avg128U = vqaddq_s32(avg128U,vmull_s16(ul_ch128[1],ul_ch128[1]));
......@@ -1376,7 +1379,7 @@ void ulsch_channel_level_NB_IoT(int32_t **drs_ch_estimates_ext,
ul_ch128+=6;
}
// }
#endif
......@@ -1439,7 +1442,7 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
// ulsch[UE_id]->harq_process->first_rb,
ulsch[UE_id]->harq_process->UL_RB_ID_NB_IoT, // index of UL NB_IoT resource block
ulsch[UE_id]->harq_process->N_sc_RU, // number of subcarriers in UL
ulsch[UE_id]->harq_process->I_sc, // subcarrier indication field
// ulsch[UE_id]->harq_process->I_sc, // subcarrier indication field
ulsch[UE_id]->harq_process->nb_rb,
l%(frame_parms->symbols_per_tti/2),
l/(frame_parms->symbols_per_tti/2),
......@@ -1468,14 +1471,15 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
*/
//////////////////////// NB_IoT: maybe, should be defined for NB-IoT
pusch_vars->ulsch_power[i] = signal_energy_nodc(pusch_vars->drs_ch_estimates[eNB_id][i],
ulsch[UE_id]->harq_process->nb_rb*12);
#ifdef LOCALIZATION
pusch_vars->subcarrier_power = (int32_t *)malloc(ulsch[UE_id]->harq_process->nb_rb*12*sizeof(int32_t));
pusch_vars->active_subcarrier = subcarrier_energy(pusch_vars->drs_ch_estimates[eNB_id][i],
ulsch[UE_id]->harq_process->nb_rb*12, pusch_vars->subcarrier_power, rx_power_correction);
#endif
// pusch_vars->ulsch_power[i] = signal_energy_nodc(pusch_vars->drs_ch_estimates[eNB_id][i],
// ulsch[UE_id]->harq_process->nb_rb*12);
pusch_vars->ulsch_power[i] = signal_energy_nodc(pusch_vars->drs_ch_estimates[eNB_id][i], 12);
// #ifdef LOCALIZATION
// pusch_vars->subcarrier_power = (int32_t *)malloc(ulsch[UE_id]->harq_process->nb_rb*12*sizeof(int32_t));
// pusch_vars->active_subcarrier = subcarrier_energy(pusch_vars->drs_ch_estimates[eNB_id][i],
// ulsch[UE_id]->harq_process->nb_rb*12, pusch_vars->subcarrier_power, rx_power_correction);
// #endif
}
// }
......@@ -1636,9 +1640,15 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
//#ifdef DEBUG_ULSCH
// Inverse-Transform equalized outputs
// printf("Doing IDFTs\n");
// lte_idft_NB_IoT(frame_parms,
// (uint32_t*)pusch_vars->rxdataF_comp[eNB_id][0],
// ulsch[UE_id]->harq_process->nb_rb*12);
// lte_idft_NB_IoT(frame_parms,
// (uint32_t*)pusch_vars->rxdataF_comp[eNB_id][0],
// ulsch[UE_id]->harq_process->12);
lte_idft_NB_IoT(frame_parms,
(uint32_t*)pusch_vars->rxdataF_comp[eNB_id][0],
ulsch[UE_id]->harq_process->nb_rb*12);
12);
// printf("Done\n");
//#endif //DEBUG_ULSCH
......@@ -1665,7 +1675,7 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
case 1:
printf("To be developped\n");
break;
case 2 :
case 2:
ulsch_qpsk_llr_NB_IoT(frame_parms,
pusch_vars->rxdataF_comp[eNB_id],
pusch_vars->llr,
......
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