channel estimation, compensation, etc ..
Added the following folder: - ../openair1/PHY/NR_ESTIMATION/ Added the following file to CMakelists.txt: - ../openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c Added the following functions: - nr_pusch_dmrs_rx - nr_gold_pusch - nr_ulsch_channel_level - nr_ulsch_channel_compensation - nr_ulsch_scale_channel is commented out (I think only used for downlink) Changes from Khalid Ahmed Mahmoud Mohamed: - nr_pusch_channel_estimation is used - nr_ulsch_scale_channel is used - nr_ulsch_channel_level is used - nr_ulsch_channel_compensation is used - multiple logging options for channel and signal magnitude
This commit is contained in:
committed by
Thomas Schlichter
parent
9d27079f05
commit
abfd072376
@@ -1394,6 +1394,8 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/filt16a_32.c
|
||||
${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
|
||||
#${OPENAIR1_DIR}/PHY/TOOLS/lte_dfts.c
|
||||
@@ -1438,6 +1440,7 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold_ue.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/filt16a_32.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
|
||||
|
||||
+18
-10
@@ -208,24 +208,32 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
||||
for (int UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
|
||||
//FIXME
|
||||
pusch_vars[UE_id] = (NR_gNB_PUSCH *)malloc16_clear( sizeof(NR_gNB_PUSCH) );
|
||||
pusch_vars[UE_id]->rxdataF_ext = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
||||
pusch_vars[UE_id]->rxdataF_ext2 = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
||||
pusch_vars[UE_id]->drs_ch_estimates = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
||||
pusch_vars[UE_id]->drs_ch_estimates_time = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
||||
pusch_vars[UE_id]->rxdataF_comp = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
||||
pusch_vars[UE_id]->ul_ch_mag = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
||||
pusch_vars[UE_id]->ul_ch_magb = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
||||
pusch_vars[UE_id]->rxdataF_ext = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
|
||||
pusch_vars[UE_id]->rxdataF_ext2 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
|
||||
pusch_vars[UE_id]->ul_ch_estimates = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
|
||||
pusch_vars[UE_id]->ul_ch_estimates_ext = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
|
||||
pusch_vars[UE_id]->ul_ch_estimates_time = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
|
||||
pusch_vars[UE_id]->rxdataF_comp = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
|
||||
pusch_vars[UE_id]->ul_ch_mag0 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
|
||||
pusch_vars[UE_id]->ul_ch_magb0 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
|
||||
pusch_vars[UE_id]->ul_ch_mag = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
|
||||
pusch_vars[UE_id]->ul_ch_magb = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
|
||||
pusch_vars[UE_id]->rho = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
|
||||
|
||||
for (i=0; i<2; i++) {
|
||||
for (i=0; i<fp->nb_antennas_rx; i++) {
|
||||
// RK 2 times because of output format of FFT!
|
||||
// FIXME We should get rid of this
|
||||
pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
|
||||
pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
|
||||
pusch_vars[UE_id]->drs_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
|
||||
pusch_vars[UE_id]->drs_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
|
||||
pusch_vars[UE_id]->ul_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
|
||||
pusch_vars[UE_id]->ul_ch_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
|
||||
pusch_vars[UE_id]->ul_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
|
||||
pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
|
||||
pusch_vars[UE_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
|
||||
pusch_vars[UE_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
|
||||
pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
|
||||
pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
|
||||
pusch_vars[UE_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) );
|
||||
}
|
||||
|
||||
pusch_vars[UE_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear
|
||||
|
||||
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "nr_ul_estimation.h"
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
#include "PHY/NR_UE_ESTIMATION/filt16a_32.h"
|
||||
|
||||
//#define DEBUG_CH
|
||||
|
||||
|
||||
int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
uint8_t gNB_offset,
|
||||
unsigned char Ns,
|
||||
unsigned short p,
|
||||
unsigned char symbol,
|
||||
unsigned short bwp_start_subcarrier,
|
||||
unsigned short nb_rb_pusch)
|
||||
{
|
||||
int pilot[1320] __attribute__((aligned(16)));
|
||||
unsigned char aarx;
|
||||
unsigned short k;
|
||||
unsigned int pilot_cnt;
|
||||
int16_t ch[2],*pil,*rxF,*ul_ch,*fl,*fm,*fr,*fml,*fmr,*fmm;
|
||||
int ch_offset,symbol_offset, length_dmrs, UE_id = 0;
|
||||
unsigned short n_idDMRS[2] = {0,1}; //to update from pusch config
|
||||
|
||||
#ifdef DEBUG_CH
|
||||
FILE *debug_ch_est;
|
||||
debug_ch_est = fopen("debug_ch_est.txt","w");
|
||||
#endif
|
||||
|
||||
//uint16_t Nid_cell = (eNB_offset == 0) ? gNB->frame_parms.Nid_cell : gNB->measurements.adj_cell_id[eNB_offset-1];
|
||||
|
||||
uint8_t nushift;
|
||||
int **ul_ch_estimates = gNB->pusch_vars[UE_id]->ul_ch_estimates;
|
||||
int **rxdataF = gNB->common_vars.rxdataF;
|
||||
|
||||
nushift = (p>>1)&1;
|
||||
gNB->frame_parms.nushift = nushift;
|
||||
|
||||
ch_offset = gNB->frame_parms.ofdm_symbol_size*symbol;
|
||||
|
||||
symbol_offset = gNB->frame_parms.ofdm_symbol_size*symbol;
|
||||
|
||||
k = bwp_start_subcarrier;
|
||||
int re_offset = k;
|
||||
|
||||
/*
|
||||
#ifdef DEBUG_CH
|
||||
printf("PUSCH Channel Estimation : gNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n", gNB_offset,ch_offset,symbol_offset,gNB->frame_parms.ofdm_symbol_size,
|
||||
gNB->frame_parms.Ncp,l,Ns,k, symbol);
|
||||
#endif
|
||||
*/
|
||||
switch (nushift) {
|
||||
case 0:
|
||||
fl = filt8_l0;
|
||||
fm = filt8_m0;
|
||||
fr = filt8_r0;
|
||||
fmm = filt8_mm0;
|
||||
fml = filt8_m0;
|
||||
fmr = filt8_mr0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
fl = filt8_l1;
|
||||
fm = filt8_m1;
|
||||
fr = filt8_r1;
|
||||
fmm = filt8_mm1;
|
||||
fml = filt8_ml1;
|
||||
fmr = filt8_m1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("pusch_channel_estimation: nushift=%d -> ERROR\n",nushift);
|
||||
return(-1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
//------------------generate DMRS------------------//
|
||||
|
||||
length_dmrs = 1; //to update from pusch config
|
||||
|
||||
nr_gold_pusch(gNB, symbol, n_idDMRS, length_dmrs);
|
||||
|
||||
nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch[gNB_offset][Ns][0], &pilot[0], 1000, 0, nb_rb_pusch);
|
||||
|
||||
//------------------------------------------------//
|
||||
|
||||
for (aarx=0; aarx<gNB->frame_parms.nb_antennas_rx; aarx++) {
|
||||
|
||||
pil = (int16_t *)&pilot[0];
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];
|
||||
ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset];
|
||||
|
||||
memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size));
|
||||
|
||||
#ifdef DEBUG_PUSCH
|
||||
printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], gNB->frame_parms.N_RB_DL);
|
||||
printf("k %d, first_carrier %d\n",k,gNB->frame_parms.first_carrier_offset);
|
||||
printf("rxF addr %p p %d\n", rxF,p);
|
||||
printf("ul_ch addr %p nushift %d\n",ul_ch,nushift);
|
||||
#endif
|
||||
//if ((gNB->frame_parms.N_RB_DL&1)==0) {
|
||||
|
||||
// Treat first 2 pilots specially (left edge)
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
|
||||
#ifdef DEBUG_PUSCH
|
||||
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
|
||||
printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
|
||||
printf("data 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[2],rxF[3],&rxF[2],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fl,
|
||||
ch,
|
||||
ul_ch,
|
||||
8);
|
||||
pil+=2;
|
||||
re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
|
||||
//for (int i= 0; i<8; i++)
|
||||
//printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i));
|
||||
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
|
||||
#ifdef DEBUG_PUSCH
|
||||
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fml,
|
||||
ch,
|
||||
ul_ch,
|
||||
8);
|
||||
pil+=2;
|
||||
re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
|
||||
//printf("ul_ch addr %p\n",ul_ch);
|
||||
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
|
||||
#ifdef DEBUG_PUSCH
|
||||
printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fmm,
|
||||
ch,
|
||||
ul_ch,
|
||||
8);
|
||||
|
||||
//for (int i= 0; i<16; i++)
|
||||
//printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i));
|
||||
|
||||
pil+=2;
|
||||
re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
|
||||
ul_ch+=8;
|
||||
|
||||
for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pusch-3); pilot_cnt+=2) {
|
||||
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
#ifdef DEBUG_CH
|
||||
fprintf(debug_ch_est, "pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
//printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fm,
|
||||
ch,
|
||||
ul_ch,
|
||||
8);
|
||||
|
||||
pil+=2;
|
||||
re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
|
||||
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
#ifdef DEBUG_PUSCH
|
||||
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fmm,
|
||||
ch,
|
||||
ul_ch,
|
||||
8);
|
||||
pil+=2;
|
||||
re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
|
||||
ul_ch+=8;
|
||||
|
||||
}
|
||||
|
||||
// Treat first 2 pilots specially (right edge)
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
#ifdef DEBUG_PUSCH
|
||||
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fm,
|
||||
ch,
|
||||
ul_ch,
|
||||
8);
|
||||
|
||||
//for (int i= 0; i<8; i++)
|
||||
//printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i));
|
||||
|
||||
pil+=2;
|
||||
re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
|
||||
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
#ifdef DEBUG_PUSCH
|
||||
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
|
||||
printf("pilot %d: rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fmr,
|
||||
ch,
|
||||
ul_ch,
|
||||
8);
|
||||
|
||||
pil+=2;
|
||||
re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
|
||||
ul_ch+=8;
|
||||
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
#ifdef DEBUG_PUSCH
|
||||
printf("pilot %d: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fr,
|
||||
ch,
|
||||
ul_ch,
|
||||
8);
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CH
|
||||
fclose(debug_ch_est);
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef __NR_UL_ESTIMATION_DEFS__H__
|
||||
#define __NR_UL_ESTIMATION_DEFS__H__
|
||||
|
||||
|
||||
#include "PHY/defs_gNB.h"
|
||||
/** @addtogroup _PHY_PARAMETER_ESTIMATION_BLOCKS_
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\brief This function performs channel estimation including frequency interpolation
|
||||
\param gNB Pointer to gNB PHY variables
|
||||
\param Ns slot number (0..19)
|
||||
\param p
|
||||
\param symbol symbol within slot
|
||||
\param bwp_start_subcarrier, first allocated subcarrier
|
||||
\param nb_rb_pusch, number of allocated RBs for this UE
|
||||
*/
|
||||
|
||||
int32_t nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
uint8_t gNB_offset,
|
||||
unsigned char Ns,
|
||||
unsigned short p,
|
||||
unsigned char symbol,
|
||||
unsigned short bwp_start_subcarrier,
|
||||
unsigned short nb_rb_pusch);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -36,6 +36,8 @@
|
||||
|
||||
#include "refsig_defs_ue.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "nr_refsig.h"
|
||||
#include "PHY/defs_gNB.h"
|
||||
|
||||
/*Table 7.4.1.1.2-1/2 from 38.211 */
|
||||
int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1}};
|
||||
@@ -48,6 +50,59 @@ short nr_rx_mod_table[14] = {0,0,23170,-23170,-23170,23170,23170,-23170,23170,2
|
||||
short nr_rx_nmod_table[14] = {0,0,-23170,23170,23170,-23170,-23170,23170,-23170,-23170,23170,23170,23170,-23170};
|
||||
|
||||
|
||||
int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
|
||||
unsigned int Ns,
|
||||
unsigned int *nr_gold_pusch,
|
||||
int32_t *output,
|
||||
unsigned short p,
|
||||
unsigned char lp,
|
||||
unsigned short nb_pusch_rb)
|
||||
{
|
||||
int8_t w,config_type;
|
||||
short *mod_table;
|
||||
unsigned char idx=0;
|
||||
|
||||
typedef int array_of_w[2];
|
||||
array_of_w *wf;
|
||||
array_of_w *wt;
|
||||
|
||||
config_type = 0; //to be updated by higher layer
|
||||
|
||||
wf = (config_type==0) ? wf1 : wf2;
|
||||
wt = (config_type==0) ? wt1 : wt2;
|
||||
|
||||
if (config_type > 1)
|
||||
LOG_E(PHY,"Bad PUSCH DMRS config type %d\n", config_type);
|
||||
|
||||
if ((p>=1000) && (p<((config_type==0) ? 1008 : 1012))) {
|
||||
if (gNB->frame_parms.Ncp == NORMAL) {
|
||||
|
||||
for (int i=0; i<nb_pusch_rb*((config_type==0) ? 6:4); i++) {
|
||||
|
||||
w = (wf[p-1000][i&1])*(wt[p-1000][lp]);
|
||||
mod_table = (w==1) ? nr_rx_mod_table : nr_rx_nmod_table;
|
||||
|
||||
idx = ((((nr_gold_pusch[(i<<1)>>5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1);
|
||||
((int16_t*)output)[i<<1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
|
||||
((int16_t*)output)[(i<<1)+1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
|
||||
#ifdef DEBUG_PUSCH
|
||||
printf("nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d\n", config_type, p, nb_pusch_rb);
|
||||
printf("wf[%d] = %d wt[%d]= %d\n", i&1, wf[p-1000][i&1], lp, wt[p-1000][lp]);
|
||||
printf("i %d idx %d pusch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, nr_gold_pusch[(i<<1)>>5], (((nr_gold_pusch[(i<<1)>>5])>>((i<<1)&0x1f))&1),
|
||||
(((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[i<<1], ((int16_t*)output)[(i<<1)+1]);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
LOG_E(PHY,"extended cp not supported for PUSCH DMRS yet\n");
|
||||
}
|
||||
} else {
|
||||
LOG_E(PHY,"Illegal p %d PUSCH DMRS port\n",p);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
|
||||
unsigned int Ns,
|
||||
|
||||
@@ -101,3 +101,59 @@ void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void nr_gold_pusch(PHY_VARS_gNB* gNB, unsigned short lbar,unsigned short *n_idDMRS, unsigned short length_dmrs)
|
||||
{
|
||||
|
||||
unsigned char ns,l;
|
||||
unsigned int n,x1,x2,x2tmp0;
|
||||
int nscid;
|
||||
unsigned int nid;
|
||||
|
||||
/// to be updated from higher layer
|
||||
//unsigned short lbar = 0;
|
||||
|
||||
for (nscid=0; nscid<2; nscid++) {
|
||||
if (n_idDMRS)
|
||||
nid = n_idDMRS[nscid];
|
||||
else
|
||||
nid = gNB->frame_parms.Nid_cell;
|
||||
|
||||
//printf("gold pdsch nid %d lbar %d\n",nid,lbar);
|
||||
|
||||
for (ns=0; ns<20; ns++) {
|
||||
|
||||
for (l=0; l<length_dmrs; l++) {
|
||||
|
||||
x2tmp0 = ((14*ns+(lbar+l)+1)*((nid<<1)+1))<<17;
|
||||
x2 = (x2tmp0+(nid<<1)+nscid)%(1<<31); //cinit
|
||||
|
||||
//printf("ns %d gold pdsch x2 %d\n",ns,x2);
|
||||
|
||||
x1 = 1+ (1<<31);
|
||||
x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
|
||||
|
||||
// skip first 50 double words (1600 bits)
|
||||
for (n=1; n<50; n++) {
|
||||
x1 = (x1>>1) ^ (x1>>4);
|
||||
x1 = x1 ^ (x1<<31) ^ (x1<<28);
|
||||
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
|
||||
x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
|
||||
//printf("x1 : %x, x2 : %x\n",x1,x2);
|
||||
}
|
||||
|
||||
for (n=0; n<52; n++) {
|
||||
x1 = (x1>>1) ^ (x1>>4);
|
||||
x1 = x1 ^ (x1<<31) ^ (x1<<28);
|
||||
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
|
||||
x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
|
||||
gNB->nr_gold_pusch[nscid][ns][l][n] = x1^x2;
|
||||
// if ((ns==2)&&(l==0))
|
||||
//printf("n=%d : c %x\n",n,x1^x2);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,4 +39,13 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB);
|
||||
void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
|
||||
void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
|
||||
|
||||
void nr_gold_pusch(PHY_VARS_gNB* gNB, unsigned short lbar,unsigned short *n_idDMRS, unsigned short length_dmrs);
|
||||
|
||||
int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
|
||||
unsigned int Ns,
|
||||
unsigned int *nr_gold_pusch,
|
||||
int32_t *output,
|
||||
unsigned short p,
|
||||
unsigned char lp,
|
||||
unsigned short nb_pusch_rb);
|
||||
#endif
|
||||
|
||||
@@ -65,7 +65,9 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
|
||||
*/
|
||||
void nr_ulsch_extract_rbs_single(int **rxdataF,
|
||||
int **ul_ch_estimates,
|
||||
int **rxdataF_ext,
|
||||
int **ul_ch_estimates_ext,
|
||||
uint32_t rxdataF_ext_offset,
|
||||
// unsigned int *rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment
|
||||
unsigned char symbol,
|
||||
@@ -73,6 +75,54 @@ void nr_ulsch_extract_rbs_single(int **rxdataF,
|
||||
unsigned short nb_rb_pusch,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
void nr_ulsch_scale_channel(int32_t **ul_ch_estimates_ext,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
NR_gNB_ULSCH_t **ulsch_gNB,
|
||||
uint8_t symbol,
|
||||
uint8_t start_symbol,
|
||||
uint16_t nb_rb);
|
||||
|
||||
|
||||
/** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal
|
||||
@param ul_ch_estimates_ext Channel estimates in allocated RBs
|
||||
@param frame_parms Pointer to frame descriptor
|
||||
@param avg Pointer to average signal strength
|
||||
@param pilots_flag Flag to indicate pilots in symbol
|
||||
@param nb_rb Number of allocated RBs
|
||||
*/
|
||||
void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t *avg,
|
||||
uint8_t symbol,
|
||||
uint32_t len,
|
||||
unsigned short nb_rb);
|
||||
|
||||
|
||||
/** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation. In addition, it computes the squared-magnitude of the channel with weightings for 16QAM/64QAM detection as well as dual-stream detection (cross-correlation)
|
||||
@param rxdataF_ext Frequency-domain received signal in RBs to be demodulated
|
||||
@param ul_ch_estimates_ext Frequency-domain channel estimates in RBs to be demodulated
|
||||
@param ul_ch_mag First Channel magnitudes (16QAM/64QAM)
|
||||
@param ul_ch_magb Second weighted Channel magnitudes (64QAM)
|
||||
@param rxdataF_comp Compensated received waveform
|
||||
@param frame_parms Pointer to frame descriptor
|
||||
@param symbol Symbol on which to operate
|
||||
@param Qm Modulation order of allocation
|
||||
@param nb_rb Number of RBs in allocation
|
||||
@param output_shift Rescaling for compensated output (should be energy-normalizing)
|
||||
*/
|
||||
void nr_ulsch_channel_compensation(int **rxdataF_ext,
|
||||
int **ul_ch_estimates_ext,
|
||||
int **ul_ch_mag,
|
||||
int **ul_ch_magb,
|
||||
int **rxdataF_comp,
|
||||
int **rho,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
unsigned char symbol,
|
||||
uint8_t pilots,
|
||||
unsigned char mod_order,
|
||||
unsigned short nb_rb,
|
||||
unsigned char output_shift);
|
||||
|
||||
/*!
|
||||
\brief This function implements the idft transform precoding in PUSCH
|
||||
\param z Pointer to input in frequnecy domain, and it is also the output in time domain
|
||||
@@ -102,6 +152,7 @@ void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp,
|
||||
void nr_ulsch_16qam_llr(int32_t *rxdataF_comp,
|
||||
int32_t **ul_ch_mag,
|
||||
int16_t *ulsch_llr,
|
||||
uint32_t nb_rb,
|
||||
uint32_t nb_re,
|
||||
uint8_t symbol);
|
||||
|
||||
@@ -118,6 +169,7 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp,
|
||||
int32_t **ul_ch_mag,
|
||||
int32_t **ul_ch_magb,
|
||||
int16_t *ulsch_llr,
|
||||
uint32_t nb_rb,
|
||||
uint32_t nb_re,
|
||||
uint8_t symbol);
|
||||
|
||||
@@ -135,6 +187,7 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp,
|
||||
int32_t **ul_ch_mag,
|
||||
int32_t **ul_ch_magb,
|
||||
int16_t *ulsch_llr,
|
||||
uint32_t nb_rb,
|
||||
uint32_t nb_re,
|
||||
uint8_t symbol,
|
||||
uint8_t mod_order);
|
||||
@@ -5,6 +5,13 @@
|
||||
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
|
||||
#include "PHY/defs_nr_common.h"
|
||||
|
||||
//#define DEBUG_CH_COMP
|
||||
//#define DEBUG_RB_EXT
|
||||
//#define DEBUG_CH_MAG
|
||||
|
||||
static short jitter[8] __attribute__ ((aligned(16))) = {1,0,0,1,0,1,1,0};
|
||||
static short jitterc[8] __attribute__ ((aligned(16))) = {0,1,1,0,1,0,0,1};
|
||||
|
||||
void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
|
||||
{
|
||||
|
||||
@@ -216,7 +223,9 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
|
||||
}
|
||||
|
||||
void nr_ulsch_extract_rbs_single(int **rxdataF,
|
||||
int **ul_ch_estimates,
|
||||
int **rxdataF_ext,
|
||||
int **ul_ch_estimates_ext,
|
||||
uint32_t rxdataF_ext_offset,
|
||||
// unsigned int *rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment
|
||||
unsigned char symbol,
|
||||
@@ -227,12 +236,22 @@ void nr_ulsch_extract_rbs_single(int **rxdataF,
|
||||
unsigned short start_re, re, nb_re_pusch;
|
||||
unsigned char aarx, is_dmrs_symbol = 0;
|
||||
uint32_t rxF_ext_index = 0;
|
||||
uint32_t ul_ch0_ext_index = 0;
|
||||
uint32_t ul_ch0_index = 0;
|
||||
|
||||
int16_t *rxF,*rxF_ext;
|
||||
int *ul_ch0,*ul_ch0_ext;
|
||||
|
||||
#ifdef DEBUG_RB_EXT
|
||||
|
||||
printf("--------------------symbol = %d-----------------------\n", symbol);
|
||||
printf("--------------------ch_ext_index = %d-----------------------\n", symbol*NR_NB_SC_PER_RB * nb_rb_pusch);
|
||||
|
||||
#endif
|
||||
|
||||
is_dmrs_symbol = (symbol == 2) ? 1 : 0; //to be updated from config
|
||||
|
||||
start_re = frame_parms->first_carrier_offset + (start_rb * NR_NB_SC_PER_RB);
|
||||
start_re = (frame_parms->first_carrier_offset + (start_rb * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size;
|
||||
|
||||
nb_re_pusch = NR_NB_SC_PER_RB * nb_rb_pusch;
|
||||
|
||||
@@ -241,19 +260,712 @@ void nr_ulsch_extract_rbs_single(int **rxdataF,
|
||||
rxF = (int16_t *)&rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size];
|
||||
rxF_ext = (int16_t *)&rxdataF_ext[aarx][symbol * nb_re_pusch]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6
|
||||
|
||||
ul_ch0 = &ul_ch_estimates[aarx][(2*(frame_parms->ofdm_symbol_size))]; // DMRS REs are only in symbol 2 (to be updated from config)
|
||||
ul_ch0_ext = &ul_ch_estimates_ext[aarx][symbol*nb_re_pusch];
|
||||
|
||||
for (re = 0; re < nb_re_pusch; re++) {
|
||||
|
||||
if ( (is_dmrs_symbol && ((re&1) != 0)) || (is_dmrs_symbol == 0) ) { // [hna] (re&1) != frame_parms->nushift) assuming only dmrs type 1 and mapping type A
|
||||
// frame_parms->nushift should be initialized with 0
|
||||
rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]);
|
||||
rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]);
|
||||
ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index];
|
||||
|
||||
#ifdef DEBUG_RB_EXT
|
||||
printf("rxF_ext[%d] = %d\n", rxF_ext_index, rxF_ext[rxF_ext_index]);
|
||||
printf("rxF_ext[%d] = %d\n", rxF_ext_index+1, rxF_ext[rxF_ext_index+1]);
|
||||
printf("ul_ch0_ext[%d] = %d\n", 2*ul_ch0_ext_index, ((int16_t *)ul_ch0_ext)[2*ul_ch0_ext_index]);
|
||||
printf("ul_ch0_ext[%d] = %d\n", 2*ul_ch0_ext_index + 1, ((int16_t *)ul_ch0_ext)[2*ul_ch0_ext_index + 1]);
|
||||
#endif
|
||||
|
||||
rxF_ext_index = rxF_ext_index + 2;
|
||||
ul_ch0_ext_index++;
|
||||
}
|
||||
ul_ch0_index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
NR_gNB_ULSCH_t **ulsch_gNB,
|
||||
uint8_t symbol,
|
||||
uint8_t pilots,
|
||||
unsigned short nb_rb)
|
||||
{
|
||||
|
||||
#if defined(__x86_64__)||defined(__i386__)
|
||||
|
||||
short rb, ch_amp;
|
||||
unsigned char aatx,aarx;
|
||||
__m128i *ul_ch128, ch_amp128;
|
||||
|
||||
// Determine scaling amplitude based the symbol
|
||||
|
||||
ch_amp = 1024*8; //((pilots) ? (ulsch_gNB[0]->sqrt_rho_b) : (ulsch_gNB[0]->sqrt_rho_a));
|
||||
|
||||
LOG_D(PHY,"Scaling PUSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n", symbol, ch_amp, pilots, nb_rb, frame_parms->Ncp, symbol);
|
||||
// printf("Scaling PUSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp);
|
||||
|
||||
ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13
|
||||
|
||||
for (aatx=0; aatx < frame_parms->nb_antenna_ports_eNB; aatx++) {
|
||||
for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
|
||||
ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*nb_rb*NR_NB_SC_PER_RB];
|
||||
|
||||
if (pilots==1){
|
||||
nb_rb = nb_rb>>1;
|
||||
}
|
||||
|
||||
|
||||
for (rb=0;rb<nb_rb;rb++) {
|
||||
|
||||
ul_ch128[0] = _mm_mulhi_epi16(ul_ch128[0], ch_amp128);
|
||||
ul_ch128[0] = _mm_slli_epi16(ul_ch128[0], 3);
|
||||
|
||||
ul_ch128[1] = _mm_mulhi_epi16(ul_ch128[1], ch_amp128);
|
||||
ul_ch128[1] = _mm_slli_epi16(ul_ch128[1], 3);
|
||||
|
||||
if (pilots) {
|
||||
ul_ch128+=2;
|
||||
} else {
|
||||
ul_ch128[2] = _mm_mulhi_epi16(ul_ch128[2], ch_amp128);
|
||||
ul_ch128[2] = _mm_slli_epi16(ul_ch128[2], 3);
|
||||
ul_ch128+=3;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//compute average channel_level on each (TX,RX) antenna pair
|
||||
void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t *avg,
|
||||
uint8_t symbol,
|
||||
uint32_t len,
|
||||
unsigned short nb_rb)
|
||||
{
|
||||
|
||||
#if defined(__x86_64__)||defined(__i386__)
|
||||
|
||||
short rb;
|
||||
unsigned char aatx, aarx, nre = 12;
|
||||
__m128i *ul_ch128, avg128U;
|
||||
|
||||
//nb_rb*nre = y * 2^x
|
||||
int16_t x = factor2(len);
|
||||
int16_t y = (len)>>x;
|
||||
//printf("nb_rb*nre = %d = %d * 2^(%d)\n",nb_rb*nre,y,x);
|
||||
|
||||
for (aatx = 0; aatx < frame_parms->nb_antennas_tx; aatx++)
|
||||
for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
//clear average level
|
||||
avg128U = _mm_setzero_si128();
|
||||
|
||||
ul_ch128=(__m128i *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12];
|
||||
|
||||
for (rb = 0; rb < nb_rb; rb++) {
|
||||
avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[0], ul_ch128[0]), x));
|
||||
avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[1], ul_ch128[1]), x));
|
||||
avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[2], ul_ch128[2]), x));
|
||||
ul_ch128+=3;
|
||||
}
|
||||
|
||||
avg[(aatx<<1)+aarx] = (((int32_t*)&avg128U)[0] +
|
||||
((int32_t*)&avg128U)[1] +
|
||||
((int32_t*)&avg128U)[2] +
|
||||
((int32_t*)&avg128U)[3] ) / y;
|
||||
|
||||
}
|
||||
|
||||
_mm_empty();
|
||||
_m_empty();
|
||||
|
||||
#elif defined(__arm__)
|
||||
|
||||
short rb;
|
||||
unsigned char aatx, aarx, nre = 12, symbol_mod;
|
||||
int32x4_t avg128U;
|
||||
int16x4_t *ul_ch128;
|
||||
|
||||
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
|
||||
|
||||
for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++)
|
||||
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||
//clear average level
|
||||
avg128U = vdupq_n_s32(0);
|
||||
// 5 is always a symbol with no pilots for both normal and extended prefix
|
||||
|
||||
ul_ch128 = (int16x4_t *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12];
|
||||
|
||||
for (rb = 0; rb < nb_rb; rb++) {
|
||||
// printf("rb %d : ",rb);
|
||||
// print_shorts("ch",&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[2], ul_ch128[2]));
|
||||
avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[3], ul_ch128[3]));
|
||||
|
||||
if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) {
|
||||
ul_ch128+=4;
|
||||
} else {
|
||||
avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[4], ul_ch128[4]));
|
||||
avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[5], ul_ch128[5]));
|
||||
ul_ch128+=6;
|
||||
}
|
||||
|
||||
/*
|
||||
if (rb==0) {
|
||||
print_shorts("ul_ch128",&ul_ch128[0]);
|
||||
print_shorts("ul_ch128",&ul_ch128[1]);
|
||||
print_shorts("ul_ch128",&ul_ch128[2]);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
if (symbol==2) //assume start symbol 2
|
||||
nre=6;
|
||||
else
|
||||
nre=12;
|
||||
|
||||
avg[(aatx<<1)+aarx] = (((int32_t*)&avg128U)[0] +
|
||||
((int32_t*)&avg128U)[1] +
|
||||
((int32_t*)&avg128U)[2] +
|
||||
((int32_t*)&avg128U)[3] ) / (nb_rb*nre);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void nr_ulsch_channel_compensation(int **rxdataF_ext,
|
||||
int **ul_ch_estimates_ext,
|
||||
int **ul_ch_mag,
|
||||
int **ul_ch_magb,
|
||||
int **rxdataF_comp,
|
||||
int **rho,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
unsigned char symbol,
|
||||
uint8_t pilots,
|
||||
unsigned char mod_order,
|
||||
unsigned short nb_rb,
|
||||
unsigned char output_shift)
|
||||
{
|
||||
|
||||
#ifdef DEBUG_CH_COMP
|
||||
int16_t *rxF, *ul_ch;
|
||||
int prnt_idx;
|
||||
|
||||
|
||||
rxF = (int16_t *)&rxdataF_ext[0][(symbol*nb_rb*12)];
|
||||
ul_ch = (int16_t *)&ul_ch_estimates_ext[0][symbol*nb_rb*12];
|
||||
|
||||
printf("--------------------symbol = %d, mod_order = %d, output_shift = %d-----------------------\n", symbol, mod_order, output_shift);
|
||||
printf("----------------Before compansation------------------\n");
|
||||
|
||||
for (prnt_idx=0;prnt_idx<12*nb_rb*2;prnt_idx++){
|
||||
|
||||
printf("rxF[%d] = %d\n", prnt_idx, rxF[prnt_idx]);
|
||||
printf("ul_ch[%d] = %d\n", prnt_idx, ul_ch[prnt_idx]);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_CH_MAG
|
||||
int16_t *ch_mag;
|
||||
int print_idx;
|
||||
|
||||
|
||||
ch_mag = (int16_t *)&ul_ch_mag[0][(symbol*nb_rb*12)];
|
||||
|
||||
printf("--------------------symbol = %d, mod_order = %d-----------------------\n", symbol, mod_order);
|
||||
printf("----------------Before computation------------------\n");
|
||||
|
||||
for (print_idx=0;print_idx<50;print_idx++){
|
||||
|
||||
printf("ch_mag[%d] = %d\n", print_idx, ch_mag[print_idx]);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__i386) || defined(__x86_64)
|
||||
|
||||
unsigned short rb;
|
||||
unsigned char aatx,aarx;
|
||||
__m128i *ul_ch128,*ul_ch128_2,*ul_ch_mag128,*ul_ch_mag128b,*rxdataF128,*rxdataF_comp128,*rho128;
|
||||
__m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b;
|
||||
QAM_amp128b = _mm_setzero_si128();
|
||||
|
||||
for (aatx=0; aatx<frame_parms->nb_antennas_tx; aatx++) {
|
||||
|
||||
if (mod_order == 4) {
|
||||
QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10)
|
||||
QAM_amp128b = _mm_setzero_si128();
|
||||
} else if (mod_order == 6) {
|
||||
QAM_amp128 = _mm_set1_epi16(QAM64_n1); //
|
||||
QAM_amp128b = _mm_set1_epi16(QAM64_n2);
|
||||
}
|
||||
|
||||
// printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol);
|
||||
|
||||
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||
|
||||
ul_ch128 = (__m128i *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12];
|
||||
ul_ch_mag128 = (__m128i *)&ul_ch_mag[(aatx<<1)+aarx][symbol*nb_rb*12];
|
||||
ul_ch_mag128b = (__m128i *)&ul_ch_magb[(aatx<<1)+aarx][symbol*nb_rb*12];
|
||||
rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*nb_rb*12];
|
||||
rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*nb_rb*12];
|
||||
|
||||
|
||||
for (rb=0; rb<nb_rb; rb++) {
|
||||
if (mod_order>2) {
|
||||
// get channel amplitude if not QPSK
|
||||
|
||||
//print_shorts("ch:",(int16_t*)&ul_ch128[0]);
|
||||
|
||||
mmtmpD0 = _mm_madd_epi16(ul_ch128[0],ul_ch128[0]);
|
||||
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
|
||||
|
||||
mmtmpD1 = _mm_madd_epi16(ul_ch128[1],ul_ch128[1]);
|
||||
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
|
||||
|
||||
mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1);
|
||||
|
||||
// store channel magnitude here in a new field of ulsch
|
||||
|
||||
ul_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0);
|
||||
ul_ch_mag128b[0] = ul_ch_mag128[0];
|
||||
ul_ch_mag128[0] = _mm_mulhi_epi16(ul_ch_mag128[0],QAM_amp128);
|
||||
ul_ch_mag128[0] = _mm_slli_epi16(ul_ch_mag128[0],1);
|
||||
|
||||
// print_ints("ch: = ",(int32_t*)&mmtmpD0);
|
||||
// print_shorts("QAM_amp:",(int16_t*)&QAM_amp128);
|
||||
// print_shorts("mag:",(int16_t*)&ul_ch_mag128[0]);
|
||||
|
||||
ul_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0);
|
||||
ul_ch_mag128b[1] = ul_ch_mag128[1];
|
||||
ul_ch_mag128[1] = _mm_mulhi_epi16(ul_ch_mag128[1],QAM_amp128);
|
||||
ul_ch_mag128[1] = _mm_slli_epi16(ul_ch_mag128[1],1);
|
||||
|
||||
if (pilots==0) {
|
||||
mmtmpD0 = _mm_madd_epi16(ul_ch128[2],ul_ch128[2]);
|
||||
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
|
||||
mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0);
|
||||
|
||||
ul_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1);
|
||||
ul_ch_mag128b[2] = ul_ch_mag128[2];
|
||||
|
||||
ul_ch_mag128[2] = _mm_mulhi_epi16(ul_ch_mag128[2],QAM_amp128);
|
||||
ul_ch_mag128[2] = _mm_slli_epi16(ul_ch_mag128[2],1);
|
||||
}
|
||||
|
||||
ul_ch_mag128b[0] = _mm_mulhi_epi16(ul_ch_mag128b[0],QAM_amp128b);
|
||||
ul_ch_mag128b[0] = _mm_slli_epi16(ul_ch_mag128b[0],1);
|
||||
|
||||
|
||||
ul_ch_mag128b[1] = _mm_mulhi_epi16(ul_ch_mag128b[1],QAM_amp128b);
|
||||
ul_ch_mag128b[1] = _mm_slli_epi16(ul_ch_mag128b[1],1);
|
||||
|
||||
if (pilots==0) {
|
||||
ul_ch_mag128b[2] = _mm_mulhi_epi16(ul_ch_mag128b[2],QAM_amp128b);
|
||||
ul_ch_mag128b[2] = _mm_slli_epi16(ul_ch_mag128b[2],1);
|
||||
}
|
||||
}
|
||||
|
||||
// multiply by conjugated channel
|
||||
mmtmpD0 = _mm_madd_epi16(ul_ch128[0],rxdataF128[0]);
|
||||
// print_ints("re",&mmtmpD0);
|
||||
|
||||
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
|
||||
mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[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[0]);
|
||||
// print_ints("im",&mmtmpD1);
|
||||
mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]);
|
||||
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
|
||||
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
|
||||
// print_ints("re(shift)",&mmtmpD0);
|
||||
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
|
||||
// print_ints("im(shift)",&mmtmpD1);
|
||||
mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
|
||||
mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
|
||||
// print_ints("c0",&mmtmpD2);
|
||||
// print_ints("c1",&mmtmpD3);
|
||||
rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
|
||||
// print_shorts("rx:",rxdataF128);
|
||||
// print_shorts("ch:",ul_ch128);
|
||||
// print_shorts("pack:",rxdataF_comp128);
|
||||
|
||||
// multiply by conjugated channel
|
||||
mmtmpD0 = _mm_madd_epi16(ul_ch128[1],rxdataF128[1]);
|
||||
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
|
||||
mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[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,rxdataF128[1]);
|
||||
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
|
||||
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);
|
||||
|
||||
rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
|
||||
// print_shorts("rx:",rxdataF128+1);
|
||||
// print_shorts("ch:",ul_ch128+1);
|
||||
// print_shorts("pack:",rxdataF_comp128+1);
|
||||
|
||||
if (pilots==0) {
|
||||
// multiply by conjugated channel
|
||||
mmtmpD0 = _mm_madd_epi16(ul_ch128[2],rxdataF128[2]);
|
||||
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
|
||||
mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[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,rxdataF128[2]);
|
||||
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
|
||||
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);
|
||||
|
||||
rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
|
||||
// print_shorts("rx:",rxdataF128+2);
|
||||
// print_shorts("ch:",ul_ch128+2);
|
||||
// print_shorts("pack:",rxdataF_comp128+2);
|
||||
|
||||
ul_ch128+=3;
|
||||
ul_ch_mag128+=3;
|
||||
ul_ch_mag128b+=3;
|
||||
rxdataF128+=3;
|
||||
rxdataF_comp128+=3;
|
||||
} else { // we have a smaller PUSCH in symbols with pilots so skip last group of 4 REs and increment less
|
||||
ul_ch128+=2;
|
||||
ul_ch_mag128+=2;
|
||||
ul_ch_mag128b+=2;
|
||||
rxdataF128+=2;
|
||||
rxdataF_comp128+=2;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rho) {
|
||||
|
||||
|
||||
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||
rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_UL*12];
|
||||
ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_UL*12];
|
||||
ul_ch128_2 = (__m128i *)&ul_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_UL*12];
|
||||
|
||||
for (rb=0; rb<nb_rb; rb++) {
|
||||
// multiply by conjugated channel
|
||||
mmtmpD0 = _mm_madd_epi16(ul_ch128[0],ul_ch128_2[0]);
|
||||
// print_ints("re",&mmtmpD0);
|
||||
|
||||
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
|
||||
mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[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[0]);
|
||||
// print_ints("im",&mmtmpD1);
|
||||
mmtmpD1 = _mm_madd_epi16(mmtmpD1,ul_ch128_2[0]);
|
||||
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
|
||||
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
|
||||
// print_ints("re(shift)",&mmtmpD0);
|
||||
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
|
||||
// print_ints("im(shift)",&mmtmpD1);
|
||||
mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
|
||||
mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
|
||||
// print_ints("c0",&mmtmpD2);
|
||||
// print_ints("c1",&mmtmpD3);
|
||||
rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
|
||||
|
||||
//print_shorts("rx:",ul_ch128_2);
|
||||
//print_shorts("ch:",ul_ch128);
|
||||
//print_shorts("pack:",rho128);
|
||||
|
||||
// multiply by conjugated channel
|
||||
mmtmpD0 = _mm_madd_epi16(ul_ch128[1],ul_ch128_2[1]);
|
||||
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
|
||||
mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[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_ch128_2[1]);
|
||||
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
|
||||
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);
|
||||
|
||||
|
||||
rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3);
|
||||
//print_shorts("rx:",ul_ch128_2+1);
|
||||
//print_shorts("ch:",ul_ch128+1);
|
||||
//print_shorts("pack:",rho128+1);
|
||||
// multiply by conjugated channel
|
||||
mmtmpD0 = _mm_madd_epi16(ul_ch128[2],ul_ch128_2[2]);
|
||||
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
|
||||
mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[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_ch128_2[2]);
|
||||
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
|
||||
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);
|
||||
|
||||
rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
|
||||
//print_shorts("rx:",ul_ch128_2+2);
|
||||
//print_shorts("ch:",ul_ch128+2);
|
||||
//print_shorts("pack:",rho128+2);
|
||||
|
||||
ul_ch128+=3;
|
||||
ul_ch128_2+=3;
|
||||
rho128+=3;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
_mm_empty();
|
||||
_m_empty();
|
||||
|
||||
#elif defined(__arm__)
|
||||
|
||||
|
||||
unsigned short rb;
|
||||
unsigned char aatx,aarx,symbol_mod,pilots=0;
|
||||
|
||||
int16x4_t *ul_ch128,*ul_ch128_2,*rxdataF128;
|
||||
int32x4_t mmtmpD0,mmtmpD1,mmtmpD0b,mmtmpD1b;
|
||||
int16x8_t *ul_ch_mag128,*ul_ch_mag128b,mmtmpD2,mmtmpD3,mmtmpD4;
|
||||
int16x8_t QAM_amp128,QAM_amp128b;
|
||||
int16x4x2_t *rxdataF_comp128,*rho128;
|
||||
|
||||
int16_t conj[4]__attribute__((aligned(16))) = {1,-1,1,-1};
|
||||
int32x4_t output_shift128 = vmovq_n_s32(-(int32_t)output_shift);
|
||||
|
||||
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
|
||||
|
||||
if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) {
|
||||
if (frame_parms->nb_antenna_ports_eNB==1) { // 10 out of 12 so don't reduce size
|
||||
nb_rb=1+(5*nb_rb/6);
|
||||
}
|
||||
else {
|
||||
pilots=1;
|
||||
}
|
||||
}
|
||||
|
||||
for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
|
||||
if (mod_order == 4) {
|
||||
QAM_amp128 = vmovq_n_s16(QAM16_n1); // 2/sqrt(10)
|
||||
QAM_amp128b = vmovq_n_s16(0);
|
||||
} else if (mod_order == 6) {
|
||||
QAM_amp128 = vmovq_n_s16(QAM64_n1); //
|
||||
QAM_amp128b = vmovq_n_s16(QAM64_n2);
|
||||
}
|
||||
// printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol);
|
||||
|
||||
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||
ul_ch128 = (int16x4_t*)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12];
|
||||
ul_ch_mag128 = (int16x8_t*)&ul_ch_mag[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12];
|
||||
ul_ch_mag128b = (int16x8_t*)&ul_ch_magb[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12];
|
||||
rxdataF128 = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_UL*12];
|
||||
rxdataF_comp128 = (int16x4x2_t*)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12];
|
||||
|
||||
for (rb=0; rb<nb_rb; rb++) {
|
||||
if (mod_order>2) {
|
||||
// get channel amplitude if not QPSK
|
||||
mmtmpD0 = vmull_s16(ul_ch128[0], ul_ch128[0]);
|
||||
// mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3];
|
||||
mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
|
||||
// mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits
|
||||
mmtmpD1 = vmull_s16(ul_ch128[1], ul_ch128[1]);
|
||||
mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
|
||||
mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
|
||||
// mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits
|
||||
mmtmpD0 = vmull_s16(ul_ch128[2], ul_ch128[2]);
|
||||
mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
|
||||
mmtmpD1 = vmull_s16(ul_ch128[3], ul_ch128[3]);
|
||||
mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
|
||||
mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
|
||||
if (pilots==0) {
|
||||
mmtmpD0 = vmull_s16(ul_ch128[4], ul_ch128[4]);
|
||||
mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
|
||||
mmtmpD1 = vmull_s16(ul_ch128[5], ul_ch128[5]);
|
||||
mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
|
||||
mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
|
||||
}
|
||||
|
||||
ul_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b);
|
||||
ul_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b);
|
||||
ul_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128);
|
||||
ul_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128);
|
||||
|
||||
if (pilots==0) {
|
||||
ul_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b);
|
||||
ul_ch_mag128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128);
|
||||
}
|
||||
}
|
||||
|
||||
mmtmpD0 = vmull_s16(ul_ch128[0], rxdataF128[0]);
|
||||
//mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])]
|
||||
mmtmpD1 = vmull_s16(ul_ch128[1], rxdataF128[1]);
|
||||
//mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])]
|
||||
mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
|
||||
vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
|
||||
//mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])]
|
||||
|
||||
mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[0],*(int16x4_t*)conj)), rxdataF128[0]);
|
||||
//mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])]
|
||||
mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[1],*(int16x4_t*)conj)), rxdataF128[1]);
|
||||
//mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
|
||||
mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
|
||||
vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
|
||||
//mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])]
|
||||
|
||||
mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
|
||||
mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
|
||||
rxdataF_comp128[0] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
|
||||
mmtmpD0 = vmull_s16(ul_ch128[2], rxdataF128[2]);
|
||||
mmtmpD1 = vmull_s16(ul_ch128[3], rxdataF128[3]);
|
||||
mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
|
||||
vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
|
||||
mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[2],*(int16x4_t*)conj)), rxdataF128[2]);
|
||||
mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[3],*(int16x4_t*)conj)), rxdataF128[3]);
|
||||
mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
|
||||
vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
|
||||
mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
|
||||
mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
|
||||
rxdataF_comp128[1] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
|
||||
|
||||
if (pilots==0) {
|
||||
mmtmpD0 = vmull_s16(ul_ch128[4], rxdataF128[4]);
|
||||
mmtmpD1 = vmull_s16(ul_ch128[5], rxdataF128[5]);
|
||||
mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
|
||||
vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
|
||||
|
||||
mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[4],*(int16x4_t*)conj)), rxdataF128[4]);
|
||||
mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[5],*(int16x4_t*)conj)), rxdataF128[5]);
|
||||
mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
|
||||
vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
|
||||
|
||||
|
||||
mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
|
||||
mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
|
||||
rxdataF_comp128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
|
||||
|
||||
|
||||
ul_ch128+=6;
|
||||
ul_ch_mag128+=3;
|
||||
ul_ch_mag128b+=3;
|
||||
rxdataF128+=6;
|
||||
rxdataF_comp128+=3;
|
||||
|
||||
} else { // we have a smaller PUSCH in symbols with pilots so skip last group of 4 REs and increment less
|
||||
ul_ch128+=4;
|
||||
ul_ch_mag128+=2;
|
||||
ul_ch_mag128b+=2;
|
||||
rxdataF128+=4;
|
||||
rxdataF_comp128+=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rho) {
|
||||
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||
rho128 = (int16x4x2_t*)&rho[aarx][symbol*frame_parms->N_RB_UL*12];
|
||||
ul_ch128 = (int16x4_t*)&ul_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_UL*12];
|
||||
ul_ch128_2 = (int16x4_t*)&ul_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_UL*12];
|
||||
for (rb=0; rb<nb_rb; rb++) {
|
||||
mmtmpD0 = vmull_s16(ul_ch128[0], ul_ch128_2[0]);
|
||||
mmtmpD1 = vmull_s16(ul_ch128[1], ul_ch128_2[1]);
|
||||
mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
|
||||
vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
|
||||
mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[0],*(int16x4_t*)conj)), ul_ch128_2[0]);
|
||||
mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[1],*(int16x4_t*)conj)), ul_ch128_2[1]);
|
||||
mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
|
||||
vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
|
||||
|
||||
mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
|
||||
mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
|
||||
rho128[0] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
|
||||
|
||||
mmtmpD0 = vmull_s16(ul_ch128[2], ul_ch128_2[2]);
|
||||
mmtmpD1 = vmull_s16(ul_ch128[3], ul_ch128_2[3]);
|
||||
mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
|
||||
vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
|
||||
mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[2],*(int16x4_t*)conj)), ul_ch128_2[2]);
|
||||
mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[3],*(int16x4_t*)conj)), ul_ch128_2[3]);
|
||||
mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
|
||||
vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
|
||||
|
||||
mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
|
||||
mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
|
||||
rho128[1] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
|
||||
|
||||
mmtmpD0 = vmull_s16(ul_ch128[0], ul_ch128_2[0]);
|
||||
mmtmpD1 = vmull_s16(ul_ch128[1], ul_ch128_2[1]);
|
||||
mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
|
||||
vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
|
||||
mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[4],*(int16x4_t*)conj)), ul_ch128_2[4]);
|
||||
mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[5],*(int16x4_t*)conj)), ul_ch128_2[5]);
|
||||
mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
|
||||
vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
|
||||
|
||||
mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
|
||||
mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
|
||||
rho128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
|
||||
|
||||
|
||||
ul_ch128+=6;
|
||||
ul_ch128_2+=6;
|
||||
rho128+=3;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DEBUG_CH_COMP
|
||||
|
||||
rxF = (int16_t *)&rxdataF_comp[0][(symbol*nb_rb*12)];
|
||||
|
||||
printf("----------------After compansation------------------\n");
|
||||
|
||||
for (prnt_idx=0;prnt_idx<12*nb_rb*2;prnt_idx++){
|
||||
|
||||
printf("rxF[%d] = %d\n", prnt_idx, rxF[prnt_idx]);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_CH_MAG
|
||||
|
||||
|
||||
ch_mag = (int16_t *)&ul_ch_mag[0][(symbol*nb_rb*12)];
|
||||
|
||||
printf("----------------After computation------------------\n");
|
||||
|
||||
for (print_idx=0;print_idx<12*nb_rb*2;print_idx++){
|
||||
|
||||
printf("ch_mag[%d] = %d\n", print_idx, ch_mag[print_idx]);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
uint8_t UE_id,
|
||||
@@ -263,24 +975,53 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
unsigned char harq_pid)
|
||||
{
|
||||
|
||||
uint8_t cw_idx, first_symbol_flag, aarx, aatx, pilots; // pilots, a flag to indicate DMRS REs in current symbol
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15;
|
||||
uint32_t nb_re_pusch;
|
||||
|
||||
if(symbol == rel15_ul->start_symbol)
|
||||
gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0;
|
||||
uint32_t nb_re_pusch, bwp_start_subcarrier;
|
||||
int avgs;
|
||||
int avg[4];
|
||||
|
||||
if (symbol == 2) // [hna] here it is assumed that symbol 2 carries 6 DMRS REs (dmrs-type 1)
|
||||
cw_idx = 0; // temp implementation
|
||||
pilots = 0;
|
||||
first_symbol_flag = 0;
|
||||
|
||||
if(symbol == rel15_ul->start_symbol){
|
||||
gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0;
|
||||
first_symbol_flag = 1;
|
||||
}
|
||||
|
||||
if (symbol == 2){ // [hna] here it is assumed that symbol 2 carries 6 DMRS REs (dmrs-type 1)
|
||||
nb_re_pusch = rel15_ul->number_rbs * 6;
|
||||
else
|
||||
pilots = 1;
|
||||
} else {
|
||||
nb_re_pusch = rel15_ul->number_rbs * NR_NB_SC_PER_RB;
|
||||
pilots = 0;
|
||||
}
|
||||
|
||||
bwp_start_subcarrier = (rel15_ul->start_rb*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size;
|
||||
|
||||
//----------------------------------------------------------
|
||||
//--------------------- Channel estimation ---------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
if (pilots == 1)
|
||||
nr_pusch_channel_estimation(gNB,
|
||||
0,
|
||||
nr_tti_rx,
|
||||
0, // p
|
||||
symbol,
|
||||
bwp_start_subcarrier,
|
||||
rel15_ul->number_rbs);
|
||||
|
||||
//----------------------------------------------------------
|
||||
//--------------------- RBs extraction ---------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
|
||||
gNB->pusch_vars[UE_id]->ul_ch_estimates,
|
||||
gNB->pusch_vars[UE_id]->rxdataF_ext,
|
||||
gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
|
||||
gNB->pusch_vars[UE_id]->rxdataF_ext_offset,
|
||||
// rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment
|
||||
symbol,
|
||||
@@ -288,6 +1029,44 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
rel15_ul->number_rbs,
|
||||
frame_parms);
|
||||
|
||||
nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
|
||||
frame_parms,
|
||||
gNB->ulsch,
|
||||
symbol,
|
||||
pilots,
|
||||
rel15_ul->number_rbs);
|
||||
|
||||
if (first_symbol_flag==1) {
|
||||
|
||||
nr_ulsch_channel_level(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
|
||||
frame_parms,
|
||||
avg,
|
||||
symbol,
|
||||
nb_re_pusch,
|
||||
rel15_ul->number_rbs);
|
||||
avgs = 0;
|
||||
|
||||
for (aatx=0;aatx<frame_parms->nb_antennas_tx;aatx++)
|
||||
for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++)
|
||||
avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
|
||||
|
||||
gNB->pusch_vars[UE_id]->log2_maxh = (log2_approx(avgs)/2)+1;
|
||||
|
||||
}
|
||||
|
||||
nr_ulsch_channel_compensation(gNB->pusch_vars[UE_id]->rxdataF_ext,
|
||||
gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
|
||||
gNB->pusch_vars[UE_id]->ul_ch_mag0,
|
||||
gNB->pusch_vars[UE_id]->ul_ch_magb0,
|
||||
gNB->pusch_vars[UE_id]->rxdataF_comp,
|
||||
(frame_parms->nb_antennas_tx>1) ? gNB->pusch_vars[UE_id]->rho : NULL,
|
||||
frame_parms,
|
||||
symbol,
|
||||
pilots,
|
||||
rel15_ul->Qm,
|
||||
rel15_ul->number_rbs,
|
||||
gNB->pusch_vars[UE_id]->log2_maxh);
|
||||
|
||||
#ifdef NR_SC_FDMA
|
||||
nr_idft(&((uint32_t*)gNB->pusch_vars[UE_id]->rxdataF_ext[0])[symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB], nb_re_pusch);
|
||||
#endif
|
||||
@@ -296,14 +1075,15 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
//-------------------- LLRs computation --------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_ext[0][symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB],
|
||||
gNB->pusch_vars[UE_id]->ul_ch_mag,
|
||||
gNB->pusch_vars[UE_id]->ul_ch_magb,
|
||||
nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_comp[0][symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB],
|
||||
gNB->pusch_vars[UE_id]->ul_ch_mag0,
|
||||
gNB->pusch_vars[UE_id]->ul_ch_magb0,
|
||||
&gNB->pusch_vars[UE_id]->llr[gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->Qm],
|
||||
rel15_ul->number_rbs,
|
||||
nb_re_pusch,
|
||||
symbol,
|
||||
rel15_ul->Qm);
|
||||
|
||||
|
||||
gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re_pusch;
|
||||
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
* \warning
|
||||
*/
|
||||
|
||||
|
||||
#include "PHY/defs_nr_common.h"
|
||||
#include "PHY/sse_intrin.h"
|
||||
#include "PHY/impl_defs_top.h"
|
||||
@@ -71,23 +70,20 @@ void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp,
|
||||
void nr_ulsch_16qam_llr(int32_t *rxdataF_comp,
|
||||
int32_t **ul_ch_mag,
|
||||
int16_t *ulsch_llr,
|
||||
uint32_t nb_rb,
|
||||
uint32_t nb_re,
|
||||
uint8_t symbol)
|
||||
{
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
__m128i *rxF = (__m128i*)rxdataF_comp;
|
||||
// __m128i *ch_mag; // [hna] This should be uncommented once channel estimation is implemented
|
||||
__m128i *ch_mag;
|
||||
__m128i llr128[2];
|
||||
uint32_t *llr32;
|
||||
|
||||
// [hna] temp_channel and one_over_sqrt_2 are for temporary use until channel estimation is implemented
|
||||
// else ul_ch_mag and ul_ch_magb should be used after channel estimation has benn implemented
|
||||
__m128i temp_channel;
|
||||
int16_t one_over_sqrt_2 = 23170;
|
||||
|
||||
#elif defined(__arm__)
|
||||
int16x8_t *rxF = (int16x8_t*)&rxdataF_comp;
|
||||
// int16x8_t *ch_mag; // [hna] This should be uncommented once channel estimation is implemented
|
||||
int16x8_t *ch_mag;
|
||||
int16x8_t xmm0;
|
||||
int16_t *llr16;
|
||||
#endif
|
||||
@@ -103,21 +99,16 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp,
|
||||
llr16 = (int16_t*)ulsch_llr;
|
||||
#endif
|
||||
|
||||
// [hna] This should be uncommented once channel estimation is implemented
|
||||
// ------------------------------------------------------------
|
||||
// #if defined(__x86_64__) || defined(__i386__)
|
||||
// ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*nb_rb*12)];
|
||||
// #elif defined(__arm__)
|
||||
// ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)];
|
||||
// #endif
|
||||
// ------------------------------------------------------------
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*nb_rb*12)];
|
||||
#elif defined(__arm__)
|
||||
ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)];
|
||||
#endif
|
||||
|
||||
len_mod4 = nb_re&3;
|
||||
nb_re >>= 2; // length in quad words (4 REs)
|
||||
nb_re += (len_mod4 == 0 ? 0 : 1);
|
||||
|
||||
temp_channel = _mm_set1_epi16((QAM16_n1 * one_over_sqrt_2)>>(2*15-AMP_SHIFT));
|
||||
|
||||
for (i=0; i<nb_re; i++) {
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386)
|
||||
@@ -125,7 +116,7 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp,
|
||||
xmm0 = _mm_abs_epi16(rxF[i]); // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I|
|
||||
|
||||
|
||||
xmm0 = _mm_subs_epi16(temp_channel,xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2
|
||||
xmm0 = _mm_subs_epi16(ch_mag[i],xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2
|
||||
|
||||
llr128[0] = _mm_unpacklo_epi32(rxF[i],xmm0); // llr128[0] contains the llrs of the 1st and 2nd REs
|
||||
llr128[1] = _mm_unpackhi_epi32(rxF[i],xmm0); // llr128[1] contains the llrs of the 3rd and 4th REs
|
||||
@@ -186,52 +177,43 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp,
|
||||
int32_t **ul_ch_mag,
|
||||
int32_t **ul_ch_magb,
|
||||
int16_t *ulsch_llr,
|
||||
uint32_t nb_rb,
|
||||
uint32_t nb_re,
|
||||
uint8_t symbol)
|
||||
{
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
__m128i *rxF = (__m128i*)rxdataF_comp;
|
||||
// __m128i *ch_mag,*ch_magb; // [hna] This should be uncommented once channel estimation is implemented
|
||||
|
||||
// [hna] temp_channel and one_over_sqrt_2 are for temporary use until channel estimation is implemented
|
||||
// else ul_ch_mag and ul_ch_magb should be used after channel estimation has been implemented
|
||||
__m128i temp_channel[2];
|
||||
int16_t one_over_sqrt_2 = 23170;
|
||||
|
||||
__m128i *ch_mag,*ch_magb;
|
||||
#elif defined(__arm__)
|
||||
int16x8_t *rxF = (int16x8_t*)&rxdataF_comp;
|
||||
// int16x8_t *ch_mag,*ch_magb; // [hna] This should be uncommented once channel estimation is implemented
|
||||
int16x8_t *ch_mag,*ch_magb; // [hna] This should be uncommented once channel estimation is implemented
|
||||
int16x8_t xmm1,xmm2;
|
||||
#endif
|
||||
|
||||
int i;
|
||||
unsigned char len_mod4;
|
||||
|
||||
// [hna] This should be uncommented once channel estimation is implemented
|
||||
// -------------------------------------------------------------------------
|
||||
// #if defined(__x86_64__) || defined(__i386__)
|
||||
// ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*frame_parms->N_RB_UL*12)];
|
||||
// ch_magb = (__m128i*)&ul_ch_magb[0][(symbol*frame_parms->N_RB_UL*12)];
|
||||
// #elif defined(__arm__)
|
||||
// ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*frame_parms->N_RB_UL*12)];
|
||||
// ch_magb = (int16x8_t*)&ul_ch_magb[0][(symbol*frame_parms->N_RB_UL*12)];
|
||||
// #endif
|
||||
// -------------------------------------------------------------------------
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*nb_rb*12)];
|
||||
ch_magb = (__m128i*)&ul_ch_magb[0][(symbol*nb_rb*12)];
|
||||
#elif defined(__arm__)
|
||||
ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)];
|
||||
ch_magb = (int16x8_t*)&ul_ch_magb[0][(symbol*nb_rb*12)];
|
||||
#endif
|
||||
|
||||
len_mod4 = nb_re&3;
|
||||
nb_re = nb_re>>2; // length in quad words (4 REs)
|
||||
nb_re += ((len_mod4 == 0) ? 0 : 1);
|
||||
|
||||
temp_channel[0] = _mm_set1_epi16((QAM64_n1 * one_over_sqrt_2)>>(2*15-AMP_SHIFT));
|
||||
temp_channel[1] = _mm_set1_epi16((QAM64_n2 * one_over_sqrt_2)>>(2*15-AMP_SHIFT));
|
||||
|
||||
|
||||
for (i=0; i<nb_re; i++) {
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
xmm1 = _mm_abs_epi16(rxF[i]);
|
||||
xmm1 = _mm_subs_epi16(temp_channel[0],xmm1);
|
||||
xmm1 = _mm_subs_epi16(ch_mag[i],xmm1);
|
||||
xmm2 = _mm_abs_epi16(xmm1);
|
||||
xmm2 = _mm_subs_epi16(temp_channel[1],xmm2);
|
||||
xmm2 = _mm_subs_epi16(ch_magb[i],xmm2);
|
||||
#elif defined(__arm__)
|
||||
xmm1 = vabsq_s16(rxF[i]);
|
||||
xmm1 = vsubq_s16(ch_mag[i],xmm1);
|
||||
@@ -331,6 +313,7 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp,
|
||||
int32_t **ul_ch_mag,
|
||||
int32_t **ul_ch_magb,
|
||||
int16_t *ulsch_llr,
|
||||
uint32_t nb_rb,
|
||||
uint32_t nb_re,
|
||||
uint8_t symbol,
|
||||
uint8_t mod_order)
|
||||
@@ -346,6 +329,7 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp,
|
||||
nr_ulsch_16qam_llr(rxdataF_comp,
|
||||
ul_ch_mag,
|
||||
ulsch_llr,
|
||||
nb_rb,
|
||||
nb_re,
|
||||
symbol);
|
||||
break;
|
||||
@@ -354,6 +338,7 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp,
|
||||
ul_ch_mag,
|
||||
ul_ch_magb,
|
||||
ulsch_llr,
|
||||
nb_rb,
|
||||
nb_re,
|
||||
symbol);
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
#include "filt16a_32.h"
|
||||
|
||||
short filt16a_l0[16] = {
|
||||
16384,12288,8192,4096,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
short filt16a_r0[16] = {
|
||||
0,0,0,0,0,4096,8192,12288,16384,20480,24576,28672,0,0,0,0};
|
||||
|
||||
short filt16a_m0[16] = {
|
||||
0,4096,8192,12288,16384,12288,8192,4096,0,-4096,-8192,-12288,0,0,0,0};
|
||||
|
||||
short filt16a_l1[16] = {
|
||||
20480,16384,12288,8192,4096,0,0,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
short filt16a_r1[16] = {
|
||||
0,0,0,0,0,0,4096,8192,12288,16384,20480,24576,0,0,0,0};
|
||||
|
||||
short filt16a_m1[16] = {
|
||||
-4096,0,4096,8192,12288,16384,12288,8192,4096,0,-4096,-8192,0,0,0,0};
|
||||
|
||||
short filt16a_l2[16] = {
|
||||
24576,20480,16384,12288,8192,4096,0,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
short filt16a_r2[16] = {
|
||||
0,0,0,0,0,0,0,4096,8192,12288,16384,20480,0,0,0,0};
|
||||
|
||||
short filt16a_m2[16] = {
|
||||
-8192,-4096,0,4096,8192,12288,16384,12288,8192,4096,0,-4096,0,0,0,0};
|
||||
|
||||
short filt16a_l3[16] = {
|
||||
28672,24576,20480,16384,12288,8192,4096,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
short filt16a_r3[16] = {
|
||||
0,0,0,0,0,0,0,0,4096,8192,12288,16384,0,0,0,0};
|
||||
|
||||
short filt16a_m3[16] = {
|
||||
-12288,-8192,-4096,0,4096,8192,12288,16384,12288,8192,4096,0,0,0,0,0};
|
||||
|
||||
short filt16a_l0_dc[16] = {
|
||||
16384,12288,8192,4096,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
short filt16a_r0_dc[16] = {
|
||||
0,0,0,0,0,3276,9830,13107,16384,19660,22937,26214,0,0,0,0};
|
||||
|
||||
short filt16a_m0_dc[16] = {
|
||||
0,4096,8192,12288,16384,13107,6553,3276,0,-3277,-6554,-9831,0,0,0,0};
|
||||
|
||||
short filt16a_l1_dc[16] = {
|
||||
16384,12288,8192,4096,0,-4096,0,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
short filt16a_r1_dc[16] = {
|
||||
0,0,0,0,0,0,6553,9830,13107,16384,19660,22937,0,0,0,0};
|
||||
|
||||
short filt16a_m1_dc[16] = {
|
||||
-4096,0,4096,8192,12288,16384,9830,6553,3276,0,-3277,-6554,0,0,0,0};
|
||||
|
||||
short filt16a_l2_dc[16] = {
|
||||
26214,22937,19660,16384,13107,9830,6553,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
short filt16a_r2_dc[16] = {
|
||||
0,0,0,0,0,0,0,4096,8192,12288,16384,20480,0,0,0,0};
|
||||
|
||||
short filt16a_m2_dc[16] = {
|
||||
-6554,-3277,0,3276,6553,6553,16384,12288,8192,4096,0,-4096,0,0,0,0};
|
||||
|
||||
short filt16a_l3_dc[16] = {
|
||||
26214,22937,19660,16384,13107,9830,3276,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
short filt16a_r3_dc[16] = {
|
||||
0,0,0,0,0,0,0,0,4096,8192,12288,16384,0,0,0,0};
|
||||
|
||||
short filt16a_m3_dc[16] = {
|
||||
-9831,-6554,-3277,0,3276,6553,9830,16384,12288,8192,4096,0,0,0,0,0};
|
||||
|
||||
short filt16a_1[16] = {
|
||||
16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384};
|
||||
|
||||
short filt16a_2l0[16] = {
|
||||
16384,12288,8192,4096,-4096,0,0,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
short filt16a_2r0[16] = {
|
||||
0,4096,8192,12288,16384,20480,0,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
short filt16a_2l1[16] = {
|
||||
20480,16384,12288,8192,4096,0,0,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
short filt16a_2r1[16] = {
|
||||
-4096,0,4096,8192,12288,16384,0,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
/*filter8*/
|
||||
short filt8_l0[8] = {
|
||||
16384,8192,0,0,0,0,0,0};
|
||||
|
||||
short filt8_mr0[8] = {
|
||||
0,0,0,8192,16384,8192,0,-8192};
|
||||
|
||||
short filt8_r0[8] = {
|
||||
0,8192,16384,24576,0,0,0,0};
|
||||
|
||||
short filt8_m0[8] = {
|
||||
0,8192,16384,8192,0,0,0,0};
|
||||
|
||||
short filt8_mm0[8]= {
|
||||
0,0,0,8192,16384,8192,0,0};
|
||||
|
||||
short filt8_l1[8] = {
|
||||
24576,16384,0,0,0,0,0,0};
|
||||
|
||||
short filt8_ml1[8] = {
|
||||
-8192,0,8192,16384,8192,0,0,0};
|
||||
|
||||
short filt8_r1[8] = {
|
||||
0,0,8192,16384,0,0,0,0};
|
||||
|
||||
short filt8_m1[8] = {
|
||||
0,0,8192,16384,8192,0,0,0};
|
||||
|
||||
short filt8_mm1[8]= {
|
||||
0,0,0,0,8192,16384,8192,0};
|
||||
@@ -1,117 +1,104 @@
|
||||
short filt16a_l0[16] = {
|
||||
16384,12288,8192,4096,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
short filt16a_r0[16] = {
|
||||
0,0,0,0,0,4096,8192,12288,16384,20480,24576,28672,0,0,0,0};
|
||||
#ifndef __FILT16A_32__H__
|
||||
#define __FILT16A_32__H__
|
||||
|
||||
short filt16a_m0[16] = {
|
||||
0,4096,8192,12288,16384,12288,8192,4096,0,-4096,-8192,-12288,0,0,0,0};
|
||||
extern short filt16a_l0[16];
|
||||
|
||||
short filt16a_l1[16] = {
|
||||
20480,16384,12288,8192,4096,0,0,0,0,0,0,0,0,0,0,0};
|
||||
extern short filt16a_r0[16];
|
||||
|
||||
short filt16a_r1[16] = {
|
||||
0,0,0,0,0,0,4096,8192,12288,16384,20480,24576,0,0,0,0};
|
||||
extern short filt16a_m0[16];
|
||||
|
||||
short filt16a_m1[16] = {
|
||||
-4096,0,4096,8192,12288,16384,12288,8192,4096,0,-4096,-8192,0,0,0,0};
|
||||
extern short filt16a_l1[16];
|
||||
|
||||
short filt16a_l2[16] = {
|
||||
24576,20480,16384,12288,8192,4096,0,0,0,0,0,0,0,0,0,0};
|
||||
extern short filt16a_r1[16];
|
||||
|
||||
short filt16a_r2[16] = {
|
||||
0,0,0,0,0,0,0,4096,8192,12288,16384,20480,0,0,0,0};
|
||||
extern short filt16a_m1[16];
|
||||
|
||||
short filt16a_m2[16] = {
|
||||
-8192,-4096,0,4096,8192,12288,16384,12288,8192,4096,0,-4096,0,0,0,0};
|
||||
extern short filt16a_l2[16];
|
||||
|
||||
short filt16a_l3[16] = {
|
||||
28672,24576,20480,16384,12288,8192,4096,0,0,0,0,0,0,0,0,0};
|
||||
extern short filt16a_r2[16];
|
||||
|
||||
short filt16a_r3[16] = {
|
||||
0,0,0,0,0,0,0,0,4096,8192,12288,16384,0,0,0,0};
|
||||
extern short filt16a_m2[16];
|
||||
|
||||
short filt16a_m3[16] = {
|
||||
-12288,-8192,-4096,0,4096,8192,12288,16384,12288,8192,4096,0,0,0,0,0};
|
||||
extern short filt16a_l3[16];
|
||||
|
||||
short filt16a_l0_dc[16] = {
|
||||
16384,12288,8192,4096,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
extern short filt16a_r3[16];
|
||||
|
||||
short filt16a_r0_dc[16] = {
|
||||
0,0,0,0,0,3276,9830,13107,16384,19660,22937,26214,0,0,0,0};
|
||||
extern short filt16a_m3[16];
|
||||
|
||||
short filt16a_m0_dc[16] = {
|
||||
0,4096,8192,12288,16384,13107,6553,3276,0,-3277,-6554,-9831,0,0,0,0};
|
||||
extern short filt16a_l0_dc[16];
|
||||
|
||||
short filt16a_l1_dc[16] = {
|
||||
16384,12288,8192,4096,0,-4096,0,0,0,0,0,0,0,0,0,0};
|
||||
extern short filt16a_r0_dc[16];
|
||||
|
||||
short filt16a_r1_dc[16] = {
|
||||
0,0,0,0,0,0,6553,9830,13107,16384,19660,22937,0,0,0,0};
|
||||
extern short filt16a_m0_dc[16];
|
||||
|
||||
short filt16a_m1_dc[16] = {
|
||||
-4096,0,4096,8192,12288,16384,9830,6553,3276,0,-3277,-6554,0,0,0,0};
|
||||
extern short filt16a_l1_dc[16];
|
||||
|
||||
short filt16a_l2_dc[16] = {
|
||||
26214,22937,19660,16384,13107,9830,6553,0,0,0,0,0,0,0,0,0};
|
||||
extern short filt16a_r1_dc[16];
|
||||
|
||||
short filt16a_r2_dc[16] = {
|
||||
0,0,0,0,0,0,0,4096,8192,12288,16384,20480,0,0,0,0};
|
||||
extern short filt16a_m1_dc[16];
|
||||
|
||||
short filt16a_m2_dc[16] = {
|
||||
-6554,-3277,0,3276,6553,6553,16384,12288,8192,4096,0,-4096,0,0,0,0};
|
||||
extern short filt16a_l2_dc[16];
|
||||
|
||||
short filt16a_l3_dc[16] = {
|
||||
26214,22937,19660,16384,13107,9830,3276,0,0,0,0,0,0,0,0,0};
|
||||
extern short filt16a_r2_dc[16];
|
||||
|
||||
short filt16a_r3_dc[16] = {
|
||||
0,0,0,0,0,0,0,0,4096,8192,12288,16384,0,0,0,0};
|
||||
extern short filt16a_m2_dc[16];
|
||||
|
||||
short filt16a_m3_dc[16] = {
|
||||
-9831,-6554,-3277,0,3276,6553,9830,16384,12288,8192,4096,0,0,0,0,0};
|
||||
extern short filt16a_l3_dc[16];
|
||||
|
||||
short filt16a_1[16] = {
|
||||
16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384};
|
||||
extern short filt16a_r3_dc[16];
|
||||
|
||||
short filt16a_2l0[16] = {
|
||||
16384,12288,8192,4096,-4096,0,0,0,0,0,0,0,0,0,0,0};
|
||||
extern short filt16a_m3_dc[16];
|
||||
|
||||
short filt16a_2r0[16] = {
|
||||
0,4096,8192,12288,16384,20480,0,0,0,0,0,0,0,0,0,0};
|
||||
extern short filt16a_1[16];
|
||||
|
||||
short filt16a_2l1[16] = {
|
||||
20480,16384,12288,8192,4096,0,0,0,0,0,0,0,0,0,0,0};
|
||||
extern short filt16a_2l0[16];
|
||||
|
||||
short filt16a_2r1[16] = {
|
||||
-4096,0,4096,8192,12288,16384,0,0,0,0,0,0,0,0,0,0};
|
||||
extern short filt16a_2r0[16];
|
||||
|
||||
extern short filt16a_2l1[16];
|
||||
|
||||
extern short filt16a_2r1[16];
|
||||
|
||||
/*filter8*/
|
||||
short filt8_l0[8] = {
|
||||
16384,8192,0,0,0,0,0,0};
|
||||
extern short filt8_l0[8];
|
||||
|
||||
short filt8_mr0[8] = {
|
||||
0,0,0,8192,16384,8192,0,-8192};
|
||||
extern short filt8_mr0[8];
|
||||
|
||||
short filt8_r0[8] = {
|
||||
0,8192,16384,24576,0,0,0,0};
|
||||
extern short filt8_r0[8];
|
||||
|
||||
short filt8_m0[8] = {
|
||||
0,8192,16384,8192,0,0,0,0};
|
||||
extern short filt8_m0[8];
|
||||
|
||||
short filt8_mm0[8]= {
|
||||
0,0,0,8192,16384,8192,0,0};
|
||||
extern short filt8_mm0[8];
|
||||
|
||||
short filt8_l1[8] = {
|
||||
24576,16384,0,0,0,0,0,0};
|
||||
extern short filt8_l1[8];
|
||||
|
||||
short filt8_ml1[8] = {
|
||||
-8192,0,8192,16384,8192,0,0,0};
|
||||
extern short filt8_ml1[8];
|
||||
|
||||
short filt8_r1[8] = {
|
||||
0,0,8192,16384,0,0,0,0};
|
||||
extern short filt8_r1[8];
|
||||
|
||||
short filt8_m1[8] = {
|
||||
0,0,8192,16384,8192,0,0,0};
|
||||
extern short filt8_m1[8];
|
||||
|
||||
short filt8_mm1[8]= {
|
||||
0,0,0,0,8192,16384,8192,0};
|
||||
extern short filt8_mm1[8];
|
||||
|
||||
#endif
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "PHY/TOOLS/tools_defs.h"
|
||||
|
||||
//#define DEBUG_SCFDMA
|
||||
//#define DEBUG_PUSCH_MAPPING
|
||||
|
||||
|
||||
int generate_ue_ulsch_params(PHY_VARS_NR_UE *UE,
|
||||
@@ -342,6 +343,7 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1]);
|
||||
#endif
|
||||
|
||||
|
||||
dmrs_idx++;
|
||||
k_prime++;
|
||||
k_prime&=1;
|
||||
|
||||
+31
-2
@@ -366,11 +366,15 @@ typedef struct {
|
||||
/// \brief Hold the channel estimates in time domain based on DRS.
|
||||
/// - first index: rx antenna id [0..nb_antennas_rx[
|
||||
/// - second index: ? [0..4*ofdm_symbol_size[
|
||||
int32_t **drs_ch_estimates_time;
|
||||
int32_t **ul_ch_estimates_time;
|
||||
/// \brief Hold the channel estimates in frequency domain based on DRS.
|
||||
/// - first index: rx antenna id [0..nb_antennas_rx[
|
||||
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
|
||||
int32_t **drs_ch_estimates;
|
||||
int32_t **ul_ch_estimates;
|
||||
/// \brief Uplink channel estimates extracted in PRBS.
|
||||
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
|
||||
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
|
||||
int32_t **ul_ch_estimates_ext;
|
||||
/// \brief Holds the compensated signal.
|
||||
/// - first index: rx antenna id [0..nb_antennas_rx[
|
||||
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
|
||||
@@ -383,6 +387,28 @@ typedef struct {
|
||||
/// - first index: rx antenna id [0..nb_antennas_rx[
|
||||
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
|
||||
int32_t **ul_ch_magb;
|
||||
/// \brief Cross-correlation of two UE signals.
|
||||
/// - first index: rx antenna [0..nb_antennas_rx[
|
||||
/// - second index: symbol [0..]
|
||||
int32_t **rho;
|
||||
/// \f$\log_2(\max|H_i|^2)\f$
|
||||
int16_t log2_maxh;
|
||||
/// \brief Magnitude of Uplink Channel first layer (16QAM level/First 64QAM level).
|
||||
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
|
||||
/// - second index: ? [0..168*N_RB_UL[
|
||||
int32_t **ul_ch_mag0;
|
||||
/// \brief Magnitude of Uplink Channel second layer (16QAM level/First 64QAM level).
|
||||
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
|
||||
/// - second index: ? [0..168*N_RB_UL[
|
||||
int32_t **ul_ch_mag1[8][8];
|
||||
/// \brief Magnitude of Uplink Channel, first layer (2nd 64QAM level).
|
||||
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
|
||||
/// - second index: ? [0..168*N_RB_UL[
|
||||
int32_t **ul_ch_magb0;
|
||||
/// \brief Magnitude of Uplink Channel second layer (2nd 64QAM level).
|
||||
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
|
||||
/// - second index: ? [0..168*N_RB_UL[
|
||||
int32_t **ul_ch_magb1[8][8];
|
||||
/// measured RX power based on DRS
|
||||
int ulsch_power[2];
|
||||
/// \brief llr values.
|
||||
@@ -641,6 +667,9 @@ typedef struct PHY_VARS_gNB_s {
|
||||
|
||||
/// PDSCH DMRS sequence
|
||||
uint32_t ****nr_gold_pdsch_dmrs;
|
||||
|
||||
/// PUSCH DMRS
|
||||
uint32_t nr_gold_pusch[2][20][2][52];
|
||||
|
||||
/// Indicator set to 0 after first SR
|
||||
uint8_t first_sr[NUMBER_OF_UE_MAX];
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
|
||||
/// First Amplitude for QAM16 (\f$ 2^{15} \times 2/\sqrt{10}\f$)
|
||||
#define QAM16_n1 20724
|
||||
|
||||
/// Second Amplitude for QAM16 (\f$ 2^{15} \times 1/\sqrt{10}\f$)
|
||||
#define QAM16_n2 10362
|
||||
|
||||
|
||||
@@ -497,6 +497,8 @@ int main(int argc, char **argv)
|
||||
//---------------------- count errors ----------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
printf("available_bits = %d\n",available_bits);
|
||||
|
||||
for (i = 0; i < available_bits; i++) {
|
||||
|
||||
if(((ulsch_ue[0]->g[i] == 0) && (gNB->pusch_vars[UE_id]->llr[i] <= 0)) ||
|
||||
@@ -511,6 +513,7 @@ int main(int argc, char **argv)
|
||||
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < TBS; i++) {
|
||||
|
||||
estimated_output_bit[i] = (ulsch_gNB->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7);
|
||||
|
||||
Reference in New Issue
Block a user