diff --git a/openair1/PHY/MODULATION/modulation_UE.h b/openair1/PHY/MODULATION/modulation_UE.h index 92afcea724..9734c02907 100644 --- a/openair1/PHY/MODULATION/modulation_UE.h +++ b/openair1/PHY/MODULATION/modulation_UE.h @@ -48,12 +48,13 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue, int no_prefix, int reset_freq_est); -int slot_fep_pbch(PHY_VARS_NR_UE *phy_vars_ue, +int nr_slot_fep(PHY_VARS_NR_UE *phy_vars_ue, unsigned char l, unsigned char Ns, int sample_offset, int no_prefix, - int reset_freq_est); + int reset_freq_est, + NR_CHANNEL_EST_t channel); int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue, unsigned char l, diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c index 28fc0e02ff..b1291695b4 100644 --- a/openair1/PHY/MODULATION/slot_fep.c +++ b/openair1/PHY/MODULATION/slot_fep.c @@ -23,17 +23,19 @@ #include "PHY/defs_nr_UE.h" #include "modulation_UE.h" #include "PHY/LTE_ESTIMATION/lte_estimation.h" +#include "PHY/NR_UE_ESTIMATION/nr_estimation.h" //#define DEBUG_FEP #define SOFFSET 0 -int slot_fep_pbch(PHY_VARS_NR_UE *ue, +int nr_slot_fep(PHY_VARS_NR_UE *ue, unsigned char l, unsigned char Ns, int sample_offset, int no_prefix, - int reset_freq_est) + int reset_freq_est, + NR_CHANNEL_EST_t channel) { NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; NR_UE_COMMON *common_vars = &ue->common_vars; @@ -47,6 +49,11 @@ int slot_fep_pbch(PHY_VARS_NR_UE *ue, int i; unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10; unsigned int rx_offset; + //NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[Ns>>1]][0]; + uint16_t coreset_start_subcarrier = frame_parms->first_carrier_offset; + uint16_t nb_rb_coreset = 24; + uint16_t bwp_start_subcarrier = frame_parms->first_carrier_offset; + uint16_t nb_rb_pdsch = 100; /*LTE_UE_DLSCH_t **dlsch_ue = phy_vars_ue->dlsch_ue[eNB_id]; unsigned char harq_pid = dlsch_ue[0]->current_harq_pid; @@ -181,7 +188,10 @@ int slot_fep_pbch(PHY_VARS_NR_UE *ue, } if (ue->perfect_ce == 0) { - if ((l>0) && (l<4)) { + + switch(channel){ + case NR_PBCH_EST: + if ((l>4) && (l<8)) { for (aa=0; aanb_antenna_ports_eNB; aa++) { #ifdef DEBUG_FEP @@ -196,7 +206,9 @@ int slot_fep_pbch(PHY_VARS_NR_UE *ue, l, symbol); } - +#if UE_TIMING_TRACE + stop_meas(&ue->dlsch_channel_estimation_stats); +#endif // do frequency offset estimation here! // use channel estimates from current symbol (=ch_t) and last symbol (ch_{t-1}) @@ -221,6 +233,60 @@ int slot_fep_pbch(PHY_VARS_NR_UE *ue, } } + break; + + case NR_PDCCH_EST: + for (aa=0; aanb_antenna_ports_eNB; aa++) { + +#ifdef DEBUG_FEP + printf("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l); +#endif +#if UE_TIMING_TRACE + start_meas(&ue->dlsch_channel_estimation_stats); +#endif + nr_pdcch_channel_estimation(ue,eNB_id,0, + Ns, + aa, + l, + symbol, + coreset_start_subcarrier, + nb_rb_coreset); +#if UE_TIMING_TRACE + stop_meas(&ue->dlsch_channel_estimation_stats); +#endif + } + break; + + case NR_PDSCH_EST: + for (aa=0; aanb_antenna_ports_eNB; aa++) { + +#ifdef DEBUG_FEP + printf("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l); +#endif +#if UE_TIMING_TRACE + start_meas(&ue->dlsch_channel_estimation_stats); +#endif + nr_pdsch_channel_estimation(ue,eNB_id,0, + Ns, + aa, + l, + symbol, + bwp_start_subcarrier, + nb_rb_pdsch); +#if UE_TIMING_TRACE + stop_meas(&ue->dlsch_channel_estimation_stats); +#endif + } + break; + + case NR_SSS_EST: + break; + + default: + LOG_E(PHY,"[UE][FATAL] Unknown channel format %d\n",channel); + return(-1); + break; + } } diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 26d883eb17..941853388f 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -50,20 +50,72 @@ int wt1[8][2] = {{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1}}; int wf2[12][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1},{1,1},{1,-1},{1,1},{1,1}}; int wt2[12][2] = {{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1}}; -//short nr_mod_table[14] = {0,0,-23170,-23170,23170,23170,-23170,-23170,-23170,23170,23170,-23170,23170,23170}; - short nr_rx_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,23170,-23170,-23170,23170,23170,-23170,23170,23170,-23170,-23170,-23170,23170}; -//short nr_mod_table[14] = {0,0,23170,23170,-23170,-23170,23170,23170,23170,-23170,-23170,23170,-23170,-23170}; -//extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT]; +short nr_rx_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,23170,-23170,-23170,23170,23170,-23170,23170,23170,-23170,-23170,-23170,23170}; + +int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, + uint8_t eNB_offset, + unsigned int Ns, + unsigned int nr_gold_pdcch[7][20][3][10], + int32_t *output, + unsigned short p, + int length_dmrs, + unsigned short nb_rb_coreset) +{ + int32_t qpsk[4],n; + int w,ind,l,ind_dword,ind_qpsk_symb,kp,k; + short pamp; + + // Compute the correct pilot amplitude, sqrt_rho_b = Q3.13 + pamp = ONE_OVER_SQRT2_Q15; + + // This includes complex conjugate for channel estimation + ((short *)&qpsk[0])[0] = pamp; + ((short *)&qpsk[0])[1] = -pamp; + ((short *)&qpsk[1])[0] = -pamp; + ((short *)&qpsk[1])[1] = -pamp; + ((short *)&qpsk[2])[0] = pamp; + ((short *)&qpsk[2])[1] = pamp; + ((short *)&qpsk[3])[0] = -pamp; + ((short *)&qpsk[3])[1] = pamp; + + if (p==2000) { + // r_n from 38.211 7.4.1.3 + for (n=0; n>4; + ind_qpsk_symb = ind&0xf; + + output[k] = qpsk[(nr_gold_pdcch[eNB_offset][Ns][l][ind_dword]>>(2*ind_qpsk_symb))&3]; + +#ifdef DEBUG_DL_DMRS + LOG_I(PHY,"Ns %d, p %d, ind_dword %d, ind_qpsk_symbol %d\n", + Ns,p,idx_dword,idx_qpsk_symb); + LOG_I(PHY,"index = %d\n",(nr_gold_pdsch[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3); +#endif + + k++; + } + } + } + } else { + LOG_E(PHY,"Illegal PDCCH DMRS port %d\n",p); + } + + return(0); +} int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, - unsigned int ncp, + uint8_t eNB_offset, unsigned int Ns, unsigned int nr_gold_pdsch[2][20][2][21], int32_t *output, unsigned short p, int length_dmrs, - unsigned short nb_pdsch_rb) + unsigned short nb_rb_pdsch) { int32_t qpsk[4],nqpsk[4],*qpsk_p, n; int w,mprime,ind,l,ind_dword,ind_qpsk_symb,kp,lp, config_type, k; @@ -77,7 +129,7 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, printf("dmrs config type %d port %d\n", config_type, p); // Compute the correct pilot amplitude, sqrt_rho_b = Q3.13 - pamp = 23170; //ONE_OVER_SQRT2_Q15; + pamp = ONE_OVER_SQRT2_Q15; // This includes complex conjugate for channel estimation ((short *)&qpsk[0])[0] = pamp; @@ -105,10 +157,9 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, LOG_E(PHY,"Bad PDSCH DMRS config type %d\n", config_type); if ((p>=1000) && (p<((config_type==0) ? 1008 : 1012))) { - if (/*ue->frame_parms.Ncp == NORMAL*/ncp ==0) { // r_n from 38.211 7.4.1.1 - for (n=0; n>4; ind_qpsk_symb = ind&0xf; - output[k] = qpsk_p[(ue->nr_gold_pdsch[0][Ns][lp][ind_dword]>>(2*ind_qpsk_symb))&3]; + output[k] = qpsk_p[(nr_gold_pdsch[0][Ns][lp][ind_dword]>>(2*ind_qpsk_symb))&3]; #ifdef DEBUG_DL_DMRS @@ -131,9 +182,6 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, } } } - } else { - LOG_E(PHY,"extended cp not supported for PDSCH DMRS yet\n"); - } } else { LOG_E(PHY,"Illegal p %d PDSCH DMRS port\n",p); } diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c index 1386f9846b..d43d7235ed 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold_ue.c +++ b/openair1/PHY/NR_REFSIG/nr_gold_ue.c @@ -64,11 +64,54 @@ void nr_gold_pbch(PHY_VARS_NR_UE* ue) } -void nr_gold_pdsch(PHY_VARS_NR_UE* ue,unsigned short lbar,unsigned int nr_gold_pdsch[2][20][2][21],unsigned int Nid_cell, unsigned short *n_idDMRS, unsigned short length_dmrs) +void nr_gold_pdcch(PHY_VARS_NR_UE* ue,unsigned int Nid_cell, unsigned short n_idDMRS, unsigned short length_dmrs) { unsigned char ns,l; - unsigned int n,x1,x2,x2tmp0,x2tmp1, x2tmp2,x2s; + unsigned int n,x1,x2,x2tmp0; + unsigned int nid; + + if (n_idDMRS) + nid = n_idDMRS; + else + nid = Nid_cell; + + for (ns=0; ns<20; ns++) { + + for (l=0; l>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<10; 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); + ue->nr_gold_pdcch[0][ns][l][n] = x1^x2; + //printf("n=%d : c %x\n",n,x1^x2); + } + } + } +} + +void nr_gold_pdsch(PHY_VARS_NR_UE* ue,unsigned short lbar,unsigned int Nid_cell, unsigned short *n_idDMRS, unsigned short length_dmrs) +{ + + unsigned char ns,l; + unsigned int n,x1,x2,x2tmp0; int nscid; unsigned int nid; @@ -86,7 +129,7 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue,unsigned short lbar,unsigned int nr_gold_p for (l=0; l>1) ^ (x2>>2) ^ (x2>>3))<<31); @@ -105,7 +148,7 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue,unsigned short lbar,unsigned int nr_gold_p 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); - nr_gold_pdsch[nscid][ns][l][n] = x1^x2; + ue->nr_gold_pdsch[nscid][ns][l][n] = x1^x2; //printf("n=%d : c %x\n",n,x1^x2); } diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index 2d4db86ef9..ba2b7e69d9 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -31,20 +31,36 @@ */ int nr_pbch_dmrs_rx(unsigned int *nr_gold_pbch, int32_t *output ); -/*int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, - unsigned int ncp, +/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS. +@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables + */ +int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, + uint8_t eNB_offset, + unsigned int Ns, + unsigned int nr_gold_pdcch[7][20][3][10], + int32_t *output, + unsigned short p, + int length_dmrs, + unsigned short nb_rb_corset); + +int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, + uint8_t eNB_offset, unsigned int Ns, unsigned int nr_gold_pdsch[2][20][2][21], int32_t *output, unsigned short p, int length_dmrs, - unsigned short nb_pdsch_rb);*/ + unsigned short nb_rb_pdsch); void nr_gold_pbch(PHY_VARS_NR_UE* ue); +void nr_gold_pdcch(PHY_VARS_NR_UE* ue, + unsigned int Nid_cell, + unsigned short n_idDMRS, + unsigned short length_dmrs); + void nr_gold_pdsch(PHY_VARS_NR_UE* ue, unsigned short lbar, - unsigned int nr_gold_pdsch[2][20][2][21], unsigned int Nid_cell, unsigned short *n_idDMRS, unsigned short length_dmrs); diff --git a/openair1/PHY/NR_REFSIG/ss_pbch_nr.h b/openair1/PHY/NR_REFSIG/ss_pbch_nr.h index e230d8035b..5cd58ea5b6 100644 --- a/openair1/PHY/NR_REFSIG/ss_pbch_nr.h +++ b/openair1/PHY/NR_REFSIG/ss_pbch_nr.h @@ -51,10 +51,10 @@ #define PSS_SC_START_NR (52) /* see from TS 38.211 table 7.4.3.1-1: Resources within an SS/PBCH block for PSS... */ /* define ofdm symbol offset in the SS/PBCH block of NR synchronisation */ -#define PSS_SYMBOL_NB (0) /* symbol numbers for each element */ -#define PBCH_SYMBOL_NB (1) -#define SSS_SYMBOL_NB (2) -#define PBCH_LAST_SYMBOL_NB (3) +#define PSS_SYMBOL_NB (4) /* symbol numbers for each element */ +#define PBCH_SYMBOL_NB (5) +#define SSS_SYMBOL_NB (6) +#define PBCH_LAST_SYMBOL_NB (7) /* SS/PBCH parameters */ #define N_RB_SS_PBCH_BLOCK (20) diff --git a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h index a37a591d2f..52356a9438 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h +++ b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h @@ -84,3 +84,28 @@ short filt16a_2l1[16] = { 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,8192,16384,8192,0,-8192,0,0}; + +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_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}; diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 87361f5e9e..2f2c741a16 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -221,3 +221,364 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, return(0); } +int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, + uint8_t eNB_id, + uint8_t eNB_offset, + unsigned char Ns, + unsigned char p, + unsigned char l, + unsigned char symbol, + unsigned short coreset_start_subcarrier, + unsigned short nb_rb_coreset) +{ + int pilot[2][200] __attribute__((aligned(16))); + unsigned char aarx; + unsigned short k; + unsigned int pilot_cnt; + int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr; + int ch_offset,symbol_offset; + + //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; + + uint8_t nushift; + int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset]; + int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF; + + nushift = 1; + ue->frame_parms.nushift = nushift; + + if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage + ch_offset = ue->frame_parms.ofdm_symbol_size ; + else + ch_offset = ue->frame_parms.ofdm_symbol_size*symbol; + + symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol; + + k = coreset_start_subcarrier; + +#ifdef DEBUG_CH + printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d cell_id %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns>>1], eNB_offset,Nid_cell,ch_offset,ue->frame_parms.ofdm_symbol_size, + ue->frame_parms.Ncp,l,Ns,k, symbol); +#endif + + fl = filt16a_l1; + fm = filt16a_m1; + fr = filt16a_r1; + + // generate pilot + nr_pdcch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdcch[eNB_offset][Ns][symbol], &pilot[p][0],2000,symbol, nb_rb_coreset); + + for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { + + pil = (int16_t *)&pilot[p][0]; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; + dl_ch = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset]; + + memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size)); + if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha + multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1), + ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1), + 1,ue->frame_parms.ofdm_symbol_size); +#ifdef DEBUG_CH + printf("ch est pilot addr %p RB_DL %d\n",&pilot[p][0], ue->frame_parms.N_RB_DL); + printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset); + printf("rxF addr %p\n", rxF); + printf("dl_ch addr %p\n",dl_ch); +#endif + if ((ue->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_CH + 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]); +#endif + multadd_real_vector_complex_scalar(fl, + ch, + dl_ch, + 16); + pil+=2; + rxF+=8; + //for (int i= 0; i<8; i++) + //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_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_CH + 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(fm, + ch, + dl_ch, + 16); + pil+=2; + rxF+=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_CH + 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(fr, + ch, + dl_ch, + 16); + pil+=2; + rxF+=8; + dl_ch+=24; + k+=12; + + for (pilot_cnt=3; pilot_cnt<(3*nb_rb_coreset); pilot_cnt+=3) { + + if (k >= ue->frame_parms.ofdm_symbol_size){ + k-=ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];} + + 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 + 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(fl, + ch, + dl_ch, + 16); + + //for (int i= 0; i<8; i++) + // printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i)); + + pil+=2; + rxF+=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_CH + 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(fm, + ch, + dl_ch, + 16); + pil+=2; + rxF+=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_CH + 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(fr, + ch, + dl_ch, + 16); + pil+=2; + rxF+=8; + dl_ch+=24; + k+=12; + + } + + + } + + } + + return(0); +} + +int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, + uint8_t eNB_id, + uint8_t eNB_offset, + unsigned char Ns, + unsigned char p, + unsigned char l, + unsigned char symbol, + unsigned short bwp_start_subcarrier, + unsigned short nb_rb_pdsch) +{ + int pilot[2][200] __attribute__((aligned(16))); + unsigned char aarx; + unsigned short k; + unsigned int pilot_cnt; + int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr,*fml,*fmr; + int ch_offset,symbol_offset; + + //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; + + uint8_t nushift; + int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset]; + int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF; + + nushift = (p>>1)&1; + ue->frame_parms.nushift = nushift; + + if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage + ch_offset = ue->frame_parms.ofdm_symbol_size ; + else + ch_offset = ue->frame_parms.ofdm_symbol_size*symbol; + + symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol; + + k = bwp_start_subcarrier; + +#ifdef DEBUG_CH + printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d cell_id %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns>>1], eNB_offset,Nid_cell,ch_offset,ue->frame_parms.ofdm_symbol_size, + ue->frame_parms.Ncp,l,Ns,k, symbol); +#endif + + switch (nushift) { + case 0: + fl = filt8_l0; + fm = filt8_m0; + fr = filt8_r0; + fml = filt8_m0; + fmr = filt8_mr0; + break; + + case 1: + fl = filt8_l1; + fm = filt8_m1; + fr = filt8_r1; + fml = filt8_ml1; + fmr = filt8_m1; + break; + + default: + msg("pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift); + return(-1); + break; + } + + + // generate pilot + nr_pdsch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][symbol], &pilot[p][0],1000,1,nb_rb_pdsch); + + for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { + + pil = (int16_t *)&pilot[p][0]; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; + dl_ch = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset]; + + memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size)); + if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha + multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1), + ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1), + 1,ue->frame_parms.ofdm_symbol_size); +#ifdef DEBUG_CH + printf("ch est pilot addr %p RB_DL %d\n",&pilot[p][0], ue->frame_parms.N_RB_DL); + printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset); + printf("rxF addr %p\n", rxF); + printf("dl_ch addr %p\n",dl_ch); +#endif + if ((ue->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_CH + 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]); +#endif + multadd_real_vector_complex_scalar(fl, + ch, + dl_ch, + 8); + pil+=2; + rxF+=4; + //for (int i= 0; i<8; i++) + //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_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_CH + 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, + dl_ch, + 8); + pil+=2; + rxF+=4; + dl_ch+=4; + k+=4; + + for (pilot_cnt=2; pilot_cnt<(6*(nb_rb_pdsch-1)+4); pilot_cnt+=2) { + if ((pilot_cnt%6)==0) + dl_ch+=4; + + if (k >= ue->frame_parms.ofdm_symbol_size){ + k-=ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];} + + 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 + 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, + dl_ch, + 8); + + pil+=2; + rxF+=4; + dl_ch+=4; + + 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 + 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(fm, + ch, + dl_ch, + 8); + pil+=2; + rxF+=4; + dl_ch+=4; + k+=4; + + } + + // 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_CH + 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]); +#endif + multadd_real_vector_complex_scalar(fmr, + ch, + dl_ch, + 8); + pil+=2; + rxF+=4; + //for (int i= 0; i<8; i++) + //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_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_CH + 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(fr, + ch, + dl_ch, + 8); + pil+=2; + rxF+=4; + dl_ch+=4; + k+=4; + + } + + } + + return(0); +} + diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 7ec222727b..fb012b03fa 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -19,12 +19,12 @@ * contact@openairinterface.org */ -#ifndef __LTE_ESTIMATION_DEFS__H__ -#define __LTE_ESTIMATION_DEFS__H__ +#ifndef __NR_ESTIMATION_DEFS__H__ +#define __NR_ESTIMATION_DEFS__H__ #include "PHY/defs_nr_UE.h" -#include "PHY/defs_gNB.h" +//#include "PHY/defs_gNB.h" /** @addtogroup _PHY_PARAMETER_ESTIMATION_BLOCKS_ * @{ */ @@ -42,13 +42,15 @@ \param l symbol within slot \param symbol symbol within frame */ -int nr_dl_channel_estimation(PHY_VARS_NR_UE *ue, +int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t eNB_offset, unsigned char Ns, unsigned char p, unsigned char l, - unsigned char symbol); + unsigned char symbol, + unsigned short coreset_start_subcarrier, + unsigned short nb_rb_coreset); int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, uint8_t eNB_id, @@ -57,4 +59,14 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, unsigned char p, unsigned char l, unsigned char symbol); + +int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, + uint8_t eNB_id, + uint8_t eNB_offset, + unsigned char Ns, + unsigned char p, + unsigned char l, + unsigned char symbol, + unsigned short bwp_start_subcarrier, + unsigned short nb_rb_pdsch); #endif diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 874855e2fe..02a7d717a3 100755 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -1141,16 +1141,15 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { if (high_speed_flag == 1){ - dl_ch0 = &dl_ch_estimates[aarx][5 + (symbol * (frame_parms->ofdm_symbol_size))]; + dl_ch0 = &dl_ch_estimates[aarx][(symbol * (frame_parms->ofdm_symbol_size))]; #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> dl_ch0 = &dl_ch_estimates[aarx = (%d)][5 + (symbol * (frame_parms->ofdm_symbol_size (%d))) = (%d)]\n", - aarx,frame_parms->ofdm_symbol_size,5 + (symbol * (frame_parms->ofdm_symbol_size))); - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> why pointer is pointing to that position (what does '5' mean)?\n"); + printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> dl_ch0 = &dl_ch_estimates[aarx = (%d)][ (symbol * (frame_parms->ofdm_symbol_size (%d))) = (%d)]\n", + aarx,frame_parms->ofdm_symbol_size,(symbol * (frame_parms->ofdm_symbol_size))); #endif } else { - dl_ch0 = &dl_ch_estimates[aarx][5]; + dl_ch0 = &dl_ch_estimates[aarx][0]; #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> dl_ch0 = &dl_ch_estimates[aarx = (%d)][5]\n",aarx); + printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> dl_ch0 = &dl_ch_estimates[aarx = (%d)][0]\n",aarx); #endif } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 5b641b102a..42aaa10e25 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -58,6 +58,7 @@ int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode) uint8_t l,pbch_decoded,frame_mod4,pbch_tx_ant,dummy; NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; char phich_resource[6]; + int ret =-1; #ifdef DEBUG_INITIAL_SYNCH LOG_I(PHY,"[UE%d] Initial sync: starting PBCH detection (rx_offset %d)\n",ue->Mod_id, @@ -68,28 +69,31 @@ int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode) frame_parms->nb_prefix_samples0 = 0; //symbol 1 - slot_fep_pbch(ue, + nr_slot_fep(ue, 1, 0, ue->rx_offset, 0, - 1); + 1, + NR_PBCH_EST); //symbol 2 - slot_fep_pbch(ue, + nr_slot_fep(ue, 2, 0, ue->rx_offset, 0, - 1); + 1, + NR_PBCH_EST); //symbol 3 - slot_fep_pbch(ue, + nr_slot_fep(ue, 3, 0, ue->rx_offset, 0, - 1); + 1, + NR_PBCH_EST); frame_parms->nb_prefix_samples0 = nb_prefix_samples0; @@ -98,7 +102,7 @@ int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode) printf("pbch_detection nid_cell %d\n",frame_parms->Nid_cell); //for (frame_mod4=0; frame_mod4<4; frame_mod4++) { - pbch_tx_ant = nr_rx_pbch(ue, + ret = nr_rx_pbch(ue, &ue->proc.proc_rxtx[0], ue->pbch_vars[0], frame_parms, @@ -112,9 +116,9 @@ int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode) //} - if (pbch_decoded) { + if (ret==0) { - frame_parms->nb_antenna_ports_eNB = pbch_tx_ant; + frame_parms->nb_antenna_ports_eNB = 1; //pbch_tx_ant; // set initial transmission mode to 1 or 2 depending on number of detected TX antennas //frame_parms->mode1_flag = (pbch_tx_ant==1); @@ -128,13 +132,7 @@ int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode) for(int i=0; iproc.proc_rxtx[i].frame_rx = (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2; - ue->proc.proc_rxtx[i].frame_rx = (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2; -#ifndef USER_MODE - // one frame delay - ue->proc.proc_rxtx[i].frame_rx ++; -#endif ue->proc.proc_rxtx[i].frame_tx = ue->proc.proc_rxtx[0].frame_rx; } #ifdef DEBUG_INITIAL_SYNCH @@ -157,7 +155,7 @@ char prefix_string[2][9] = {"NORMAL","EXTENDED"}; int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) { - int32_t sync_pos, sync_pos2, k_ssb, N_ssb_crb; + int32_t sync_pos, sync_pos2, k_ssb, N_ssb_crb, sync_pos_slot; int32_t metric_fdd_ncp=0; uint8_t phase_fdd_ncp; @@ -200,8 +198,19 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) /* process pss search on received buffer */ sync_pos = pss_synchro_nr(ue, NO_RATE_CHANGE); + sync_pos_slot = (frame_parms->samples_per_tti>>1) - 4*(frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples); + + if (sync_pos >= frame_parms->nb_prefix_samples) + sync_pos2 = sync_pos - frame_parms->nb_prefix_samples; + else + sync_pos2 = sync_pos + FRAME_LENGTH_COMPLEX_SAMPLES - frame_parms->nb_prefix_samples; + /* offset is used by sss serach as it is returned from pss search */ - ue->rx_offset = sync_pos; + if (sync_pos2 >= sync_pos_slot) + ue->rx_offset = sync_pos2 - sync_pos_slot; + else + ue->rx_offset = FRAME_LENGTH_COMPLEX_SAMPLES + sync_pos2 - sync_pos_slot; + // write_output("rxdata1.m","rxd1",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index ad9e0262e4..d181c81fca 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -498,7 +498,7 @@ unsigned char sign(int8_t x) { uint8_t pbch_deinterleaving_pattern[32] = {28,0,31,30,1,29,25,27,22,2,24,3,4,5,6,7,18,21,20,8,9,10,11,19,26,12,13,14,15,16,23,17}; -uint16_t nr_rx_pbch( PHY_VARS_NR_UE *ue, +int nr_rx_pbch( PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, NR_UE_PBCH *nr_ue_pbch_vars, NR_DL_FRAME_PARMS *frame_parms, @@ -546,7 +546,7 @@ uint16_t nr_rx_pbch( PHY_VARS_NR_UE *ue, // clear LLR buffer memset(nr_ue_pbch_vars->llr,0,NR_POLAR_PBCH_E); - for (symbol=1; symbol<4; symbol++) { + for (symbol=5; symbol<8; symbol++) { //printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF); //write_output("rxdataF0_pbch.m","rxF0pbch",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF,frame_parms->ofdm_symbol_size*4,2,1); diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c index 1afcf95310..3231e82035 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c @@ -424,20 +424,22 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max) // Do FFTs for SSS/PSS // SSS - slot_fep_pbch(ue, + nr_slot_fep(ue, SSS_SYMBOL_NB, // symbol number 0, // Ns slot number ue->rx_offset, // sample_offset of int16_t 0, // no_prefix - 1); // reset frequency estimation + 1, // reset frequency estimation + NR_SSS_EST); // PSS - slot_fep_pbch(ue, + nr_slot_fep(ue, PSS_SYMBOL_NB, 0, ue->rx_offset, 0, - 1); + 1, + NR_SSS_EST); frame_parms->nb_prefix_samples0 = nb_prefix_samples0; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 42f6f570f9..3bdb827ffb 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -312,6 +312,13 @@ typedef struct { UE_nr_rxtx_proc_t proc_rxtx[RX_NB_TH]; } UE_nr_proc_t; +typedef enum { + NR_PBCH_EST=0, + NR_PDCCH_EST, + NR_PDSCH_EST, + NR_SSS_EST, +} NR_CHANNEL_EST_t; + #define debug_msg if (((mac_xface->frame%100) == 0) || (mac_xface->frame < 50)) msg typedef struct { @@ -1028,6 +1035,7 @@ typedef struct { nr_ue_if_module_t *if_inst; nr_downlink_indication_t dl_indication; + nr_uplink_indication_t ul_indication; // point to the current rxTx thread index uint8_t current_thread_id[10]; @@ -1078,7 +1086,7 @@ typedef struct { uint32_t nr_gold_pdsch[2][20][2][21]; /// PDCCH DMRS - uint32_t nr_gold_pdcch[10][3][42]; + uint32_t nr_gold_pdcch[7][20][3][10]; uint32_t X_u[64][839]; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 0efd98e87c..9157ede2a5 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -5901,6 +5901,7 @@ int phy_procedures_UE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_ LOG_D(PHY," ------ --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx); + nr_gold_pdcch(ue,ue->frame_parms.Nid_cell, 0, 3); for (; l<=3; l++) { if (abstraction_flag == 0) { @@ -5908,12 +5909,13 @@ int phy_procedures_UE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_ start_meas(&ue->ofdm_demod_stats); #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); - slot_fep_pbch(ue, + nr_slot_fep(ue, l, (nr_tti_rx<<1), 0, 0, - 0); + 0, + NR_PDCCH_EST); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE stop_meas(&ue->ofdm_demod_stats); @@ -5970,6 +5972,17 @@ int phy_procedures_UE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_ #endif LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx); + //to update from pdsch config + nr_gold_pdsch(ue,0,ue->frame_parms.Nid_cell, 0, 1); + + nr_slot_fep(ue, + 2, //to be updated from higher layer + (nr_tti_rx<<1), + 0, + 0, + 0, + NR_PDSCH_EST); + #if UE_TIMING_TRACE start_meas(&ue->generic_stat); #endif @@ -5994,7 +6007,6 @@ int phy_procedures_UE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_ if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN); ue_pdsch_procedures(ue, - proc, eNB_id, SI_PDSCH, diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 5c3ba3d414..cd9785f7fe 100755 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -19,7 +19,7 @@ * contact@openairinterface.org */ -/* \file config.c +/* \file config_ue.c * \brief UE and eNB configuration performed by RRC or as a consequence of RRC procedures * \author R. Knopp, K.H. HSU * \date 2018 diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index b5278ffacb..5640c45b82 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -63,15 +63,22 @@ typedef struct { //// MAC config - NR_DRX_Config_t *drx_Config; /* OPTIONAL */ - NR_SchedulingRequestConfig_t *schedulingRequestConfig; /* OPTIONAL */ - NR_BSR_Config_t *bsr_Config; /* OPTIONAL */ - NR_TAG_Config_t *tag_Config; /* OPTIONAL */ - NR_PHR_Config_t *phr_Config; /* OPTIONAL */ + NR_DRX_Config_t *drx_Config; + NR_SchedulingRequestConfig_t *schedulingRequestConfig; + NR_BSR_Config_t *bsr_Config; + NR_TAG_Config_t *tag_Config; + NR_PHR_Config_t *phr_Config; + NR_RNTI_Value_t *cs_RNTI; + NR_MIB_t *mib; + + /// Type0-PDCCH seach space coreset + uint32_t num_rbs; + uint32_t num_symbols; + uint32_t rb_offset; - NR_RNTI_Value_t *cs_RNTI; /* OPTIONAL */ + + /// Type0-PDCCH seach space - NR_MIB_t *mib; //// FAPI-like interface fapi_nr_tx_request_t tx_request; @@ -80,9 +87,12 @@ typedef struct { fapi_nr_dci_indication_t dci_indication; fapi_nr_rx_indication_t rx_indication; + /// Interface module instances nr_ue_if_module_t *if_module; nr_scheduled_response_t scheduled_response; nr_phy_config_t phy_config; + + } NR_UE_MAC_INST_t; /*@}*/ diff --git a/openair2/LAYER2/NR_MAC_UE/mac_extern.h b/openair2/LAYER2/NR_MAC_UE/mac_extern.h new file mode 100644 index 0000000000..4539b85cfe --- /dev/null +++ b/openair2/LAYER2/NR_MAC_UE/mac_extern.h @@ -0,0 +1,81 @@ +/* + * 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 + */ + +/* \file extern.h + * \brief extern variables for MAC layer + * \author R. Knopp, K.H. HSU + * \date 2018 + * \version 0.1 + * \company Eurecom / NTUST + * \email: knopp@eurecom.fr, kai-hsiang.hsu@eurecom.fr + * \note + * \warning + */ + + +extern const int32_t table_38213_13_1_c2[16]; +extern const int32_t table_38213_13_1_c3[16]; +extern const int32_t table_38213_13_1_c4[16]; + +extern const int32_t table_38213_13_2_c2[16]; +extern const int32_t table_38213_13_2_c3[16]; +extern const int32_t table_38213_13_2_c4[16]; + +extern const int32_t table_38213_13_3_c2[16]; +extern const int32_t table_38213_13_3_c3[16]; +extern const int32_t table_38213_13_3_c4[16]; + +extern const int32_t table_38213_13_4_c2[16]; +extern const int32_t table_38213_13_4_c3[16]; +extern const int32_t table_38213_13_4_c4[16]; + +extern const int32_t table_38213_13_5_c2[16]; +extern const int32_t table_38213_13_5_c3[16]; +extern const int32_t table_38213_13_5_c4[16]; + +extern const int32_t table_38213_13_6_c2[16]; +extern const int32_t table_38213_13_6_c3[16]; +extern const int32_t table_38213_13_6_c4[16]; + +extern const int32_t table_38213_13_7_c2[16]; +extern const int32_t table_38213_13_7_c3[16]; +extern const int32_t table_38213_13_7_c4[16]; + +extern const int32_t table_38213_13_8_c2[16]; +extern const int32_t table_38213_13_8_c3[16]; +extern const int32_t table_38213_13_8_c4[16]; + +extern const int32_t table_38213_13_9_c2[16]; +extern const int32_t table_38213_13_9_c3[16]; +extern const int32_t table_38213_13_9_c4[16]; + +extern const int32_t table_38213_13_10_c2[16]; +extern const int32_t table_38213_13_10_c3[16]; +extern const int32_t table_38213_13_10_c4[16]; + +extern const float table_38213_13_11_c1[16]; +extern const int32_t table_38213_13_11_c2[16]; +extern const float table_38213_13_11_c3[16]; +extern const int32_t table_38213_13_11_c4[16]; + +extern const float table_38213_13_12_c1[16]; +extern const int32_t table_38213_13_12_c2[16]; +extern const float table_38213_13_12_c3[16]; \ No newline at end of file diff --git a/openair2/LAYER2/NR_MAC_UE/mac_vars.c b/openair2/LAYER2/NR_MAC_UE/mac_vars.c index d995bdb2d0..228a599b56 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_vars.c +++ b/openair2/LAYER2/NR_MAC_UE/mac_vars.c @@ -32,6 +32,59 @@ #include "mac_defs.h" -NR_UE_MAC_INST_t UE_mac_inst; //[NB_MODULE_MAX]; +#define reserved 0xffff +// specification mapping talbe, table_38$x_$y_$z_c$a +// - $x: specification +// - $y: subclause-major +// - $z: subclause-minor +// - $a: ($a)th of column in table, start from zero +const int32_t table_38213_13_1_c2[16] = {24, 24, 24, 24, 24, 24, 48, 48, 48, 48, 48, 48, 96, 96, 96, reserved}; // index 15 reserved +const int32_t table_38213_13_1_c3[16] = { 2, 2, 2, 3, 3, 3, 1, 1, 2, 2, 3, 3, 1, 2, 3, reserved}; // index 15 reserved +const int32_t table_38213_13_1_c4[16] = { 0, 2, 4, 0, 2, 4, 12, 16, 12, 16, 12, 16, 38, 38, 38, reserved}; // index 15 reserved + +const int32_t table_38213_13_2_c2[16] = {24, 24, 24, 24, 24, 24, 24, 24, 48, 48, 48, 48, 48, 48, reserved, reserved}; // index 14-15 reserved +const int32_t table_38213_13_2_c3[16] = { 2, 2, 2, 2, 3, 3, 3, 3, 1, 1, 2, 2, 3, 3, reserved, reserved}; // index 14-15 reserved +const int32_t table_38213_13_2_c4[16] = { 5, 6, 7, 8, 5, 6, 7, 8, 18, 20, 18, 20, 18, 20, reserved, reserved}; // index 14-15 reserved + +const int32_t table_38213_13_3_c2[16] = {48, 48, 48, 48, 48, 48, 96, 96, 96, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved +const int32_t table_38213_13_3_c3[16] = { 1, 1, 2, 2, 3, 3, 1, 2, 3, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved +const int32_t table_38213_13_3_c4[16] = { 2, 6, 2, 6, 2, 6, 28, 28, 28, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved + +const int32_t table_38213_13_4_c2[16] = {24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 48, 48, 48, 48, 48, 48}; +const int32_t table_38213_13_4_c3[16] = { 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 1, 1, 1, 2, 2, 2}; +const int32_t table_38213_13_4_c4[16] = { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 12, 14, 16, 12, 14, 16}; + +const int32_t table_38213_13_5_c2[16] = {48, 48, 48, 96, 96, 96, 96, 96, 96, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved +const int32_t table_38213_13_5_c3[16] = { 1, 2, 3, 1, 1, 2, 2, 3, 3, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved +const int32_t table_38213_13_5_c4[16] = { 4, 4, 4, 0, 56, 0, 56, 0, 56, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved + +const int32_t table_38213_13_6_c2[16] = {24, 24, 24, 24, 48, 48, 48, 48, 48, 48, reserved, reserved, reserved, reserved, reserved, reserved}; // index 10-15 reserved +const int32_t table_38213_13_6_c3[16] = { 2, 2, 3, 3, 1, 1, 2, 2, 3, 3, reserved, reserved, reserved, reserved, reserved, reserved}; // index 10-15 reserved +const int32_t table_38213_13_6_c4[16] = { 0, 4, 0, 4, 0, 28, 0, 28, 0, 28, reserved, reserved, reserved, reserved, reserved, reserved}; // index 10-15 reserved + +const int32_t table_38213_13_7_c2[16] = {48, 48, 48, 48, 48, 48, 96, 96, 48, 48, 96, 96, reserved, reserved, reserved, reserved}; // index 12-15 reserved +const int32_t table_38213_13_7_c3[16] = { 1, 1, 2, 2, 3, 3, 1, 2, 1, 1, 1, 1, reserved, reserved, reserved, reserved}; // index 12-15 reserved +const int32_t table_38213_13_7_c4[16] = { 0, 8, 0, 8, 0, 8, 28, 28,-41, 49,-41, 97, reserved, reserved, reserved, reserved}; // index 12-15 reserved, condition A as default + +const int32_t table_38213_13_8_c2[16] = { 1, 1, 1, 1, 3, 3, 3, 3, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 15 reserved +const int32_t table_38213_13_8_c3[16] = {24, 24, 48, 48, 24, 24, 48, 48, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 15 reserved +const int32_t table_38213_13_8_c4[16] = { 0, 4, 14, 14,-20, 24,-20, 48, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 15 reserved, condition A as default + +const int32_t table_38213_13_9_c2[16] = {96, 96, 96, 96, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 04-15 reserved +const int32_t table_38213_13_9_c3[16] = { 1, 1, 2, 2, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 04-15 reserved +const int32_t table_38213_13_9_c4[16] = { 0, 16, 0, 16, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 04-15 reserved + +const int32_t table_38213_13_10_c2[16] = {48, 48, 48, 48, 24, 24, 48, 48, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 08-15 reserved +const int32_t table_38213_13_10_c3[16] = { 1, 1, 2, 2, 1, 1, 1, 1, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 08-15 reserved +const int32_t table_38213_13_10_c4[16] = { 0, 8, 0, 8,-41, 25,-41, 49, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 08-15 reserved, condition A as default + +const float table_38213_13_11_c1[16] = { 0, 0, 2, 2, 5, 5, 7, 7, 0, 5, 0, 0, 2, 2, 5, 5}; +const int32_t table_38213_13_11_c2[16] = { 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1}; +const float table_38213_13_11_c3[16] = { 1, 0.5f, 1, 0.5f, 1, 0.5f, 1, 0.5f, 1, 1, 1, 1, 1, 1, 1, 1}; +const int32_t table_38213_13_11_c4[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 1, 2}; // i is even as default + +const float table_38213_13_12_c1[16] = { 0, 0, 2.5f, 2.5f, 5, 5, 0, 2.5f, 5, 7.5f, 7.5f, 7.5f, 0, 5, reserved, reserved}; // index 14-15 reserved +const int32_t table_38213_13_12_c2[16] = { 1, 2, 1, 2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 1, reserved, reserved}; // index 14-15 reserved +const float table_38213_13_12_c3[16] = { 1, 0.5f, 1, 0.5f, 1, 0.5f, 0.5f, 0.5f, 0.5f, 1, 0.5f, 0.5f, 1, 1, reserved, reserved}; // index 14-15 reserved diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index d742132ca0..ae3818f35d 100755 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -31,10 +31,34 @@ */ #include "mac_proto.h" +#include "mac_extern.h" #include "RRC/NR_UE/rrc_proto.h" +#include "assertions.h" #include +typedef enum subcarrier_spacing_e { + scs_15kHz = 0x1, + scs_30kHz = 0x2, + scs_60kHz = 0x4, + scs_120kHz = 0x8, + scs_240kHz = 0x16 +} subcarrier_spacing_t; + +typedef enum channel_bandwidth_e { + bw_5MHz = 0x1, + bw_10MHz = 0x2, + bw_20MHz = 0x4, + bw_40MHz = 0x8, + bw_80MHz = 0x16, + bw_100MHz = 0x32 +} channel_bandwidth_t; + +typedef enum frequency_range_e { + FR1 = 0, + FR2 +} frequency_range_t; + int8_t nr_ue_decode_mib( module_id_t module_id, int cc_id, @@ -75,6 +99,7 @@ int8_t nr_ue_decode_mib( } } +#if 0 printf("system frame number(6 MSB bits): %d\n", mac->mib->systemFrameNumber.buf[0]); printf("system frame number(with LSB): %d\n", (int)frame); printf("subcarrier spacing: %d\n", (int)mac->mib->subCarrierSpacingCommon); @@ -85,6 +110,190 @@ int8_t nr_ue_decode_mib( printf("intra frequcney reselection: %d\n", (int)mac->mib->intraFreqReselection); printf("half frame bit(extra bits): %d\n", (int)half_frame_bit); printf("ssb index(extra bits): %d\n", (int)ssb_index); +#endif + + subcarrier_spacing_t scs_ssb = scs_15kHz; // default for testing + subcarrier_spacing_t scs_pdcch = scs_15kHz; // default for testing + channel_bandwidth_t min_channel_bw = bw_5MHz; // deafult for testing + uint32_t ssb_coreset_multiplexing_pattern; + uint32_t is_condition_A = 1; + frequency_range_t frequency_range = FR1; + uint32_t index_4msb = (mac->mib->pdcch_ConfigSIB1 >> 4) & 0xf; + uint32_t index_4lsb = (mac->mib->pdcch_ConfigSIB1 & 0xf); + + // type0-pdcch coreset + switch( (scs_ssb << 5)|scs_pdcch ){ + case (scs_15kHz << 5) | scs_15kHz : + AssertFatal(index_4msb < 15, "38.213 Table 13-1 4 MSB out of range\n"); + ssb_coreset_multiplexing_pattern = 1; + mac->num_rbs = table_38213_13_1_c2[index_4msb]; + mac->num_symbols = table_38213_13_1_c3[index_4msb]; + mac->rb_offset = table_38213_13_1_c4[index_4msb]; + break; + + case (scs_15kHz << 5) | scs_30kHz: + AssertFatal(index_4msb < 14, "38.213 Table 13-2 4 MSB out of range\n"); + ssb_coreset_multiplexing_pattern = 1; + mac->num_rbs = table_38213_13_2_c2[index_4msb]; + mac->num_symbols = table_38213_13_2_c3[index_4msb]; + mac->rb_offset = table_38213_13_2_c4[index_4msb]; + break; + + case (scs_30kHz << 5) | scs_15kHz: + if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){ + AssertFatal(index_4msb < 9, "38.213 Table 13-3 4 MSB out of range\n"); + ssb_coreset_multiplexing_pattern = 1; + mac->num_rbs = table_38213_13_3_c2[index_4msb]; + mac->num_symbols = table_38213_13_3_c3[index_4msb]; + mac->rb_offset = table_38213_13_3_c4[index_4msb]; + }else if(min_channel_bw & bw_40MHz){ + AssertFatal(index_4msb < 9, "38.213 Table 13-5 4 MSB out of range\n"); + ssb_coreset_multiplexing_pattern = 1; + mac->num_rbs = table_38213_13_5_c2[index_4msb]; + mac->num_symbols = table_38213_13_5_c3[index_4msb]; + mac->rb_offset = table_38213_13_5_c4[index_4msb]; + }else{ ; } + + break; + + case (scs_30kHz << 5) | scs_30kHz: + if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){ + ssb_coreset_multiplexing_pattern = 1; + mac->num_rbs = table_38213_13_4_c2[index_4msb]; + mac->num_symbols = table_38213_13_4_c3[index_4msb]; + mac->rb_offset = table_38213_13_4_c4[index_4msb]; + }else if(min_channel_bw & bw_40MHz){ + AssertFatal(index_4msb < 10, "38.213 Table 13-6 4 MSB out of range\n"); + ssb_coreset_multiplexing_pattern = 1; + mac->num_rbs = table_38213_13_6_c2[index_4msb]; + mac->num_symbols = table_38213_13_6_c3[index_4msb]; + mac->rb_offset = table_38213_13_6_c4[index_4msb]; + }else{ ; } + break; + + case (scs_120kHz << 5) | scs_60kHz: + AssertFatal(index_4msb < 12, "38.213 Table 13-7 4 MSB out of range\n"); + if(index_4msb & 0x7){ + ssb_coreset_multiplexing_pattern = 1; + }else if(index_4msb & 0x18){ + ssb_coreset_multiplexing_pattern = 2; + }else{ ; } + + mac->num_rbs = table_38213_13_7_c2[index_4msb]; + mac->num_symbols = table_38213_13_7_c3[index_4msb]; + if(!is_condition_A && (index_4msb == 8 || index_4msb == 10)){ + mac->rb_offset = table_38213_13_7_c4[index_4msb] - 1; + }else{ + mac->rb_offset = table_38213_13_7_c4[index_4msb]; + } + break; + + case (scs_120kHz << 5) | scs_120kHz: + AssertFatal(index_4msb < 8, "38.213 Table 13-8 4 MSB out of range\n"); + if(index_4msb & 0x3){ + ssb_coreset_multiplexing_pattern = 1; + }else if(index_4msb & 0x0c){ + ssb_coreset_multiplexing_pattern = 3; + } + + mac->num_rbs = table_38213_13_8_c2[index_4msb]; + mac->num_symbols = table_38213_13_8_c3[index_4msb]; + if(!is_condition_A && (index_4msb == 4 || index_4msb == 6)){ + mac->rb_offset = table_38213_13_8_c4[index_4msb] - 1; + }else{ + mac->rb_offset = table_38213_13_8_c4[index_4msb]; + } + break; + + case (scs_240kHz << 5) | scs_60kHz: + AssertFatal(index_4msb < 4, "38.213 Table 13-9 4 MSB out of range\n"); + ssb_coreset_multiplexing_pattern = 1; + mac->num_rbs = table_38213_13_9_c2[index_4msb]; + mac->num_symbols = table_38213_13_9_c3[index_4msb]; + mac->rb_offset = table_38213_13_9_c4[index_4msb]; + break; + + case (scs_240kHz << 5) | scs_120kHz: + AssertFatal(index_4msb < 8, "38.213 Table 13-10 4 MSB out of range\n"); + if(index_4msb & 0x3){ + ssb_coreset_multiplexing_pattern = 1; + }else if(index_4msb & 0x0c){ + ssb_coreset_multiplexing_pattern = 2; + } + mac->num_rbs = table_38213_13_10_c2[index_4msb]; + mac->num_symbols = table_38213_13_10_c3[index_4msb]; + if(!is_condition_A && (index_4msb == 4 || index_4msb == 6)){ + mac->rb_offset = table_38213_13_10_c4[index_4msb]-1; + }else{ + mac->rb_offset = table_38213_13_10_c4[index_4msb]; + } + + break; + + default: + break; + } + + // type0-pdcch search space + float big_o; + uint32_t number_of_search_space_per_slot; + float big_m; + uint32_t first_symbol_index; + + const uint32_t num_symbols_coreset = 0; // check after + uint32_t ii = 0; // check later + uint32_t kk = 0; + if(ssb_coreset_multiplexing_pattern == 1 && frequency_range == FR1){ + big_o = table_38213_13_11_c1[index_4lsb]; + number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb]; + big_m = table_38213_13_11_c3[index_4lsb]; + + if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 7) && (ii&1)){ + first_symbol_index = num_symbols_coreset; + }else{ + first_symbol_index = table_38213_13_11_c4[index_4lsb]; + } + } + + if(ssb_coreset_multiplexing_pattern == 1 && frequency_range == FR2){ + big_o = table_38213_13_12_c1[index_4lsb]; + number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb]; + big_m = table_38213_13_12_c3[index_4lsb]; + + if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 10) && (ii&1)){ + first_symbol_index = 7; + }else if((index_4lsb == 6 || index_4lsb == 7 || index_4lsb == 8 || index_4lsb == 11) && (ii&1)){ + first_symbol_index = num_symbols_coreset; + }else{ + first_symbol_index = 0; + } + } + + if(ssb_coreset_multiplexing_pattern == 2){ + if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_60kHz)){ + // 38.213 Table 13-13 + AssertFatal(index_4lsb == 0, "38.213 Table 13-13 4 LSB out of range\n"); + // TODO check PDCCH monitoring occasions (SFN and slot number) + // TODO check first symbol index + //first_symbol_index = + }else if((scs_ssb == scs_240kHz) && (scs_pdcch == scs_120kHz)){ + // 38.213 Table 13-14 + AssertFatal(index_4lsb == 0, "38.213 Table 13-14 4 LSB out of range\n"); + // TODO check PDCCH monitoring occasions (SFN and slot number) + // TODO check first symbol index + //first_symbol_index = + }else{ ; } + } + + if(ssb_coreset_multiplexing_pattern == 3){ + if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_120kHz)){ + // 38.213 Table 13-15 + AssertFatal(index_4lsb == 0, "38.213 Table 13-15 4 LSB out of range\n"); + // TODO check PDCCH monitoring occasions (SFN and slot number) + // TODO check first symbol index + //first_symbol_index = + }else{ ; } + } // fill in the elements in config request inside P5 message mac->phy_config.config_req.pbch_config.system_frame_number = frame; // after calculation diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index eb4e9919d9..c3298a8482 100755 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -62,6 +62,34 @@ int8_t handle_bcch_dlsch(uint32_t pdu_len, uint8_t *pduP){ return 0; } +int8_t nr_ue_ul_indication(nr_uplink_indication_t *ul_info){ + + NR_UE_L2_STATE_t ret; + + ret = nr_ue_scheduler( + ul_info->module_id, + ul_info->gNB_index, + ul_info->cc_id, + ul_info->frame, + ul_info->slot, + 0, 0); // TODO check tx/rx frame/slot is need for NR version + + switch(ret){ + case CONNECTION_OK: + break; + case CONNECTION_LOST: + break; + case PHY_RESYNCH: + break; + case PHY_HO_PRACH: + break; + default: + break; + } + + return 0; +} + int8_t nr_ue_dl_indication(nr_downlink_indication_t *dl_info){ module_id_t module_id = dl_info->module_id; @@ -99,11 +127,16 @@ int8_t nr_ue_dl_indication(nr_downlink_indication_t *dl_info){ nr_ue_if_module_t *nr_ue_if_module_init(uint32_t module_id){ if (nr_ue_if_module_inst[module_id] == NULL) { - nr_ue_if_module_inst[module_id] = (nr_ue_if_module_t*)malloc(sizeof(nr_ue_if_module_t)); + nr_ue_if_module_inst[module_id] = (nr_ue_if_module_t *)malloc(sizeof(nr_ue_if_module_t)); memset((void*)nr_ue_if_module_inst[module_id],0,sizeof(nr_ue_if_module_t)); - nr_ue_if_module_inst[module_id]->CC_mask=0; + nr_ue_if_module_inst[module_id]->cc_mask=0; + nr_ue_if_module_inst[module_id]->current_frame = 0; + nr_ue_if_module_inst[module_id]->current_slot = 0; + nr_ue_if_module_inst[module_id]->phy_config_request = NULL; + nr_ue_if_module_inst[module_id]->scheduled_response = NULL; nr_ue_if_module_inst[module_id]->dl_indication = nr_ue_dl_indication; + nr_ue_if_module_inst[module_id]->ul_indication = nr_ue_ul_indication; } return nr_ue_if_module_inst[module_id]; diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h index 426255e9f3..677e494ce6 100755 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h @@ -40,11 +40,9 @@ typedef struct { /// module id module_id_t module_id; /// component carrier id - int CC_id; + int cc_id; /// frame frame_t frame; - /// subframe - sub_frame_t subframe; /// slot uint8_t slot; @@ -57,6 +55,20 @@ typedef struct { } nr_downlink_indication_t; + +typedef struct { + /// module id + module_id_t module_id; + /// gNB index + uint32_t gNB_index; + /// component carrier id + int cc_id; + /// frame + frame_t frame; + /// slot + uint32_t slot; +} nr_uplink_indication_t; + // Downlink subframe P7 @@ -104,7 +116,7 @@ typedef struct { * -1: Failed to consume bytes. Abort the mission. * Non-negative return values indicate success, and ignored. */ -typedef int8_t(nr_ue_scheduled_response_f)(nr_scheduled_response_t *scheduled_response); +typedef int8_t (nr_ue_scheduled_response_f)(nr_scheduled_response_t *scheduled_response); /* @@ -114,7 +126,7 @@ typedef int8_t(nr_ue_scheduled_response_f)(nr_scheduled_response_t *scheduled_re * -1: Failed to consume bytes. Abort the mission. * Non-negative return values indicate success, and ignored. */ -typedef int8_t(nr_ue_phy_config_request_f)(nr_phy_config_t *phy_config); +typedef int8_t (nr_ue_phy_config_request_f)(nr_phy_config_t *phy_config); /* @@ -124,18 +136,27 @@ typedef int8_t(nr_ue_phy_config_request_f)(nr_phy_config_t *phy_config); * -1: Failed to consume bytes. Abort the mission. * Non-negative return values indicate success, and ignored. */ -typedef int8_t(nr_ue_dl_indication_f)(nr_downlink_indication_t *dl_info); +typedef int8_t (nr_ue_dl_indication_f)(nr_downlink_indication_t *dl_info); +/* + * Generic type of an application-defined callback to return various + * types of data to the application. + * EXPECTED RETURN VALUES: + * -1: Failed to consume bytes. Abort the mission. + * Non-negative return values indicate success, and ignored. + */ +typedef int8_t (nr_ue_ul_indication_f)(nr_uplink_indication_t *ul_info); // TODO check this stuff can be reuse of need modification typedef struct nr_ue_if_module_s { nr_ue_scheduled_response_f *scheduled_response; nr_ue_phy_config_request_f *phy_config_request; nr_ue_dl_indication_f *dl_indication; + nr_ue_ul_indication_f *ul_indication; - uint32_t CC_mask; - uint16_t current_frame; - uint8_t current_subframe; + uint32_t cc_mask; + uint32_t current_frame; + uint32_t current_slot; //pthread_mutex_t nr_if_mutex; } nr_ue_if_module_t; diff --git a/targets/RT/USER/nr-ue.c b/targets/RT/USER/nr-ue.c index 3c8f073f6b..7ccbcac485 100644 --- a/targets/RT/USER/nr-ue.c +++ b/targets/RT/USER/nr-ue.c @@ -214,26 +214,28 @@ void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_ void init_UE(int nb_inst) { - int inst; - for (inst=0; inst < nb_inst; inst++) { - // UE->rfdevice.type = NONE_DEV; - PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0]; - LOG_I(PHY,"Initializing memory for UE instance %d (%p)\n",inst,PHY_vars_UE_g[inst]); - PHY_vars_UE_g[inst][0] = init_nr_ue_vars(NULL,inst,0); + int inst; + NR_UE_MAC_INST_t *mac_inst; + for (inst=0; inst < nb_inst; inst++) { + // UE->rfdevice.type = NONE_DEV; + PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0]; + LOG_I(PHY,"Initializing memory for UE instance %d (%p)\n",inst,PHY_vars_UE_g[inst]); + PHY_vars_UE_g[inst][0] = init_nr_ue_vars(NULL,inst,0); - AssertFatal((UE->if_inst = nr_ue_if_module_init(inst)) != NULL,"Can't register interface module\n"); -nr_l3_init_ue(); -nr_l2_init_ue(); -NR_UE_MAC_INST_t *UE_MAC_INST = get_mac_inst(0); -UE_MAC_INST->if_module = UE->if_inst; - UE->if_inst->scheduled_response = nr_ue_scheduled_response; - UE->if_inst->phy_config_request = nr_ue_phy_config_request; + AssertFatal((UE->if_inst = nr_ue_if_module_init(inst)) != NULL, "can not initial IF module\n"); + nr_l3_init_ue(); + nr_l2_init_ue(); + + mac_inst = get_mac_inst(0); + mac_inst->if_module = UE->if_inst; + UE->if_inst->scheduled_response = nr_ue_scheduled_response; + UE->if_inst->phy_config_request = nr_ue_phy_config_request; - AssertFatal(0 == pthread_create(&UE->proc.pthread_ue, - &UE->proc.attr_ue, - UE_thread, - (void*)UE), ""); - } + AssertFatal(0 == pthread_create(&UE->proc.pthread_ue, + &UE->proc.attr_ue, + UE_thread, + (void*)UE), ""); + } printf("UE threads created by %ld\n", gettid()); #if 0 @@ -621,6 +623,23 @@ static void *UE_thread_rxn_txnp4(void *arg) { #endif if (UE->mac_enabled==1) { + // trigger L2 to run ue_scheduler thru IF module + // [TODO] mapping right after NR initial sync + if(1) + if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL){ + UE->ul_indication.module_id = 0; + UE->ul_indication.gNB_index = 0; + UE->ul_indication.cc_id = 0; + + // [TODO] mapping right after NR initial sync + //UE->ul_indication.frame = ; + //UE->ul_indication.slot = ; + + UE->if_inst->ul_indication(&UE->ul_indication); + } + + + #ifdef NEW_MAC ret = mac_xface->ue_scheduler(UE->Mod_id, proc->frame_rx, @@ -827,7 +846,7 @@ void *UE_thread(void *arg) { (void**)UE->common_vars.rxdata, UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, UE->frame_parms.nb_antennas_rx),""); - slot_fep_pbch(UE,0, 0, 0, 0, 0); + nr_slot_fep(UE,0, 0, 0, 0, 0, NR_PBCH_EST); } //UE->mode != loop_through_memory else rt_sleep_ns(1000*1000);