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, ...@@ -45,6 +45,17 @@ int lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB,
uint8_t Ns, uint8_t Ns,
uint8_t cooperation_flag); 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, int16_t lte_ul_freq_offset_estimation_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t *ul_ch_estimates, int32_t *ul_ch_estimates,
uint16_t nb_rb); 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 ...@@ -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 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[30][33];
int16_t *ul_ref_sigs_rx[30][4]; //these contain the sequences in repeated format and quantized to QPSK ifdef IFFT_FPGA 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] = { ...@@ -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 1,-1,-1, 1,-1, 1, 1,-1,-1, 1, 1,-1, 1,-1,-1, 1
}; };
// void generate_ul_ref_sigs(void) // void generate_ul_ref_sigs(void)
// { // {
// double qbar,phase; // double qbar,phase;
...@@ -181,7 +183,7 @@ void generate_ul_ref_sigs_rx_NB_IoT(void) ...@@ -181,7 +183,7 @@ void generate_ul_ref_sigs_rx_NB_IoT(void)
for (n=0; n<sequence_length[index_Nsc_RU]; n++) { 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][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][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 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) ...@@ -194,7 +196,7 @@ void generate_ul_ref_sigs_rx_NB_IoT(void)
for (n=0; n<sequence_length[index_Nsc_RU]; n++) { 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][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][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 ))); 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; break;
...@@ -203,7 +205,7 @@ void generate_ul_ref_sigs_rx_NB_IoT(void) ...@@ -203,7 +205,7 @@ void generate_ul_ref_sigs_rx_NB_IoT(void)
for (n=0; n<sequence_length[index_Nsc_RU]; n++) { 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][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][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 ))); 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; break;
......
...@@ -223,7 +223,7 @@ void ulsch_extract_rbs_single_NB_IoT(int32_t **rxdataF, ...@@ -223,7 +223,7 @@ void ulsch_extract_rbs_single_NB_IoT(int32_t **rxdataF,
// uint32_t first_rb, // uint32_t first_rb,
uint32_t UL_RB_ID_NB_IoT, // index of UL NB_IoT resource block uint32_t UL_RB_ID_NB_IoT, // index of UL NB_IoT resource block
uint8_t N_sc_RU, // number of subcarriers in UL 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, uint32_t nb_rb,
uint8_t l, uint8_t l,
uint8_t Ns, uint8_t Ns,
......
...@@ -549,7 +549,7 @@ void ulsch_extract_rbs_single_NB_IoT(int32_t **rxdataF, ...@@ -549,7 +549,7 @@ void ulsch_extract_rbs_single_NB_IoT(int32_t **rxdataF,
// uint32_t first_rb, // uint32_t first_rb,
uint32_t UL_RB_ID_NB_IoT, // index of UL NB_IoT resource block uint32_t UL_RB_ID_NB_IoT, // index of UL NB_IoT resource block
uint8_t N_sc_RU, // number of subcarriers in UL 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, uint32_t nb_rb,
uint8_t l, uint8_t l,
uint8_t Ns, uint8_t Ns,
...@@ -560,10 +560,10 @@ void ulsch_extract_rbs_single_NB_IoT(int32_t **rxdataF, ...@@ -560,10 +560,10 @@ void ulsch_extract_rbs_single_NB_IoT(int32_t **rxdataF,
uint8_t aarx,n; uint8_t aarx,n;
// int32_t *rxF,*rxF_ext; // int32_t *rxF,*rxF_ext;
//uint8_t symbol = l+Ns*frame_parms->symbols_per_tti/2; //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 uint8_t symbol = l+(7*(Ns&1)); ///symbol within sub-frame
uint16_t ul_sc_start; // subcarrier start index into UL RB // 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++) { for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
...@@ -574,9 +574,10 @@ void ulsch_extract_rbs_single_NB_IoT(int32_t **rxdataF, ...@@ -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 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 // 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, ...@@ -595,9 +596,11 @@ void ulsch_extract_rbs_single_NB_IoT(int32_t **rxdataF,
// } // }
} else { // RB NB-IoT is in the second half } 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 // 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, ...@@ -1350,7 +1353,7 @@ void ulsch_channel_level_NB_IoT(int32_t **drs_ch_estimates_ext,
avg128U = _mm_setzero_si128(); avg128U = _mm_setzero_si128();
ul_ch128=(__m128i *)drs_ch_estimates_ext[aarx]; 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[0],ul_ch128[0]));
avg128U = _mm_add_epi32(avg128U,_mm_madd_epi16(ul_ch128[1],ul_ch128[1])); 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, ...@@ -1359,13 +1362,13 @@ void ulsch_channel_level_NB_IoT(int32_t **drs_ch_estimates_ext,
ul_ch128+=3; ul_ch128+=3;
} // }
#elif defined(__arm__) #elif defined(__arm__)
avg128U = vdupq_n_s32(0); avg128U = vdupq_n_s32(0);
ul_ch128=(int16x4_t *)drs_ch_estimates_ext[aarx]; 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[0],ul_ch128[0]));
avg128U = vqaddq_s32(avg128U,vmull_s16(ul_ch128[1],ul_ch128[1])); 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, ...@@ -1376,7 +1379,7 @@ void ulsch_channel_level_NB_IoT(int32_t **drs_ch_estimates_ext,
ul_ch128+=6; ul_ch128+=6;
} // }
#endif #endif
...@@ -1439,7 +1442,7 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -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->first_rb,
ulsch[UE_id]->harq_process->UL_RB_ID_NB_IoT, // index of UL NB_IoT resource block 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->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, ulsch[UE_id]->harq_process->nb_rb,
l%(frame_parms->symbols_per_tti/2), l%(frame_parms->symbols_per_tti/2),
l/(frame_parms->symbols_per_tti/2), l/(frame_parms->symbols_per_tti/2),
...@@ -1450,7 +1453,7 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1450,7 +1453,7 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
UE_id, UE_id,
l%(frame_parms->symbols_per_tti/2), l%(frame_parms->symbols_per_tti/2),
l/(frame_parms->symbols_per_tti/2), l/(frame_parms->symbols_per_tti/2),
cooperation_flag); cooperation_flag);
} }
// if(cooperation_flag == 2) { // if(cooperation_flag == 2) {
...@@ -1468,14 +1471,15 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1468,14 +1471,15 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
*/ */
//////////////////////// NB_IoT: maybe, should be defined for NB-IoT //////////////////////// NB_IoT: maybe, should be defined for NB-IoT
pusch_vars->ulsch_power[i] = signal_energy_nodc(pusch_vars->drs_ch_estimates[eNB_id][i], // pusch_vars->ulsch_power[i] = signal_energy_nodc(pusch_vars->drs_ch_estimates[eNB_id][i],
ulsch[UE_id]->harq_process->nb_rb*12); // ulsch[UE_id]->harq_process->nb_rb*12);
pusch_vars->ulsch_power[i] = signal_energy_nodc(pusch_vars->drs_ch_estimates[eNB_id][i], 12);
#ifdef LOCALIZATION // #ifdef LOCALIZATION
pusch_vars->subcarrier_power = (int32_t *)malloc(ulsch[UE_id]->harq_process->nb_rb*12*sizeof(int32_t)); // 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], // 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); // ulsch[UE_id]->harq_process->nb_rb*12, pusch_vars->subcarrier_power, rx_power_correction);
#endif // #endif
} }
// } // }
...@@ -1636,9 +1640,15 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1636,9 +1640,15 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
//#ifdef DEBUG_ULSCH //#ifdef DEBUG_ULSCH
// Inverse-Transform equalized outputs // Inverse-Transform equalized outputs
// printf("Doing IDFTs\n"); // printf("Doing IDFTs\n");
lte_idft_NB_IoT(frame_parms, // 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], (uint32_t*)pusch_vars->rxdataF_comp[eNB_id][0],
ulsch[UE_id]->harq_process->nb_rb*12); 12);
// printf("Done\n"); // printf("Done\n");
//#endif //DEBUG_ULSCH //#endif //DEBUG_ULSCH
...@@ -1665,7 +1675,7 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, ...@@ -1665,7 +1675,7 @@ void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
case 1: case 1:
printf("To be developped\n"); printf("To be developped\n");
break; break;
case 2 : case 2:
ulsch_qpsk_llr_NB_IoT(frame_parms, ulsch_qpsk_llr_NB_IoT(frame_parms,
pusch_vars->rxdataF_comp[eNB_id], pusch_vars->rxdataF_comp[eNB_id],
pusch_vars->llr, 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