From e72d0483b4b3627ab03ce5a0abd21366c44e11c3 Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Mon, 7 Dec 2020 09:49:39 +0100 Subject: [PATCH 01/40] Add PDSCH precoder functions, fix pusch_rx for 2 rx antennas, fix nr_dlsim for 2x1 MIMO simulation --- executables/nr-gnb.c | 15 +- openair1/PHY/INIT/nr_parms.c | 4 +- openair1/PHY/MODULATION/nr_modulation.c | 137 ++++++++++++++++++ openair1/PHY/MODULATION/nr_modulation.h | 18 ++- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 3 +- openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 71 ++++++--- openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c | 1 + openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 2 +- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 20 ++- openair1/PHY/defs_gNB.h | 4 +- openair1/SCHED_NR/nr_ru_procedures.c | 2 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 4 +- openair1/SIMULATION/NR_PHY/dlsim.c | 75 ++++++---- .../CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 8 +- 14 files changed, 287 insertions(+), 77 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index be9261a117..1d23c72315 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -261,13 +261,14 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t L1_nr_prach_procedures(gNB,frame_rx,slot_rx); //apply the rx signal rotation here - apply_nr_rotation_ul(&gNB->frame_parms, - gNB->common_vars.rxdataF[0], - slot_rx, - 0, - gNB->frame_parms.Ncp==EXTENDED?12:14, - gNB->frame_parms.ofdm_symbol_size); - + for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) { + apply_nr_rotation_ul(&gNB->frame_parms, + gNB->common_vars.rxdataF[aa], + slot_rx, + 0, + gNB->frame_parms.Ncp==EXTENDED?12:14, + gNB->frame_parms.ofdm_symbol_size); + } phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx); } diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index ba4147e5cd..c381c5c71c 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -284,9 +284,9 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, fp->slots_per_frame = 10* fp->slots_per_subframe; - fp->nb_antenna_ports_gNB = cfg->carrier_config.num_tx_ant.value;// It corresponds to pdsch_AntennaPorts + fp->nb_antenna_ports_gNB = 1; // It corresponds to the number of common antenna ports fp->nb_antennas_rx = cfg->carrier_config.num_rx_ant.value; // It denotes the number of rx antennas at gNB - fp->nb_antennas_tx = 1; // It corresponds to the number of UE Tx antennas + fp->nb_antennas_tx = cfg->carrier_config.num_tx_ant.value; // It corresponds to pdsch_AntennaPorts fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe; diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index 0a7088ba39..04955c31a4 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -22,6 +22,102 @@ #include "nr_modulation.h" #include "PHY/NR_REFSIG/nr_mod_table.h" +//Table 6.3.1.5-1 Precoding Matrix W 1 layer 2 antenna ports 'n' = -1 and 'o' = -j +char nr_W_1l_2p[6][2][1] = { + {{'1'}, {'0'}},//pmi 0 + {{'0'}, {'1'}}, + {{'1'}, {'1'}}, + {{'1'}, {'n'}}, + {{'1'}, {'j'}}, + {{'1'}, {'o'}}//pmi 5 +}; + +//Table 6.3.1.5-3 Precoding Matrix W 1 layer 4 antenna ports 'n' = -1 and 'o' = -j +char nr_W_1l_4p[28][4][1] = { + {{'1'}, {'0'}, {'0'}, {'0'}},//pmi 0 + {{'0'}, {'1'}, {'0'}, {'0'}}, + {{'0'}, {'0'}, {'1'}, {'0'}}, + {{'0'}, {'0'}, {'0'}, {'1'}}, + {{'1'}, {'0'}, {'1'}, {'0'}}, + {{'1'}, {'0'}, {'n'}, {'0'}}, + {{'1'}, {'0'}, {'j'}, {'0'}}, + {{'1'}, {'0'}, {'o'}, {'0'}},//pmi 7 + {{'0'}, {'1'}, {'0'}, {'1'}},//pmi 8 + {{'0'}, {'1'}, {'0'}, {'n'}}, + {{'0'}, {'1'}, {'0'}, {'j'}}, + {{'0'}, {'1'}, {'0'}, {'o'}}, + {{'1'}, {'1'}, {'1'}, {'1'}}, + {{'1'}, {'1'}, {'j'}, {'j'}}, + {{'1'}, {'1'}, {'n'}, {'n'}}, + {{'1'}, {'1'}, {'o'}, {'o'}}, + {{'1'}, {'j'}, {'1'}, {'j'}},//pmi 16 + {{'1'}, {'j'}, {'j'}, {'n'}}, + {{'1'}, {'j'}, {'n'}, {'o'}}, + {{'1'}, {'j'}, {'o'}, {'1'}}, + {{'1'}, {'n'}, {'1'}, {'n'}}, + {{'1'}, {'n'}, {'j'}, {'o'}}, + {{'1'}, {'n'}, {'n'}, {'1'}}, + {{'1'}, {'n'}, {'o'}, {'j'}},//pmi 23 + {{'1'}, {'o'}, {'1'}, {'o'}},//pmi 24 + {{'1'}, {'o'}, {'j'}, {'1'}}, + {{'1'}, {'o'}, {'n'}, {'j'}}, + {{'1'}, {'o'}, {'o'}, {'n'}}//pmi 27 +}; + +//Table 6.3.1.5-4 Precoding Matrix W 2 antenna ports layers 2 'n' = -1 and 'o' = -j +char nr_W_2l_2p[3][2][2] = { + {{'1', '0'}, {'0', '1'}},//pmi 0 + {{'1', '1'}, {'1', 'n'}}, + {{'1', '1'}, {'j', 'o'}} //pmi 2 + +}; + +//Table 6.3.1.5-5 Precoding Matrix W 2 layers 4 antenna ports 'n' = -1 and 'o' = -j +char nr_W_2l_4p[22][4][2] = { + {{'1', '0'}, {'0', '1'}, {'0', '0'}, {'0', '0'}},//pmi 0 + {{'1', '0'}, {'0', '0'}, {'0', '1'}, {'0', '0'}}, + {{'1', '0'}, {'0', '0'}, {'0', '0'}, {'0', '1'}}, + {{'0', '0'}, {'1', '0'}, {'0', '1'}, {'0', '0'}},//pmi 3 + {{'0', '0'}, {'1', '0'}, {'0', '0'}, {'0', '1'}},//pmi 4 + {{'0', '0'}, {'0', '0'}, {'1', '0'}, {'0', '1'}}, + {{'1', '0'}, {'0', '1'}, {'1', '0'}, {'0', 'o'}}, + {{'1', '0'}, {'0', '1'}, {'1', '0'}, {'0', 'j'}}, + {{'1', '0'}, {'0', '1'}, {'o', '0'}, {'0', '1'}},//pmi 8 + {{'1', '0'}, {'0', '1'}, {'o', '0'}, {'0', 'n'}}, + {{'1', '0'}, {'0', '1'}, {'n', '0'}, {'0', 'o'}}, + {{'1', '0'}, {'0', '1'}, {'n', '0'}, {'0', 'j'}},//pmi 11 + {{'1', '0'}, {'0', '1'}, {'j', '0'}, {'0', '1'}},//pmi 12 + {{'1', '0'}, {'0', '1'}, {'j', '0'}, {'0', 'n'}}, + {{'1', '1'}, {'1', '1'}, {'1', 'n'}, {'1', 'n'}}, + {{'1', '1'}, {'1', '1'}, {'j', 'o'}, {'j', 'o'}},//pmi 15 + {{'1', '1'}, {'j', 'j'}, {'1', 'n'}, {'j', 'o'}},//pmi 16 + {{'1', '1'}, {'j', 'j'}, {'j', 'o'}, {'n', '1'}}, + {{'1', '1'}, {'n', 'n'}, {'1', 'n'}, {'n', '1'}}, + {{'1', '1'}, {'n', 'n'}, {'j', 'o'}, {'o', 'j'}},//pmi 19 + {{'1', '1'}, {'o', 'o'}, {'1', 'n'}, {'o', 'j'}}, + {{'1', '1'}, {'o', 'o'}, {'j', 'o'}, {'1', 'n'}}//pmi 21 +}; + +//Table 6.3.1.5-6 Precoding Matrix W 3 layers 4 antenna ports 'n' = -1 and 'o' = -j +char nr_W_3l_4p[7][4][3] = { + {{'1', '0', '0'}, {'0', '1', '0'}, {'0', '0', '1'},{'0', '0', '0'}},//pmi 0 + {{'1', '0', '0'}, {'0', '1', '0'}, {'1', '0', '0'},{'0', '0', '1'}}, + {{'1', '0', '0'}, {'0', '1', '0'}, {'n', '0', '0'},{'0', '0', '1'}}, + {{'1', '1', '1'}, {'1', 'n', '1'}, {'1', '1', 'n'},{'1', 'n', 'n'}},//pmi 3 + {{'1', '1', '1'}, {'1', 'n', '1'}, {'j', 'j', 'o'},{'j', 'o', 'o'}},//pmi 4 + {{'1', '1', '1'}, {'n', '1', 'n'}, {'1', '1', 'n'},{'n', '1', '1'}}, + {{'1', '1', '1'}, {'n', '1', 'n'}, {'j', 'j', 'o'},{'o', 'j', 'j'}} +}; + +//Table 6.3.1.5-7 Precoding Matrix W 4 layers 4 antenna ports 'n' = -1 and 'o' = -j +char nr_W_4l_4p[5][4][4] = { + {{'1', '0', '0', '0'}, {'0', '1', '0', '0'}, {'0', '0', '1', '0'}, {'0', '0', '0', '1'}},//pmi 0 + {{'1', '1', '0', '0'}, {'0', '0', '1', '1'}, {'1', 'n', '0', '0'}, {'0', '0', '1', 'n'}}, + {{'1', '1', '0', '0'}, {'0', '0', '1', '1'}, {'j', 'o', '0', '0'}, {'0', '0', 'j', 'o'}}, + {{'1', '1', '1', '1'}, {'1', 'n', '1', 'n'}, {'1', '1', 'n', 'n'}, {'1', 'n', 'n', '1'}},//pmi 3 + {{'1', '1', '1', '1'}, {'1', 'n', '1', 'n'}, {'j', 'j', 'o', 'o'}, {'j', 'o', 'o', 'j'}}//pmi 4 +}; + void nr_modulation(uint32_t *in, uint32_t length, uint16_t mod_order, @@ -534,3 +630,44 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq) { Ncpm1=Ncp; } } + +int nr_layer_precoder(int16_t **datatx_F_precoding, char *prec_matrix, uint8_t n_layers, int32_t re_offset) +{ + int32_t precodatatx_F = 0; + for (int al = 0; al>15); + ((int16_t *)precodatatx_F)[1] = (int16_t)((((int16_t *)precodatatx_F)[1]*ONE_OVER_SQRT2_Q15)>>15);*/ +} diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index 3d2be905ac..b9326271d9 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -28,7 +28,13 @@ #include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h" #define DMRS_MOD_ORDER 2 - +/*Precoding matices: W[pmi][antenna_port][layer]*/ +extern char nr_W_1l_2p[6][2][1]; +extern char nr_W_2l_2p[3][2][2]; +extern char nr_W_1l_4p[28][4][1]; +extern char nr_W_2l_4p[22][4][2]; +extern char nr_W_3l_4p[7][4][3]; +extern char nr_W_4l_4p[5][4][4]; /*! \brief Perform NR modulation. TS 38.211 V15.4.0 subclause 5.1 @param[in] in, Pointer to input bits @param[in] length, size of input bits @@ -118,4 +124,14 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, int first_symbol, int nsymb, int length); + +/*! \brief Perform NR precoding. TS 38.211 V15.4.0 subclause 6.3.1.5 + @param[in] datatx_F_precoding, Pointer to n_layers*re data array + @param[in] prec_matrix, Pointer to precoding matrix + @param[in] n_layers, number of DLSCH layers +*/ +int nr_layer_precoder(int16_t **datatx_F_precoding, + char *prec_matrix, + uint8_t n_layers, + int32_t re_offset); #endif diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 713e71674b..a0fc83d183 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -75,7 +75,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, symbol_offset = gNB->frame_parms.ofdm_symbol_size*symbol; k = bwp_start_subcarrier; - int re_offset = k; + int re_offset; uint16_t nb_rb_pusch = pusch_pdu->rb_size; @@ -161,6 +161,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, pil = (int16_t *)&pilot[0]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; + re_offset = k; memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size)); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index e3627b9344..1a3493cdb1 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -142,6 +142,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5]; int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs; int16_t **tx_layers = (int16_t**)dlsch->txdataF; + int16_t **txdataF_precoding = (int16_t**)dlsch->txdataF_precoding; int8_t Wf[2], Wt[2], l0, l_prime, l_overline, delta; uint8_t dmrs_Type = rel15->dmrsConfigType; int nb_re_dmrs; @@ -266,9 +267,6 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, } #endif - /// Antenna port mapping - //to be moved to init phase potentially, for now tx_layers 1-8 are mapped on antenna ports 1000-1007 - /// DMRS QPSK modulation for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { if (rel15->dlDmrsSymbPos & (1 << l)) { @@ -292,7 +290,9 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, uint16_t start_sc = frame_parms->first_carrier_offset + (rel15->rbStart+rel15->BWPStart)*NR_NB_SC_PER_RB; if (start_sc >= frame_parms->ofdm_symbol_size) start_sc -= frame_parms->ofdm_symbol_size; - + + int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP; + #ifdef DEBUG_DLSCH_MAPPING printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n", start_sc, rel15->StartSymbolIndex, rel15->rbSize, nb_re,rel15->nrOfLayers); @@ -313,9 +313,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, 1+dmrs_Type,ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime, l0, dmrs_symbol); #endif - uint16_t m=0, dmrs_idx=0, k=0; - - int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP; + uint16_t m=0, dmrs_idx=0; // Loop Over OFDM symbols: for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { @@ -349,7 +347,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, nr_modulation(pdsch_dmrs[l][0], (n_ptrs<<1), DMRS_MOD_ORDER, mod_ptrs); } } - k = start_sc; + uint16_t k = start_sc; // Loop Over SCs: for (int i=0; irbSize*NR_NB_SC_PER_RB; i++) { /* check if cuurent RE is PTRS RE*/ @@ -369,12 +367,12 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, /* Map DMRS Symbol */ if ( ( dmrs_symbol_map & (1 << l) ) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) { - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[l][dmrs_idx<<1]) >> 15; - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; + txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[l][dmrs_idx<<1]) >> 15; + txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; #ifdef DEBUG_DLSCH_MAPPING printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n", - dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); + dmrs_idx, l, k, k_prime, n, txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], + txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); #endif dmrs_idx++; k_prime++; @@ -383,8 +381,8 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, } /* Map PTRS Symbol */ else if(is_ptrs_re){ - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[ptrs_idx<<1]) >> 15; - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[(ptrs_idx<<1) + 1])>> 15; + txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[ptrs_idx<<1]) >> 15; + txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[(ptrs_idx<<1) + 1])>> 15; #ifdef DEBUG_DLSCH_MAPPING printf("ptrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n", ptrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], @@ -393,17 +391,20 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, ptrs_idx++; } /* Map DATA Symbol */ - else { - if( (!(dmrs_symbol_map & (1 << l))) || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,frame_parms->ofdm_symbol_size,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) { - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15; - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15; + else if( (!(dmrs_symbol_map & (1 << l))) || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,frame_parms->ofdm_symbol_size,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) { + txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15; + txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15; #ifdef DEBUG_DLSCH_MAPPING - printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", - m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); + printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", + m, l, k, txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], + txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); #endif - m++; - } + m++; + } + /* mute RE */ + else { + txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = 0; + txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = 0; } if (++k >= frame_parms->ofdm_symbol_size) k -= frame_parms->ofdm_symbol_size; @@ -411,6 +412,30 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, } // symbol loop }// layer loop + ///Layer Precoding and Antenna port mapping + // tx_layers 1-8 are mapped on antenna ports 1000-1007 + uint8_t pmi = 2; + + for (int ap=0; apnb_antennas_tx; ap++) { + char *W_prec = nr_W_1l_2p[pmi][ap];//nr_W_1l_4p, nr_W_2l_2p, nr_W_2l_4p, nr_W_3l_4p, and nr_W_4l_4p + for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { + uint16_t k = start_sc; + + for (int i=0; irbSize*NR_NB_SC_PER_RB; i++) { + int32_t re_offset = l*frame_parms->ofdm_symbol_size + k; + int32_t precodatatx_F = nr_layer_precoder(txdataF_precoding, W_prec, rel15->nrOfLayers, re_offset+txdataF_offset); + ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[0]; + ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[1]; +#ifdef DEBUG_DLSCH_MAPPING + printf("antenna %d\t l %d \t k %d \t txdataF: %d %d\n", + ap, l, k, ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)], + ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)]); +#endif + if (++k >= frame_parms->ofdm_symbol_size) + k -= frame_parms->ofdm_symbol_size; + } //RE loop + } // symbol loop + }// port loop dlsch->slot_tx[slot]=0; }// dlsch loop diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index cb395ff4af..59c3048171 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -176,6 +176,7 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, } dlsch->txdataF[layer] = (int32_t *)malloc16((NR_MAX_PDSCH_ENCODED_LENGTH/NR_MAX_NB_LAYERS)*sizeof(int32_t)); // NR_MAX_NB_LAYERS is already included in NR_MAX_PDSCH_ENCODED_LENGTH + dlsch->txdataF_precoding[layer] = (int32_t *)malloc16((14*frame_parms->ofdm_symbol_size)*sizeof(int32_t)); } for (int q=0; qnb_antenna_ports_gNB; aatx++) { - for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) { + for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) { ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*(off+(nb_rb*NR_NB_SC_PER_RB))]; @@ -377,7 +379,6 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, } } } - } #endif } @@ -394,6 +395,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, short rb; unsigned char aatx, aarx; + char nb_antennas_ue_tx = 1; __m128i *ul_ch128, avg128U; int16_t x = factor2(len); @@ -405,7 +407,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, int off = 0; #endif - for (aatx = 0; aatx < frame_parms->nb_antennas_tx; aatx++) + for (aatx = 0; aatx < nb_antennas_ue_tx; aatx++) for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { //clear average level avg128U = _mm_setzero_si128(); @@ -546,11 +548,12 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, unsigned short rb; unsigned char aatx,aarx; + char nb_antennas_ue_tx = 1; __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; aatxnb_antennas_tx; aatx++) { + for (aatx=0; aatxframe_parms; nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[ulsch_id][0]->harq_processes[harq_pid]->ulsch_pdu; @@ -1185,7 +1189,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, avgs = 0; - for (aatx=0;aatxnb_antennas_tx;aatx++) + for (aatx=0;aatxnb_antennas_rx;aarx++) avgs = cmax(avgs,avg[(aatx<<1)+aarx]); @@ -1203,7 +1207,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, gNB->pusch_vars[ulsch_id]->ul_ch_mag0, gNB->pusch_vars[ulsch_id]->ul_ch_magb0, gNB->pusch_vars[ulsch_id]->rxdataF_comp, - (frame_parms->nb_antennas_tx>1) ? gNB->pusch_vars[ulsch_id]->rho : NULL, + (nb_antennas_ue_tx>1) ? gNB->pusch_vars[ulsch_id]->rho : NULL, frame_parms, symbol, dmrs_symbol_flag, diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 7b33b2040f..8940141487 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -140,8 +140,10 @@ typedef struct { typedef struct { /// Pointers to 16 HARQ processes for the DLSCH NR_DL_gNB_HARQ_t *harq_processes[NR_MAX_NB_HARQ_PROCESSES]; - /// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding) + /// TX buffers for UE-spec transmission (antenna layers 1,...,4 after to precoding) int32_t *txdataF[NR_MAX_NB_LAYERS]; + /// TX buffers for UE-spec transmission (antenna ports 1000 or 1001,...,1007, before precoding) + int32_t *txdataF_precoding[NR_MAX_NB_LAYERS]; /// Modulated symbols buffer int32_t *mod_symbs[NR_MAX_NB_CODEWORDS]; /// beamforming weights for UE-spec transmission (antenna ports 5 or 7..14), for each codeword, maximum 4 layers? diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index a78b1f4805..bc9d119af4 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -323,7 +323,7 @@ static void *nr_feptx_thread(void *param) { slot, l+i, aa, - nb_antenna_ports); + ru->nb_log_antennas); } } stop_meas(&ru->precoding_stats); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 6b5c1a9b22..5d43eeb619 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -207,7 +207,9 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, //apply the OFDM symbol rotation here - apply_nr_rotation(fp,(int16_t*) &gNB->common_vars.txdataF[0][txdataF_offset],slot,0,fp->Ncp==EXTENDED?12:14,fp->ofdm_symbol_size); + for (aa=0; aacarrier_config.num_tx_ant.value; aa++) { + apply_nr_rotation(fp,(int16_t*) &gNB->common_vars.txdataF[aa][txdataF_offset],slot,0,fp->Ncp==EXTENDED?12:14,fp->ofdm_symbol_size); + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX+offset,0); } diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 19dd861c56..083756d24e 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -615,7 +615,7 @@ int main(int argc, char **argv) prepare_scc(rrc.carrier.servingcellconfigcommon); uint64_t ssb_bitmap; fill_scc(rrc.carrier.servingcellconfigcommon,&ssb_bitmap,N_RB_DL,N_RB_DL,mu,mu); - + ssb_bitmap = 1;// Enable only first SSB with index ssb_indx=0 fix_scc(scc,ssb_bitmap); fill_default_secondaryCellGroup(scc, @@ -640,9 +640,9 @@ int main(int argc, char **argv) AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface"); gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; // common configuration - rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL); + rrc_mac_config_req_gNB(0,0,n_tx,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL); // UE dedicated configuration - rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); + rrc_mac_config_req_gNB(0,0,n_tx,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); phy_init_nr_gNB(gNB,0,0); N_RB_DL = gNB->frame_parms.N_RB_DL; // stub to configure frame_parms @@ -702,28 +702,28 @@ int main(int argc, char **argv) frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; //frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; - s_re = malloc(2*sizeof(double*)); - s_im = malloc(2*sizeof(double*)); - r_re = malloc(2*sizeof(double*)); - r_im = malloc(2*sizeof(double*)); - txdata = malloc(2*sizeof(int*)); - - for (i=0; i<2; i++) { + s_re = malloc(n_tx*sizeof(double*)); + s_im = malloc(n_tx*sizeof(double*)); + r_re = malloc(n_rx*sizeof(double*)); + r_im = malloc(n_rx*sizeof(double*)); + txdata = malloc(n_tx*sizeof(int*)); + for (i=0; iframe_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS)); + UE->frame_parms.nb_antennas_rx = n_rx; if (run_initial_sync==1) UE->is_synchronized = 0; else {UE->is_synchronized = 1; UE->UE_mode[0]=PUSCH;} @@ -955,7 +956,15 @@ int main(int argc, char **argv) fwrite(txdata[0],sizeof(int32_t),frame_length_complex_samples,output_fd); } - int txlev = signal_energy(&txdata[0][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples); + int txlev[n_tx]; + int txlev_sum = 0; + int l_ofdm = 6; + for (aa=0; aaofdm_symbol_size + (l_ofdm-1)*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples); + txlev_sum += txlev[aa]; + if (n_trials==1) printf("txlev[%d] = %d (%f dB) txlev_sum %d\n",aa,txlev[aa],10*log10((double)txlev[aa]),txlev_sum); + } // if (n_trials==1) printf("txlev %d (%f)\n",txlev,10*log10((double)txlev)); @@ -964,27 +973,37 @@ int main(int argc, char **argv) i++) { for (aa=0; aanb_antennas_tx; aa++) { - r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]); - r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]); + s_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]); + s_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]); } } double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size); //AWGN - sigma2_dB = 10 * log10((double)txlev * ((double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize))) - SNR; + sigma2_dB = 10 * log10((double)txlev_sum * ((double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize))) - SNR; sigma2 = pow(10, sigma2_dB/10); - if (n_trials==1) printf("sigma2 %f (%f dB), txlev %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize)); + if (n_trials==1) printf("sigma2 %f (%f dB), txlev_sum %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev_sum),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize)); + for (aa=0; aaget_samples_slot_timestamp(slot,frame_parms,0); iget_samples_slot_timestamp(slot+1,frame_parms,0); i++) { - for (aa=0; aanb_antennas_rx; aa++) { - ((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + for (int aa_rx=0; aa_rxcommon_vars.rxdata[aa_rx])[2*i] = (short) ((r_re[aa_rx][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short*) UE->common_vars.rxdata[aa_rx])[2*i+1] = (short) ((r_im[aa_rx][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); /* Add phase noise if enabled */ if (pdu_bit_map & 0x1) { - phase_noise(ts, &((short*) UE->common_vars.rxdata[aa])[2*i], - &((short*) UE->common_vars.rxdata[aa])[2*i+1]); + phase_noise(ts, &((short*) UE->common_vars.rxdata[aa_rx])[2*i], + &((short*) UE->common_vars.rxdata[aa_rx])[2*i+1]); } } } @@ -1159,12 +1178,14 @@ int main(int argc, char **argv) } }*/ - for (i = 0; i < 2; i++) { + for (i = 0; i < n_tx; i++) { free(s_re[i]); free(s_im[i]); + free(txdata[i]); + } + for (i = 0; i < n_rx; i++) { free(r_re[i]); free(r_im[i]); - free(txdata[i]); } free(s_re); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 1cd3b01b6c..a9bdcb510c 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -23,7 +23,7 @@ gNBs = ////////// Physical parameters: ssb_SubcarrierOffset = 0; - pdsch_AntennaPorts = 1; + pdsch_AntennaPorts = 2; servingCellConfigCommon = ( { @@ -240,8 +240,8 @@ L1s = ( RUs = ( { local_rf = "yes" - nb_tx = 1 - nb_rx = 1 + nb_tx = 2 + nb_rx = 2 att_tx = 0 att_rx = 0; bands = [7]; @@ -249,7 +249,7 @@ RUs = ( max_rxgain = 75; eNB_instances = [0]; ##beamforming 1x2 matrix: 1 layer x 2 antennas - bf_weights = [0x00007fff, 0x0000]; + bf_weights = [0x00007fff, 0x00007fff]; ##beamforming 1x4 matrix: 1 layer x 4 antennas #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000]; ## beamforming 2x2 matrix: From 58f4f155cc18bb4d8da916527d45a8c4f3bab02a Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Wed, 9 Dec 2020 08:37:14 +0100 Subject: [PATCH 02/40] Enable beamforming for 2 tx antenna ports and fix corresponding segmentation error --- openair1/PHY/INIT/nr_init_ru.c | 8 ++++---- openair1/PHY/MODULATION/beamforming.c | 9 +++++---- openair1/PHY/MODULATION/nr_modulation.h | 3 ++- openair1/SCHED_NR/nr_ru_procedures.c | 13 +++++++------ .../CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 4 ++-- 5 files changed, 20 insertions(+), 17 deletions(-) diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index 648b820f07..0aac86e5be 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -125,7 +125,7 @@ int nr_phy_init_RU(RU_t *ru) { int beam_count = 0; if (ru->nb_tx>1) {//Enable beamforming when nb_tx > 1 for (p=0;pnb_log_antennas;p++) { - if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0 + //if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0 beam_count++; } AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx)); @@ -133,7 +133,7 @@ int nr_phy_init_RU(RU_t *ru) { int l_ind = 0; for (i=0; inb_log_antennas;p++) { - if ((fp->L_ssb >> (63-p)) & 0x01) { + //if ((fp->L_ssb >> (63-p)) & 0x01) { ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*)); for (j=0; jnb_tx; j++) { ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t)); @@ -142,8 +142,8 @@ int nr_phy_init_RU(RU_t *ru) { //printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j); l_ind++; } // for j - } // for p - } + //} + } // for p } //for i } } // !=IF5 diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c index b1f419b172..4405c46abf 100644 --- a/openair1/PHY/MODULATION/beamforming.c +++ b/openair1/PHY/MODULATION/beamforming.c @@ -145,7 +145,8 @@ int nr_beam_precoding(int32_t **txdataF, int slot, int symbol, int aa, - int nb_antenna_ports) + int nb_antenna_ports, + int offset) { @@ -155,14 +156,14 @@ int nr_beam_precoding(int32_t **txdataF, memset(&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],0,sizeof(int32_t)*(frame_parms->ofdm_symbol_size)); for (p=0; pL_ssb >> (63-p)) & 0x01) { - multadd_cpx_vector((int16_t*)&txdataF[p][symbol*frame_parms->ofdm_symbol_size], + //if ((frame_parms->L_ssb >> (63-p)) & 0x01) { + multadd_cpx_vector((int16_t*)&txdataF[p][(symbol*frame_parms->ofdm_symbol_size)+offset], (int16_t*)beam_weights[p][aa], (int16_t*)&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size], 0, frame_parms->ofdm_symbol_size, 15); - } + //} } return 0; } diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index b9326271d9..d81fd0f2c8 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -106,7 +106,8 @@ int nr_beam_precoding(int32_t **txdataF, int slot, int symbol, int aa, - int nb_antenna_ports + int nb_antenna_ports, + int offset ); void apply_nr_rotation(NR_DL_FRAME_PARMS *fp, diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index bc9d119af4..7e39582251 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -285,7 +285,6 @@ static void *nr_feptx_thread(void *param) { NR_DL_FRAME_PARMS *fp; int ofdm_mask_full; int txdataF_offset; - int32_t *txdataF; while (!oai_exit) { ret = 0; if (wait_on_condition(&feptx->mutex_feptx,&feptx->cond_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break; @@ -314,16 +313,16 @@ static void *nr_feptx_thread(void *param) { } else { bw = ru->beam_weights[0]; - txdataF = &ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset]; for(i=0; isymbols_per_slot>>1; ++i){ - nr_beam_precoding(&txdataF, + nr_beam_precoding(ru->gNB_list[0]->common_vars.txdataF, ru->common.txdataF_BF, fp, bw, slot, l+i, aa, - ru->nb_log_antennas); + ru->nb_log_antennas, + txdataF_offset);//here } } stop_meas(&ru->precoding_stats); @@ -362,7 +361,8 @@ static void *nr_feptx_thread(void *param) { slot, l, aa, - nb_antenna_ports); + ru->nb_log_antennas, + 0); } stop_meas(&ru->precoding_stats); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 0); @@ -485,7 +485,8 @@ void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx) { tti_tx, l, aa, - ru->nb_log_antennas); + ru->nb_log_antennas, + 0); }// for (aa=0;aanb_tx;aa++) }// for (l=0;lsymbols_per_slot;l++) }// if (ru->nb_tx == 1) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index a9bdcb510c..d7985eb8cd 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -249,11 +249,11 @@ RUs = ( max_rxgain = 75; eNB_instances = [0]; ##beamforming 1x2 matrix: 1 layer x 2 antennas - bf_weights = [0x00007fff, 0x00007fff]; + #bf_weights = [0x00007fff, 0x00007fff]; ##beamforming 1x4 matrix: 1 layer x 4 antennas #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000]; ## beamforming 2x2 matrix: - # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; + bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; ## beamforming 4x4 matrix: #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; From 03803a12f2ce529fe88dba6d75c7cfdf279024b3 Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Tue, 22 Dec 2020 15:51:55 +0100 Subject: [PATCH 03/40] Debug: add more VCD functions to trace UE timing --- common/utils/LOG/vcd_signal_dumper.c | 5 +++++ common/utils/LOG/vcd_signal_dumper.h | 5 +++++ common/utils/T/T_defs.h | 2 +- common/utils/T/T_messages.txt | 20 ++++++++++++++++++++ openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 12 ++++++++---- 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c index bd598b48da..5bf9759933 100644 --- a/common/utils/LOG/vcd_signal_dumper.c +++ b/common/utils/LOG/vcd_signal_dumper.c @@ -302,6 +302,9 @@ const char* eurecomFunctionsNames[] = { /* PHY signals */ "ue_synch", "ue_slot_fep", + "ue_slot_fep_pdcch", + "ue_slot_fep_pbch", + "ue_slot_fep_pdsch", "ue_slot_fep_mbsfn", "ue_slot_fep_mbsfn_khz_1dot25", "ue_rrc_measurements", @@ -390,6 +393,8 @@ const char* eurecomFunctionsNames[] = { "rx_pmch", "rx_pmch_khz_1dot25", "pdsch_procedures", + "pdsch_procedures_crnti", + //"dlsch_procedures_crnti", "pdsch_procedures_si", "pdsch_procedures_p", "pdsch_procedures_ra", diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h index f9f5868260..fb27c19973 100644 --- a/common/utils/LOG/vcd_signal_dumper.h +++ b/common/utils/LOG/vcd_signal_dumper.h @@ -283,6 +283,9 @@ typedef enum { /* PHY signals */ VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SYNCH, VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, + VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, + VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PBCH, + VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN, VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN_KHZ_1DOT25, VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, @@ -371,9 +374,11 @@ typedef enum { VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH, VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH_KHZ_1DOT25, VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, + VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, + //VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PROC_C, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_CONFIG_SIB2, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_CONFIG_SIB1_ENB, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_CONFIG_SIB2_ENB, diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index 7b5304b1cb..1236c96a33 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -73,7 +73,7 @@ typedef struct { } T_cache_t; /* number of VCD functions (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_FUNCTIONS (269) +#define VCD_NUM_FUNCTIONS (273) /* number of VCD variables (to be kept up to date! see in T_messages.txt) */ #define VCD_NUM_VARIABLES (187) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 06ee5bf12b..3336f2165d 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -2403,6 +2403,21 @@ ID = VCD_FUNCTION_UE_SLOT_FEP GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value VCD_NAME = ue_slot_fep +ID = VCD_FUNCTION_UE_SLOT_FEP_PDCCH + DESC = VCD function UE_SLOT_FEP_PDCCH + GROUP = ALL:VCD:UE:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = ue_slot_fep_pdcch +ID = VCD_FUNCTION_UE_SLOT_FEP_PBCH + DESC = VCD function UE_SLOT_FEP_PBCH + GROUP = ALL:VCD:UE:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = ue_slot_fep_pbch +ID = VCD_FUNCTION_UE_SLOT_FEP_PDSCH + DESC = VCD function UE_SLOT_FEP_PDSCH + GROUP = ALL:VCD:UE:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = ue_slot_fep_pdsch ID = VCD_FUNCTION_UE_SLOT_FEP_MBSFN DESC = VCD function UE_SLOT_FEP_MBSFN GROUP = ALL:VCD:UE:VCD_FUNCTION @@ -2843,6 +2858,11 @@ ID = VCD_FUNCTION_PDSCH_PROC GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value VCD_NAME = pdsch_procedures +ID = VCD_FUNCTION_PDSCH_PROC_C + DESC = VCD function PDSCH_PROC_C + GROUP = ALL:VCD:UE:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = pdsch_procedures_crnti ID = VCD_FUNCTION_PDSCH_PROC_SI DESC = VCD function PDSCH_PROC_SI GROUP = ALL:VCD:UE:VCD_FUNCTION diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 8629d07410..08b219504e 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -1760,6 +1760,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, // looking for pbch only in slot where it is supposed to be if (slot_ssb) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PBCH, VCD_FUNCTION_IN); LOG_D(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx); for (int i=1; i<4; i++) { @@ -1801,6 +1802,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__); nr_ue_rrc_measurements(ue, proc, nr_slot_rx); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PBCH, VCD_FUNCTION_OUT); } } @@ -1814,12 +1816,12 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, nr_gold_pdcch(ue, 0, 2); LOG_D(PHY," ------ --> PDCCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_IN); for (uint16_t l=0; lofdm_demod_stats); #endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); nr_slot_fep(ue, proc, l, @@ -1843,7 +1845,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, fp->first_carrier_offset+(pdcch_vars->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12, coreset_nb_rb); - 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); #endif @@ -1851,6 +1852,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, dci_cnt = dci_cnt + nr_ue_pdcch_procedures(gNB_id, ue, proc); } } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT); if (dci_cnt > 0) { @@ -1866,6 +1868,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, } if (dlsch) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_IN); uint8_t harq_pid = dlsch->current_harq_pid; NR_DL_UE_HARQ_t *dlsch0_harq = dlsch->harq_processes[harq_pid]; uint16_t nb_symb_sch = dlsch0_harq->nb_symbols; @@ -1888,6 +1891,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, 0, 0); } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_OUT); } } else { LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: No DCIs found\n", ue->Mod_id, frame_rx, nr_slot_rx); @@ -1901,7 +1905,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, // do procedures for C-RNTI int ret_pdsch = 0; if (ue->dlsch[proc->thread_id][gNB_id][0]->active == 1) { - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_IN); ret_pdsch = nr_ue_pdsch_procedures(ue, proc, gNB_id, @@ -1910,6 +1914,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, NULL); nr_ue_measurement_procedures(2, ue, proc, gNB_id, nr_slot_rx, mode); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_OUT); } // do procedures for SI-RNTI @@ -1960,7 +1965,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, // deactivate dlsch once dlsch proc is done ue->dlsch_p[gNB_id]->active = 0; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT); } From 74009a7200fdb3a286279cc343193990eae62b8f Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Wed, 13 Jan 2021 09:54:38 +0100 Subject: [PATCH 04/40] Enable dmrsConfigType2 for pdsch --- openair1/PHY/INIT/nr_init_ue.c | 2 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 2 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 2 +- openair2/RRC/NR/rrc_gNB_reconfig.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index ff1b00e65e..cb29b9194b 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -514,7 +514,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, // dmrs_Uplink_Config->pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0; // dmrs_Uplink_Config->pusch_maxLength = pusch_len1; //-------------------------------------------------// - ue->dmrs_DownlinkConfig.pdsch_dmrs_type = pdsch_dmrs_type1; + ue->dmrs_DownlinkConfig.pdsch_dmrs_type = pdsch_dmrs_type2; ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition = pdsch_dmrs_pos0; ue->dmrs_DownlinkConfig.pdsch_maxLength = pdsch_len1; //-------------------------------------------------// diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index e15963f355..a2c8e54f58 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -861,7 +861,7 @@ void nr_generate_Msg2(module_id_t module_idP, pdsch_pdu_rel15->nrOfLayers = 1; pdsch_pdu_rel15->transmissionScheme = 0; pdsch_pdu_rel15->refPoint = 0; - pdsch_pdu_rel15->dmrsConfigType = 0; + pdsch_pdu_rel15->dmrsConfigType = 1;//Enable Msg2 to use pdsch_dmrs_type2 pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu_rel15->SCID = 0; pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 2; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index f0f809fb39..354f32bdd7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -133,7 +133,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, pdsch_pdu_rel15->transmissionScheme = 0; pdsch_pdu_rel15->refPoint = 0; // Point A - pdsch_pdu_rel15->dmrsConfigType = 0; // Type 1 by default for InitialBWP + pdsch_pdu_rel15->dmrsConfigType = 1; // Type 2 by default for InitialBWP pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu_rel15->SCID = 0; pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 1; diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 56b3b74050..6fad4ba89c 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -636,7 +636,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup)); - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=NULL; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type)); bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID0=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID1=NULL; From bd31209f791c4c6df56fd45f1ff20128b2f7643d Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Wed, 20 Jan 2021 11:03:35 +0100 Subject: [PATCH 05/40] remove dependency of PDSCH antenna number from PUSCH Rx antenna number --- openair2/LAYER2/NR_MAC_gNB/config.c | 2 +- .../GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index bd6a8f3384..21371d5e32 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -275,7 +275,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm num_ssb += (cfg->ssb_table.ssb_mask_list[1].ssb_mask.value>>i)&1; } - cfg->carrier_config.num_rx_ant.value = cfg->carrier_config.num_tx_ant.value; + cfg->carrier_config.num_rx_ant.value = 1;//cfg->carrier_config.num_tx_ant.value; cfg->carrier_config.num_rx_ant.tl.tag = NFAPI_NR_CONFIG_NUM_RX_ANT_TAG; LOG_I(MAC,"Set TX/RX antenna number to %d (num ssb %d: %x,%x)\n",cfg->carrier_config.num_tx_ant.value,num_ssb,cfg->ssb_table.ssb_mask_list[0].ssb_mask.value,cfg->ssb_table.ssb_mask_list[1].ssb_mask.value); AssertFatal(cfg->carrier_config.num_tx_ant.value > 0,"carrier_config.num_tx_ant.value %d !\n",cfg->carrier_config.num_tx_ant.value ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index d7985eb8cd..cc8aa298ba 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -241,7 +241,7 @@ RUs = ( { local_rf = "yes" nb_tx = 2 - nb_rx = 2 + nb_rx = 1 att_tx = 0 att_rx = 0; bands = [7]; From 0ae83fac6df2bb76c29c5a57150ee73b5caed9b0 Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Wed, 20 Jan 2021 11:06:20 +0100 Subject: [PATCH 06/40] Fix dl PDSCH channel estimation to support multi-port channel estimation --- openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 6cb0a612e9..9c65333302 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -690,7 +690,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12 - BWPStart; uint8_t config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type; int8_t delta = get_delta(p, config_type); - nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][symbol][0], &pilot[0],1000,0,nb_rb_pdsch+rb_offset); + nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][symbol][0], &pilot[0],1000+p,0,nb_rb_pdsch+rb_offset); if (config_type == pdsch_dmrs_type1){ nushift = (p>>1)&1; From d4bd15f5ad928e11070f2f886ce755583f7e4e79 Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Wed, 20 Jan 2021 11:09:05 +0100 Subject: [PATCH 07/40] increase CirSize to avoid overflow in the case of multi-transmit antennas for gNB --- targets/ARCH/rfsimulator/simulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 79bf3dd077..b469211a35 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -54,7 +54,7 @@ #include #define PORT 4043 //default TCP port for this simulator -#define CirSize 307200 // 100ms is enough +#define CirSize 6144000 // 100ms is enough #define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t)) #define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b))) From 4b541b444d1a213d5adfb04f64714d4ed6628057 Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Thu, 21 Jan 2021 16:30:05 +0100 Subject: [PATCH 08/40] Extend the UE side to support 4 Rx antennas --- cmake_targets/CMakeLists.txt | 2 +- openair1/PHY/INIT/nr_init_ue.c | 74 +++++++++---------- openair1/PHY/INIT/nr_parms.c | 5 ++ .../nr_dl_channel_estimation.c | 10 +-- openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c | 7 +- 5 files changed, 50 insertions(+), 48 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index b2ede601f7..3f433b7f16 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -833,7 +833,7 @@ add_library(F1AP # Hardware dependant options ################################### -add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4") +add_list1_option(NB_ANTENNAS_RX "4" "Number of antennas in reception" "1" "2" "4") add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4") add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "OAI_USRP" "OAI_BLADERF" "OAI_LMSSDR" "OAI_SIMU") diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index cb29b9194b..1e4cbf1ff8 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -381,30 +381,30 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch, pdsch->llr128 = (int16_t **)malloc16_clear( sizeof(int16_t *) ); // FIXME! no further allocation for (int16_t*)pdsch->llr128 !!! expect SIGSEGV // FK, 11-3-2015: this is only as a temporary pointer, no memory is stored there - pdsch->rxdataF_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pdsch->rxdataF_uespec_pilots = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pdsch->rxdataF_comp0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pdsch->rxdataF_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->rxdataF_uespec_pilots = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->rxdataF_comp0 = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); pdsch->rho = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->dl_ch_estimates = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pdsch->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pdsch->dl_bf_ch_estimates = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pdsch->dl_bf_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pdsch->dl_ch_estimates = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_bf_ch_estimates = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_bf_ch_estimates_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); //pdsch->dl_ch_rho_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); //pdsch->dl_ch_rho2_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->dl_ch_mag0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pdsch->dl_ch_magb0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pdsch->dl_ch_magr0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pdsch->ptrs_phase_per_slot = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pdsch->ptrs_re_per_slot = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pdsch->dl_ch_ptrs_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pdsch->dl_ch_mag0 = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_ch_magb0 = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_ch_magr0 = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->ptrs_phase_per_slot = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->ptrs_re_per_slot = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_ch_ptrs_estimates_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); // the allocated memory size is fixed: - AssertFatal( fp->nb_antennas_rx <= 2, "nb_antennas_rx > 2" ); + AssertFatal( fp->nb_antennas_rx <= 4, "nb_antennas_rx > 4" );//Extend the max number of UE Rx antennas to 4 for (int i=0; inb_antennas_rx; i++) { pdsch->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) ); - for (int j=0; j<4; j++) { //fp->nb_antennas_tx; j++) - const int idx = (j<<1)+i; + for (int j=0; j<4; j++) { //4: DL antenna ports + const int idx = (j*fp->nb_antennas_rx)+i; const size_t num = 7*2*fp->N_RB_DL*12; pdsch->rxdataF_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); pdsch->rxdataF_uespec_pilots[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12); @@ -449,15 +449,13 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, uint16_t N_n_scid[2] = {0,1}; // [HOTFIX] This is a temporary implementation of scramblingID0 and scramblingID1 which are given by DMRS-UplinkConfig int n_scid; abstraction_flag = 0; - fp->nb_antennas_tx = 1; - fp->nb_antennas_rx=1; // dmrs_UplinkConfig_t *dmrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig; // ptrs_UplinkConfig_t *ptrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig; LOG_I(PHY, "Initializing UE vars (abstraction %u) for gNB TXant %u, UE RXant %u\n", abstraction_flag, fp->nb_antennas_tx, fp->nb_antennas_rx); //LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_eNB_INST); phy_init_nr_top(ue); // many memory allocation sizes are hard coded - AssertFatal( fp->nb_antennas_rx <= 2, "hard coded allocation for ue_common_vars->dl_ch_estimates[eNB_id]" ); + AssertFatal( fp->nb_antennas_rx <= 4, "hard coded allocation for ue_common_vars->dl_ch_estimates[eNB_id]" ); AssertFatal( nb_connected_eNB <= NUMBER_OF_CONNECTED_eNB_MAX, "n_connected_eNB is too large" ); // init phy_vars_ue @@ -654,12 +652,12 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, } for (th_id=0; th_idpdsch_vars[th_id][eNB_id]->dl_ch_rho2_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + ue->pdsch_vars[th_id][eNB_id]->dl_ch_rho2_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); } for (i=0; inb_antennas_rx; i++) for (j=0; j<4; j++) { - const int idx = (j<<1)+i; + const int idx = (j*fp->nb_antennas_rx)+i; const size_t num = 7*2*fp->N_RB_DL*12+4; for (th_id=0; th_idpdsch_vars[th_id][eNB_id]->rxdataF_comp1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - ue->pdsch_vars[th_id][eNB_id]->dl_ch_rho_ext[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - ue->pdsch_vars[th_id][eNB_id]->dl_ch_mag1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - ue->pdsch_vars[th_id][eNB_id]->dl_ch_magb1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + ue->pdsch_vars[th_id][eNB_id]->rxdataF_comp1[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + ue->pdsch_vars[th_id][eNB_id]->dl_ch_rho_ext[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + ue->pdsch_vars[th_id][eNB_id]->dl_ch_mag1[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + ue->pdsch_vars[th_id][eNB_id]->dl_ch_magb1[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); } for (int i=0; inb_antennas_rx; i++) for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++) - const int idx = (j<<1)+i; + const int idx = (j*fp->nb_antennas_rx)+i; for (th_id=0; th_idpdsch_vars[th_id][eNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); @@ -697,20 +695,20 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, ue->pdcch_vars[th_id][eNB_id]->llr16 = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); ue->pdcch_vars[th_id][eNB_id]->wbar = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); ue->pdcch_vars[th_id][eNB_id]->e_rx = (int16_t *)malloc16_clear( 4*2*100*12 ); - ue->pdcch_vars[th_id][eNB_id]->rxdataF_comp = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - ue->pdcch_vars[th_id][eNB_id]->dl_ch_rho_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + ue->pdcch_vars[th_id][eNB_id]->rxdataF_comp = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + ue->pdcch_vars[th_id][eNB_id]->dl_ch_rho_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); ue->pdcch_vars[th_id][eNB_id]->rho = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - ue->pdcch_vars[th_id][eNB_id]->rxdataF_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - ue->pdcch_vars[th_id][eNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + ue->pdcch_vars[th_id][eNB_id]->rxdataF_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + ue->pdcch_vars[th_id][eNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); // Channel estimates - ue->pdcch_vars[th_id][eNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); - ue->pdcch_vars[th_id][eNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); + ue->pdcch_vars[th_id][eNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear(4*fp->nb_antennas_rx*sizeof(int32_t *)); + ue->pdcch_vars[th_id][eNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear(4*fp->nb_antennas_rx*sizeof(int32_t *)); for (i=0; inb_antennas_rx; i++) { ue->pdcch_vars[th_id][eNB_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(100*12*4) ); for (j=0; j<4; j++) { - int idx = (j<<1) + i; + int idx = (j*fp->nb_antennas_rx)+i; ue->pdcch_vars[th_id][eNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) ); ue->pdcch_vars[th_id][eNB_id]->dl_ch_estimates_time[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 ); // size_t num = 7*2*fp->N_RB_DL*12; @@ -725,10 +723,10 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, // PBCH pbch_vars[eNB_id]->rxdataF_ext = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - pbch_vars[eNB_id]->rxdataF_comp = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pbch_vars[eNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pbch_vars[eNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pbch_vars[eNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pbch_vars[eNB_id]->rxdataF_comp = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + pbch_vars[eNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + pbch_vars[eNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + pbch_vars[eNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); pbch_vars[eNB_id]->llr = (int16_t *)malloc16_clear( 1920 ); // prach_vars[eNB_id]->prachF = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); prach_vars[eNB_id]->prach = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); @@ -737,7 +735,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, pbch_vars[eNB_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*20*12*4 ); for (j=0; j<4; j++) {//fp->nb_antennas_tx;j++) { - int idx = (j<<1)+i; + int idx = (j*fp->nb_antennas_rx)+i; pbch_vars[eNB_id]->rxdataF_comp[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*20*12*4 ); pbch_vars[eNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size) ); pbch_vars[eNB_id]->dl_ch_estimates_time[idx]= (int32_t *)malloc16_clear( sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size) ); diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index c381c5c71c..814177a86c 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -334,6 +334,11 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, uint8_t Nid_cell = 0; int Ncp = NORMAL; + if(fp->nb_antennas_rx == 0) + fp->nb_antennas_rx = 1; + if(fp->nb_antennas_tx == 0) + fp->nb_antennas_tx = 1; + // default values until overwritten by RRCConnectionReconfiguration fp->nb_antenna_ports_gNB = nb_ant_ports_gNB; fp->tdd_config = tdd_cfg; 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 9c65333302..ac9def26c0 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -77,9 +77,9 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, // generate pilot nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]); - int re_offset = ssb_offset; for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { + int re_offset = ssb_offset; pil = (int16_t *)&pilot[0]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -277,9 +277,9 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, // generate pilot nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]); - int re_offset = ssb_offset; for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { + int re_offset = ssb_offset; pil = (int16_t *)&pilot[0]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; @@ -456,12 +456,12 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, // do ifft of channel estimate for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) for (p=0; pframe_parms.nb_antenna_ports_gNB; p++) { - if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx]) + if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx]) { LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d ch_offset %d\n", Ns, proc->thread_id, symbol, ch_offset); idft(idftsizeidx, - (int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx][ch_offset], - (int16_t*) ue->pbch_vars[eNB_offset]->dl_ch_estimates_time[(p<<1)+aarx],1); + (int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx][ch_offset], + (int16_t*) ue->pbch_vars[eNB_offset]->dl_ch_estimates_time[(p*ue->frame_parms.nb_antennas_rx)+aarx],1); } } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 4d21fe782b..26508de8c5 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -59,16 +59,15 @@ uint16_t nr_pbch_extract(int **rxdataF, uint8_t i,j,aarx; int32_t *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; int nushiftmod4 = frame_parms->nushift; - unsigned int rx_offset = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; //and - - // if (rx_offset>= frame_parms->ofdm_symbol_size) rx_offset-=frame_parms->ofdm_symbol_size; - rx_offset=(rx_offset)%(frame_parms->ofdm_symbol_size); AssertFatal(symbol>=1 && symbol<5, "symbol %d illegal for PBCH extraction\n", symbol); for (aarx=0; aarxnb_antennas_rx; aarx++) { + unsigned int rx_offset = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; + rx_offset = (rx_offset)%(frame_parms->ofdm_symbol_size); + rxF = &rxdataF[aarx][(symbol+s_offset)*frame_parms->ofdm_symbol_size]; rxF_ext = &rxdataF_ext[aarx][symbol*20*12]; #ifdef DEBUG_PBCH From b962cc94ce94b405fa519dd034da455e048ab684 Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Sat, 23 Jan 2021 08:00:56 +0100 Subject: [PATCH 09/40] Add rb extract to support multiple tx layers feature for MIMO mode --- .../nr_dl_channel_estimation.c | 6 +- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 274 ++++++++---------- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 61 ++-- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 2 +- .../CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 4 +- 5 files changed, 145 insertions(+), 202 deletions(-) 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 ac9def26c0..69f8a39e77 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -672,7 +672,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; if (ue->high_speed_flag == 0) - ch_offset = ue->frame_parms.ofdm_symbol_size ; + ch_offset = ue->frame_parms.ofdm_symbol_size; else ch_offset = ue->frame_parms.ofdm_symbol_size*symbol; @@ -694,7 +694,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, if (config_type == pdsch_dmrs_type1){ nushift = (p>>1)&1; - ue->frame_parms.nushift = nushift; + if (p<4) ue->frame_parms.nushift = nushift; switch (delta) { case 0://port 0,1 @@ -734,7 +734,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, } } else {//pdsch_dmrs_type2 nushift = delta; - ue->frame_parms.nushift = nushift; + if (p<6) ue->frame_parms.nushift = nushift; switch (delta) { case 0://port 0,1 fl = filt8_l2;//left interpolation Filter should be fml diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 316eb53029..0ec1198fd4 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -332,84 +332,38 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pilots = ((1<dlDmrsSymbPos)>0 ? 1 : 0; - if (frame_parms->nb_antenna_ports_gNB>1 && beamforming_mode==0) { -#ifdef DEBUG_DLSCH_MOD - LOG_I(PHY,"dlsch: using pmi %x (%p)\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),dlsch[0]); -#endif - + if (beamforming_mode==0) {//No beamforming #if UE_TIMING_TRACE start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #endif - nb_rb = nr_dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, + if (dlsch0_harq->Nl > 1)//More than or equal 2 layers + nb_rb = nr_dlsch_extract_rbs_multiple(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, pdsch_vars[eNB_id]->dl_ch_estimates, pdsch_vars[eNB_id]->rxdataF_ext, pdsch_vars[eNB_id]->dl_ch_estimates_ext, - dlsch0_harq->pmi_alloc, - pdsch_vars[eNB_id]->pmi_ext, symbol, pilots, + config_type, start_rb, nb_rb_pdsch, - nr_slot_rx, ue->high_speed_flag, + dlsch0_harq->Nl, frame_parms, - dlsch0_harq->mimo_mode); -#ifdef DEBUG_DLSCH_MOD - printf("dlsch: using pmi %lx, pmi_ext ",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); - for (rb=0;rbpmi_ext[rb]); - printf("\n"); -#endif + dlsch0_harq->dlDmrsSymbPos); - if (rx_type >= rx_IC_single_stream) { - if (eNB_id_in_connected_eNB) // we are in TM5 - nb_rb = nr_dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, - pdsch_vars[eNB_id]->dl_ch_estimates, - pdsch_vars[eNB_id_i]->rxdataF_ext, - pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, - dlsch0_harq->pmi_alloc, - pdsch_vars[eNB_id_i]->pmi_ext, - symbol, - pilots, - start_rb, - nb_rb_pdsch, - nr_slot_rx, - ue->high_speed_flag, - frame_parms, - dlsch0_harq->mimo_mode); - else - nb_rb = nr_dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, - pdsch_vars[eNB_id]->dl_ch_estimates, - pdsch_vars[eNB_id_i]->rxdataF_ext, - pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, - dlsch0_harq->pmi_alloc, - pdsch_vars[eNB_id_i]->pmi_ext, - symbol, - pilots, - start_rb, - nb_rb_pdsch, - nr_slot_rx, - ue->high_speed_flag, - frame_parms, - dlsch0_harq->mimo_mode); - } - } else if (beamforming_mode==0) { //else if nb_antennas_ports_gNB==1 && beamforming_mode == 0 - //printf("start nr dlsch extract nr_slot_rx %d thread id %d \n", nr_slot_rx, proc->thread_id); + else// one layer nb_rb = nr_dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, pdsch_vars[eNB_id]->dl_ch_estimates, pdsch_vars[eNB_id]->rxdataF_ext, pdsch_vars[eNB_id]->dl_ch_estimates_ext, - dlsch0_harq->pmi_alloc, - pdsch_vars[eNB_id]->pmi_ext, symbol, pilots, config_type, start_rb + dlsch0_harq->BWPStart, nb_rb_pdsch, - nr_slot_rx, ue->high_speed_flag, - frame_parms, - dlsch0_harq->dlDmrsSymbPos); + frame_parms, + dlsch0_harq->dlDmrsSymbPos); } /*else if(beamforming_mode>7) { LOG_W(PHY,"dlsch_demodulation: beamforming mode not supported yet.\n"); @@ -437,7 +391,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #if UE_TIMING_TRACE start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #endif - n_tx = frame_parms->nb_antenna_ports_gNB; + n_tx = dlsch0_harq->Nl; n_rx = frame_parms->nb_antennas_rx; nr_dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext, @@ -2098,22 +2052,17 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, int **dl_ch_estimates, int **rxdataF_ext, int **dl_ch_estimates_ext, - unsigned short pmi, - unsigned char *pmi_ext, unsigned char symbol, uint8_t pilots, uint8_t config_type, unsigned short start_rb, unsigned short nb_rb_pdsch, - unsigned char nr_slot_rx, uint32_t high_speed_flag, - NR_DL_FRAME_PARMS *frame_parms, - uint16_t dlDmrsSymbPos) { - - + NR_DL_FRAME_PARMS *frame_parms, + uint16_t dlDmrsSymbPos) { unsigned short k,rb; - unsigned char i,aarx; //,nsymb,sss_symb,pss_symb=0,l; + unsigned char i,aarx; int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; int8_t validDmrsEst = 0; //store last DMRS Symbol index @@ -2146,21 +2095,23 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))]; } if (pilots==0) { - memcpy((void*)rxF_ext,(void*)rxF,12*sizeof(*rxF_ext)); - memcpy((void*)dl_ch0_ext,(void*)dl_ch0,12*sizeof(*dl_ch0_ext)); - dl_ch0_ext+=12; - rxF_ext+=12; + memcpy((void*)rxF_ext,(void*)rxF,12*sizeof(*rxF_ext)); + memcpy((void*)dl_ch0_ext,(void*)dl_ch0,12*sizeof(*dl_ch0_ext)); + dl_ch0_ext+=12; + rxF_ext+=12; } else {//the symbol contains DMRS - j=0; - if (config_type==pdsch_dmrs_type1){ - for (i = (1-frame_parms->nushift); i<12; i+=2) { - rxF_ext[j]=rxF[i]; - dl_ch0_ext[j]=dl_ch0[i]; - j++; - } - dl_ch0_ext+=6; - rxF_ext+=6; - } else { + j=0; + if (config_type==pdsch_dmrs_type1){ + if (frame_parms->nushift == 0) {//data is multiplexed + for (i = (1-frame_parms->nushift); i<12; i+=2) { + rxF_ext[j]=rxF[i]; + dl_ch0_ext[j]=dl_ch0[i]; + j++; + } + dl_ch0_ext+=6; + rxF_ext+=6; + } + } else {//pdsch_dmrs_type2 for (i = (2+frame_parms->nushift); i<6; i++) { rxF_ext[j]=rxF[i]; dl_ch0_ext[j]=dl_ch0[i]; @@ -2171,8 +2122,8 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, dl_ch0_ext[j]=dl_ch0[i]; j++; } - dl_ch0_ext+= 8; - rxF_ext+= 8; + dl_ch0_ext+= j; + rxF_ext+= j; } } @@ -2186,101 +2137,102 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, } } - - return(nb_rb_pdsch/frame_parms->nb_antennas_rx); + return(nb_rb_pdsch); } -unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF, - int **dl_ch_estimates, - int **rxdataF_ext, - int **dl_ch_estimates_ext, - unsigned short pmi, - unsigned char *pmi_ext, - unsigned char symbol, - uint8_t pilots, - unsigned short start_rb, - unsigned short nb_rb_pdsch, - unsigned char nr_slot_rx, - uint32_t high_speed_flag, - NR_DL_FRAME_PARMS *frame_parms, - MIMO_mode_t mimo_mode) { +unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF, + int **dl_ch_estimates, + int **rxdataF_ext, + int **dl_ch_estimates_ext, + unsigned char symbol, + uint8_t pilots, + uint8_t config_type, + unsigned short start_rb, + unsigned short nb_rb_pdsch, + uint32_t high_speed_flag, + uint8_t Nl, + NR_DL_FRAME_PARMS *frame_parms, + uint16_t dlDmrsSymbPos) { - int prb,nb_rb=0; - unsigned short k; - int i,j,aarx; - int32_t *dl_ch0=NULL,*dl_ch0_ext=NULL,*dl_ch1=NULL,*dl_ch1_ext=NULL,*rxF=NULL,*rxF_ext=NULL; + unsigned short k,rb; + unsigned char j,i,aarx,aatx; + int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; + int8_t validDmrsEst = 0; //store last DMRS Symbol index - k = frame_parms->first_carrier_offset + 516; //0 + if (config_type==pdsch_dmrs_type1) + AssertFatal(frame_parms->nushift ==0 || frame_parms->nushift == 1, + "nushift %d is illegal\n",frame_parms->nushift); + else + AssertFatal(frame_parms->nushift ==0 || frame_parms->nushift == 2 || frame_parms->nushift == 4, + "nushift %d is illegal\n",frame_parms->nushift); + + validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos,symbol); for (aarx=0; aarxnb_antennas_rx; aarx++) { - if (high_speed_flag==1) { - dl_ch0 = &dl_ch_estimates[aarx][symbol*(frame_parms->ofdm_symbol_size)]; - dl_ch1 = &dl_ch_estimates[2+aarx][symbol*(frame_parms->ofdm_symbol_size)]; - } else { - dl_ch0 = &dl_ch_estimates[aarx][0]; - dl_ch1 = &dl_ch_estimates[2+aarx][0]; - } + k = frame_parms->first_carrier_offset + NR_NB_SC_PER_RB*start_rb; + if (k>frame_parms->ofdm_symbol_size) + k = k-frame_parms->ofdm_symbol_size; - //pmi_loc = pmi_ext; + rxF_ext = &rxdataF_ext[aarx][symbol*(nb_rb_pdsch*12)]; + rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))]; - // pointers to extracted RX signals and channel estimates - rxF_ext = &rxdataF_ext[aarx][symbol*(nb_rb_pdsch*12)]; - dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(nb_rb_pdsch*12)]; - dl_ch1_ext = &dl_ch_estimates_ext[2+aarx][symbol*(nb_rb_pdsch*12)]; + for (aatx=0; aatxN_RB_DL; prb++) { - //skip_half=0; + dl_ch0 = &dl_ch_estimates[(aatx*frame_parms->nb_antennas_rx)+aarx][(validDmrsEst*(frame_parms->ofdm_symbol_size))]; + dl_ch0_ext = &dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*(nb_rb_pdsch*NR_NB_SC_PER_RB)]; - if ((frame_parms->N_RB_DL&1) == 0) { // even number of RBs + for (rb = 0; rb < nb_rb_pdsch; rb++) { - // For second half of RBs skip DC carrier - if (k>=frame_parms->ofdm_symbol_size) { - rxF = &rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))]; - k=k-(frame_parms->ofdm_symbol_size); - } + if (pilots==0) {//data symbol only + if (aatx==0) {//Extract Rx signal only + memcpy((void*)rxF_ext,(void*)rxF,12*sizeof(*rxF_ext)); + rxF_ext+=12; + } + memcpy((void*)dl_ch0_ext,(void*)dl_ch0,12*sizeof(*dl_ch0_ext));//Extract Channel Estimate + dl_ch0_ext+=12; + } else {//the symbol contains DMRS + j=0; + if (config_type==pdsch_dmrs_type1) { + if (frame_parms->nushift == 0) {//data is multiplexed + for (i = (1-frame_parms->nushift); i<12; i+=2) { + if (aatx==0) rxF_ext[j]=rxF[i]; + dl_ch0_ext[j]=dl_ch0[i]; + j++; + } + dl_ch0_ext+=6; + if (aatx==0) rxF_ext+=6; + } + } else {//pdsch_dmrs_type2 + for (i = (2+frame_parms->nushift); i<6; i++) { + if (aatx==0) rxF_ext[j]=rxF[i]; + dl_ch0_ext[j]=dl_ch0[i]; + j++; + } + for (i = (8+frame_parms->nushift); i<12; i++) { + if (aatx==0) rxF_ext[j]=rxF[i]; + dl_ch0_ext[j]=dl_ch0[i]; + j++; + } + dl_ch0_ext+= j; + if (aatx==0) rxF_ext+= j; + } + } - /* - if (mimo_mode <= PUSCH_PRECODING1) - *pmi_loc = (pmi>>((prb>>2)<<1))&3; - else - *pmi_loc=(pmi>>prb)&1;*/ + dl_ch0+=12; + if (aatx==0) { + rxF+=12; + k+=12; + if (k>=frame_parms->ofdm_symbol_size) { + k=k-(frame_parms->ofdm_symbol_size); + rxF = &rxdataF[aarx][k+(symbol*(frame_parms->ofdm_symbol_size))]; + } + } + }//rb + }//aatx + }//aarx - // *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb); - // pmi_loc++; - - - if (pilots == 0) { - - memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); - memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int)); - memcpy(rxF_ext,rxF,12*sizeof(int)); - dl_ch0_ext +=12; - dl_ch1_ext +=12; - rxF_ext +=12; - } else { // pilots==1 - j=0; - for (i=0; i<12; i++) { - if ((i&1)!=frame_parms->nushift) { - rxF_ext[j]=rxF[i]; - // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j]=dl_ch0[i]; - dl_ch1_ext[j++]=dl_ch1[i]; - } - } - dl_ch0_ext+=6; - dl_ch1_ext+=6; - rxF_ext+=6; - } // pilots==1 - - dl_ch0+=12; - dl_ch1+=12; - rxF+=12; - k+=12; - } - } // for prb - } // for aarx - return(nb_rb/frame_parms->nb_antennas_rx); + return(nb_rb_pdsch); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 6648197153..7ce81de8ce 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -686,11 +686,8 @@ void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms, int32_t **dl_ch_estimates, int32_t **rxdataF_ext, int32_t **dl_ch_estimates_ext, - uint16_t pmi, - uint8_t *pmi_ext, uint32_t *rb_alloc, uint8_t symbol, - uint8_t nr_slot_rx, NR_DL_FRAME_PARMS *frame_parms) \brief This function extracts the received resource blocks, both channel estimates and data symbols, for the current allocation and for single antenna eNB transmission. @@ -698,11 +695,8 @@ void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms, @param dl_ch_estimates Channel estimates of current slot @param rxdataF_ext FFT output for RBs in this allocation @param dl_ch_estimates_ext Channel estimates for RBs in this allocation - @param pmi subband Precoding matrix indicator - @param pmi_ext Extracted PMI for chosen RBs @param rb_alloc RB allocation vector @param symbol Symbol to extract - @param nr_slot_rx Slot number @param high_speed_flag @param frame_parms Pointer to frame descriptor */ @@ -710,55 +704,52 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, int **dl_ch_estimates, int **rxdataF_ext, int **dl_ch_estimates_ext, - unsigned short pmi, - unsigned char *pmi_ext, unsigned char symbol, uint8_t pilots, uint8_t config_type, unsigned short start_rb, - unsigned short nb_pdsch_rb, - unsigned char nr_slot_rx, + unsigned short nb_rb_pdsch, uint32_t high_speed_flag, NR_DL_FRAME_PARMS *frame_parms, uint16_t dlDmrsSymbPos); -/** \fn dlsch_extract_rbs_dual(int32_t **rxdataF, +/** \fn dlsch_extract_rbs_multiple(int32_t **rxdataF, int32_t **dl_ch_estimates, int32_t **rxdataF_ext, int32_t **dl_ch_estimates_ext, - uint16_t pmi, - uint8_t *pmi_ext, - uint32_t *rb_alloc, - uint8_t symbol, - NR_DL_FRAME_PARMS *frame_parms) + unsigned char symbol + uint8_t pilots, + uint8_t config_type, + unsigned short start_rb, + unsigned short nb_rb_pdsch, + uint32_t high_speed_flag, + uint8_t Nl, + NR_DL_FRAME_PARMS *frame_parms, + uint16_t dlDmrsSymbPos) \brief This function extracts the received resource blocks, both channel estimates and data symbols, - for the current allocation and for dual antenna eNB transmission. + for the current allocation and for multiple layer antenna gNB transmission. @param rxdataF Raw FFT output of received signal @param dl_ch_estimates Channel estimates of current slot @param rxdataF_ext FFT output for RBs in this allocation @param dl_ch_estimates_ext Channel estimates for RBs in this allocation - @param pmi subband Precoding matrix indicator - @param pmi_ext Extracted PMI for chosen RBs - @param rb_alloc RB allocation vector + @param Nl nb of antenna layers @param symbol Symbol to extract - @param nr_slot_rx Slot index @param high_speed_flag @param frame_parms Pointer to frame descriptor */ -unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF, - int **dl_ch_estimates, - int **rxdataF_ext, - int **dl_ch_estimates_ext, - unsigned short pmi, - unsigned char *pmi_ext, - unsigned char symbol, - uint8_t pilots, - unsigned short start_rb, - unsigned short nb_rb_pdsch, - unsigned char nr_slot_rx, - uint32_t high_speed_flag, - NR_DL_FRAME_PARMS *frame_parms, - MIMO_mode_t mimo_mode); +unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF, + int **dl_ch_estimates, + int **rxdataF_ext, + int **dl_ch_estimates_ext, + unsigned char symbol, + uint8_t pilots, + uint8_t config_type, + unsigned short start_rb, + unsigned short nb_rb_pdsch, + uint32_t high_speed_flag, + uint8_t Nl, + NR_DL_FRAME_PARMS *frame_parms, + uint16_t dlDmrsSymbPos); /** \fn dlsch_extract_rbs_TM7(int32_t **rxdataF, int32_t **dl_bf_ch_estimates, diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 08b219504e..42e4930ed2 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -741,7 +741,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ for (m = s0; m < (s0 +s1); m++) { if (((1<harq_processes[harq_pid]->dlDmrsSymbPos) > 0) { - for (uint8_t aatx=0; aatx<1; aatx++) {//for MIMO Config: it shall loop over no_layers + for (uint8_t aatx=0; aatxharq_processes[harq_pid]->Nl; aatx++) {//for MIMO Config: it shall loop over no_layers nr_pdsch_channel_estimation(ue, proc, 0 /*eNB_id*/, diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index cc8aa298ba..0c3bb35200 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -23,7 +23,7 @@ gNBs = ////////// Physical parameters: ssb_SubcarrierOffset = 0; - pdsch_AntennaPorts = 2; + pdsch_AntennaPorts = 1; servingCellConfigCommon = ( { @@ -240,7 +240,7 @@ L1s = ( RUs = ( { local_rf = "yes" - nb_tx = 2 + nb_tx = 1 nb_rx = 1 att_tx = 0 att_rx = 0; From 0f55139dc6d033f7b228ecee95c0888d778e1498 Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Sun, 24 Jan 2021 04:50:37 +0100 Subject: [PATCH 10/40] Extend nr_dlsch demoulation to support multiple Rx antennas with MRC --- openair1/PHY/INIT/nr_init_ue.c | 8 +- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 786 +++++++++--------- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 13 + openair1/PHY/defs_nr_UE.h | 6 +- 4 files changed, 430 insertions(+), 383 deletions(-) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 1e4cbf1ff8..4641976cf4 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -642,14 +642,9 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, ue->pdsch_vars[th_id][eNB_id]->llr[1] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) ); ue->pdsch_vars[th_id][eNB_id]->layer_llr[1] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) ); ue->pdsch_vars[th_id][eNB_id]->llr128_2ndstream = (int16_t **)malloc16_clear( sizeof(int16_t *) ); - ue->pdsch_vars[th_id][eNB_id]->rho = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); + ue->pdsch_vars[th_id][eNB_id]->rho = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); } - for (int i=0; inb_antennas_rx; i++) { - for (th_id=0; th_idpdsch_vars[th_id][eNB_id]->rho[i] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); - } - } for (th_id=0; th_idpdsch_vars[th_id][eNB_id]->dl_ch_rho2_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); @@ -662,6 +657,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, for (th_id=0; th_idpdsch_vars[th_id][eNB_id]->dl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + ue->pdsch_vars[th_id][eNB_id]->rho[idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 0ec1198fd4..04790ce254 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -145,7 +145,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, PHY_NR_MEASUREMENTS *measurements = &ue->measurements; NR_UE_DLSCH_t **dlsch; - int avg[4]; + int avg[16]; // int avg_0[2]; // int avg_1[2]; @@ -396,6 +396,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, nr_dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, + n_tx, + n_rx, dlsch, symbol, pilots, @@ -416,63 +418,46 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #endif if (first_symbol_flag==1) { if (beamforming_mode==0){ - if (dlsch0_harq->mimo_modedl_ch_estimates_ext, + nr_dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, + n_tx, avg, symbol, len, nb_rb); - avgs = 0; - for (aatx=0;aatxnb_antenna_ports_gNB;aatx++) - for (aarx=0;aarxnb_antennas_rx;aarx++) - avgs = cmax(avgs,avg[(aatx<<1)+aarx]); + avgs = 0; + for (aatx=0;aatxnb_antennas_rx+aarx]); + avgs = cmax(avgs,avg[(aatx*frame_parms->nb_antennas_rx)+aarx]); + //LOG_I(PHY, "avgs Power per SC is %d\n", avgs); + median[(aatx*frame_parms->nb_antennas_rx)+aarx] = avg[(aatx*frame_parms->nb_antennas_rx)+aarx]; + } + pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2)+3; + //LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, pdsch_vars[eNB_id]->log2_maxh); - pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2)+3; - } - else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) - { - nr_dlsch_channel_level_median(pdsch_vars[eNB_id]->dl_ch_estimates_ext, - median, - n_tx, - n_rx, - 2*len,// subcarriers Re Im - 0); + if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { + nr_dlsch_channel_level_median(pdsch_vars[eNB_id]->dl_ch_estimates_ext, + median, + n_tx, + n_rx, + len, + symbol*nb_rb*12); - for (aatx = 0; aatx < n_tx; ++aatx) - { - for (aarx = 0; aarx < n_rx; ++aarx) - { - avgs = cmax(avgs, median[aatx*n_rx + aarx]); - } - } - - pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1; // this might need to be tuned - - } + for (aatx = 0; aatx < n_tx; aatx++) { + for (aarx = 0; aarx < n_rx; aarx++) { + avgs = cmax(avgs, median[aatx*n_rx + aarx]); + } + } + pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;} } - //#ifdef UE_DEBUG_TRACE LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n", - frame%1024,nr_slot_rx, pdsch_vars[eNB_id]->log2_maxh, - pdsch_vars[eNB_id]->log2_maxh0, - pdsch_vars[eNB_id]->log2_maxh1, - avg[0],avgs); - //LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode); - //#endif - - //wait until pdcch is decoded - //proc->channel_level = 1; + frame%1024,nr_slot_rx, pdsch_vars[eNB_id]->log2_maxh, + pdsch_vars[eNB_id]->log2_maxh0, + pdsch_vars[eNB_id]->log2_maxh1, + avg[0],avgs); } - /* - uint32_t wait = 0; - while(proc->channel_level == 0) - { - usleep(1); - wait++; - } - */ - #if T_TRACER if (type == PDSCH) { @@ -504,6 +489,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->rxdataF_comp0, (aatx>1) ? pdsch_vars[eNB_id]->rho : NULL, frame_parms, + n_tx, symbol, pilots, first_symbol_flag, @@ -514,48 +500,17 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, /*if (symbol == 5) { write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); } */ - - /*if ((rx_type==rx_IC_single_stream) && - (eNB_id_in_connected_eNB)) { - nr_dlsch_channel_compensation(pdsch_vars[eNB_id_i]->rxdataF_ext, - pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, - pdsch_vars[eNB_id_i]->dl_ch_mag0, - pdsch_vars[eNB_id_i]->dl_ch_magb0, - pdsch_vars[eNB_id_i]->rxdataF_comp0, - (aatx>1) ? pdsch_vars[eNB_id_i]->rho : NULL, - frame_parms, - symbol, - first_symbol_flag, - i_mod, - nb_rb, - pdsch_vars[eNB_id]->log2_maxh, - measurements); // log2_maxh+I0_shift -#ifdef DEBUG_PHY - if (symbol == 5) { - write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); - write_output("rxF_comp_i.m","rxF_c_i",&pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); - } -#endif - - dlsch_dual_stream_correlation(frame_parms, - symbol, - nb_rb, - pdsch_vars[eNB_id]->dl_ch_estimates_ext, - pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[eNB_id]->log2_maxh); - }*/ } else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM){ nr_dlsch_channel_compensation_core(pdsch_vars[eNB_id]->rxdataF_ext, - pdsch_vars[eNB_id]->dl_ch_estimates_ext, - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_magb0, - pdsch_vars[eNB_id]->rxdataF_comp0, //rxdataF_comp - NULL, - n_tx, - n_rx, + pdsch_vars[eNB_id]->dl_ch_estimates_ext, + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_magb0, + pdsch_vars[eNB_id]->rxdataF_comp0, //rxdataF_comp + NULL, + n_tx, + n_rx, dlsch0_harq->Qm, pdsch_vars[eNB_id]->log2_maxh, 2*len, // subcarriers Re Im @@ -592,8 +547,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, write_output("rho0_1.m.m","rho0_1",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 write_output("rho2_1.m","rho2_1",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM } */ - - } + } #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); @@ -608,9 +562,18 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #endif - if (frame_parms->nb_antennas_rx > 1) { - if (dlsch0_harq->mimo_mode == NR_DUALSTREAM){ - nr_dlsch_detection_mrc_core(pdsch_vars[eNB_id]->rxdataF_comp0, + if (frame_parms->nb_antennas_rx > 1) { + if (dlsch0_harq->mimo_moderxdataF_comp0, + (n_tx>1) ? pdsch_vars[eNB_id]->rho : NULL, + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_magb0, + n_tx, + n_rx, + symbol, + nb_rb); + } else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM){ + nr_dlsch_detection_mrc_core(pdsch_vars[eNB_id]->rxdataF_comp0, NULL, pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], pdsch_vars[eNB_id]->dl_ch_rho2_ext, @@ -628,7 +591,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, } */ } } - //printf("start compute LLR\n"); if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { rxdataF_comp_ptr = pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round]; @@ -819,8 +781,9 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, int **rxdataF_comp, int **rho, NR_DL_FRAME_PARMS *frame_parms, + uint8_t nb_aatx, unsigned char symbol, - uint8_t pilots, + uint8_t pilots, uint8_t first_symbol_flag, unsigned char mod_order, unsigned short nb_rb, @@ -830,266 +793,286 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, #if defined(__i386) || defined(__x86_64) - unsigned short rb; - unsigned char aatx,aarx; - __m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*dl_ch_mag128r,*rxdataF128,*rxdataF_comp128,*rho128; - __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b,QAM_amp128r; - QAM_amp128b = _mm_setzero_si128(); + unsigned short rb; + unsigned char aatx,aarx; + __m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128,*rho128; + __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b; + QAM_amp128b = _mm_setzero_si128(); - for (aatx=0; aatxnb_antenna_ports_gNB; aatx++) { - if (mod_order == 4) { - QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10) - QAM_amp128b = _mm_setzero_si128(); - QAM_amp128r = _mm_setzero_si128(); - } else if (mod_order == 6) { - QAM_amp128 = _mm_set1_epi16(QAM64_n1); // - QAM_amp128b = _mm_set1_epi16(QAM64_n2); - QAM_amp128r = _mm_setzero_si128(); - } else if (mod_order == 8) { - QAM_amp128 = _mm_set1_epi16(QAM256_n1); - QAM_amp128b = _mm_set1_epi16(QAM256_n2); - QAM_amp128r = _mm_set1_epi16(QAM256_n3); - } + for (aatx=0; aatxnb_antennas_rx; aarx++) { + for (aarx=0; aarxnb_antennas_rx; aarx++) { - dl_ch128 = (__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12]; - dl_ch_mag128 = (__m128i *)&dl_ch_mag[(aatx<<1)+aarx][symbol*nb_rb*12]; - dl_ch_mag128b = (__m128i *)&dl_ch_magb[(aatx<<1)+aarx][symbol*nb_rb*12]; - dl_ch_mag128r = (__m128i *)&dl_ch_magr[(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]; + dl_ch128 = (__m128i *)&dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; + dl_ch_mag128 = (__m128i *)&dl_ch_mag[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; + dl_ch_mag128b = (__m128i *)&dl_ch_magb[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; + rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*nb_rb*12]; + rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; - for (rb=0; rb2) { - // get channel amplitude if not QPSK + for (rb=0; rb2) { + // get channel amplitude if not QPSK - mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128[0]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128[0]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); + mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); - // store channel magnitude here in a new field of dlsch + // store channel magnitude here in a new field of dlsch - dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag128b[0] = dl_ch_mag128[0]; - dl_ch_mag128r[0] = dl_ch_mag128[0]; - dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); - dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); - //print_ints("Re(ch):",(int16_t*)&mmtmpD0); - //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128); - //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]); - dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag128b[1] = dl_ch_mag128[1]; - dl_ch_mag128r[1] = dl_ch_mag128[1]; - dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); - dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1); + dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128b[0] = dl_ch_mag128[0]; + dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); + dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); + //print_ints("Re(ch):",(int16_t*)&mmtmpD0); + //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128); + //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]); + dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128b[1] = dl_ch_mag128[1]; + dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); + dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1); - if (pilots==0) { - mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); + if (pilots==0) { + mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); - dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); - dl_ch_mag128b[2] = dl_ch_mag128[2]; - dl_ch_mag128r[2] = dl_ch_mag128[2]; + dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); + dl_ch_mag128b[2] = dl_ch_mag128[2]; - dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128); - dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1); - } + dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128); + dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1); + } - dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); - dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); + dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); + dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); - dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); - dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); + dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); + dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); - dl_ch_mag128r[0] = _mm_mulhi_epi16(dl_ch_mag128r[0],QAM_amp128r); - dl_ch_mag128r[0] = _mm_slli_epi16(dl_ch_mag128r[0],1); + if (pilots==0) { + dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b); + dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); + } + } - dl_ch_mag128r[1] = _mm_mulhi_epi16(dl_ch_mag128r[1],QAM_amp128r); - dl_ch_mag128r[1] = _mm_slli_epi16(dl_ch_mag128r[1],1); + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); + // print_ints("re",&mmtmpD0); - if (pilots==0) { - dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b); - dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_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); - dl_ch_mag128r[2] = _mm_mulhi_epi16(dl_ch_mag128r[2],QAM_amp128r); - dl_ch_mag128r[2] = _mm_slli_epi16(dl_ch_mag128r[2],1); - } - } + /*if (rb==0) { + printf("arx%d atx%d rb_index %d SC 0 symbol%d\n",aarx,aatx,rb,symbol);// + printf("rx_F_re: %d rx_F_im: %d \n",((int16_t*)&rxdataF128[0])[0],((int16_t*)&rxdataF128[0])[1]); + printf("ch_re = %d ch_im = %d \n",((int16_t*)&dl_ch128[0])[0],((int16_t*)&dl_ch128[0])[1]);// + printf("rx_Fcomp_re: %d rx_Fcomp_im: %d \n",((int16_t*)&rxdataF_comp128[0])[0],((int16_t*)&rxdataF_comp128[0])[1]); + }*/ + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_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); - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); - // print_ints("re",&mmtmpD0); + rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+1); + // print_shorts("ch:",dl_ch128+1); + // print_shorts("pack:",rxdataF_comp128+1); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_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:",dl_ch128); - // print_shorts("pack:",rxdataF_comp128); + if (pilots==0) { + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_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); - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_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[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+2); + // print_shorts("ch:",dl_ch128+2); + // print_shorts("pack:",rxdataF_comp128+2); - rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch128+1); - // print_shorts("pack:",rxdataF_comp128+1); + dl_ch128+=3; + dl_ch_mag128+=3; + dl_ch_mag128b+=3; + rxdataF128+=3; + rxdataF_comp128+=3; + } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less + dl_ch128+=2; + dl_ch_mag128+=2; + dl_ch_mag128b+=2; + rxdataF128+=2; + rxdataF_comp128+=2; + } + } + } + } - if (pilots==0) { - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_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); + if (rho) { + //rho[aatx*n_rx+0] = Cov(H_0,0,H*_0,aatx), aatx=0,...n_tx-1 + //rho[aatx*n_rx+1] = Cov(H_1,1,H*_1,aatx), aatx=0,...n_tx-1 + //rho[aatx*n_rx+aarx] = Cov(H_aarx,arrx,H*_aarx,aatx), aatx=0,...n_tx-1 - rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch128+2); - // print_shorts("pack:",rxdataF_comp128+2); + int avg_rho_re[nb_aatx][frame_parms->nb_antennas_rx]; + int avg_rho_im[nb_aatx][frame_parms->nb_antennas_rx]; + for (aarx=0; aarxnb_antennas_rx; aarx++) { - dl_ch128+=3; - dl_ch_mag128+=3; - dl_ch_mag128b+=3; - dl_ch_mag128r+=3; - rxdataF128+=3; - rxdataF_comp128+=3; - } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less - dl_ch128+=2; - dl_ch_mag128+=2; - dl_ch_mag128b+=2; - dl_ch_mag128r+=2; - rxdataF128+=2; - rxdataF_comp128+=2; - } + dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*nb_rb*12];//H_{aarx,0} - } - } - } + for (aatx=1; aatxnb_antennas_rx+aarx][symbol*nb_rb*12];//(aatx*frame_parms->nb_antennas_rx)+ + dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_rb*12]; + for (rb=0; rbnb_antennas_rx; aarx++) { - rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_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,dl_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); - for (rb=0; rbrx_correlation[0][0][aarx] = signal_energy(&rho[aarx][symbol*nb_rb*12],rb*12); + avg_rho_re[aatx][aarx] = 16*avg_rho_re[aatx][aarx]/(nb_rb*12); + avg_rho_im[aatx][aarx] = 16*avg_rho_im[aatx][aarx]/(nb_rb*12); - } + printf("rho_rx%d tx%d= Re: %d Im: %d\n",aarx, aatx, avg_rho_re[aatx][aarx], avg_rho_im[aatx][aarx]); + } + } + } + } - if (first_symbol_flag==1) { - measurements->rx_correlation[0][aarx] = signal_energy(&rho[aarx][symbol*nb_rb*12],rb*12); - } - } - } - - _mm_empty(); - _m_empty(); + _mm_empty(); + _m_empty(); #elif defined(__arm__) @@ -1499,6 +1482,8 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext, void nr_dlsch_scale_channel(int **dl_ch_estimates_ext, NR_DL_FRAME_PARMS *frame_parms, + uint8_t n_tx, + uint8_t n_rx, NR_UE_DLSCH_t **dlsch_ue, uint8_t symbol, uint8_t pilots, @@ -1523,10 +1508,10 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext, ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13 - for (aatx=0; aatxnb_antenna_ports_gNB; aatx++) { - for (aarx=0; aarxnb_antennas_rx; aarx++) { + for (aatx=0; aatx4) ? 4 : x; - int16_t y = (len)>>x; - //printf("len = %d = %d * 2^(%d)\n",len,y,x); + //nb_rb*nre = y * 2^x + int16_t x = factor2(len); + //x = (x>4) ? 4 : x; + int16_t y = (len)>>x; + //printf("len = %d = %d * 2^(%d)\n",len,y,x); - AssertFatal(y!=0,"Cannot divide by zero: in function %s of file %s\n", __func__, __FILE__); + AssertFatal(y!=0,"Cannot divide by zero: in function %s of file %s\n", __func__, __FILE__); - for (aatx=0; aatxnb_antenna_ports_gNB; aatx++) - for (aarx=0; aarxnb_antennas_rx; aarx++) { - //clear average level - avg128D = _mm_setzero_si128(); - // 5 is always a symbol with no pilots for both normal and extended prefix + for (aatx=0; aatxnb_antennas_rx; aarx++) { + //clear average level + avg128D = _mm_setzero_si128(); - dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12]; + dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; - for (rb=0;rbnb_antennas_rx)+aarx] =(((int32_t*)&avg128D)[0] + + ((int32_t*)&avg128D)[1] + + ((int32_t*)&avg128D)[2] + + ((int32_t*)&avg128D)[3])/y; + // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); + } - _mm_empty(); - _m_empty(); + _mm_empty(); + _m_empty(); #elif defined(__arm__) @@ -1671,48 +1656,48 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext, #if defined(__x86_64__)||defined(__i386__) - short ii; - int aatx,aarx; - int length2; - int max = 0, min=0; - int norm_pack; - __m128i *dl_ch128, norm128D; + short ii; + int aatx,aarx; + int length2; + int max = 0, min=0; + int norm_pack; + __m128i *dl_ch128, norm128D; - for (aatx=0; aatx>2; + length2 = length>>2;//length = number of REs, hence length2=nb_REs*(32/128) in SIMD loop - for (ii=0;ii max) - max = norm_pack; - if (norm_pack < min) - min = norm_pack; + if (norm_pack > max) + max = norm_pack;//store values more than max + if (norm_pack < min) + min = norm_pack;//store values less than min - dl_ch128+=1; - } + dl_ch128+=1; + } - median[aatx*n_rx + aarx] = (max+min)>>1; + median[aatx*n_rx + aarx] = (max+min)>>1; - // printf("Channel level median [%d]: %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx]); - } - } + //printf("Channel level median [%d]: %d max = %d min = %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx],max,min); + } + } - _mm_empty(); - _m_empty(); + _mm_empty(); + _m_empty(); #elif defined(__arm__) @@ -2235,6 +2220,59 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF, return(nb_rb_pdsch); } +void nr_dlsch_detection_mrc(int **rxdataF_comp, + int **rho, + int **dl_ch_mag, + int **dl_ch_magb, + short n_tx, + short n_rx, + unsigned char symbol, + unsigned short nb_rb) { +#if defined(__x86_64__)||defined(__i386__) + unsigned char aatx, aarx; + int i; + __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b; + + if (n_rx>1) { + for (aatx=0; aatxN_RB_DL*12]; + rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12]; + for (i=0; i Date: Sun, 24 Jan 2021 05:08:43 +0100 Subject: [PATCH 11/40] MIMO 4x4 with 1 layer test commit --- openair1/PHY/INIT/nr_parms.c | 2 +- openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 4 ++-- .../CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 814177a86c..7fa39b1f9c 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -335,7 +335,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, int Ncp = NORMAL; if(fp->nb_antennas_rx == 0) - fp->nb_antennas_rx = 1; + fp->nb_antennas_rx = 4; if(fp->nb_antennas_tx == 0) fp->nb_antennas_tx = 1; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 1a3493cdb1..b6cdac3f47 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -414,10 +414,10 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, ///Layer Precoding and Antenna port mapping // tx_layers 1-8 are mapped on antenna ports 1000-1007 - uint8_t pmi = 2; + uint8_t pmi = 6; for (int ap=0; apnb_antennas_tx; ap++) { - char *W_prec = nr_W_1l_2p[pmi][ap];//nr_W_1l_4p, nr_W_2l_2p, nr_W_2l_4p, nr_W_3l_4p, and nr_W_4l_4p + char *W_prec = nr_W_1l_4p[pmi][ap];//nr_W_1l_4p, nr_W_2l_2p, nr_W_2l_4p, nr_W_3l_4p, and nr_W_4l_4p for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { uint16_t k = start_sc; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 0c3bb35200..f83b082211 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -23,7 +23,7 @@ gNBs = ////////// Physical parameters: ssb_SubcarrierOffset = 0; - pdsch_AntennaPorts = 1; + pdsch_AntennaPorts = 4; servingCellConfigCommon = ( { @@ -240,7 +240,7 @@ L1s = ( RUs = ( { local_rf = "yes" - nb_tx = 1 + nb_tx = 4 nb_rx = 1 att_tx = 0 att_rx = 0; @@ -253,9 +253,9 @@ RUs = ( ##beamforming 1x4 matrix: 1 layer x 4 antennas #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000]; ## beamforming 2x2 matrix: - bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; + # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; ## beamforming 4x4 matrix: - #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; clock_src = "external"; From 53046a928985af10542da6088544ab043fcaf105 Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Tue, 26 Jan 2021 11:28:03 +0100 Subject: [PATCH 12/40] add zero forcing receiver for 2 tx layers and 2 or 4 rx antennas for PDSCH --- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 665 +++++++++++++++++- 1 file changed, 655 insertions(+), 10 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 04790ce254..df82f1299a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -84,8 +84,8 @@ unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{ */ //unsigned char offset_mumimo_llr_drange[29][3]= {{0, 6, 5},{0, 4, 5},{0, 4, 5},{0, 5, 4},{0, 5, 6},{0, 5, 3},{0, 4, 4},{0, 4, 4},{0, 3, 3},{0, 1, 2},{1, 1, 0},{1, 3, 2},{3, 4, 1},{2, 0, 0},{2, 2, 2},{1, 1, 1},{2, 1, 0},{2, 1, 1},{1, 0, 1},{1, 0, 1},{0, 0, 0},{1, 0, 0},{0, 0, 0},{0, 1, 0},{1, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}}; - -extern void print_shorts(char *s,int16_t *x); +#define print_ints(s,x) printf("%s %d %d %d %d\n",s,(x)[0],(x)[1],(x)[2],(x)[3]) +#define print_shorts(s,x) printf("%s %d,%d,%d,%d,%d,%d,%d,%d\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7]) static void nr_dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext, int **dl_ch_estimates_ext_i, @@ -96,6 +96,16 @@ static void nr_dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext, int length, int start_point); +uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp, + int **dl_ch_mag, + int **dl_ch_magb, + int **dl_ch_estimates_ext, + unsigned short nb_rb, + unsigned char n_rx, + unsigned char mod_order, + int shift, + unsigned char symbol); + static void nr_dlsch_layer_demapping(int16_t **llr_cw, uint8_t Nl, uint8_t mod_order, @@ -487,7 +497,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_magb0, pdsch_vars[eNB_id]->dl_ch_magr0, pdsch_vars[eNB_id]->rxdataF_comp0, - (aatx>1) ? pdsch_vars[eNB_id]->rho : NULL, + (n_tx>1) ? pdsch_vars[eNB_id]->rho : NULL, frame_parms, n_tx, symbol, @@ -565,13 +575,25 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, if (frame_parms->nb_antennas_rx > 1) { if (dlsch0_harq->mimo_moderxdataF_comp0, - (n_tx>1) ? pdsch_vars[eNB_id]->rho : NULL, - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_magb0, - n_tx, - n_rx, - symbol, - nb_rb); + (n_tx>1)? pdsch_vars[eNB_id]->rho : NULL, + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_magb0, + n_tx, + n_rx, + symbol, + nb_rb); + + if (n_tx == 2) + nr_zero_forcing_rx_2layers(pdsch_vars[eNB_id]->rxdataF_comp0, + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_magb0, + pdsch_vars[eNB_id]->dl_ch_estimates_ext, + nb_rb, + n_rx, + dlsch0_harq->Qm, + pdsch_vars[eNB_id]->log2_maxh, + symbol); + } else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM){ nr_dlsch_detection_mrc_core(pdsch_vars[eNB_id]->rxdataF_comp0, NULL, @@ -2274,6 +2296,629 @@ void nr_dlsch_detection_mrc(int **rxdataF_comp, #endif } +/* Zero Forcing Rx function: nr_det_HhH() + * + * + * */ +void nr_det_HhH(int32_t *after_mf_00,//a + int32_t *after_mf_01,//b + int32_t *after_mf_10,//c + int32_t *after_mf_11,//d + int32_t *det_fin,//1/ad-bc + unsigned short nb_rb, + unsigned char symbol) +{ + int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ; + unsigned short rb; + __m128i *after_mf_00_128,*after_mf_01_128, *after_mf_10_128, *after_mf_11_128, ad_re_128, bc_re_128; //ad_im_128, bc_im_128; + __m128i *det_fin_128, det_re_128; //det_im_128, tmp_det0, tmp_det1; + + after_mf_00_128 = (__m128i *)after_mf_00; + after_mf_01_128 = (__m128i *)after_mf_01; + after_mf_10_128 = (__m128i *)after_mf_10; + after_mf_11_128 = (__m128i *)after_mf_11; + + det_fin_128 = (__m128i *)det_fin; + + for (rb=0; rb<3*nb_rb; rb++) { + + // complex multiplication (I_a+jQ_a)(I_d+jQ_d) = (I_aI_d - Q_aQ_d) + j(Q_aI_d + I_aQ_d) + // The imag part is often zero, we compute only the real part + ad_re_128 = _mm_sign_epi16(after_mf_00_128[0],*(__m128i*)&nr_conjug2[0]); + ad_re_128 = _mm_madd_epi16(ad_re_128,after_mf_11_128[0]); //Re: I_a0*I_d0 - Q_a1*Q_d1 + //ad_im_128 = _mm_shufflelo_epi16(after_mf_00_128[0],_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits + //ad_im_128 = _mm_shufflehi_epi16(ad_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits + //ad_im_128 = _mm_madd_epi16(ad_im_128,after_mf_11_128[0]);//Im: (Q_aI_d + I_aQ_d) + + // complex multiplication (I_b+jQ_b)(I_c+jQ_c) = (I_bI_c - Q_bQ_c) + j(Q_bI_c + I_bQ_c) + // The imag part is often zero, we compute only the real part + bc_re_128 = _mm_sign_epi16(after_mf_01_128[0],*(__m128i*)&nr_conjug2[0]); + bc_re_128 = _mm_madd_epi16(bc_re_128,after_mf_10_128[0]); //Re: I_b0*I_c0 - Q_b1*Q_c1 + //bc_im_128 = _mm_shufflelo_epi16(after_mf_01_128[0],_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_b0 Q_b1 I_b2 Q_b3]_64bits to [Q_b1 I_b0 Q_b3 I_b2]_64bits + //bc_im_128 = _mm_shufflehi_epi16(bc_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_b0 Q_b1 I_b2 Q_b3]_64bits to [Q_b1 I_b0 Q_b3 I_b2]_64bits + //bc_im_128 = _mm_madd_epi16(bc_im_128,after_mf_10_128[0]);//Im: (Q_bI_c + I_bQ_c) + + det_re_128 = _mm_sub_epi32(ad_re_128, bc_re_128); + //det_im_128 = _mm_sub_epi32(ad_im_128, bc_im_128); + + //convert back to Q15 before packing + det_re_128 = _mm_srai_epi32(det_re_128,8);//(2^15/64*2) + //det_im_128 = _mm_srai_epi32(det_im_128,8); + + //tmp_det0 = _mm_unpacklo_epi32(det_re_128,det_im_128); + ////print_ints("unpack lo:",&tmp_det0[rb]); + //tmp_det1 = _mm_unpackhi_epi32(det_re_128,det_im_128); + ////print_ints("unpack hi:",&tmp_det1[rb]); + //det_matrix_128[0] = _mm_packs_epi32(tmp_det0,tmp_det1); + det_fin_128[0] = _mm_abs_epi32(det_re_128); + + if ((rb==0)&&(symbol==1)) { + printf("\n Computing det_HhH_inv \n"); + print_ints("det_re_128:",(int32_t*)&det_re_128); + //print_ints("det_im_128:",(int32_t*)&det_im_128); + print_ints("det_fin_128:",(int32_t*)&det_fin_128[0]); + } + + det_fin_128+=1; + after_mf_00_128+=1; + after_mf_01_128+=1; + after_mf_10_128+=1; + after_mf_11_128+=1; + } + _mm_empty(); + _m_empty(); +} + + +/* Zero Forcing Rx function: nr_inv_comp_muli + * Complex number multi: z = x*y + * = (x_re*y_re - x_im*y_im) + j(x_im*y_re + x_re*y_im) + * */ +__m128i nr_inv_comp_muli(__m128i input_x, + __m128i input_y) +{ + int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ; + + __m128i xy_re_128, xy_im_128; + __m128i output_z, tmp_z0, tmp_z1; + + // complex multiplication (x_re + jx_im)*(y_re + jy_im) = (x_re*y_re - x_im*y_im) + j(x_im*y_re + x_re*y_im) + + // the real part + xy_re_128 = _mm_sign_epi16(input_x,*(__m128i*)&nr_conjug2[0]); + xy_re_128 = _mm_madd_epi16(xy_re_128,input_y); //Re: (x_re*y_re - x_im*y_im) + + // the imag part + xy_im_128 = _mm_shufflelo_epi16(input_x,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits + xy_im_128 = _mm_shufflehi_epi16(xy_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits + xy_im_128 = _mm_madd_epi16(xy_im_128,input_y);//Im: (x_im*y_re + x_re*y_im) + + //convert back to Q15 before packing + + xy_re_128 = _mm_srai_epi32(xy_re_128,4);//(2^15/64*2*16) + xy_im_128 = _mm_srai_epi32(xy_im_128,4); + + tmp_z0 = _mm_unpacklo_epi32(xy_re_128,xy_im_128); + //print_ints("unpack lo:",&tmp_z0[0]); + tmp_z1 = _mm_unpackhi_epi32(xy_re_128,xy_im_128); + //print_ints("unpack hi:",&tmp_z1[0]); + output_z = _mm_packs_epi32(tmp_z0,tmp_z1); + _mm_empty(); + _m_empty(); + return(output_z); +} + +/* Zero Forcing Rx function: nr_conjch0_mult_ch1() + * + * + * */ +void nr_conjch0_mult_ch1(int *ch0, + int *ch1, + int32_t *ch0conj_ch1, + unsigned short nb_rb, + unsigned char output_shift0) +{ + //This function is used to compute multiplications in H_hermitian * H matrix + short nr_conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1}; + unsigned short rb; + __m128i *dl_ch0_128,*dl_ch1_128, *ch0conj_ch1_128, mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; + + dl_ch0_128 = (__m128i *)ch0; + dl_ch1_128 = (__m128i *)ch1; + + ch0conj_ch1_128 = (__m128i *)ch0conj_ch1; + + for (rb=0; rb<3*nb_rb; rb++) { + + mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]); + mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[0],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&nr_conjugate[0]); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch1_128[0]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + + ch0conj_ch1_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + + /*printf("\n Computing conjugates \n"); + print_shorts("ch0:",(int16_t*)&dl_ch0_128[0]); + print_shorts("ch1:",(int16_t*)&dl_ch1_128[0]); + print_shorts("pack:",(int16_t*)&ch0conj_ch1_128[0]);*/ + + dl_ch0_128+=1; + dl_ch1_128+=1; + ch0conj_ch1_128+=1; + } + _mm_empty(); + _m_empty(); +} + +/* Zero Forcing Rx function: nr_construct_HhH_elements() + * + * + * */ +void nr_construct_HhH_elements(int *conjch00_ch00, + int *conjch01_ch01, + int *conjch11_ch11, + int *conjch10_ch10,// + int *conjch20_ch20, + int *conjch21_ch21, + int *conjch30_ch30, + int *conjch31_ch31, + int *conjch00_ch01,//00_01 + int *conjch01_ch00,//01_00 + int *conjch10_ch11,//10_11 + int *conjch11_ch10,//11_10 + int *conjch20_ch21, + int *conjch21_ch20, + int *conjch30_ch31, + int *conjch31_ch30, + int32_t *after_mf_00, + int32_t *after_mf_01, + int32_t *after_mf_10, + int32_t *after_mf_11, + unsigned short nb_rb, + unsigned char symbol) +{ + //This function is used to construct the (H_hermitian * H matrix) matrix elements + unsigned short rb; + __m128i *conjch00_ch00_128, *conjch01_ch01_128, *conjch11_ch11_128, *conjch10_ch10_128; + __m128i *conjch20_ch20_128, *conjch21_ch21_128, *conjch30_ch30_128, *conjch31_ch31_128; + __m128i *conjch00_ch01_128, *conjch01_ch00_128, *conjch10_ch11_128, *conjch11_ch10_128; + __m128i *conjch20_ch21_128, *conjch21_ch20_128, *conjch30_ch31_128, *conjch31_ch30_128; + __m128i *after_mf_00_128, *after_mf_01_128, *after_mf_10_128, *after_mf_11_128; + + conjch00_ch00_128 = (__m128i *)conjch00_ch00; + conjch01_ch01_128 = (__m128i *)conjch01_ch01; + conjch11_ch11_128 = (__m128i *)conjch11_ch11; + conjch10_ch10_128 = (__m128i *)conjch10_ch10; + + conjch20_ch20_128 = (__m128i *)conjch20_ch20; + conjch21_ch21_128 = (__m128i *)conjch21_ch21; + conjch30_ch30_128 = (__m128i *)conjch30_ch30; + conjch31_ch31_128 = (__m128i *)conjch31_ch31; + + conjch00_ch01_128 = (__m128i *)conjch00_ch01; + conjch01_ch00_128 = (__m128i *)conjch01_ch00; + conjch10_ch11_128 = (__m128i *)conjch10_ch11; + conjch11_ch10_128 = (__m128i *)conjch11_ch10; + + conjch20_ch21_128 = (__m128i *)conjch20_ch21; + conjch21_ch20_128 = (__m128i *)conjch21_ch20; + conjch30_ch31_128 = (__m128i *)conjch30_ch31; + conjch31_ch30_128 = (__m128i *)conjch31_ch30; + + after_mf_00_128 = (__m128i *)after_mf_00; + after_mf_01_128 = (__m128i *)after_mf_01; + after_mf_10_128 = (__m128i *)after_mf_10; + after_mf_11_128 = (__m128i *)after_mf_11; + + for (rb=0; rb<3*nb_rb; rb++) { + + after_mf_00_128[0] =_mm_adds_epi16(conjch00_ch00_128[0],conjch10_ch10_128[0]);//00_00 + 10_10 + if (conjch20_ch20 != NULL) after_mf_00_128[0] =_mm_adds_epi16(after_mf_00_128[0],conjch20_ch20_128[0]); + if (conjch30_ch30 != NULL) after_mf_00_128[0] =_mm_adds_epi16(after_mf_00_128[0],conjch30_ch30_128[0]); + + after_mf_11_128[0] =_mm_adds_epi16(conjch01_ch01_128[0], conjch11_ch11_128[0]); //01_01 + 11_11 + if (conjch21_ch21 != NULL) after_mf_11_128[0] =_mm_adds_epi16(after_mf_11_128[0],conjch21_ch21_128[0]); + if (conjch31_ch31 != NULL) after_mf_11_128[0] =_mm_adds_epi16(after_mf_11_128[0],conjch31_ch31_128[0]); + + after_mf_01_128[0] =_mm_adds_epi16(conjch00_ch01_128[0], conjch10_ch11_128[0]);//00_01 + 10_11 + if (conjch20_ch21 != NULL) after_mf_01_128[0] =_mm_adds_epi16(after_mf_01_128[0],conjch20_ch21_128[0]); + if (conjch30_ch31 != NULL) after_mf_01_128[0] =_mm_adds_epi16(after_mf_01_128[0],conjch30_ch31_128[0]); + + after_mf_10_128[0] =_mm_adds_epi16(conjch01_ch00_128[0], conjch11_ch10_128[0]);//01_00 + 11_10 + if (conjch21_ch20 != NULL) after_mf_10_128[0] =_mm_adds_epi16(after_mf_10_128[0],conjch21_ch20_128[0]); + if (conjch31_ch30 != NULL) after_mf_10_128[0] =_mm_adds_epi16(after_mf_10_128[0],conjch31_ch30_128[0]); + + if ((rb==0)&&(symbol==1)) + { + printf(" \n construct_HhH_elements \n"); + print_shorts("after_mf_00_128:",(int16_t*)&after_mf_00_128[0]); + print_shorts("after_mf_01_128:",(int16_t*)&after_mf_01_128[0]); + print_shorts("after_mf_10_128:",(int16_t*)&after_mf_10_128[0]); + print_shorts("after_mf_11_128:",(int16_t*)&after_mf_11_128[0]); + } + + conjch00_ch00_128+=1; + conjch10_ch10_128+=1; + conjch01_ch01_128+=1; + conjch11_ch11_128+=1; + + if (conjch20_ch20 != NULL) conjch20_ch20_128+=1; + if (conjch21_ch21 != NULL) conjch21_ch21_128+=1; + if (conjch30_ch30 != NULL) conjch30_ch30_128+=1; + if (conjch31_ch31 != NULL) conjch31_ch31_128+=1; + + conjch00_ch01_128+=1; + conjch01_ch00_128+=1; + conjch10_ch11_128+=1; + conjch11_ch10_128+=1; + + if (conjch20_ch21 != NULL) conjch20_ch21_128+=1; + if (conjch21_ch20 != NULL) conjch21_ch20_128+=1; + if (conjch30_ch31 != NULL) conjch30_ch31_128+=1; + if (conjch31_ch30 != NULL) conjch31_ch30_128+=1; + + after_mf_00_128 += 1; + after_mf_01_128 += 1; + after_mf_10_128 += 1; + after_mf_11_128 += 1; + } + _mm_empty(); + _m_empty(); +} + +/* Zero Forcing Rx function: nr_zero_forcing_rx_2layers() + * + * + * */ +uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp, + int **dl_ch_mag, + int **dl_ch_magb, + int **dl_ch_estimates_ext, + unsigned short nb_rb, + unsigned char n_rx, + unsigned char mod_order, + int shift, + unsigned char symbol) +{ + int *ch00, *ch01, *ch10, *ch11; + int *ch20, *ch30, *ch21, *ch31; + + /* we need at least alignment to 16 bytes, let's put 32 to be sure + * (maybe not necessary but doesn't hurt) + */ + int32_t conjch00_ch01[12*nb_rb] __attribute__((aligned(32))); + int32_t conjch01_ch00[12*nb_rb] __attribute__((aligned(32))); + int32_t conjch10_ch11[12*nb_rb] __attribute__((aligned(32))); + int32_t conjch11_ch10[12*nb_rb] __attribute__((aligned(32))); + int32_t conjch00_ch00[12*nb_rb] __attribute__((aligned(32))); + int32_t conjch01_ch01[12*nb_rb] __attribute__((aligned(32))); + int32_t conjch10_ch10[12*nb_rb] __attribute__((aligned(32))); + int32_t conjch11_ch11[12*nb_rb] __attribute__((aligned(32))); + int32_t conjch20_ch20[12*nb_rb] __attribute__((aligned(32))); + int32_t conjch21_ch21[12*nb_rb] __attribute__((aligned(32))); + int32_t conjch30_ch30[12*nb_rb] __attribute__((aligned(32))); + int32_t conjch31_ch31[12*nb_rb] __attribute__((aligned(32))); + int32_t conjch20_ch21[12*nb_rb] __attribute__((aligned(32))); + int32_t conjch30_ch31[12*nb_rb] __attribute__((aligned(32))); + int32_t conjch21_ch20[12*nb_rb] __attribute__((aligned(32))); + int32_t conjch31_ch30[12*nb_rb] __attribute__((aligned(32))); + + int32_t af_mf_00[12*nb_rb] __attribute__((aligned(32))); + int32_t af_mf_01[12*nb_rb] __attribute__((aligned(32))); + int32_t af_mf_10[12*nb_rb] __attribute__((aligned(32))); + int32_t af_mf_11[12*nb_rb] __attribute__((aligned(32))); + int32_t determ_fin[12*nb_rb] __attribute__((aligned(32))); + + switch (n_rx) { + case 2:// + ch00 = (int *)&dl_ch_estimates_ext[0][symbol*nb_rb*12]; + ch01 = (int *)&dl_ch_estimates_ext[2][symbol*nb_rb*12]; + ch10 = (int *)&dl_ch_estimates_ext[1][symbol*nb_rb*12]; + ch11 = (int *)&dl_ch_estimates_ext[3][symbol*nb_rb*12]; + ch20 = NULL; + ch21 = NULL; + ch30 = NULL; + ch31 = NULL; + break; + + case 4:// + ch00 = (int *)&dl_ch_estimates_ext[0][symbol*nb_rb*12]; + ch01 = (int *)&dl_ch_estimates_ext[4][symbol*nb_rb*12]; + ch10 = (int *)&dl_ch_estimates_ext[1][symbol*nb_rb*12]; + ch11 = (int *)&dl_ch_estimates_ext[5][symbol*nb_rb*12]; + ch20 = (int *)&dl_ch_estimates_ext[2][symbol*nb_rb*12]; + ch21 = (int *)&dl_ch_estimates_ext[6][symbol*nb_rb*12]; + ch30 = (int *)&dl_ch_estimates_ext[3][symbol*nb_rb*12]; + ch31 = (int *)&dl_ch_estimates_ext[7][symbol*nb_rb*12]; + break; + + default: + return -1; + break; + } + + /* 1- Compute the rx channel matrix after compensation: (1/2^log2_max)x(H_herm x H) + * for n_rx = 2 + * |conj_H_00 conj_H_10| | H_00 H_01| |(conj_H_00xH_00+conj_H_10xH_10) (conj_H_00xH_01+conj_H_10xH_11)| + * | | x | | = | | + * |conj_H_01 conj_H_11| | H_10 H_11| |(conj_H_01xH_00+conj_H_11xH_10) (conj_H_01xH_01+conj_H_11xH_11)| + * + */ + + if (n_rx>=2){ + // (1/2^log2_maxh)*conj_H_00xH_00: (1/(64*2))conjH_00*H_00*2^15 + nr_conjch0_mult_ch1(ch00, + ch00, + conjch00_ch00, + nb_rb, + shift); + // (1/2^log2_maxh)*conj_H_10xH_10: (1/(64*2))conjH_10*H_10*2^15 + nr_conjch0_mult_ch1(ch10, + ch10, + conjch10_ch10, + nb_rb, + shift); + // conj_H_00xH_01 + nr_conjch0_mult_ch1(ch00, + ch01, + conjch00_ch01, + nb_rb, + shift); // this shift is equal to the channel level log2_maxh + // conj_H_10xH_11 + nr_conjch0_mult_ch1(ch10, + ch11, + conjch10_ch11, + nb_rb, + shift); + // conj_H_01xH_01 + nr_conjch0_mult_ch1(ch01, + ch01, + conjch01_ch01, + nb_rb, + shift); + // conj_H_11xH_11 + nr_conjch0_mult_ch1(ch11, + ch11, + conjch11_ch11, + nb_rb, + shift); + // conj_H_01xH_00 + nr_conjch0_mult_ch1(ch01, + ch00, + conjch01_ch00, + nb_rb, + shift); + // conj_H_11xH_10 + nr_conjch0_mult_ch1(ch11, + ch10, + conjch11_ch10, + nb_rb, + shift); + } + if (n_rx==4){ + // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2*16))conjH_20*H_20*2^15 + nr_conjch0_mult_ch1(ch20, + ch20, + conjch20_ch20, + nb_rb, + shift); + + // (1/2^log2_maxh)*conj_H_30xH_30: (1/(64*2*4))conjH_30*H_30*2^15 + nr_conjch0_mult_ch1(ch30, + ch30, + conjch30_ch30, + nb_rb, + shift); + + // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15 + nr_conjch0_mult_ch1(ch20, + ch21, + conjch20_ch21, + nb_rb, + shift); + + nr_conjch0_mult_ch1(ch30, + ch31, + conjch30_ch31, + nb_rb, + shift); + + nr_conjch0_mult_ch1(ch21, + ch21, + conjch21_ch21, + nb_rb, + shift); + + nr_conjch0_mult_ch1(ch31, + ch31, + conjch31_ch31, + nb_rb, + shift); + + // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15 + nr_conjch0_mult_ch1(ch21, + ch20, + conjch21_ch20, + nb_rb, + shift); + + nr_conjch0_mult_ch1(ch31, + ch30, + conjch31_ch30, + nb_rb, + shift); + + nr_construct_HhH_elements(conjch00_ch00, + conjch01_ch01, + conjch11_ch11, + conjch10_ch10,// + conjch20_ch20, + conjch21_ch21, + conjch30_ch30, + conjch31_ch31, + conjch00_ch01, + conjch01_ch00, + conjch10_ch11, + conjch11_ch10,// + conjch20_ch21, + conjch21_ch20, + conjch30_ch31, + conjch31_ch30, + af_mf_00, + af_mf_01, + af_mf_10, + af_mf_11, + nb_rb, + symbol); + } + if (n_rx==2){ + nr_construct_HhH_elements(conjch00_ch00, + conjch01_ch01, + conjch11_ch11, + conjch10_ch10,// + NULL, + NULL, + NULL, + NULL, + conjch00_ch01, + conjch01_ch00, + conjch10_ch11, + conjch11_ch10,// + NULL, + NULL, + NULL, + NULL, + af_mf_00, + af_mf_01, + af_mf_10, + af_mf_11, + nb_rb, + symbol); + } + //det_HhH = ad -bc + nr_det_HhH(af_mf_00,//a + af_mf_01,//b + af_mf_10,//c + af_mf_11,//d + determ_fin, + nb_rb, + symbol); + /* 2- Compute the channel matrix inversion ********************************** + * + * |(conj_H_00xH_00+conj_H_10xH_10) (conj_H_00xH_01+conj_H_10xH_11)| + * A= | | + * |(conj_H_01xH_00+conj_H_11xH_10) (conj_H_01xH_01+conj_H_11xH_11)| + * + * + * + *inv(A) =(1/det)*[d -b + * -c a] + * + * + **************************************************************************/ + __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128b_0,*dl_ch_mag128_1,*dl_ch_mag128b_1,*determ_fin_128; + __m128i mmtmpD2,mmtmpD3,mmtmpD0,mmtmpD1,QAM_amp128,QAM_amp128b; + __m128i *after_mf_a_128,*after_mf_b_128, *after_mf_c_128, *after_mf_d_128; + + determ_fin_128 = (__m128i *)&determ_fin[0]; + + rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][symbol*nb_rb*12];//aatx=0 @ aarx =0 + rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[n_rx][symbol*nb_rb*12];//aatx=1 @ aarx =0 + + dl_ch_mag128_0 = (__m128i *)&dl_ch_mag[0][symbol*nb_rb*12]; + dl_ch_mag128_1 = (__m128i *)&dl_ch_mag[n_rx][symbol*nb_rb*12]; + dl_ch_mag128b_0 = (__m128i *)&dl_ch_magb[0][symbol*nb_rb*12]; + dl_ch_mag128b_1 = (__m128i *)&dl_ch_magb[n_rx][symbol*nb_rb*12]; + + after_mf_a_128 = (__m128i *)af_mf_00; + after_mf_b_128 = (__m128i *)af_mf_01; + after_mf_c_128 = (__m128i *)af_mf_10; + after_mf_d_128 = (__m128i *)af_mf_11; + + QAM_amp128b = _mm_setzero_si128(); + + 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); + } + + for (int rb=0; rb<3*nb_rb; rb++) { + if (mod_order>2) { + // get channel determ (da -bc) if not QPSK + mmtmpD0 = _mm_packs_epi32(determ_fin_128[0],determ_fin_128[0]);//convert 32 bits to 16 bits + + dl_ch_mag128_0[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128b_0[0] = dl_ch_mag128_0[0]; + + dl_ch_mag128_0[0] = _mm_mulhi_epi16(dl_ch_mag128_0[0],QAM_amp128); + dl_ch_mag128_0[0] = _mm_slli_epi16(dl_ch_mag128_0[0],1);//aatx=0 @ aarx =0 + dl_ch_mag128_1[0] = dl_ch_mag128_0[0];//aatx=1 @ aarx =0 + + dl_ch_mag128b_0[0] = _mm_mulhi_epi16(dl_ch_mag128b_0[0],QAM_amp128b); + dl_ch_mag128b_0[0] = _mm_slli_epi16(dl_ch_mag128b_0[0],1);//aatx=0 @ aarx = + dl_ch_mag128b_1[0] = dl_ch_mag128b_0[0];//aatx=1 @ aarx =0 + + if ((rb==0)&&(symbol==1)) { + printf("\n Signal mag after ZF \n"); + print_shorts("mag layer 1:",(int16_t*)&dl_ch_mag128_0[0]); + print_shorts("mag layer 2:",(int16_t*)&dl_ch_mag128_1[0]); + print_shorts("magb layer 1:",(int16_t*)&dl_ch_mag128b_0[0]); + print_shorts("magb layer 2:",(int16_t*)&dl_ch_mag128b_1[0]); + } + } + // multiply by channel Inv + //rxdataF_zf128_0 = rxdataF_comp128_0*d - b*rxdataF_comp128_1 + //rxdataF_zf128_1 = rxdataF_comp128_1*a - c*rxdataF_comp128_0 + mmtmpD2 = nr_inv_comp_muli(rxdataF_comp128_0[0],//x + after_mf_d_128[0]);//y + mmtmpD3 = nr_inv_comp_muli(rxdataF_comp128_1[0],//x + after_mf_b_128[0]);//y + //mmtmpD2[0] - mmtmpD3[0] + //rxdataF_zf128_0 + mmtmpD0 = _mm_sub_epi16(mmtmpD2, mmtmpD3); + + mmtmpD2 = nr_inv_comp_muli(rxdataF_comp128_1[0],//x + after_mf_a_128[0]);//y + mmtmpD3 = nr_inv_comp_muli(rxdataF_comp128_0[0],//x + after_mf_c_128[0]);//y + //mmtmpD2[0] - mmtmpD3[0] + //rxdataF_zf128_1 + mmtmpD1 = _mm_sub_epi16(mmtmpD2, mmtmpD3); + + rxdataF_comp128_0[0] = mmtmpD0; + rxdataF_comp128_1[0] = mmtmpD1; + + if ((rb==0)&&(symbol==1)) { + printf("\n Rx signal after ZF \n"); + print_shorts("Rx layer 1:",(int16_t*)&rxdataF_comp128_0[0]); + print_shorts("Rx layer 2:",(int16_t*)&rxdataF_comp128_1[0]); + } + + determ_fin_128 += 1; + dl_ch_mag128_0 += 1; + dl_ch_mag128b_0 += 1; + dl_ch_mag128_1 += 1; + dl_ch_mag128b_1 += 1; + rxdataF_comp128_0 += 1; + rxdataF_comp128_1 += 1; + after_mf_a_128 += 1; + after_mf_b_128 += 1; + after_mf_c_128 += 1; + after_mf_d_128 += 1; + } + _mm_empty(); + _m_empty(); + return(0); +} + static void nr_dlsch_layer_demapping(int16_t **llr_cw, uint8_t Nl, uint8_t mod_order, From e4370cc30b81cba33d8411bbb2f0c9bede014133 Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Tue, 26 Jan 2021 12:02:29 +0100 Subject: [PATCH 13/40] remove printf in nr_zero_forcing receiver --- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index df82f1299a..db5f800383 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -1082,13 +1082,12 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, dl_ch128_2+=3; rho128+=3; } - if (first_symbol_flag==1) { - //measurements->rx_correlation[0][0][aarx] = signal_energy(&rho[aarx][symbol*nb_rb*12],rb*12); - avg_rho_re[aatx][aarx] = 16*avg_rho_re[aatx][aarx]/(nb_rb*12); - avg_rho_im[aatx][aarx] = 16*avg_rho_im[aatx][aarx]/(nb_rb*12); - - printf("rho_rx%d tx%d= Re: %d Im: %d\n",aarx, aatx, avg_rho_re[aatx][aarx], avg_rho_im[aatx][aarx]); - } + /*if (first_symbol_flag==1) { + //measurements->rx_correlation[0][0][aarx] = signal_energy(&rho[aarx][symbol*nb_rb*12],rb*12); + avg_rho_re[aatx][aarx] = 16*avg_rho_re[aatx][aarx]/(nb_rb*12); + avg_rho_im[aatx][aarx] = 16*avg_rho_im[aatx][aarx]/(nb_rb*12); + printf("rho_rx%d tx%d= Re: %d Im: %d\n",aarx, aatx, avg_rho_re[aatx][aarx], avg_rho_im[aatx][aarx]); + }*/ } } } @@ -2352,12 +2351,12 @@ void nr_det_HhH(int32_t *after_mf_00,//a //det_matrix_128[0] = _mm_packs_epi32(tmp_det0,tmp_det1); det_fin_128[0] = _mm_abs_epi32(det_re_128); - if ((rb==0)&&(symbol==1)) { + /*if ((rb==0)&&(symbol==1)) { printf("\n Computing det_HhH_inv \n"); print_ints("det_re_128:",(int32_t*)&det_re_128); //print_ints("det_im_128:",(int32_t*)&det_im_128); print_ints("det_fin_128:",(int32_t*)&det_fin_128[0]); - } + }*/ det_fin_128+=1; after_mf_00_128+=1; @@ -2533,14 +2532,14 @@ void nr_construct_HhH_elements(int *conjch00_ch00, if (conjch21_ch20 != NULL) after_mf_10_128[0] =_mm_adds_epi16(after_mf_10_128[0],conjch21_ch20_128[0]); if (conjch31_ch30 != NULL) after_mf_10_128[0] =_mm_adds_epi16(after_mf_10_128[0],conjch31_ch30_128[0]); - if ((rb==0)&&(symbol==1)) + /*if ((rb==0)&&(symbol==1)) { - printf(" \n construct_HhH_elements \n"); - print_shorts("after_mf_00_128:",(int16_t*)&after_mf_00_128[0]); - print_shorts("after_mf_01_128:",(int16_t*)&after_mf_01_128[0]); - print_shorts("after_mf_10_128:",(int16_t*)&after_mf_10_128[0]); - print_shorts("after_mf_11_128:",(int16_t*)&after_mf_11_128[0]); - } + printf(" \n construct_HhH_elements \n"); + print_shorts("after_mf_00_128:",(int16_t*)&after_mf_00_128[0]); + print_shorts("after_mf_01_128:",(int16_t*)&after_mf_01_128[0]); + print_shorts("after_mf_10_128:",(int16_t*)&after_mf_10_128[0]); + print_shorts("after_mf_11_128:",(int16_t*)&after_mf_11_128[0]); + }*/ conjch00_ch00_128+=1; conjch10_ch10_128+=1; @@ -2896,11 +2895,11 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp, rxdataF_comp128_0[0] = mmtmpD0; rxdataF_comp128_1[0] = mmtmpD1; - if ((rb==0)&&(symbol==1)) { - printf("\n Rx signal after ZF \n"); - print_shorts("Rx layer 1:",(int16_t*)&rxdataF_comp128_0[0]); - print_shorts("Rx layer 2:",(int16_t*)&rxdataF_comp128_1[0]); - } + /*if ((rb==0)&&(symbol==1)) { + printf("\n Rx signal after ZF \n"); + print_shorts("Rx layer 1:",(int16_t*)&rxdataF_comp128_0[0]); + print_shorts("Rx layer 2:",(int16_t*)&rxdataF_comp128_1[0]); + }*/ determ_fin_128 += 1; dl_ch_mag128_0 += 1; From fd8cf7769c69c1b42fe5c49d141779f190c3f102 Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Wed, 27 Jan 2021 12:39:05 +0100 Subject: [PATCH 14/40] Modify and fix nr_dlsim to support 4*4 MIMO with 1 layer --- openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 4 ++-- openair1/SIMULATION/NR_PHY/dlsim.c | 17 +++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index b6cdac3f47..78cf5a7ebf 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -414,10 +414,10 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, ///Layer Precoding and Antenna port mapping // tx_layers 1-8 are mapped on antenna ports 1000-1007 - uint8_t pmi = 6; + uint8_t pmi = 4;//hard coded, should be changed later from the upper layer for (int ap=0; apnb_antennas_tx; ap++) { - char *W_prec = nr_W_1l_4p[pmi][ap];//nr_W_1l_4p, nr_W_2l_2p, nr_W_2l_4p, nr_W_3l_4p, and nr_W_4l_4p + char *W_prec = nr_W_1l_4p[pmi][ap];//Hard coded, should be changed later from the upper layer for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { uint16_t k = start_sc; diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 083756d24e..9aab17cc67 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -393,7 +393,7 @@ int main(int argc, char **argv) case 'y': n_tx=atoi(optarg); - if ((n_tx==0) || (n_tx>2)) { + if ((n_tx==0) || (n_tx>4)) {//extend gNB to support n_tx = 4 printf("Unsupported number of tx antennas %d\n",n_tx); exit(-1); } @@ -403,7 +403,7 @@ int main(int argc, char **argv) case 'z': n_rx=atoi(optarg); - if ((n_rx==0) || (n_rx>2)) { + if ((n_rx==0) || (n_rx>4)) {//extend UE to support n_tx = 4 printf("Unsupported number of rx antennas %d\n",n_rx); exit(-1); } @@ -921,9 +921,9 @@ int main(int argc, char **argv) int txdataF_offset = (slot%2) * frame_parms->samples_per_slot_wCP; if (n_trials==1) { - LOG_M("txsigF0.m","txsF0", &gNB->common_vars.txdataF[0][txdataF_offset],frame_parms->samples_per_slot_wCP,1,1); + LOG_M("txsigF0.m","txsF0=", &gNB->common_vars.txdataF[0][txdataF_offset+2*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); if (gNB->frame_parms.nb_antennas_tx>1) - LOG_M("txsigF1.m","txsF1", &gNB->common_vars.txdataF[1][txdataF_offset],frame_parms->samples_per_slot_wCP,1,1); + LOG_M("txsigF1.m","txsF1=", &gNB->common_vars.txdataF[1][txdataF_offset+2*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); } int tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); if (n_trials==1) printf("tx_offset %d, txdataF_offset %d \n", tx_offset,txdataF_offset); @@ -947,9 +947,11 @@ int main(int argc, char **argv) } if (n_trials==1) { - LOG_M("txsig0.m","txs0", &txdata[0][tx_offset],frame_parms->get_samples_slot_timestamp(slot,frame_parms,0),1,1); - if (gNB->frame_parms.nb_antennas_tx>1) - LOG_M("txsig1.m","txs1", &txdata[1][tx_offset],frame_parms->get_samples_slot_timestamp(slot,frame_parms,0),1,1); + char filename[100];//LOG_M + for (aa=0;aaofdm_symbol_size+frame_parms->nb_prefix_samples0],6*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples),1,1); + } } if (output_fd) { printf("writing txdata to binary file\n"); @@ -966,7 +968,6 @@ int main(int argc, char **argv) if (n_trials==1) printf("txlev[%d] = %d (%f dB) txlev_sum %d\n",aa,txlev[aa],10*log10((double)txlev[aa]),txlev_sum); } - // if (n_trials==1) printf("txlev %d (%f)\n",txlev,10*log10((double)txlev)); for (i=(frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)); i<(frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0)); From 9e8f0055ef824359cf135aac8e294ce0ef9f8043 Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Wed, 27 Jan 2021 14:14:57 +0100 Subject: [PATCH 15/40] Bug in PUSH when config.num_rx_antis equal to config.num_tx_ant --- openair2/LAYER2/NR_MAC_gNB/config.c | 2 +- .../GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 21371d5e32..bd6a8f3384 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -275,7 +275,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm num_ssb += (cfg->ssb_table.ssb_mask_list[1].ssb_mask.value>>i)&1; } - cfg->carrier_config.num_rx_ant.value = 1;//cfg->carrier_config.num_tx_ant.value; + cfg->carrier_config.num_rx_ant.value = cfg->carrier_config.num_tx_ant.value; cfg->carrier_config.num_rx_ant.tl.tag = NFAPI_NR_CONFIG_NUM_RX_ANT_TAG; LOG_I(MAC,"Set TX/RX antenna number to %d (num ssb %d: %x,%x)\n",cfg->carrier_config.num_tx_ant.value,num_ssb,cfg->ssb_table.ssb_mask_list[0].ssb_mask.value,cfg->ssb_table.ssb_mask_list[1].ssb_mask.value); AssertFatal(cfg->carrier_config.num_tx_ant.value > 0,"carrier_config.num_tx_ant.value %d !\n",cfg->carrier_config.num_tx_ant.value ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index f83b082211..8ad31635b2 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -241,7 +241,7 @@ RUs = ( { local_rf = "yes" nb_tx = 4 - nb_rx = 1 + nb_rx = 4 att_tx = 0 att_rx = 0; bands = [7]; @@ -253,7 +253,7 @@ RUs = ( ##beamforming 1x4 matrix: 1 layer x 4 antennas #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000]; ## beamforming 2x2 matrix: - # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; + bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; ## beamforming 4x4 matrix: bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; From dfe4bf4a305c39c221873ece8c86ea36712e0b73 Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Fri, 29 Jan 2021 16:59:39 +0100 Subject: [PATCH 16/40] Remove dependency of pdsch_Antennports and gNB num_rx_antenna (hardcoded in this commit) --- openair2/LAYER2/NR_MAC_gNB/config.c | 2 +- .../GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index bd6a8f3384..d9ca0ad009 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -275,7 +275,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm num_ssb += (cfg->ssb_table.ssb_mask_list[1].ssb_mask.value>>i)&1; } - cfg->carrier_config.num_rx_ant.value = cfg->carrier_config.num_tx_ant.value; + cfg->carrier_config.num_rx_ant.value = 1; //cfg->carrier_config.num_tx_ant.value; cfg->carrier_config.num_rx_ant.tl.tag = NFAPI_NR_CONFIG_NUM_RX_ANT_TAG; LOG_I(MAC,"Set TX/RX antenna number to %d (num ssb %d: %x,%x)\n",cfg->carrier_config.num_tx_ant.value,num_ssb,cfg->ssb_table.ssb_mask_list[0].ssb_mask.value,cfg->ssb_table.ssb_mask_list[1].ssb_mask.value); AssertFatal(cfg->carrier_config.num_tx_ant.value > 0,"carrier_config.num_tx_ant.value %d !\n",cfg->carrier_config.num_tx_ant.value ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 8ad31635b2..f83b082211 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -241,7 +241,7 @@ RUs = ( { local_rf = "yes" nb_tx = 4 - nb_rx = 4 + nb_rx = 1 att_tx = 0 att_rx = 0; bands = [7]; @@ -253,7 +253,7 @@ RUs = ( ##beamforming 1x4 matrix: 1 layer x 4 antennas #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000]; ## beamforming 2x2 matrix: - bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; + # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; ## beamforming 4x4 matrix: bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; From 3fdb550909a965af48d48b9d95f9ec5516655d0f Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Fri, 29 Jan 2021 17:19:41 +0100 Subject: [PATCH 17/40] reconfigure dmrs_type 1 for RA and phy_test mode --- openair1/PHY/INIT/nr_init_ue.c | 2 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 2 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 2 +- openair2/RRC/NR/rrc_gNB_reconfig.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 4641976cf4..0fa800571a 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -512,7 +512,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, // dmrs_Uplink_Config->pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0; // dmrs_Uplink_Config->pusch_maxLength = pusch_len1; //-------------------------------------------------// - ue->dmrs_DownlinkConfig.pdsch_dmrs_type = pdsch_dmrs_type2; + ue->dmrs_DownlinkConfig.pdsch_dmrs_type = pdsch_dmrs_type1; ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition = pdsch_dmrs_pos0; ue->dmrs_DownlinkConfig.pdsch_maxLength = pdsch_len1; //-------------------------------------------------// diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index a2c8e54f58..499ac7c983 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -861,7 +861,7 @@ void nr_generate_Msg2(module_id_t module_idP, pdsch_pdu_rel15->nrOfLayers = 1; pdsch_pdu_rel15->transmissionScheme = 0; pdsch_pdu_rel15->refPoint = 0; - pdsch_pdu_rel15->dmrsConfigType = 1;//Enable Msg2 to use pdsch_dmrs_type2 + pdsch_pdu_rel15->dmrsConfigType = 0;//Reconfigure Msg2 to use pdsch_dmrs_type1 pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu_rel15->SCID = 0; pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 2; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 354f32bdd7..f0f809fb39 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -133,7 +133,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, pdsch_pdu_rel15->transmissionScheme = 0; pdsch_pdu_rel15->refPoint = 0; // Point A - pdsch_pdu_rel15->dmrsConfigType = 1; // Type 2 by default for InitialBWP + pdsch_pdu_rel15->dmrsConfigType = 0; // Type 1 by default for InitialBWP pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu_rel15->SCID = 0; pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 1; diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 6fad4ba89c..7acce22fd0 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -636,7 +636,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup)); - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=NULL;//calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type)); bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID0=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID1=NULL; From 88f293d3bad01444025eaf6d11699231c907d8e0 Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Fri, 29 Jan 2021 17:42:26 +0100 Subject: [PATCH 18/40] clean up nr_dlsch_demodulation, solve bug in nr_rb_extract to consider data/dmrs multiplexing/no data, and remove ra_pdsch hack in phy_procedures_nr_ue --- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 951 +++++++++--------- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 10 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 60 +- 3 files changed, 498 insertions(+), 523 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index db5f800383..e36b1994ae 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -183,7 +183,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, //int16_t *pllr_symbol_cw1_deint; //uint16_t bundle_L = 2; uint8_t pilots=0; - uint8_t config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type; + uint8_t config_type;// We should not use ue->dmrs_DownlinkConfig.pdsch_dmrs_type; uint16_t n_tx=1, n_rx=1; int32_t median[16]; uint32_t len; @@ -341,39 +341,40 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #endif pilots = ((1<dlDmrsSymbPos)>0 ? 1 : 0; + config_type = dlsch0_harq->dmrsConfigType; if (beamforming_mode==0) {//No beamforming #if UE_TIMING_TRACE start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #endif if (dlsch0_harq->Nl > 1)//More than or equal 2 layers - nb_rb = nr_dlsch_extract_rbs_multiple(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, - pdsch_vars[eNB_id]->dl_ch_estimates, - pdsch_vars[eNB_id]->rxdataF_ext, - pdsch_vars[eNB_id]->dl_ch_estimates_ext, - symbol, - pilots, - config_type, - start_rb, - nb_rb_pdsch, - ue->high_speed_flag, - dlsch0_harq->Nl, - frame_parms, - dlsch0_harq->dlDmrsSymbPos); + nb_rb = nr_dlsch_extract_rbs_multiple(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, + pdsch_vars[eNB_id]->dl_ch_estimates, + pdsch_vars[eNB_id]->rxdataF_ext, + pdsch_vars[eNB_id]->dl_ch_estimates_ext, + symbol, + pilots, + config_type, + start_rb, + nb_rb_pdsch, + dlsch0_harq->n_dmrs_cdm_groups, + dlsch0_harq->Nl, + frame_parms, + dlsch0_harq->dlDmrsSymbPos); else// one layer - nb_rb = nr_dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, - pdsch_vars[eNB_id]->dl_ch_estimates, - pdsch_vars[eNB_id]->rxdataF_ext, - pdsch_vars[eNB_id]->dl_ch_estimates_ext, - symbol, - pilots, - config_type, - start_rb + dlsch0_harq->BWPStart, - nb_rb_pdsch, - ue->high_speed_flag, - frame_parms, - dlsch0_harq->dlDmrsSymbPos); + nb_rb = nr_dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, + pdsch_vars[eNB_id]->dl_ch_estimates, + pdsch_vars[eNB_id]->rxdataF_ext, + pdsch_vars[eNB_id]->dl_ch_estimates_ext, + symbol, + pilots, + config_type, + start_rb + dlsch0_harq->BWPStart, + nb_rb_pdsch, + dlsch0_harq->n_dmrs_cdm_groups, + frame_parms, + dlsch0_harq->dlDmrsSymbPos); } /*else if(beamforming_mode>7) { LOG_W(PHY,"dlsch_demodulation: beamforming mode not supported yet.\n"); @@ -405,14 +406,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, n_rx = frame_parms->nb_antennas_rx; nr_dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - n_tx, - n_rx, - dlsch, - symbol, - pilots, - len, - nb_rb); + frame_parms, + n_tx, + n_rx, + dlsch, + symbol, + pilots, + len, + nb_rb); #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); @@ -429,12 +430,12 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, if (first_symbol_flag==1) { if (beamforming_mode==0){ nr_dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - n_tx, - avg, - symbol, - len, - nb_rb); + frame_parms, + n_tx, + avg, + symbol, + len, + nb_rb); avgs = 0; for (aatx=0;aatxlog2_maxh = (log2_approx(avgs)/2) + 1;} + pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1; + } } LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n", frame%1024,nr_slot_rx, pdsch_vars[eNB_id]->log2_maxh, @@ -492,28 +494,23 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, // Now channel compensation if (dlsch0_harq->mimo_moderxdataF_ext, - pdsch_vars[eNB_id]->dl_ch_estimates_ext, - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_magb0, - pdsch_vars[eNB_id]->dl_ch_magr0, - pdsch_vars[eNB_id]->rxdataF_comp0, - (n_tx>1) ? pdsch_vars[eNB_id]->rho : NULL, - frame_parms, - n_tx, - symbol, - pilots, - first_symbol_flag, - dlsch0_harq->Qm, - nb_rb, - pdsch_vars[eNB_id]->log2_maxh, - measurements); // log2_maxh+I0_shift - /*if (symbol == 5) { - write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); - } */ - } - - else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM){ - nr_dlsch_channel_compensation_core(pdsch_vars[eNB_id]->rxdataF_ext, + pdsch_vars[eNB_id]->dl_ch_estimates_ext, + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_magb0, + pdsch_vars[eNB_id]->dl_ch_magr0, + pdsch_vars[eNB_id]->rxdataF_comp0, + (n_tx>1) ? pdsch_vars[eNB_id]->rho : NULL, + frame_parms, + n_tx, + symbol, + pilots, + first_symbol_flag, + dlsch0_harq->Qm, + nb_rb, + pdsch_vars[eNB_id]->log2_maxh, + measurements); // log2_maxh+I0_shift + } else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM){ + nr_dlsch_channel_compensation_core(pdsch_vars[eNB_id]->rxdataF_ext, pdsch_vars[eNB_id]->dl_ch_estimates_ext, pdsch_vars[eNB_id]->dl_ch_mag0, pdsch_vars[eNB_id]->dl_ch_magb0, @@ -521,42 +518,19 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, NULL, n_tx, n_rx, - dlsch0_harq->Qm, - pdsch_vars[eNB_id]->log2_maxh, - 2*len, // subcarriers Re Im - 0); // we start from the beginning of the vector - /* if (symbol == 5) { - write_output("rxF_comp_d00.m","rxF_c_d00",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM - write_output("rxF_comp_d01.m","rxF_c_d01",&pdsch_vars[eNB_id]->rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 - write_output("rxF_comp_d10.m","rxF_c_d10",&pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 - write_output("rxF_comp_d11.m","rxF_c_d11",&pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM - } */ - // compute correlation between signal and interference channels (rho12 and rho21) - nr_dlsch_dual_stream_correlation_core(pdsch_vars[eNB_id]->dl_ch_estimates_ext, - &(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - n_tx, - n_rx, - pdsch_vars[eNB_id]->log2_maxh, - 2*len, - 0); - //printf("rho stream1 =%d\n", &pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round] ); - nr_dlsch_dual_stream_correlation_core(&(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), - pdsch_vars[eNB_id]->dl_ch_estimates_ext, - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - n_tx, - n_rx, - pdsch_vars[eNB_id]->log2_maxh, - 2*len, - 0); - // printf("rho stream2 =%d\n",&pdsch_vars[eNB_id]->dl_ch_rho2_ext ); - //printf("TM3 log2_maxh : %d\n",pdsch_vars[eNB_id]->log2_maxh); - /* if (symbol == 5) { - write_output("rho0_0.m","rho0_0",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM - write_output("rho2_0.m","rho2_0",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 - write_output("rho0_1.m.m","rho0_1",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 - write_output("rho2_1.m","rho2_1",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM - } */ + dlsch0_harq->Qm, + pdsch_vars[eNB_id]->log2_maxh, + 2*len, // subcarriers Re Im + 0); // we start from the beginning of the vector + // compute correlation between signal and interference channels (rho12 and rho21) + nr_dlsch_dual_stream_correlation_core(pdsch_vars[eNB_id]->dl_ch_estimates_ext, + &(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), + pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + n_tx, + n_rx, + pdsch_vars[eNB_id]->log2_maxh, + 2*len, + 0); } #if UE_TIMING_TRACE @@ -597,23 +571,19 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, } else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM){ nr_dlsch_detection_mrc_core(pdsch_vars[eNB_id]->rxdataF_comp0, NULL, - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_magb0, + pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[eNB_id]->dl_ch_rho2_ext, + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_magb0, NULL, NULL, n_tx, n_rx, 2*len, 0); - /* if (symbol == 5) { - write_output("rho0_mrc.m","rho0_0",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM - write_output("rho2_mrc.m","rho2_0",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 - } */ - } - } - //printf("start compute LLR\n"); + } + } + //printf("start compute LLR\n"); if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { rxdataF_comp_ptr = pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round]; dl_ch_mag_ptr = pdsch_vars[eNB_id]->dl_ch_mag1[harq_pid][round]; @@ -815,289 +785,304 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, #if defined(__i386) || defined(__x86_64) - unsigned short rb; - unsigned char aatx,aarx; - __m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128,*rho128; - __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b; - QAM_amp128b = _mm_setzero_si128(); + unsigned short rb; + unsigned char aatx,aarx; + __m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*dl_ch_mag128r,*rxdataF128,*rxdataF_comp128,*rho128; + __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b,QAM_amp128r; + QAM_amp128b = _mm_setzero_si128(); - for (aatx=0; aatxnb_antennas_rx; aarx++) { + + dl_ch128 = (__m128i *)&dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; + dl_ch_mag128 = (__m128i *)&dl_ch_mag[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; + dl_ch_mag128b = (__m128i *)&dl_ch_magb[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; + dl_ch_mag128r = (__m128i *)&dl_ch_magr[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; + rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*nb_rb*12]; + rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; + + for (rb=0; rb2) { + // get channel amplitude if not QPSK + + mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128[0]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + + mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + + mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); + + // store channel magnitude here in a new field of dlsch + + dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128b[0] = dl_ch_mag128[0]; + dl_ch_mag128r[0] = dl_ch_mag128[0]; + dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); + dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); + //print_ints("Re(ch):",(int16_t*)&mmtmpD0); + //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128); + //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]); + dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128b[1] = dl_ch_mag128[1]; + dl_ch_mag128r[1] = dl_ch_mag128[1]; + dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); + dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1); + + if (pilots==0) { + mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); + + dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); + dl_ch_mag128b[2] = dl_ch_mag128[2]; + dl_ch_mag128r[2] = dl_ch_mag128[2]; + + dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128); + dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1); + } + + dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); + dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); + + dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); + dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); + + dl_ch_mag128r[0] = _mm_mulhi_epi16(dl_ch_mag128r[0],QAM_amp128r); + dl_ch_mag128r[0] = _mm_slli_epi16(dl_ch_mag128r[0],1); + + dl_ch_mag128r[1] = _mm_mulhi_epi16(dl_ch_mag128r[1],QAM_amp128r); + dl_ch_mag128r[1] = _mm_slli_epi16(dl_ch_mag128r[1],1); + + if (pilots==0) { + dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b); + dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); + + dl_ch_mag128r[2] = _mm_mulhi_epi16(dl_ch_mag128r[2],QAM_amp128r); + dl_ch_mag128r[2] = _mm_slli_epi16(dl_ch_mag128r[2],1); + } + } + + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); + // print_ints("re",&mmtmpD0); + + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_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); + + //printf("arx%d atx%d rb_index %d symbol%d\n",aarx,aatx,rb,symbol); + //print_shorts("rx:",(int16_t*)&rxdataF128[0]); + //print_shorts("ch:",(int16_t*)&dl_ch128[0]); + //print_shorts("pack:",(int16_t*)&rxdataF_comp128[0]); + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_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:",(int16_t*)&rxdataF128[1]); + //print_shorts("ch:",(int16_t*)&dl_ch128[1]); + //print_shorts("pack:",(int16_t*)&rxdataF_comp128[1]); + + if (pilots==0) { + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_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:",(int16_t*)&rxdataF128[2]); + //print_shorts("ch:",(int16_t*)&dl_ch128[2]); + //print_shorts("pack:",(int16_t*)&rxdataF_comp128[2]); + + dl_ch128+=3; + dl_ch_mag128+=3; + dl_ch_mag128b+=3; + dl_ch_mag128r+=3; + rxdataF128+=3; + rxdataF_comp128+=3; + } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less + dl_ch128+=2; + dl_ch_mag128+=2; + dl_ch_mag128b+=2; + dl_ch_mag128r+=2; + rxdataF128+=2; + rxdataF_comp128+=2; } + } + } + } + if (rho) { + //rho[aatx*n_rx+0] = Cov(H_0,0,H*_0,aatx), aatx=0,...n_tx-1 + //rho[aatx*n_rx+1] = Cov(H_1,1,H*_1,aatx), aatx=0,...n_tx-1 + //rho[aatx*n_rx+aarx] = Cov(H_aarx,arrx,H*_aarx,aatx), aatx=0,...n_tx-1 - // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol); + int avg_rho_re[nb_aatx][frame_parms->nb_antennas_rx]; + int avg_rho_im[nb_aatx][frame_parms->nb_antennas_rx]; - for (aarx=0; aarxnb_antennas_rx; aarx++) { + for (aarx=0; aarxnb_antennas_rx; aarx++) { + dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*nb_rb*12];//H_{aarx,0} - dl_ch128 = (__m128i *)&dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; - dl_ch_mag128 = (__m128i *)&dl_ch_mag[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; - dl_ch_mag128b = (__m128i *)&dl_ch_magb[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; - rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*nb_rb*12]; - rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; + for (aatx=1; aatxnb_antennas_rx+aarx][symbol*nb_rb*12]; + dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_rb*12]; + for (rb=0; rb2) { - // get channel amplitude if not QPSK + avg_rho_re[aatx][aarx] +=(((int16_t*)&rho128[0])[0]+ + ((int16_t*)&rho128[0])[2] + + ((int16_t*)&rho128[0])[4] + + ((int16_t*)&rho128[0])[6])/16; - mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128[0]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + avg_rho_im[aatx][aarx] +=(((int16_t*)&rho128[0])[1]+ + ((int16_t*)&rho128[0])[3] + + ((int16_t*)&rho128[0])[5] + + ((int16_t*)&rho128[0])[7])/16; - mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_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,dl_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:",dl_ch128_2+1); + //print_shorts("ch:",dl_ch128+1); + //print_shorts("pack:",rho128+1); - mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); + // multiply by conjugated channel - // store channel magnitude here in a new field of dlsch + avg_rho_re[aatx][aarx] +=(((int16_t*)&rho128[1])[0]+ + ((int16_t*)&rho128[1])[2] + + ((int16_t*)&rho128[1])[4] + + ((int16_t*)&rho128[1])[6])/16; - dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag128b[0] = dl_ch_mag128[0]; - dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); - dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); - //print_ints("Re(ch):",(int16_t*)&mmtmpD0); - //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128); - //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]); - dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag128b[1] = dl_ch_mag128[1]; - dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); - dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1); + avg_rho_im[aatx][aarx] +=(((int16_t*)&rho128[1])[1]+ + ((int16_t*)&rho128[1])[3] + + ((int16_t*)&rho128[1])[5] + + ((int16_t*)&rho128[1])[7])/16; - if (pilots==0) { - mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); + mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128_2[2]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_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,dl_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); - dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); - dl_ch_mag128b[2] = dl_ch_mag128[2]; + rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + //print_shorts("rx:",dl_ch128_2+2); + //print_shorts("ch:",dl_ch128+2); + //print_shorts("pack:",rho128+2); - dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128); - dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1); - } + avg_rho_re[aatx][aarx] +=(((int16_t*)&rho128[2])[0]+ + ((int16_t*)&rho128[2])[2] + + ((int16_t*)&rho128[2])[4] + + ((int16_t*)&rho128[2])[6])/16; - dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); - dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); + avg_rho_im[aatx][aarx] +=(((int16_t*)&rho128[2])[1]+ + ((int16_t*)&rho128[2])[3] + + ((int16_t*)&rho128[2])[5] + + ((int16_t*)&rho128[2])[7])/16; - - dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); - dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); - - if (pilots==0) { - dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b); - dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); - } - } - - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); - // print_ints("re",&mmtmpD0); - - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_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); - - /*if (rb==0) { - printf("arx%d atx%d rb_index %d SC 0 symbol%d\n",aarx,aatx,rb,symbol);// - printf("rx_F_re: %d rx_F_im: %d \n",((int16_t*)&rxdataF128[0])[0],((int16_t*)&rxdataF128[0])[1]); - printf("ch_re = %d ch_im = %d \n",((int16_t*)&dl_ch128[0])[0],((int16_t*)&dl_ch128[0])[1]);// - printf("rx_Fcomp_re: %d rx_Fcomp_im: %d \n",((int16_t*)&rxdataF_comp128[0])[0],((int16_t*)&rxdataF_comp128[0])[1]); - }*/ - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_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:",dl_ch128+1); - // print_shorts("pack:",rxdataF_comp128+1); - - if (pilots==0) { - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_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:",dl_ch128+2); - // print_shorts("pack:",rxdataF_comp128+2); - - dl_ch128+=3; - dl_ch_mag128+=3; - dl_ch_mag128b+=3; - rxdataF128+=3; - rxdataF_comp128+=3; - } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less - dl_ch128+=2; - dl_ch_mag128+=2; - dl_ch_mag128b+=2; - rxdataF128+=2; - rxdataF_comp128+=2; - } - } - } - } - - if (rho) { - //rho[aatx*n_rx+0] = Cov(H_0,0,H*_0,aatx), aatx=0,...n_tx-1 - //rho[aatx*n_rx+1] = Cov(H_1,1,H*_1,aatx), aatx=0,...n_tx-1 - //rho[aatx*n_rx+aarx] = Cov(H_aarx,arrx,H*_aarx,aatx), aatx=0,...n_tx-1 - - int avg_rho_re[nb_aatx][frame_parms->nb_antennas_rx]; - int avg_rho_im[nb_aatx][frame_parms->nb_antennas_rx]; - for (aarx=0; aarxnb_antennas_rx; aarx++) { - - dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*nb_rb*12];//H_{aarx,0} - - for (aatx=1; aatxnb_antennas_rx+aarx][symbol*nb_rb*12];//(aatx*frame_parms->nb_antennas_rx)+ - dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_rb*12]; - for (rb=0; rbrx_correlation[0][0][aarx] = signal_energy(&rho[aarx][symbol*nb_rb*12],rb*12); - avg_rho_re[aatx][aarx] = 16*avg_rho_re[aatx][aarx]/(nb_rb*12); - avg_rho_im[aatx][aarx] = 16*avg_rho_im[aatx][aarx]/(nb_rb*12); - printf("rho_rx%d tx%d= Re: %d Im: %d\n",aarx, aatx, avg_rho_re[aatx][aarx], avg_rho_im[aatx][aarx]); - }*/ - } - } - } - - _mm_empty(); - _m_empty(); + dl_ch128+=3; + dl_ch128_2+=3; + rho128+=3; + } + /*if (first_symbol_flag==1) { + * //measurements->rx_correlation[0][0][aarx] = signal_energy(&rho[aarx][symbol*nb_rb*12],rb*12); + * avg_rho_re[aatx][aarx] = 16*avg_rho_re[aatx][aarx]/(nb_rb*12); + * avg_rho_im[aatx][aarx] = 16*avg_rho_im[aatx][aarx]/(nb_rb*12); + * printf("rho_rx%d tx%d= Re: %d Im: %d\n",aarx, aatx, avg_rho_re[aatx][aarx], avg_rho_im[aatx][aarx]); + * }*/ + } + } + } + _mm_empty(); + _m_empty(); #elif defined(__arm__) - unsigned short rb; unsigned char aatx,aarx,symbol_mod,pilots=0; @@ -2055,32 +2040,37 @@ void nr_dlsch_detection_mrc_core(int **rxdataF_comp, //============================================================================================== unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, - int **dl_ch_estimates, - int **rxdataF_ext, - int **dl_ch_estimates_ext, - unsigned char symbol, - uint8_t pilots, - uint8_t config_type, - unsigned short start_rb, - unsigned short nb_rb_pdsch, - uint32_t high_speed_flag, - NR_DL_FRAME_PARMS *frame_parms, - uint16_t dlDmrsSymbPos) { + int **dl_ch_estimates, + int **rxdataF_ext, + int **dl_ch_estimates_ext, + unsigned char symbol, + uint8_t pilots, + uint8_t config_type, + unsigned short start_rb, + unsigned short nb_rb_pdsch, + uint8_t n_dmrs_cdm_groups, + NR_DL_FRAME_PARMS *frame_parms, + uint16_t dlDmrsSymbPos) +{ unsigned short k,rb; - unsigned char i,aarx; + unsigned char nushift,i,aarx; int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; int8_t validDmrsEst = 0; //store last DMRS Symbol index unsigned char j=0; - if (config_type==pdsch_dmrs_type1) - AssertFatal(frame_parms->nushift ==0 || frame_parms->nushift == 1, - "nushift %d is illegal\n",frame_parms->nushift); - else - AssertFatal(frame_parms->nushift ==0 || frame_parms->nushift == 2 || frame_parms->nushift == 4, - "nushift %d is illegal\n",frame_parms->nushift); + if (config_type==pdsch_dmrs_type1){ + AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2, + "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); + nushift = n_dmrs_cdm_groups -1;//delta in Table 7.4.1.1.2-1 + + } else { + AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2 || n_dmrs_cdm_groups == 3, + "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); + nushift = (n_dmrs_cdm_groups -1)<<1;//delta in Table 7.4.1.1.2-2 + } for (aarx=0; aarxnb_antennas_rx; aarx++) { @@ -2101,29 +2091,29 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))]; } if (pilots==0) { - memcpy((void*)rxF_ext,(void*)rxF,12*sizeof(*rxF_ext)); - memcpy((void*)dl_ch0_ext,(void*)dl_ch0,12*sizeof(*dl_ch0_ext)); - dl_ch0_ext+=12; - rxF_ext+=12; + memcpy((void*)rxF_ext,(void*)rxF,12*sizeof(*rxF_ext)); + memcpy((void*)dl_ch0_ext,(void*)dl_ch0,12*sizeof(*dl_ch0_ext)); + dl_ch0_ext+=12; + rxF_ext+=12; } else {//the symbol contains DMRS - j=0; - if (config_type==pdsch_dmrs_type1){ - if (frame_parms->nushift == 0) {//data is multiplexed - for (i = (1-frame_parms->nushift); i<12; i+=2) { - rxF_ext[j]=rxF[i]; - dl_ch0_ext[j]=dl_ch0[i]; - j++; - } - dl_ch0_ext+=6; - rxF_ext+=6; - } + j=0; + if (config_type==pdsch_dmrs_type1){ + if (nushift == 0) {//data is multiplexed + for (i = (1-nushift); i<12; i+=2) { + rxF_ext[j]=rxF[i]; + dl_ch0_ext[j]=dl_ch0[i]; + j++; + } + dl_ch0_ext+=6; + rxF_ext+=6; + } } else {//pdsch_dmrs_type2 - for (i = (2+frame_parms->nushift); i<6; i++) { + for (i = (2+nushift); i<6; i++) { rxF_ext[j]=rxF[i]; dl_ch0_ext[j]=dl_ch0[i]; j++; } - for (i = (8+frame_parms->nushift); i<12; i++) { + for (i = (8+nushift); i<12; i++) { rxF_ext[j]=rxF[i]; dl_ch0_ext[j]=dl_ch0[i]; j++; @@ -2147,93 +2137,98 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, } unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF, - int **dl_ch_estimates, - int **rxdataF_ext, - int **dl_ch_estimates_ext, - unsigned char symbol, - uint8_t pilots, - uint8_t config_type, - unsigned short start_rb, - unsigned short nb_rb_pdsch, - uint32_t high_speed_flag, - uint8_t Nl, - NR_DL_FRAME_PARMS *frame_parms, - uint16_t dlDmrsSymbPos) { + int **dl_ch_estimates, + int **rxdataF_ext, + int **dl_ch_estimates_ext, + unsigned char symbol, + uint8_t pilots, + uint8_t config_type, + unsigned short start_rb, + unsigned short nb_rb_pdsch, + uint8_t n_dmrs_cdm_groups, + uint8_t Nl, + NR_DL_FRAME_PARMS *frame_parms, + uint16_t dlDmrsSymbPos) +{ unsigned short k,rb; - unsigned char j,i,aarx,aatx; + unsigned char nushift,j,i,aarx,aatx; int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; int8_t validDmrsEst = 0; //store last DMRS Symbol index - if (config_type==pdsch_dmrs_type1) - AssertFatal(frame_parms->nushift ==0 || frame_parms->nushift == 1, - "nushift %d is illegal\n",frame_parms->nushift); - else - AssertFatal(frame_parms->nushift ==0 || frame_parms->nushift == 2 || frame_parms->nushift == 4, - "nushift %d is illegal\n",frame_parms->nushift); + if (config_type==pdsch_dmrs_type1){ + AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2, + "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); + nushift = n_dmrs_cdm_groups -1;//delta in Table 7.4.1.1.2-1 + + } else { + AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2 || n_dmrs_cdm_groups == 3, + "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); + nushift = (n_dmrs_cdm_groups -1)<<1;//delta in Table 7.4.1.1.2-2 + } validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos,symbol); for (aarx=0; aarxnb_antennas_rx; aarx++) { - k = frame_parms->first_carrier_offset + NR_NB_SC_PER_RB*start_rb; - if (k>frame_parms->ofdm_symbol_size) - k = k-frame_parms->ofdm_symbol_size; + k = frame_parms->first_carrier_offset + NR_NB_SC_PER_RB*start_rb; + if (k>frame_parms->ofdm_symbol_size) + k = k-frame_parms->ofdm_symbol_size; - rxF_ext = &rxdataF_ext[aarx][symbol*(nb_rb_pdsch*12)]; - rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))]; + rxF_ext = &rxdataF_ext[aarx][symbol*(nb_rb_pdsch*12)]; + rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))]; for (aatx=0; aatxnb_antennas_rx)+aarx][(validDmrsEst*(frame_parms->ofdm_symbol_size))]; - dl_ch0_ext = &dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*(nb_rb_pdsch*NR_NB_SC_PER_RB)]; + dl_ch0 = &dl_ch_estimates[(aatx*frame_parms->nb_antennas_rx)+aarx][(validDmrsEst*(frame_parms->ofdm_symbol_size))]; + dl_ch0_ext = &dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*(nb_rb_pdsch*NR_NB_SC_PER_RB)]; - for (rb = 0; rb < nb_rb_pdsch; rb++) { + for (rb = 0; rb < nb_rb_pdsch; rb++) { - if (pilots==0) {//data symbol only - if (aatx==0) {//Extract Rx signal only - memcpy((void*)rxF_ext,(void*)rxF,12*sizeof(*rxF_ext)); - rxF_ext+=12; - } - memcpy((void*)dl_ch0_ext,(void*)dl_ch0,12*sizeof(*dl_ch0_ext));//Extract Channel Estimate - dl_ch0_ext+=12; - } else {//the symbol contains DMRS - j=0; - if (config_type==pdsch_dmrs_type1) { - if (frame_parms->nushift == 0) {//data is multiplexed - for (i = (1-frame_parms->nushift); i<12; i+=2) { - if (aatx==0) rxF_ext[j]=rxF[i]; - dl_ch0_ext[j]=dl_ch0[i]; - j++; - } - dl_ch0_ext+=6; - if (aatx==0) rxF_ext+=6; - } - } else {//pdsch_dmrs_type2 - for (i = (2+frame_parms->nushift); i<6; i++) { - if (aatx==0) rxF_ext[j]=rxF[i]; - dl_ch0_ext[j]=dl_ch0[i]; - j++; - } - for (i = (8+frame_parms->nushift); i<12; i++) { - if (aatx==0) rxF_ext[j]=rxF[i]; - dl_ch0_ext[j]=dl_ch0[i]; - j++; - } - dl_ch0_ext+= j; - if (aatx==0) rxF_ext+= j; - } - } + if (pilots==0) {//data symbol only + if (aatx==0) {//Extract Rx signal only + memcpy((void*)rxF_ext,(void*)rxF,12*sizeof(*rxF_ext)); + rxF_ext+=12; + } + memcpy((void*)dl_ch0_ext,(void*)dl_ch0,12*sizeof(*dl_ch0_ext));//Extract Channel Estimate + dl_ch0_ext+=12; + } else {//the symbol contains DMRS + j=0; + if (config_type==pdsch_dmrs_type1) { + if (nushift == 0) {//data is multiplexed + for (i = (1-nushift); i<12; i+=2) { + if (aatx==0) rxF_ext[j]=rxF[i]; + dl_ch0_ext[j]=dl_ch0[i]; + j++; + } + dl_ch0_ext+=6; + if (aatx==0) rxF_ext+=6; + } + } else {//pdsch_dmrs_type2 + for (i = (2+nushift); i<6; i++) { + if (aatx==0) rxF_ext[j]=rxF[i]; + dl_ch0_ext[j]=dl_ch0[i]; + j++; + } + for (i = (8+nushift); i<12; i++) { + if (aatx==0) rxF_ext[j]=rxF[i]; + dl_ch0_ext[j]=dl_ch0[i]; + j++; + } + dl_ch0_ext+= j; + if (aatx==0) rxF_ext+= j; + } + } - dl_ch0+=12; - if (aatx==0) { - rxF+=12; - k+=12; - if (k>=frame_parms->ofdm_symbol_size) { - k=k-(frame_parms->ofdm_symbol_size); - rxF = &rxdataF[aarx][k+(symbol*(frame_parms->ofdm_symbol_size))]; - } - } + dl_ch0+=12; + if (aatx==0) { + rxF+=12; + k+=12; + if (k>=frame_parms->ofdm_symbol_size) { + k=k-(frame_parms->ofdm_symbol_size); + rxF = &rxdataF[aarx][k+(symbol*(frame_parms->ofdm_symbol_size))]; + } + } }//rb }//aatx }//aarx diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 0be6201954..547c55a799 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -697,7 +697,7 @@ void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms, @param dl_ch_estimates_ext Channel estimates for RBs in this allocation @param rb_alloc RB allocation vector @param symbol Symbol to extract - @param high_speed_flag + @param n_dmrs_cdm_groups @param frame_parms Pointer to frame descriptor */ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, @@ -709,7 +709,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, uint8_t config_type, unsigned short start_rb, unsigned short nb_rb_pdsch, - uint32_t high_speed_flag, + uint8_t n_dmrs_cdm_groups, NR_DL_FRAME_PARMS *frame_parms, uint16_t dlDmrsSymbPos); @@ -722,7 +722,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, uint8_t config_type, unsigned short start_rb, unsigned short nb_rb_pdsch, - uint32_t high_speed_flag, + uint8_t n_dmrs_cdm_groups, uint8_t Nl, NR_DL_FRAME_PARMS *frame_parms, uint16_t dlDmrsSymbPos) @@ -734,7 +734,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, @param dl_ch_estimates_ext Channel estimates for RBs in this allocation @param Nl nb of antenna layers @param symbol Symbol to extract - @param high_speed_flag + @param n_dmrs_cdm_groups @param frame_parms Pointer to frame descriptor */ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF, @@ -746,7 +746,7 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF, uint8_t config_type, unsigned short start_rb, unsigned short nb_rb_pdsch, - uint32_t high_speed_flag, + uint8_t n_dmrs_cdm_groups, uint8_t Nl, NR_DL_FRAME_PARMS *frame_parms, uint16_t dlDmrsSymbPos); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 42e4930ed2..333107dcd1 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -796,43 +796,24 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ slot = 1; start_meas(&ue->dlsch_llr_stats_parallelization[proc->thread_id][slot]); #endif - // process DLSCH received in first slot - // skip DMRS symbols (will have to check later if PDSCH/DMRS are multiplexed - if (((1<harq_processes[harq_pid]->dlDmrsSymbPos) == 0) { + // process DLSCH received symbols in the slot + // symbol by symbol processing (if data/DMRS are multiplexed is checked inside the function) + if (pdsch == PDSCH || pdsch == SI_PDSCH || pdsch == RA_PDSCH) { if (nr_rx_pdsch(ue, - proc, - pdsch, - eNB_id, - eNB_id_i, - frame_rx, - nr_slot_rx, - m, - first_symbol_flag, - dual_stream_UE, - i_mod, - dlsch0->current_harq_pid) < 0) - return -1; - } - else { // This is to adjust the llr offset in the case of skipping over a dmrs symbol (i.e. in case of no PDSCH REs in DMRS) - if (pdsch == RA_PDSCH) ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m]=ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m-1]; - else if (pdsch == PDSCH || pdsch == SI_PDSCH) { - if (nr_rx_pdsch(ue, - proc, - pdsch, - eNB_id, - eNB_id_i, - frame_rx, - nr_slot_rx, - m, - first_symbol_flag, - dual_stream_UE, - i_mod, - dlsch0->current_harq_pid) < 0) - return -1; - } - else AssertFatal(1==0,"Not RA_PDSCH, SI_PDSCH or PDSCH\n"); - } - if (pdsch == PDSCH) LOG_D(PHY,"Done processing symbol %d : llr_offset %d\n",m,ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m]); + proc, + pdsch, + eNB_id, + eNB_id_i, + frame_rx, + nr_slot_rx, + m, + first_symbol_flag, + dual_stream_UE, + i_mod, + dlsch0->current_harq_pid) < 0) + return -1; + } else AssertFatal(1==0,"Not RA_PDSCH, SI_PDSCH or PDSCH\n"); + #if UE_TIMING_TRACE stop_meas(&ue->dlsch_llr_stats_parallelization[proc->thread_id][slot]); #if DISABLE_LOG_X @@ -842,10 +823,9 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ #endif #endif - if(first_symbol_flag) - { - proc->first_symbol_available = 1; - } + if(first_symbol_flag) { + proc->first_symbol_available = 1; + } } // CRNTI active } return 0; From d7facef8a4b9fd488cb73a9f5be16aa64b404680 Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Fri, 29 Jan 2021 18:03:03 +0100 Subject: [PATCH 19/40] Back to SISO mode --- openair1/PHY/INIT/nr_parms.c | 2 +- .../CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 7fa39b1f9c..814177a86c 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -335,7 +335,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, int Ncp = NORMAL; if(fp->nb_antennas_rx == 0) - fp->nb_antennas_rx = 4; + fp->nb_antennas_rx = 1; if(fp->nb_antennas_tx == 0) fp->nb_antennas_tx = 1; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index f83b082211..25aa57b92c 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -23,7 +23,7 @@ gNBs = ////////// Physical parameters: ssb_SubcarrierOffset = 0; - pdsch_AntennaPorts = 4; + pdsch_AntennaPorts = 1; servingCellConfigCommon = ( { @@ -240,7 +240,7 @@ L1s = ( RUs = ( { local_rf = "yes" - nb_tx = 4 + nb_tx = 1 nb_rx = 1 att_tx = 0 att_rx = 0; @@ -255,7 +255,7 @@ RUs = ( ## beamforming 2x2 matrix: # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; ## beamforming 4x4 matrix: - bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; + #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; clock_src = "external"; From ad2b04c1d16eafa0e60d2e7dc7987dba02477202 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 1 Feb 2021 11:06:43 +0100 Subject: [PATCH 20/40] fix compile warning by removing unused variable 'nb_antenna_ports' --- openair1/SCHED_NR/nr_ru_procedures.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 7e39582251..160fc44d58 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -279,7 +279,7 @@ static void *nr_feptx_thread(void *param) { RU_feptx_t *feptx = (RU_feptx_t *)param; RU_t *ru; - int aa, slot, start, l, nb_antenna_ports, ret; + int aa, slot, start, l, ret; int i; int32_t ***bw; NR_DL_FRAME_PARMS *fp; @@ -298,7 +298,6 @@ static void *nr_feptx_thread(void *param) { l = feptx->symbol; fp = ru->nr_frame_parms; start = feptx->symbol; - nb_antenna_ports = feptx->nb_antenna_ports; ofdm_mask_full = (1<<(ru->nb_tx*2))-1; if(ru->num_gNB != 0){ From 283a060497e64ca5037f497b9535cb5bb7dfa4cc Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Mon, 1 Feb 2021 20:00:26 +0100 Subject: [PATCH 21/40] Allow gNB to read pusch_AntennPorts from config file --- .../conf_files/gnb.band78.tm1.106PRB.usrpn300.conf | 13 ++++++++++--- openair1/SIMULATION/NR_PHY/dlsim.c | 7 ++++--- openair1/SIMULATION/NR_PHY/ulsim.c | 4 ++-- openair2/COMMON/rrc_messages_types.h | 1 + openair2/GNB_APP/gnb_config.c | 2 ++ openair2/GNB_APP/gnb_paramdef.h | 7 +++++-- openair2/LAYER2/NR_MAC_gNB/config.c | 13 ++++++++----- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 6 ++++-- openair2/RRC/NR/nr_rrc_defs.h | 1 + openair2/RRC/NR/rrc_gNB.c | 2 ++ openair2/RRC/NR/rrc_gNB_nsa.c | 1 + .../CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 4 ++-- 12 files changed, 42 insertions(+), 19 deletions(-) diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf index aeba400cad..46da933158 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -23,7 +23,8 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; - + pusch_AntennaPorts = 1; + servingCellConfigCommon = ( { #spCellConfigCommon @@ -248,8 +249,14 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 75; eNB_instances = [0]; - #beamforming 1x4 matrix: - bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + ##beamforming 1x2 matrix: 1 layer x 2 antennas + #bf_weights = [0x00007fff, 0x00007fff]; + ##beamforming 1x4 matrix: 1 layer x 4 antennas + #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000]; + ## beamforming 2x2 matrix: + #bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; + ## beamforming 4x4 matrix: + #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; clock_src = "external"; } diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 9aab17cc67..eed12d593c 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -126,7 +126,8 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( } void config_common(int Mod_idP, - int pdsch_AntennaPorts, + int pdsch_AntennaPorts, + int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc ); @@ -640,9 +641,9 @@ int main(int argc, char **argv) AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface"); gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; // common configuration - rrc_mac_config_req_gNB(0,0,n_tx,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL); + rrc_mac_config_req_gNB(0,0,n_tx,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL); // UE dedicated configuration - rrc_mac_config_req_gNB(0,0,n_tx,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); + rrc_mac_config_req_gNB(0,0,n_tx,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); phy_init_nr_gNB(gNB,0,0); N_RB_DL = gNB->frame_parms.N_RB_DL; // stub to configure frame_parms diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 670cf5cc9f..d6ae318912 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -607,9 +607,9 @@ int main(int argc, char **argv) gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; // common configuration - rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL); + rrc_mac_config_req_gNB(0,0,1,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL); // UE dedicated configuration - rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); + rrc_mac_config_req_gNB(0,0,1,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); phy_init_nr_gNB(gNB,0,0); N_RB_DL = gNB->frame_parms.N_RB_DL; diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 02f878ee2e..a2968391d0 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -407,6 +407,7 @@ typedef struct NRRrcConfigurationReq_s { NR_ServingCellConfigCommon_t *scc; int ssb_SubcarrierOffset; int pdsch_AntennaPorts; + int pusch_AntennaPorts; int pusch_TargetSNRx10; int pucch_TargetSNRx10; } gNB_RrcConfigurationReq; diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 940d07c16d..02d8ad9e42 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -665,6 +665,8 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { NRRRC_CONFIGURATION_REQ (msg_p).ssb_SubcarrierOffset = *GNBParamList.paramarray[i][GNB_SSB_SUBCARRIEROFFSET_IDX].iptr; printf("pdsch_AntennaPorts %d\n",*GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_IDX].iptr); NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts = *GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_IDX].iptr; + printf("pusch_AntennaPorts %d\n",*GNBParamList.paramarray[i][GNB_PUSCH_ANTENNAPORTS_IDX].iptr); + NRRRC_CONFIGURATION_REQ (msg_p).pusch_AntennaPorts = *GNBParamList.paramarray[i][GNB_PUSCH_ANTENNAPORTS_IDX].iptr; printf("pusch_TargetSNRx10 %d\n",*GNBParamList.paramarray[i][GNB_PUSCH_TARGETPOW_X10_IDX].iptr); NRRRC_CONFIGURATION_REQ (msg_p).pusch_TargetSNRx10 = *GNBParamList.paramarray[i][GNB_PUSCH_TARGETPOW_X10_IDX].iptr; printf("pucch_TargetSNRx10 %d\n",*GNBParamList.paramarray[i][GNB_PUCCH_TARGETPOW_X10_IDX].iptr); diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 981f2ba193..e1da6f98de 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -120,6 +120,7 @@ typedef enum { #define GNB_CONFIG_STRING_REMOTE_S_PORTD "remote_s_portd" #define GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET "ssb_SubcarrierOffset" #define GNB_CONFIG_STRING_PDSCHANTENNAPORTS "pdsch_AntennaPorts" +#define GNB_CONFIG_STRING_PUSCHANTENNAPORTS "pusch_AntennaPorts" #define GNB_CONFIG_STRING_PUSCHTARGETPOWX10 "pusch_TargetSNRx10" #define GNB_CONFIG_STRING_PUCCHTARGETPOWX10 "pucch_TargetSNRx10" @@ -144,6 +145,7 @@ typedef enum { {GNB_CONFIG_STRING_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \ {GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET, NULL, 0, iptr:NULL, defintval:31, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_PDSCHANTENNAPORTS, NULL, 0, iptr:NULL, defintval:1, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_PUSCHANTENNAPORTS, NULL, 0, iptr:NULL, defintval:1, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_PUSCHTARGETPOWX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_PUCCHTARGETPOWX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ } @@ -164,8 +166,9 @@ typedef enum { #define GNB_REMOTE_S_PORTD_IDX 13 #define GNB_SSB_SUBCARRIEROFFSET_IDX 14 #define GNB_PDSCH_ANTENNAPORTS_IDX 15 -#define GNB_PUSCH_TARGETPOW_X10_IDX 16 -#define GNB_PUCCH_TARGETPOW_X10_IDX 17 +#define GNB_PUSCH_ANTENNAPORTS_IDX 16 +#define GNB_PUSCH_TARGETPOW_X10_IDX 17 +#define GNB_PUCCH_TARGETPOW_X10_IDX 18 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} #define GNBPARAMS_CHECK { \ diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index d9ca0ad009..892b5fdd13 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -54,7 +54,7 @@ extern RAN_CONTEXT_t RC; extern void mac_top_init_gNB(void); extern uint8_t nfapi_mode; -void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) { +void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) { nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[Mod_idP]->config[0]; RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon = scc; @@ -275,7 +275,8 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm num_ssb += (cfg->ssb_table.ssb_mask_list[1].ssb_mask.value>>i)&1; } - cfg->carrier_config.num_rx_ant.value = 1; //cfg->carrier_config.num_tx_ant.value; + cfg->carrier_config.num_rx_ant.value = pusch_AntennaPorts; + AssertFatal(pusch_AntennaPorts > 0 && pusch_AntennaPorts < 13, "pusch_AntennaPorts in 1...12\n"); cfg->carrier_config.num_rx_ant.tl.tag = NFAPI_NR_CONFIG_NUM_RX_ANT_TAG; LOG_I(MAC,"Set TX/RX antenna number to %d (num ssb %d: %x,%x)\n",cfg->carrier_config.num_tx_ant.value,num_ssb,cfg->ssb_table.ssb_mask_list[0].ssb_mask.value,cfg->ssb_table.ssb_mask_list[1].ssb_mask.value); AssertFatal(cfg->carrier_config.num_tx_ant.value > 0,"carrier_config.num_tx_ant.value %d !\n",cfg->carrier_config.num_tx_ant.value ); @@ -313,9 +314,10 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm extern uint16_t sl_ahead; -int rrc_mac_config_req_gNB(module_id_t Mod_idP, - int ssb_SubcarrierOffset, +int rrc_mac_config_req_gNB(module_id_t Mod_idP, + int ssb_SubcarrierOffset, int pdsch_AntennaPorts, + int pusch_AntennaPorts, int pusch_tgt_snrx10, int pucch_tgt_snrx10, NR_ServingCellConfigCommon_t *scc, @@ -353,7 +355,8 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, LOG_I(MAC,"Configuring common parameters from NR ServingCellConfig\n"); config_common(Mod_idP, - pdsch_AntennaPorts, + pdsch_AntennaPorts, + pusch_AntennaPorts, scc); LOG_E(MAC, "%s() %s:%d RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index a8dbec98f5..20f78227ec 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -42,12 +42,14 @@ void mac_top_init_gNB(void); void config_common(int Mod_idP, int pdsch_AntennaPorts, + int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc ); -int rrc_mac_config_req_gNB(module_id_t Mod_idP, - int ssb_SubcarrierOffset, +int rrc_mac_config_req_gNB(module_id_t Mod_idP, + int ssb_SubcarrierOffset, int pdsch_AntennaPorts, + int pusch_AntennaPorts, int pusch_tgt_snrx10, int pucch_tgt_snrx10, NR_ServingCellConfigCommon_t *scc, diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index a64f2417ea..fa2cbdd476 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -399,6 +399,7 @@ typedef struct { NR_BCCH_BCH_Message_t mib; int ssb_SubcarrierOffset; int pdsch_AntennaPorts; + int pusch_AntennaPorts; int pusch_TargetSNRx10; int pucch_TargetSNRx10; NR_BCCH_DL_SCH_Message_t *siblock1; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index ba7fbe1671..1edaee72ba 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -217,6 +217,7 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration rrc_mac_config_req_gNB(rrc->module_id, rrc->carrier.ssb_SubcarrierOffset, rrc->carrier.pdsch_AntennaPorts, + rrc->carrier.pusch_AntennaPorts, rrc->carrier.pusch_TargetSNRx10, rrc->carrier.pucch_TargetSNRx10, (NR_ServingCellConfigCommon_t *)rrc->carrier.servingcellconfigcommon, @@ -298,6 +299,7 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu rrc->carrier.servingcellconfigcommon = configuration->scc; rrc->carrier.ssb_SubcarrierOffset = configuration->ssb_SubcarrierOffset; rrc->carrier.pdsch_AntennaPorts = configuration->pdsch_AntennaPorts; + rrc->carrier.pusch_AntennaPorts = configuration->pusch_AntennaPorts; rrc->carrier.pusch_TargetSNRx10 = configuration->pusch_TargetSNRx10; rrc->carrier.pucch_TargetSNRx10 = configuration->pucch_TargetSNRx10; /// System Information INIT diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 5b1fb70c52..4d3ebd6d7d 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -264,6 +264,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ rrc_mac_config_req_gNB(rrc->module_id, rrc->carrier.ssb_SubcarrierOffset, rrc->carrier.pdsch_AntennaPorts, + rrc->carrier.pusch_AntennaPorts, rrc->carrier.pusch_TargetSNRx10, rrc->carrier.pucch_TargetSNRx10, NULL, diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 25aa57b92c..6a31263b2e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -24,6 +24,7 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; servingCellConfigCommon = ( { @@ -253,10 +254,9 @@ RUs = ( ##beamforming 1x4 matrix: 1 layer x 4 antennas #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000]; ## beamforming 2x2 matrix: - # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; + #bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; ## beamforming 4x4 matrix: #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; - sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; clock_src = "external"; } From 8b00361f564131c98b8b3bb869f3908d17de2b3c Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 3 Feb 2021 10:50:38 +0100 Subject: [PATCH 22/40] fix warnings identified by CI --- common/utils/ocp_itti/intertask_interface.cpp | 4 +++- executables/nr-gnb.c | 2 +- targets/ARCH/iqplayer/iqplayer_lib.c | 1 - 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp index 2189be9fe8..c774da57e6 100644 --- a/common/utils/ocp_itti/intertask_interface.cpp +++ b/common/utils/ocp_itti/intertask_interface.cpp @@ -339,7 +339,9 @@ extern "C" { int itti_create_queue(const task_info_t *taskInfo) { pthread_mutex_lock (&lock_nb_queues); int newQueue=nb_queues++; - AssertFatal(tasks=(task_list_t **) realloc(tasks, nb_queues * sizeof(*tasks)),""); + task_list_t **new_tasks = (task_list_t **)realloc(tasks, nb_queues * sizeof(*tasks)); + AssertFatal(new_tasks != NULL, "could not realloc() tasks list"); + tasks = new_tasks; tasks[newQueue]= new task_list_t; pthread_mutex_unlock (&lock_nb_queues); LOG_I(TMR,"Starting itti queue: %s as task %d\n", taskInfo->name, newQueue); diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 1d23c72315..2fd0c0998f 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -874,7 +874,7 @@ void init_gNB_proc(int inst) { gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t)); gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); int numCPU = sysconf(_SC_NPROCESSORS_ONLN); - uint32_t num_threads_pusch; + uint32_t num_threads_pusch = 1; paramdef_t PUSCHThreads[] = NUM_THREADS_DESC; config_get( PUSCHThreads,sizeof(PUSCHThreads)/sizeof(paramdef_t),NULL); int threadCnt = min(numCPU, num_threads_pusch); diff --git a/targets/ARCH/iqplayer/iqplayer_lib.c b/targets/ARCH/iqplayer/iqplayer_lib.c index c4133d1b11..66308d4b1c 100644 --- a/targets/ARCH/iqplayer/iqplayer_lib.c +++ b/targets/ARCH/iqplayer/iqplayer_lib.c @@ -25,7 +25,6 @@ */ #define _LARGEFILE_SOURCE #define _FILE_OFFSET_BITS 64 -#define NB_ANTENNAS_RX 2 #include #include #include From 97801299dc635607b927c09511506160f6bc80ba Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 10 Feb 2021 09:10:22 +0100 Subject: [PATCH 23/40] some whitespace fixes in openair1/PHY/MODULATION/nr_modulation.c --- openair1/PHY/MODULATION/nr_modulation.c | 278 ++++++++++++------------ 1 file changed, 137 insertions(+), 141 deletions(-) diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index 04955c31a4..b41007f0e1 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -24,98 +24,97 @@ //Table 6.3.1.5-1 Precoding Matrix W 1 layer 2 antenna ports 'n' = -1 and 'o' = -j char nr_W_1l_2p[6][2][1] = { - {{'1'}, {'0'}},//pmi 0 - {{'0'}, {'1'}}, - {{'1'}, {'1'}}, - {{'1'}, {'n'}}, - {{'1'}, {'j'}}, - {{'1'}, {'o'}}//pmi 5 + {{'1'}, {'0'}},//pmi 0 + {{'0'}, {'1'}}, + {{'1'}, {'1'}}, + {{'1'}, {'n'}}, + {{'1'}, {'j'}}, + {{'1'}, {'o'}}//pmi 5 }; //Table 6.3.1.5-3 Precoding Matrix W 1 layer 4 antenna ports 'n' = -1 and 'o' = -j char nr_W_1l_4p[28][4][1] = { - {{'1'}, {'0'}, {'0'}, {'0'}},//pmi 0 - {{'0'}, {'1'}, {'0'}, {'0'}}, - {{'0'}, {'0'}, {'1'}, {'0'}}, - {{'0'}, {'0'}, {'0'}, {'1'}}, - {{'1'}, {'0'}, {'1'}, {'0'}}, - {{'1'}, {'0'}, {'n'}, {'0'}}, - {{'1'}, {'0'}, {'j'}, {'0'}}, - {{'1'}, {'0'}, {'o'}, {'0'}},//pmi 7 - {{'0'}, {'1'}, {'0'}, {'1'}},//pmi 8 - {{'0'}, {'1'}, {'0'}, {'n'}}, - {{'0'}, {'1'}, {'0'}, {'j'}}, - {{'0'}, {'1'}, {'0'}, {'o'}}, - {{'1'}, {'1'}, {'1'}, {'1'}}, - {{'1'}, {'1'}, {'j'}, {'j'}}, - {{'1'}, {'1'}, {'n'}, {'n'}}, - {{'1'}, {'1'}, {'o'}, {'o'}}, - {{'1'}, {'j'}, {'1'}, {'j'}},//pmi 16 - {{'1'}, {'j'}, {'j'}, {'n'}}, - {{'1'}, {'j'}, {'n'}, {'o'}}, - {{'1'}, {'j'}, {'o'}, {'1'}}, - {{'1'}, {'n'}, {'1'}, {'n'}}, - {{'1'}, {'n'}, {'j'}, {'o'}}, - {{'1'}, {'n'}, {'n'}, {'1'}}, - {{'1'}, {'n'}, {'o'}, {'j'}},//pmi 23 - {{'1'}, {'o'}, {'1'}, {'o'}},//pmi 24 - {{'1'}, {'o'}, {'j'}, {'1'}}, - {{'1'}, {'o'}, {'n'}, {'j'}}, - {{'1'}, {'o'}, {'o'}, {'n'}}//pmi 27 + {{'1'}, {'0'}, {'0'}, {'0'}},//pmi 0 + {{'0'}, {'1'}, {'0'}, {'0'}}, + {{'0'}, {'0'}, {'1'}, {'0'}}, + {{'0'}, {'0'}, {'0'}, {'1'}}, + {{'1'}, {'0'}, {'1'}, {'0'}}, + {{'1'}, {'0'}, {'n'}, {'0'}}, + {{'1'}, {'0'}, {'j'}, {'0'}}, + {{'1'}, {'0'}, {'o'}, {'0'}},//pmi 7 + {{'0'}, {'1'}, {'0'}, {'1'}},//pmi 8 + {{'0'}, {'1'}, {'0'}, {'n'}}, + {{'0'}, {'1'}, {'0'}, {'j'}}, + {{'0'}, {'1'}, {'0'}, {'o'}}, + {{'1'}, {'1'}, {'1'}, {'1'}}, + {{'1'}, {'1'}, {'j'}, {'j'}}, + {{'1'}, {'1'}, {'n'}, {'n'}}, + {{'1'}, {'1'}, {'o'}, {'o'}}, + {{'1'}, {'j'}, {'1'}, {'j'}},//pmi 16 + {{'1'}, {'j'}, {'j'}, {'n'}}, + {{'1'}, {'j'}, {'n'}, {'o'}}, + {{'1'}, {'j'}, {'o'}, {'1'}}, + {{'1'}, {'n'}, {'1'}, {'n'}}, + {{'1'}, {'n'}, {'j'}, {'o'}}, + {{'1'}, {'n'}, {'n'}, {'1'}}, + {{'1'}, {'n'}, {'o'}, {'j'}},//pmi 23 + {{'1'}, {'o'}, {'1'}, {'o'}},//pmi 24 + {{'1'}, {'o'}, {'j'}, {'1'}}, + {{'1'}, {'o'}, {'n'}, {'j'}}, + {{'1'}, {'o'}, {'o'}, {'n'}}//pmi 27 }; //Table 6.3.1.5-4 Precoding Matrix W 2 antenna ports layers 2 'n' = -1 and 'o' = -j char nr_W_2l_2p[3][2][2] = { - {{'1', '0'}, {'0', '1'}},//pmi 0 - {{'1', '1'}, {'1', 'n'}}, - {{'1', '1'}, {'j', 'o'}} //pmi 2 - + {{'1', '0'}, {'0', '1'}},//pmi 0 + {{'1', '1'}, {'1', 'n'}}, + {{'1', '1'}, {'j', 'o'}} //pmi 2 }; //Table 6.3.1.5-5 Precoding Matrix W 2 layers 4 antenna ports 'n' = -1 and 'o' = -j char nr_W_2l_4p[22][4][2] = { - {{'1', '0'}, {'0', '1'}, {'0', '0'}, {'0', '0'}},//pmi 0 - {{'1', '0'}, {'0', '0'}, {'0', '1'}, {'0', '0'}}, - {{'1', '0'}, {'0', '0'}, {'0', '0'}, {'0', '1'}}, - {{'0', '0'}, {'1', '0'}, {'0', '1'}, {'0', '0'}},//pmi 3 - {{'0', '0'}, {'1', '0'}, {'0', '0'}, {'0', '1'}},//pmi 4 - {{'0', '0'}, {'0', '0'}, {'1', '0'}, {'0', '1'}}, - {{'1', '0'}, {'0', '1'}, {'1', '0'}, {'0', 'o'}}, - {{'1', '0'}, {'0', '1'}, {'1', '0'}, {'0', 'j'}}, - {{'1', '0'}, {'0', '1'}, {'o', '0'}, {'0', '1'}},//pmi 8 - {{'1', '0'}, {'0', '1'}, {'o', '0'}, {'0', 'n'}}, - {{'1', '0'}, {'0', '1'}, {'n', '0'}, {'0', 'o'}}, - {{'1', '0'}, {'0', '1'}, {'n', '0'}, {'0', 'j'}},//pmi 11 - {{'1', '0'}, {'0', '1'}, {'j', '0'}, {'0', '1'}},//pmi 12 - {{'1', '0'}, {'0', '1'}, {'j', '0'}, {'0', 'n'}}, - {{'1', '1'}, {'1', '1'}, {'1', 'n'}, {'1', 'n'}}, - {{'1', '1'}, {'1', '1'}, {'j', 'o'}, {'j', 'o'}},//pmi 15 - {{'1', '1'}, {'j', 'j'}, {'1', 'n'}, {'j', 'o'}},//pmi 16 - {{'1', '1'}, {'j', 'j'}, {'j', 'o'}, {'n', '1'}}, - {{'1', '1'}, {'n', 'n'}, {'1', 'n'}, {'n', '1'}}, - {{'1', '1'}, {'n', 'n'}, {'j', 'o'}, {'o', 'j'}},//pmi 19 - {{'1', '1'}, {'o', 'o'}, {'1', 'n'}, {'o', 'j'}}, - {{'1', '1'}, {'o', 'o'}, {'j', 'o'}, {'1', 'n'}}//pmi 21 + {{'1', '0'}, {'0', '1'}, {'0', '0'}, {'0', '0'}},//pmi 0 + {{'1', '0'}, {'0', '0'}, {'0', '1'}, {'0', '0'}}, + {{'1', '0'}, {'0', '0'}, {'0', '0'}, {'0', '1'}}, + {{'0', '0'}, {'1', '0'}, {'0', '1'}, {'0', '0'}},//pmi 3 + {{'0', '0'}, {'1', '0'}, {'0', '0'}, {'0', '1'}},//pmi 4 + {{'0', '0'}, {'0', '0'}, {'1', '0'}, {'0', '1'}}, + {{'1', '0'}, {'0', '1'}, {'1', '0'}, {'0', 'o'}}, + {{'1', '0'}, {'0', '1'}, {'1', '0'}, {'0', 'j'}}, + {{'1', '0'}, {'0', '1'}, {'o', '0'}, {'0', '1'}},//pmi 8 + {{'1', '0'}, {'0', '1'}, {'o', '0'}, {'0', 'n'}}, + {{'1', '0'}, {'0', '1'}, {'n', '0'}, {'0', 'o'}}, + {{'1', '0'}, {'0', '1'}, {'n', '0'}, {'0', 'j'}},//pmi 11 + {{'1', '0'}, {'0', '1'}, {'j', '0'}, {'0', '1'}},//pmi 12 + {{'1', '0'}, {'0', '1'}, {'j', '0'}, {'0', 'n'}}, + {{'1', '1'}, {'1', '1'}, {'1', 'n'}, {'1', 'n'}}, + {{'1', '1'}, {'1', '1'}, {'j', 'o'}, {'j', 'o'}},//pmi 15 + {{'1', '1'}, {'j', 'j'}, {'1', 'n'}, {'j', 'o'}},//pmi 16 + {{'1', '1'}, {'j', 'j'}, {'j', 'o'}, {'n', '1'}}, + {{'1', '1'}, {'n', 'n'}, {'1', 'n'}, {'n', '1'}}, + {{'1', '1'}, {'n', 'n'}, {'j', 'o'}, {'o', 'j'}},//pmi 19 + {{'1', '1'}, {'o', 'o'}, {'1', 'n'}, {'o', 'j'}}, + {{'1', '1'}, {'o', 'o'}, {'j', 'o'}, {'1', 'n'}}//pmi 21 }; //Table 6.3.1.5-6 Precoding Matrix W 3 layers 4 antenna ports 'n' = -1 and 'o' = -j char nr_W_3l_4p[7][4][3] = { - {{'1', '0', '0'}, {'0', '1', '0'}, {'0', '0', '1'},{'0', '0', '0'}},//pmi 0 - {{'1', '0', '0'}, {'0', '1', '0'}, {'1', '0', '0'},{'0', '0', '1'}}, - {{'1', '0', '0'}, {'0', '1', '0'}, {'n', '0', '0'},{'0', '0', '1'}}, - {{'1', '1', '1'}, {'1', 'n', '1'}, {'1', '1', 'n'},{'1', 'n', 'n'}},//pmi 3 - {{'1', '1', '1'}, {'1', 'n', '1'}, {'j', 'j', 'o'},{'j', 'o', 'o'}},//pmi 4 - {{'1', '1', '1'}, {'n', '1', 'n'}, {'1', '1', 'n'},{'n', '1', '1'}}, - {{'1', '1', '1'}, {'n', '1', 'n'}, {'j', 'j', 'o'},{'o', 'j', 'j'}} + {{'1', '0', '0'}, {'0', '1', '0'}, {'0', '0', '1'},{'0', '0', '0'}},//pmi 0 + {{'1', '0', '0'}, {'0', '1', '0'}, {'1', '0', '0'},{'0', '0', '1'}}, + {{'1', '0', '0'}, {'0', '1', '0'}, {'n', '0', '0'},{'0', '0', '1'}}, + {{'1', '1', '1'}, {'1', 'n', '1'}, {'1', '1', 'n'},{'1', 'n', 'n'}},//pmi 3 + {{'1', '1', '1'}, {'1', 'n', '1'}, {'j', 'j', 'o'},{'j', 'o', 'o'}},//pmi 4 + {{'1', '1', '1'}, {'n', '1', 'n'}, {'1', '1', 'n'},{'n', '1', '1'}}, + {{'1', '1', '1'}, {'n', '1', 'n'}, {'j', 'j', 'o'},{'o', 'j', 'j'}} }; //Table 6.3.1.5-7 Precoding Matrix W 4 layers 4 antenna ports 'n' = -1 and 'o' = -j char nr_W_4l_4p[5][4][4] = { - {{'1', '0', '0', '0'}, {'0', '1', '0', '0'}, {'0', '0', '1', '0'}, {'0', '0', '0', '1'}},//pmi 0 - {{'1', '1', '0', '0'}, {'0', '0', '1', '1'}, {'1', 'n', '0', '0'}, {'0', '0', '1', 'n'}}, - {{'1', '1', '0', '0'}, {'0', '0', '1', '1'}, {'j', 'o', '0', '0'}, {'0', '0', 'j', 'o'}}, - {{'1', '1', '1', '1'}, {'1', 'n', '1', 'n'}, {'1', '1', 'n', 'n'}, {'1', 'n', 'n', '1'}},//pmi 3 - {{'1', '1', '1', '1'}, {'1', 'n', '1', 'n'}, {'j', 'j', 'o', 'o'}, {'j', 'o', 'o', 'j'}}//pmi 4 + {{'1', '0', '0', '0'}, {'0', '1', '0', '0'}, {'0', '0', '1', '0'}, {'0', '0', '0', '1'}},//pmi 0 + {{'1', '1', '0', '0'}, {'0', '0', '1', '1'}, {'1', 'n', '0', '0'}, {'0', '0', '1', 'n'}}, + {{'1', '1', '0', '0'}, {'0', '0', '1', '1'}, {'j', 'o', '0', '0'}, {'0', '0', 'j', 'o'}}, + {{'1', '1', '1', '1'}, {'1', 'n', '1', 'n'}, {'1', '1', 'n', 'n'}, {'1', 'n', 'n', '1'}},//pmi 3 + {{'1', '1', '1', '1'}, {'1', 'n', '1', 'n'}, {'j', 'j', 'o', 'o'}, {'j', 'o', 'o', 'j'}}//pmi 4 }; void nr_modulation(uint32_t *in, @@ -133,7 +132,7 @@ void nr_modulation(uint32_t *in, uint32_t i,j; uint32_t bit_cnt; uint64_t x,x1,x2; - + #if defined(__SSE2__) __m128i *nr_mod_table128; __m128i *out128; @@ -152,7 +151,7 @@ void nr_modulation(uint32_t *in, // the bits that are left out i = i*8/2; nr_mod_table32 = (int32_t*) nr_qpsk_mod_table; - while (i>((i*2)&0x7)) & mask); out32[i] = nr_mod_table32[idx]; i++; @@ -174,7 +173,7 @@ void nr_modulation(uint32_t *in, out64[i] = nr_16qam_byte_mod_table[in_bytes[i]]; // the bits that are left out i = i*8/4; - while (i>((i*4)&0x7)) & mask); out32[i] = nr_16qam_mod_table[idx]; i++; @@ -184,7 +183,7 @@ void nr_modulation(uint32_t *in, case 6: j = 0; for (i=0; i>12)&4095; @@ -236,7 +235,7 @@ void nr_modulation(uint32_t *in, bit_cnt += 24; } return; - + case 8: nr_mod_table32 = (int32_t*) nr_256qam_mod_table; for (i=0; i>1; i++) @@ -282,8 +281,8 @@ void nr_layer_mapping(int16_t **mod_symbs, for (int l=2; l<5; l++) { tx_layers[l][i<<1] = mod_symbs[1][(3*i+l)<<1]; tx_layers[l][(i<<1)+1] = mod_symbs[1][((3*i+l)<<1)+1]; - } - break; + } + break; case 6: for (int q=0; q<2; q++) @@ -292,7 +291,7 @@ void nr_layer_mapping(int16_t **mod_symbs, tx_layers[l][i<<1] = mod_symbs[q][(3*i+l)<<1]; tx_layers[l][(i<<1)+1] = mod_symbs[q][((3*i+l)<<1)+1]; } - break; + break; case 7: for (int i=0; id_mod; - for (int i=0; i>15; tx_layers[0][(i<<1)+1] = (mod_symbs[(i<<1)+1]*AMP)>>15; } - break; + break; case 2: case 3: case 4: mod_symbs = (int16_t *)ulsch_ue[0]->d_mod; - for (int i=0; i>15; tx_layers[l][(i<<1)+1] = (mod_symbs[((n_layers*i+l)<<1)+1]*AMP)>>15; } } - break; + break; case 5: mod_symbs = (int16_t *)ulsch_ue[0]->d_mod; @@ -367,11 +366,10 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue, tx_layers[l][i<<1] = (mod_symbs[(3*i+l)<<1]*AMP)>>15; tx_layers[l][(i<<1)+1] = (mod_symbs[((3*i+l)<<1)+1]*AMP)>>15; } - break; + break; case 6: - for (int q=0; q<2; q++){ - + for (int q=0; q<2; q++) { mod_symbs = (int16_t *)ulsch_ue[q]->d_mod; for (int i=0; i>15; } } - break; + break; case 7: mod_symbs = (int16_t *)ulsch_ue[1]->d_mod; @@ -398,11 +396,10 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue, tx_layers[l][i<<1] = (mod_symbs[((i<<2)+l)<<1]*AMP)>>15; tx_layers[l][(i<<1)+1] = (mod_symbs[(((i<<2)+l)<<1)+1]*AMP)>>15; } - break; + break; case 8: - for (int q=0; q<2; q++){ - + for (int q=0; q<2; q++) { mod_symbs = (int16_t *)ulsch_ue[q]->d_mod; for (int i=0; i>2; i++) @@ -411,10 +408,10 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue, tx_layers[l][(i<<1)+1] = (mod_symbs[(((i<<2)+l)<<1)+1]*AMP)>>15; } } - break; + break; - default: - AssertFatal(0, "Invalid number of layers %d\n", n_layers); + default: + AssertFatal(0, "Invalid number of layers %d\n", n_layers); } } @@ -598,8 +595,8 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) } -void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq) { - +void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq) +{ const int nsymb = fp->symbols_per_slot * fp->slots_per_frame/10; const double Tc=(1/480e3/4096); const double Nu=2048*64*(1/(float)(1<numerology_index)); @@ -616,57 +613,56 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq) { fp->symbol_rotation[1]=(int16_t)floor(exp_im*32767); LOG_I(PHY,"Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n",f0,nsymb); LOG_I(PHY,"Symbol rotation %d/%d => (%d,%d)\n",0,nsymb,fp->symbol_rotation[0],fp->symbol_rotation[1]); - for (int l=1;lnumerology_index))) Ncp=Ncp0; else Ncp=Ncp1; - tl += (Nu+Ncpm1)*Tc; + tl += (Nu+Ncpm1)*Tc; poff = 2*M_PI*(tl + (Ncp*Tc))*f0; exp_re = cos(poff); exp_im = sin(-poff); fp->symbol_rotation[l<<1]=(int16_t)floor(exp_re*32767); fp->symbol_rotation[1+(l<<1)]=(int16_t)floor(exp_im*32767); - LOG_I(PHY,"Symbol rotation %d/%d => tl %f (%d,%d) (%f)\n",l,nsymb,tl,fp->symbol_rotation[l<<1],fp->symbol_rotation[1+(l<<1)], - (poff/2/M_PI)-floor(poff/2/M_PI)); + LOG_I(PHY,"Symbol rotation %d/%d => tl %f (%d,%d) (%f)\n", l, nsymb, tl, fp->symbol_rotation[l<<1], fp->symbol_rotation[1+(l<<1)], (poff/2/M_PI)-floor(poff/2/M_PI)); Ncpm1=Ncp; } } int nr_layer_precoder(int16_t **datatx_F_precoding, char *prec_matrix, uint8_t n_layers, int32_t re_offset) { - int32_t precodatatx_F = 0; - for (int al = 0; al>15); ((int16_t *)precodatatx_F)[1] = (int16_t)((((int16_t *)precodatatx_F)[1]*ONE_OVER_SQRT2_Q15)>>15);*/ From 3a83e8df03271ebcfcb8a9656d5f284765ed8294 Mon Sep 17 00:00:00 2001 From: sfn Date: Fri, 12 Mar 2021 09:19:44 +0100 Subject: [PATCH 24/40] Fix pdsch UE variables memory allocation --- openair1/PHY/INIT/nr_init_ue.c | 35 ++-- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 184 +++++++++--------- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 4 +- 3 files changed, 114 insertions(+), 109 deletions(-) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 0f797ff988..7c4b342ed8 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -71,31 +71,34 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch, pdsch->llr128 = (int16_t **)malloc16_clear( sizeof(int16_t *) ); // FIXME! no further allocation for (int16_t*)pdsch->llr128 !!! expect SIGSEGV // FK, 11-3-2015: this is only as a temporary pointer, no memory is stored there - pdsch->rxdataF_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->rxdataF_uespec_pilots = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->rxdataF_comp0 = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->rho = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->dl_ch_estimates = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->dl_bf_ch_estimates = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->dl_bf_ch_estimates_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->rxdataF_ext = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->rxdataF_uespec_pilots = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->rxdataF_comp0 = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->rho = (int32_t ***)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_ch_estimates = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_ch_estimates_ext = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_bf_ch_estimates = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_bf_ch_estimates_ext = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); //pdsch->dl_ch_rho_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); //pdsch->dl_ch_rho2_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->dl_ch_mag0 = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->dl_ch_magb0 = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->dl_ch_magr0 = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->ptrs_phase_per_slot = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->ptrs_re_per_slot = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->dl_ch_ptrs_estimates_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_ch_mag0 = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_ch_magb0 = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_ch_magr0 = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->ptrs_phase_per_slot = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->ptrs_re_per_slot = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_ch_ptrs_estimates_ext = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); // the allocated memory size is fixed: AssertFatal( fp->nb_antennas_rx <= 4, "nb_antennas_rx > 4" );//Extend the max number of UE Rx antennas to 4 for (int i=0; inb_antennas_rx; i++) { - pdsch->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) ); + pdsch->rho[i] = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS*sizeof(int32_t) ); - for (int j=0; j<4; j++) { //4: DL antenna ports + for (int j=0; jnb_antennas_rx)+i; const size_t num = 7*2*fp->N_RB_DL*12; + for (int k=0; krho[i][j*NR_MAX_NB_LAYERS+k] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + } pdsch->rxdataF_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); pdsch->rxdataF_uespec_pilots[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12); pdsch->rxdataF_comp0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 5f4d952065..60811db249 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -776,7 +776,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, int **dl_ch_magb, int **dl_ch_magr, int **rxdataF_comp, - int **rho, + int ***rho, NR_DL_FRAME_PARMS *frame_parms, uint8_t nb_aatx, unsigned char symbol, @@ -791,7 +791,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, #if defined(__i386) || defined(__x86_64) unsigned short rb; - unsigned char aatx,aarx; + unsigned char aatx,aarx,atx; __m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*dl_ch_mag128r,*rxdataF128,*rxdataF_comp128,*rho128; __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b,QAM_amp128r; QAM_amp128b = _mm_setzero_si128(); @@ -964,124 +964,126 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, } } if (rho) { - //rho[aatx*n_rx+0] = Cov(H_0,0,H*_0,aatx), aatx=0,...n_tx-1 - //rho[aatx*n_rx+1] = Cov(H_1,1,H*_1,aatx), aatx=0,...n_tx-1 - //rho[aatx*n_rx+aarx] = Cov(H_aarx,arrx,H*_aarx,aatx), aatx=0,...n_tx-1 + //we compute the Tx correlation matrix for each Rx antenna + //As an example the 2x2 MIMO case requires + //rho[aarx][nb_aatx*nb_aatx] = [cov(H_aarx_0,H_aarx_0) cov(H_aarx_0,H_aarx_1) + // cov(H_aarx_1,H_aarx_0) cov(H_aarx_1,H_aarx_1)], aarx=0,...,nb_antennas_rx-1 - int avg_rho_re[nb_aatx][frame_parms->nb_antennas_rx]; - int avg_rho_im[nb_aatx][frame_parms->nb_antennas_rx]; + int avg_rho_re[frame_parms->nb_antennas_rx][nb_aatx]; + int avg_rho_im[frame_parms->nb_antennas_rx][nb_aatx]; for (aarx=0; aarxnb_antennas_rx; aarx++) { - dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*nb_rb*12];//H_{aarx,0} - for (aatx=1; aatxnb_antennas_rx+aarx][symbol*nb_rb*12]; - dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_rb*12]; + for (aatx=0; aatxnb_antennas_rx+aarx][symbol*nb_rb*12]; - for (rb=0; rbnb_antennas_rx+aarx][symbol*nb_rb*12]; - avg_rho_re[aatx][aarx] +=(((int16_t*)&rho128[0])[0]+ + for (rb=0; rbrx_correlation[0][0][aarx] = signal_energy(&rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12],rb*12); + avg_rho_re[aarx][aatx*nb_aatx+atx] = 16*avg_rho_re[aarx][aatx*nb_aatx+atx]/(nb_rb*12); + avg_rho_im[aarx][aatx*nb_aatx+atx] = 16*avg_rho_im[aarx][aatx*nb_aatx+atx]/(nb_rb*12); + printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, aatx,atx, avg_rho_re[aatx*nb_aatx+atx], avg_rho_im[aatx*nb_aatx+atx]); + } } - /*if (first_symbol_flag==1) { - * //measurements->rx_correlation[0][0][aarx] = signal_energy(&rho[aarx][symbol*nb_rb*12],rb*12); - * avg_rho_re[aatx][aarx] = 16*avg_rho_re[aatx][aarx]/(nb_rb*12); - * avg_rho_im[aatx][aarx] = 16*avg_rho_im[aatx][aarx]/(nb_rb*12); - * printf("rho_rx%d tx%d= Re: %d Im: %d\n",aarx, aatx, avg_rho_re[aatx][aarx], avg_rho_im[aatx][aarx]); - * }*/ - } - } + } + } } _mm_empty(); _m_empty(); @@ -1292,7 +1294,7 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext, int **dl_ch_mag, int **dl_ch_magb, int **rxdataF_comp, - int **rho, + int ***rho, unsigned char n_tx, unsigned char n_rx, unsigned char mod_order, @@ -1429,7 +1431,7 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext, for (aarx=0; aarx Date: Fri, 12 Mar 2021 13:04:14 +0100 Subject: [PATCH 25/40] Fix indentation issues in nr_dlsch_demodulation.c --- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 552 +++++++++--------- 1 file changed, 276 insertions(+), 276 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 60811db249..b3f3888c9c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -355,13 +355,12 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, symbol, pilots, config_type, - start_rb, + start_rb + dlsch0_harq->BWPStart, nb_rb_pdsch, dlsch0_harq->n_dmrs_cdm_groups, dlsch0_harq->Nl, frame_parms, dlsch0_harq->dlDmrsSymbPos); - else// one layer nb_rb = nr_dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, pdsch_vars[gNB_id]->dl_ch_estimates, @@ -375,11 +374,11 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dlsch0_harq->n_dmrs_cdm_groups, frame_parms, dlsch0_harq->dlDmrsSymbPos); - - } /*else if(beamforming_mode>7) { + } + else if(beamforming_mode>7) { LOG_W(PHY,"dlsch_demodulation: beamforming mode not supported yet.\n"); - }*/ - + } + //printf("nb_rb = %d, gNB_id %d\n",nb_rb,gNB_id); if (nb_rb==0) { LOG_D(PHY,"dlsch_demodulation.c: nb_rb=0\n"); @@ -447,21 +446,21 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2)+3; //LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, pdsch_vars[gNB_id]->log2_maxh); - if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { - nr_dlsch_channel_level_median(pdsch_vars[gNB_id]->dl_ch_estimates_ext, - median, - n_tx, - n_rx, - len, - symbol*nb_rb*12); + if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { + nr_dlsch_channel_level_median(pdsch_vars[gNB_id]->dl_ch_estimates_ext, + median, + n_tx, + n_rx, + len, + symbol*nb_rb*12); - for (aatx = 0; aatx < n_tx; aatx++) { - for (aarx = 0; aarx < n_rx; aarx++) { - avgs = cmax(avgs, median[aatx*n_rx + aarx]); - } - } - pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1; - } + for (aatx = 0; aatx < n_tx; aatx++) { + for (aarx = 0; aarx < n_rx; aarx++) { + avgs = cmax(avgs, median[aatx*n_rx + aarx]); + } + } + pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1; + } } LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n", frame%1024, @@ -503,28 +502,30 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[gNB_id]->dl_ch_magr0, pdsch_vars[gNB_id]->rxdataF_comp0, (n_tx>1) ? pdsch_vars[gNB_id]->rho : NULL, - frame_parms, - n_tx, - symbol, - pilots, - first_symbol_flag, - dlsch0_harq->Qm, - nb_rb, - pdsch_vars[gNB_id]->log2_maxh, - measurements); // log2_maxh+I0_shift - } else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM){ + frame_parms, + n_tx, + symbol, + pilots, + first_symbol_flag, + dlsch0_harq->Qm, + nb_rb, + pdsch_vars[gNB_id]->log2_maxh, + measurements); // log2_maxh+I0_shift + } + + else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { nr_dlsch_channel_compensation_core(pdsch_vars[gNB_id]->rxdataF_ext, - pdsch_vars[gNB_id]->dl_ch_estimates_ext, - pdsch_vars[gNB_id]->dl_ch_mag0, - pdsch_vars[gNB_id]->dl_ch_magb0, - pdsch_vars[gNB_id]->rxdataF_comp0, //rxdataF_comp - NULL, - n_tx, - n_rx, - dlsch0_harq->Qm, - pdsch_vars[gNB_id]->log2_maxh, - 2*len, // subcarriers Re Im - 0); // we start from the beginning of the vector + pdsch_vars[gNB_id]->dl_ch_estimates_ext, + pdsch_vars[gNB_id]->dl_ch_mag0, + pdsch_vars[gNB_id]->dl_ch_magb0, + pdsch_vars[gNB_id]->rxdataF_comp0, //rxdataF_comp + NULL, + n_tx, + n_rx, + dlsch0_harq->Qm, + pdsch_vars[gNB_id]->log2_maxh, + 2*len, // subcarriers Re Im + 0); // we start from the beginning of the vector // compute correlation between signal and interference channels (rho12 and rho21) nr_dlsch_dual_stream_correlation_core(pdsch_vars[gNB_id]->dl_ch_estimates_ext, &(pdsch_vars[gNB_id]->dl_ch_estimates_ext[2]), @@ -550,41 +551,40 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #endif if (frame_parms->nb_antennas_rx > 1) { - if (dlsch0_harq->mimo_moderxdataF_comp0, - (n_tx>1)? pdsch_vars[gNB_id]->rho : NULL, - pdsch_vars[gNB_id]->dl_ch_mag0, - pdsch_vars[gNB_id]->dl_ch_magb0, - n_tx, - n_rx, - symbol, - nb_rb); - - if (n_tx == 2) - nr_zero_forcing_rx_2layers(pdsch_vars[gNB_id]->rxdataF_comp0, - pdsch_vars[gNB_id]->dl_ch_mag0, - pdsch_vars[gNB_id]->dl_ch_magb0, - pdsch_vars[gNB_id]->dl_ch_estimates_ext, - nb_rb, - n_rx, - dlsch0_harq->Qm, - pdsch_vars[gNB_id]->log2_maxh, - symbol); - - } else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM){ - nr_dlsch_detection_mrc_core(pdsch_vars[gNB_id]->rxdataF_comp0, - NULL, - pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[gNB_id]->dl_ch_rho2_ext, + if (dlsch0_harq->mimo_moderxdataF_comp0, + (n_tx>1)? pdsch_vars[gNB_id]->rho : NULL, + pdsch_vars[gNB_id]->dl_ch_mag0, + pdsch_vars[gNB_id]->dl_ch_magb0, + n_tx, + n_rx, + symbol, + nb_rb); + if (n_tx == 2)//Apply zero forcing for 2 Tx layers + nr_zero_forcing_rx_2layers(pdsch_vars[gNB_id]->rxdataF_comp0, pdsch_vars[gNB_id]->dl_ch_mag0, pdsch_vars[gNB_id]->dl_ch_magb0, - NULL, - NULL, - n_tx, + pdsch_vars[gNB_id]->dl_ch_estimates_ext, + nb_rb, n_rx, - 2*len, - 0); - } + dlsch0_harq->Qm, + pdsch_vars[gNB_id]->log2_maxh, + symbol); + } + else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { + nr_dlsch_detection_mrc_core(pdsch_vars[gNB_id]->rxdataF_comp0, + NULL, + pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[gNB_id]->dl_ch_rho2_ext, + pdsch_vars[gNB_id]->dl_ch_mag0, + pdsch_vars[gNB_id]->dl_ch_magb0, + NULL, + NULL, + n_tx, + n_rx, + 2*len, + 0); + } } //printf("start compute LLR\n"); if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { @@ -841,9 +841,9 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, dl_ch_mag128r[0] = dl_ch_mag128[0]; dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); - //print_ints("Re(ch):",(int16_t*)&mmtmpD0); - //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128); - //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]); + //print_ints("Re(ch):",(int16_t*)&mmtmpD0); + //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128); + //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]); dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); dl_ch_mag128b[1] = dl_ch_mag128[1]; dl_ch_mag128r[1] = dl_ch_mag128[1]; @@ -866,22 +866,23 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); + dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); dl_ch_mag128r[0] = _mm_mulhi_epi16(dl_ch_mag128r[0],QAM_amp128r); - dl_ch_mag128r[0] = _mm_slli_epi16(dl_ch_mag128r[0],1); + dl_ch_mag128r[0] = _mm_slli_epi16(dl_ch_mag128r[0],1); - dl_ch_mag128r[1] = _mm_mulhi_epi16(dl_ch_mag128r[1],QAM_amp128r); - dl_ch_mag128r[1] = _mm_slli_epi16(dl_ch_mag128r[1],1); + dl_ch_mag128r[1] = _mm_mulhi_epi16(dl_ch_mag128r[1],QAM_amp128r); + dl_ch_mag128r[1] = _mm_slli_epi16(dl_ch_mag128r[1],1); - if (pilots==0) { - dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b); - dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); + if (pilots==0) { + dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b); + dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); - dl_ch_mag128r[2] = _mm_mulhi_epi16(dl_ch_mag128r[2],QAM_amp128r); - dl_ch_mag128r[2] = _mm_slli_epi16(dl_ch_mag128r[2],1); - } + dl_ch_mag128r[2] = _mm_mulhi_epi16(dl_ch_mag128r[2],QAM_amp128r); + dl_ch_mag128r[2] = _mm_slli_epi16(dl_ch_mag128r[2],1); + } } // multiply by conjugated channel @@ -893,67 +894,72 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, 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); + 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); + //printf("arx%d atx%d rb_index %d symbol%d\n",aarx,aatx,rb,symbol); + // print_shorts("rx:",rxdataF128); + // print_shorts("ch:",dl_ch128); + // print_shorts("pack:",rxdataF_comp128); - //printf("arx%d atx%d rb_index %d symbol%d\n",aarx,aatx,rb,symbol); + //printf("arx%d atx%d rb_index %d symbol%d\n",aarx,aatx,rb,symbol); //print_shorts("rx:",(int16_t*)&rxdataF128[0]); //print_shorts("ch:",(int16_t*)&dl_ch128[0]); //print_shorts("pack:",(int16_t*)&rxdataF_comp128[0]); - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_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); + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_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:",(int16_t*)&rxdataF128[1]); - //print_shorts("ch:",(int16_t*)&dl_ch128[1]); - //print_shorts("pack:",(int16_t*)&rxdataF_comp128[1]); + rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + //print_shorts("rx:",(int16_t*)&rxdataF128[1]); + //print_shorts("ch:",(int16_t*)&dl_ch128[1]); + //print_shorts("pack:",(int16_t*)&rxdataF_comp128[1]); - if (pilots==0) { - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_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); + if (pilots==0) { + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_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:",(int16_t*)&rxdataF128[2]); - //print_shorts("ch:",(int16_t*)&dl_ch128[2]); - //print_shorts("pack:",(int16_t*)&rxdataF_comp128[2]); + rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + //print_shorts("rx:",(int16_t*)&rxdataF128[2]); + //print_shorts("ch:",(int16_t*)&dl_ch128[2]); + //print_shorts("pack:",(int16_t*)&rxdataF_comp128[2]); - dl_ch128+=3; - dl_ch_mag128+=3; - dl_ch_mag128b+=3; - dl_ch_mag128r+=3; - rxdataF128+=3; - rxdataF_comp128+=3; - } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less - dl_ch128+=2; + dl_ch128+=3; + dl_ch_mag128+=3; + dl_ch_mag128b+=3; + dl_ch_mag128r+=3; + rxdataF128+=3; + rxdataF_comp128+=3; + } + else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less + dl_ch128+=2; dl_ch_mag128+=2; dl_ch_mag128b+=2; dl_ch_mag128r+=2; @@ -1564,41 +1570,41 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext, #if defined(__x86_64__)||defined(__i386__) - short rb; - unsigned char aatx,aarx; - __m128i *dl_ch128, avg128D; + short rb; + unsigned char aatx,aarx; + __m128i *dl_ch128, avg128D; - //nb_rb*nre = y * 2^x - int16_t x = factor2(len); - //x = (x>4) ? 4 : x; - int16_t y = (len)>>x; - //printf("len = %d = %d * 2^(%d)\n",len,y,x); + //nb_rb*nre = y * 2^x + int16_t x = factor2(len); + //x = (x>4) ? 4 : x; + int16_t y = (len)>>x; + //printf("len = %d = %d * 2^(%d)\n",len,y,x); - AssertFatal(y!=0,"Cannot divide by zero: in function %s of file %s\n", __func__, __FILE__); + AssertFatal(y!=0,"Cannot divide by zero: in function %s of file %s\n", __func__, __FILE__); - for (aatx=0; aatxnb_antennas_rx; aarx++) { - //clear average level - avg128D = _mm_setzero_si128(); + for (aatx=0; aatxnb_antennas_rx; aarx++) { + //clear average level + avg128D = _mm_setzero_si128(); - dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; + dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; - for (rb=0;rbnb_antennas_rx)+aarx] =(((int32_t*)&avg128D)[0] + - ((int32_t*)&avg128D)[1] + - ((int32_t*)&avg128D)[2] + - ((int32_t*)&avg128D)[3])/y; - // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); - } + avg[(aatx*frame_parms->nb_antennas_rx)+aarx] =(((int32_t*)&avg128D)[0] + + ((int32_t*)&avg128D)[1] + + ((int32_t*)&avg128D)[2] + + ((int32_t*)&avg128D)[3])/y; + // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); + } - _mm_empty(); - _m_empty(); + _mm_empty(); + _m_empty(); #elif defined(__arm__) @@ -1669,48 +1675,46 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext, #if defined(__x86_64__)||defined(__i386__) - short ii; - int aatx,aarx; - int length2; - int max = 0, min=0; - int norm_pack; - __m128i *dl_ch128, norm128D; + short ii; + int aatx,aarx; + int length2; + int max = 0, min=0; + int norm_pack; + __m128i *dl_ch128, norm128D; - for (aatx=0; aatx>2;//length = number of REs, hence length2=nb_REs*(32/128) in SIMD loop + length2 = length>>2;//length = number of REs, hence length2=nb_REs*(32/128) in SIMD loop - for (ii=0;ii max) - max = norm_pack;//store values more than max - if (norm_pack < min) - min = norm_pack;//store values less than min + if (norm_pack > max) + max = norm_pack;//store values more than max + if (norm_pack < min) + min = norm_pack;//store values less than min + dl_ch128+=1; + } - dl_ch128+=1; - } + median[aatx*n_rx + aarx] = (max+min)>>1; + //printf("Channel level median [%d]: %d max = %d min = %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx],max,min); + } + } - median[aatx*n_rx + aarx] = (max+min)>>1; - - //printf("Channel level median [%d]: %d max = %d min = %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx],max,min); - } - } - - _mm_empty(); - _m_empty(); + _mm_empty(); + _m_empty(); #elif defined(__arm__) @@ -2068,7 +2072,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, unsigned char j=0; - if (config_type==pdsch_dmrs_type1){ + if (config_type==pdsch_dmrs_type1) { AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2, "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); nushift = n_dmrs_cdm_groups -1;//delta in Table 7.4.1.1.2-1 @@ -2077,7 +2081,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2 || n_dmrs_cdm_groups == 3, "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); nushift = (n_dmrs_cdm_groups -1)<<1;//delta in Table 7.4.1.1.2-2 - } + } for (aarx=0; aarxnb_antennas_rx; aarx++) { @@ -2139,7 +2143,6 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, } } } - return(nb_rb_pdsch); } @@ -2163,11 +2166,10 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF, int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; int8_t validDmrsEst = 0; //store last DMRS Symbol index - if (config_type==pdsch_dmrs_type1){ + if (config_type==pdsch_dmrs_type1) { AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2, "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); nushift = n_dmrs_cdm_groups -1;//delta in Table 7.4.1.1.2-1 - } else { AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2 || n_dmrs_cdm_groups == 3, "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); @@ -2190,8 +2192,8 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF, dl_ch0 = &dl_ch_estimates[(aatx*frame_parms->nb_antennas_rx)+aarx][(validDmrsEst*(frame_parms->ofdm_symbol_size))]; dl_ch0_ext = &dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*(nb_rb_pdsch*NR_NB_SC_PER_RB)]; - for (rb = 0; rb < nb_rb_pdsch; rb++) { - + for (rb = 0; rb < nb_rb_pdsch; rb++) + { if (pilots==0) {//data symbol only if (aatx==0) {//Extract Rx signal only memcpy((void*)rxF_ext,(void*)rxF,12*sizeof(*rxF_ext)); @@ -2199,7 +2201,8 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF, } memcpy((void*)dl_ch0_ext,(void*)dl_ch0,12*sizeof(*dl_ch0_ext));//Extract Channel Estimate dl_ch0_ext+=12; - } else {//the symbol contains DMRS + } + else {//the symbol contains DMRS j=0; if (config_type==pdsch_dmrs_type1) { if (nushift == 0) {//data is multiplexed @@ -2211,7 +2214,8 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF, dl_ch0_ext+=6; if (aatx==0) rxF_ext+=6; } - } else {//pdsch_dmrs_type2 + } + else {//pdsch_dmrs_type2 for (i = (2+nushift); i<6; i++) { if (aatx==0) rxF_ext[j]=rxF[i]; dl_ch0_ext[j]=dl_ch0[i]; @@ -2236,53 +2240,50 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF, rxF = &rxdataF[aarx][k+(symbol*(frame_parms->ofdm_symbol_size))]; } } - }//rb + }//rb }//aatx }//aarx - return(nb_rb_pdsch); } void nr_dlsch_detection_mrc(int **rxdataF_comp, - int **rho, - int **dl_ch_mag, - int **dl_ch_magb, - short n_tx, - short n_rx, - unsigned char symbol, - unsigned short nb_rb) { + int **rho, + int **dl_ch_mag, + int **dl_ch_magb, + short n_tx, + short n_rx, + unsigned char symbol, + unsigned short nb_rb) { #if defined(__x86_64__)||defined(__i386__) unsigned char aatx, aarx; int i; __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b; if (n_rx>1) { - for (aatx=0; aatxN_RB_DL*12]; rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12]; for (i=0; i Date: Wed, 10 Mar 2021 15:02:54 +0100 Subject: [PATCH 26/40] Make RRC buffer sufficiently large --- openair2/RRC/LTE/defs_NB_IoT.h | 2 +- openair2/RRC/LTE/rrc_defs.h | 2 +- openair2/RRC/NR/nr_rrc_defs.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/RRC/LTE/defs_NB_IoT.h b/openair2/RRC/LTE/defs_NB_IoT.h index 91dc7aafd4..2a34971c23 100644 --- a/openair2/RRC/LTE/defs_NB_IoT.h +++ b/openair2/RRC/LTE/defs_NB_IoT.h @@ -148,7 +148,7 @@ typedef struct UE_RRC_INFO_NB_IoT_s { //Measurement Report not supported in NB-IoT #define PAYLOAD_SIZE_MAX 1024 -#define RRC_BUF_SIZE 255 +#define RRC_BUF_SIZE 8192 #define UNDEF_SECURITY_MODE 0xff #define NO_SECURITY_MODE 0x20 diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 4f55f94121..c19335910b 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -327,7 +327,7 @@ typedef enum SL_TRIGGER_e { #define MAX_MEAS_ID 6 #define PAYLOAD_SIZE_MAX 1024 -#define RRC_BUF_SIZE 255 +#define RRC_BUF_SIZE 8192 #define UNDEF_SECURITY_MODE 0xff #define NO_SECURITY_MODE 0x20 diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 36d9bdee60..af4ebfe17e 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -127,7 +127,7 @@ typedef enum UE_STATE_NR_e { #define MAX_MEAS_ID 6 #define PAYLOAD_SIZE_MAX 1024 -#define RRC_BUF_SIZE 255 +#define RRC_BUF_SIZE 8192 #define UNDEF_SECURITY_MODE 0xff #define NO_SECURITY_MODE 0x20 From 9dd8572359a03a4d576252a7d97774a8ce422317 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 10 Mar 2021 15:03:43 +0100 Subject: [PATCH 27/40] Change initial{D,U}LBWPlocationAndBandwidth for quectel to connect --- ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf | 4 ++-- ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf | 4 ++-- .../CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf | 4 ++-- .../GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf | 4 ++-- .../GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 4 ++-- .../GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf | 4 ++-- .../CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf | 4 ++-- .../CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf index decaa392d7..f6cbef9aa7 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -46,7 +46,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=41,L=24 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -89,7 +89,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf index 258618e7f0..daee5486c1 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf @@ -48,7 +48,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=84,L=13 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -90,7 +90,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf index 1cd16d0831..160f3ad7d4 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf @@ -46,7 +46,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=84,L=13 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -83,7 +83,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf index dfae41f0a6..b80d09385c 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf @@ -46,7 +46,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=0,L=50 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -89,7 +89,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index c77497dedd..58f8541717 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -46,7 +46,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=41,L=24 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -89,7 +89,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf index b3fdd79475..8589a09f8e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf @@ -46,7 +46,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=0,L=50 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -89,7 +89,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf index 108cf06033..42b87d5672 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf @@ -51,7 +51,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=41,L=24 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; # 6366 12925 12956 28875 + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -99,7 +99,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf index d28427dbf3..96df4a971f 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf @@ -51,7 +51,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=41,L=24 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; # 6366 12925 12956 28875 + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -94,7 +94,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; From 544f47bdb04c7b684c7726be8c9a4ca3ffc5ba90 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 24 Feb 2021 18:09:16 +0100 Subject: [PATCH 28/40] increasing initial[DL|UL]BWPlocationAndBandwidth for benetel config file to support newer handsets --- targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf index 504d5e7b34..c0e9e71f66 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf @@ -50,7 +50,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=84,L=13 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -92,7 +92,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; From 1c2cbc76dc9feeda58b1ecc692adb457f0b58a76 Mon Sep 17 00:00:00 2001 From: sfn Date: Mon, 15 Mar 2021 21:43:04 +0100 Subject: [PATCH 29/40] review pdsch precoding --- openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 72 ++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 15 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index fff79d0e4e..e92ebadd08 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -413,25 +413,67 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, ///Layer Precoding and Antenna port mapping // tx_layers 1-8 are mapped on antenna ports 1000-1007 - uint8_t pmi = 4;//hard coded, should be changed later from the upper layer - + // The precoding info is supported by nfapi such as numPRGs, prgSize, and PMIdx + // The same precoding matrix is applied on prgSize RBs, Thus + // pmi = PMIdx[rbidx/prgSize], rbidx =0,...,rbSize-1 + // The Precoding matrix: + // The Codebook Type I and Type II are not supported yet. + // We adopt the precoding matrices of PUSCH for 4 layers. + uint8_t pmi; for (int ap=0; apnb_antennas_tx; ap++) { - char *W_prec = nr_W_1l_4p[pmi][ap];//Hard coded, should be changed later from the upper layer + for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { uint16_t k = start_sc; - for (int i=0; irbSize*NR_NB_SC_PER_RB; i++) { - int32_t re_offset = l*frame_parms->ofdm_symbol_size + k; - int32_t precodatatx_F = nr_layer_precoder(txdataF_precoding, W_prec, rel15->nrOfLayers, re_offset+txdataF_offset); - ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[0]; - ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[1]; -#ifdef DEBUG_DLSCH_MAPPING - printf("antenna %d\t l %d \t k %d \t txdataF: %d %d\n", - ap, l, k, ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)], - ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)]); -#endif - if (++k >= frame_parms->ofdm_symbol_size) - k -= frame_parms->ofdm_symbol_size; + for (int rb=0; rbrbSize; rb++) { + //get pmi info + if (rel15->precodingAndBeamforming.prgSize > 0) + pmi = rel15->precodingAndBeamforming.PMIdx[(int)rb/rel15->precodingAndBeamforming.prgSize]; + else + pmi = 0;//no precoding + + //get the precoding matrix weights: + char *W_prec; + switch (frame_parms->nb_antennas_tx) { + case 1://1 antenna port + W_prec = nr_W_1l_2p[pmi][ap]; + break; + case 2://2 antenna ports + if (rel15->nrOfLayers == 1)//1 layer + W_prec = nr_W_1l_2p[pmi][ap]; + else//2 layers + W_prec = nr_W_2l_2p[pmi][ap]; + break; + case 4://4 antenna ports + if (rel15->nrOfLayers == 1)//1 layer + W_prec = nr_W_1l_4p[pmi][ap]; + else if (rel15->nrOfLayers == 2)//2 layers + W_prec = nr_W_2l_4p[pmi][ap]; + else if (rel15->nrOfLayers == 3)//3 layers + W_prec = nr_W_3l_4p[pmi][ap]; + else//4 layers + W_prec = nr_W_4l_4p[pmi][ap]; + break; + default: + LOG_D(PHY,"Precoding 1,2, or 4 antenna ports are currently supported\n"); + W_prec = nr_W_1l_2p[pmi][ap]; + break; + } + + for (int i=0; iofdm_symbol_size + k; + int32_t precodatatx_F = nr_layer_precoder(txdataF_precoding, W_prec, rel15->nrOfLayers, re_offset+txdataF_offset); + ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[0]; + ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[1]; + #ifdef DEBUG_DLSCH_MAPPING + printf("antenna %d\t l %d \t k %d \t txdataF: %d %d\n", + ap, l, k, ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)], + ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)]); + #endif + if (++k >= frame_parms->ofdm_symbol_size) { + k -= frame_parms->ofdm_symbol_size; + } + } } //RE loop } // symbol loop }// port loop From f1083dc14a36cb776d512902d086c240c47b872b Mon Sep 17 00:00:00 2001 From: sfn Date: Tue, 16 Mar 2021 14:32:12 +0100 Subject: [PATCH 30/40] Extend nr_dlsim to simulate performance over MIMO Rayleigh1 fading for MIMO test --- openair1/SIMULATION/NR_PHY/dlsim.c | 35 +++++-- .../SIMULATION/TOOLS/multipath_tv_channel.c | 91 ++++++++++--------- openair1/SIMULATION/TOOLS/random_channel.c | 8 +- 3 files changed, 78 insertions(+), 56 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 423f6bfa9d..03fbbdc260 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -297,7 +297,7 @@ int main(int argc, char **argv) //uint8_t frame_mod4,num_pdcch_symbols = 0; - SCM_t channel_model=AWGN;//Rayleigh1_anticorr; + SCM_t channel_model=Rayleigh1;//AWGN Rayleigh1 Rayleigh1_anticorr; NB_UE_INST = 1; //double pbch_sinr; @@ -753,7 +753,7 @@ int main(int argc, char **argv) gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model, - fs, + fs/1e6,//sampling frequency in MHz bw, 30e-9, 0, @@ -1030,7 +1030,6 @@ int main(int argc, char **argv) if (n_trials==1) printf("txlev[%d] = %d (%f dB) txlev_sum %d\n",aa,txlev[aa],10*log10((double)txlev[aa]),txlev_sum); } - for (i=(frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)); i<(frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0)); i++) { @@ -1040,27 +1039,43 @@ int main(int argc, char **argv) s_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]); } } + double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size); - //AWGN + //Compute AWGN variance sigma2_dB = 10 * log10((double)txlev_sum * ((double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize))) - SNR; sigma2 = pow(10, sigma2_dB/10); if (n_trials==1) printf("sigma2 %f (%f dB), txlev_sum %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev_sum),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize)); + for (aa=0; aaget_samples_slot_timestamp(slot,frame_parms,0); iget_samples_slot_timestamp(slot+1,frame_parms,0); i++) { for (int aa_rx=0; aa_rxcommon_vars.rxdata[aa_rx])[2*i] = (short) ((r_re[aa_rx][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); ((short*) UE->common_vars.rxdata[aa_rx])[2*i+1] = (short) ((r_im[aa_rx][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); /* Add phase noise if enabled */ @@ -1246,6 +1261,8 @@ int main(int argc, char **argv) } }*/ + free_channel_desc_scm(gNB2UE); + for (i = 0; i < n_tx; i++) { free(s_re[i]); free(s_im[i]); diff --git a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c index d344992586..c68ce73758 100644 --- a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c +++ b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c @@ -48,9 +48,9 @@ void multipath_tv_channel(channel_desc_t *desc, printf("[TV CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d max_doppler %g\n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length, desc->max_Doppler); #endif - tx = (double complex **)malloc(desc->nb_tx*sizeof(double complex)); - rx = (double complex **)malloc(desc->nb_rx*sizeof(double complex)); - H_t= (double complex ** *) malloc(desc->nb_tx*desc->nb_rx*sizeof(double complex **)); + tx = (double complex **)malloc(desc->nb_tx*sizeof(double complex *)); + rx = (double complex **)malloc(desc->nb_rx*sizeof(double complex *)); + H_t= (double complex ***) malloc(desc->nb_tx*desc->nb_rx*sizeof(double complex **)); // tv_H_t = (double complex *) malloc(length*sizeof(double complex)); rx_temp= (double complex *) calloc(length,sizeof(double complex)); @@ -63,10 +63,10 @@ void multipath_tv_channel(channel_desc_t *desc, } for(i=0; inb_tx*desc->nb_rx; i++) { - H_t[i] = (double complex **) malloc(length*sizeof(double complex *)); + H_t[i] = (double complex **)malloc(desc->nb_taps*sizeof(double complex *)); - for(j=0; jnb_taps,sizeof(double complex)); + for(j=0; jnb_taps; j++) { + H_t[i][j] = (double complex *)calloc(length,sizeof(double complex)); } } @@ -116,7 +116,7 @@ void multipath_tv_channel(channel_desc_t *desc, free(rx); for(i=0; inb_rx*desc->nb_tx; i++) { - for(j=0; jnb_taps; j++) { free(H_t[i][j]); } @@ -131,14 +131,29 @@ void multipath_tv_channel(channel_desc_t *desc, void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length){ int i,j,p,l,k; - double *alpha,*phi_rad,pi=acos(-1),*w_Hz; + double *alpha,***phi_rad,pi=acos(-1),***w_Hz; alpha = (double *)calloc(desc->nb_paths,sizeof(double)); - phi_rad = (double *)calloc(desc->nb_paths,sizeof(double)); - w_Hz = (double *)calloc(desc->nb_paths,sizeof(double)); + phi_rad = (double ***)malloc(desc->nb_rx*desc->nb_tx*sizeof(double **)); + w_Hz = (double ***)malloc(desc->nb_rx*desc->nb_tx*sizeof(double **)); - for(i=0; inb_paths; i++) { - w_Hz[i]=desc->max_Doppler*cos(frand_a_b(0,2*pi)); - phi_rad[i]=frand_a_b(0,2*pi); + for(i=0; inb_tx*desc->nb_rx; i++) { + phi_rad[i] = (double **) malloc(desc->nb_taps*sizeof(double *)); + w_Hz[i] = (double **) malloc(desc->nb_taps*sizeof(double *)); + for(j=0; jnb_taps; j++) { + phi_rad[i][j] = (double *) malloc(desc->nb_paths*sizeof(double)); + w_Hz[i][j] = (double *) malloc(desc->nb_paths*sizeof(double)); + } + } + + for(i=0; inb_tx*desc->nb_rx; i++) { + for (j = 0; jnb_taps; j++) { + for(k=0; knb_paths; k++) { + w_Hz[i][j][k] = desc->max_Doppler*cos(frand_a_b(0,2*M_PI)); + phi_rad[i][j][k] = frand_a_b(0,2*M_PI); + //printf("w_hz[%d][%d][%d]=f_d*cos(theta) = %f\n",i,j,k,w_Hz[i][j][k]); + //printf("phi_rad[%d][%d][%d] = %f\n",i,j,k,phi_rad[i][j][k]); + } + } } if(desc->ricean_factor == 1) { @@ -153,44 +168,34 @@ void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length){ } } - /* - // This is the code when we only consider a SISO case - for(i=0;inb_taps;j++) - { - for(p=0;pnb_paths;p++) - { - H[i][j] += sqrt(desc->amps[j]/2)*alpha[p]*cexp(-I*(2*pi*w_Hz[p]*i*(1/(desc->sampling_rate*1e6))+phi_rad[p])); - } - } - } - for(j=0;jnb_paths;j++) - { - phi_rad[j] = fmod(2*pi*w_Hz[j]*(length-1)*(1/desc->sampling_rate)+phi_rad[j],2*pi); - } - */ - - // if MIMO + // SISO or MIMO for (i=0; inb_rx; i++) { for(j=0; jnb_tx; j++) { - for(k=0; knb_taps; l++) { - H[i+(j*desc->nb_rx)][k][l] = 0; - + for(k=0; knb_taps; k++) { + for(l=0; lnb_paths; p++) { - H[i+(j*desc->nb_rx)][k][l] += sqrt(desc->amps[l]/2)*alpha[p]*cexp(I*(2*pi*w_Hz[p]*k*(1/(desc->sampling_rate*1e6))+phi_rad[p])); + H[i+(j*desc->nb_rx)][k][l] += sqrt(desc->amps[k])*alpha[p]*cexp(I*(2*pi*w_Hz[i+(j*desc->nb_rx)][k][p]*l*(1/(desc->sampling_rate*1e6))+phi_rad[i+(j*desc->nb_rx)][k][p])); } } - } - - for(j=0; jnb_paths; j++) { - phi_rad[j] = fmod(2*pi*w_Hz[j]*(length-1)*(1/desc->sampling_rate)+phi_rad[j],2*pi); + //printf("H[tx%d][rx%d][k%d] = %f+j%f \n",j,i,k,creal(H[i+(j*desc->nb_rx)][k][0]),cimag(H[i+(j*desc->nb_rx)][k][0])); } } } - + //accumlate the phase + /*for(k=0; knb_taps; k++) { + * for(j=0; jnb_paths; j++) { + * desc->random_phase[k][j] = fmod(2*pi*w_Hz[k][j]*(length-1)*(1/(desc->sampling_rate*1e6))+phi_rad[k][j],2*pi); + * } + * }*/ free(alpha); + for(i=0; inb_rx*desc->nb_tx; i++) { + for (j=0; jnb_taps; j++) { + free(w_Hz[i][j]); + free(phi_rad[i][j]); + } + free(w_Hz[i]); + free(phi_rad[i]); + } free(w_Hz); free(phi_rad); } @@ -203,7 +208,7 @@ void tv_conv(double complex **h, double complex *x, double complex *y, uint32_t for(i=0; i<((int)nb_samples-dd); i++) { for(j=0; jj) - y[i+dd] += creal(h[i][j])*creal(x[i-j])-cimag(h[i][j])*cimag(x[i-j]) + I*(creal(h[i][j])*cimag(x[i-j])+cimag(h[i][j])*creal(x[i-j])); + y[i+dd] += creal(h[j][i])*creal(x[i-j])-cimag(h[j][i])*cimag(x[i-j]) + I*(creal(h[j][i])*cimag(x[i-j])+cimag(h[j][i])*creal(x[i-j])); } } } diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index 8c063fadc0..47597f4d6e 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -61,7 +61,7 @@ static telnetshell_vardef_t channelmod_vardef[] = { static double snr_dB=25; static double sinr_dB=0; static unsigned int max_chan; -static channel_desc_t** defined_channels; +static channel_desc_t **defined_channels; void fill_channel_desc(channel_desc_t *chan_desc, uint8_t nb_tx, uint8_t nb_rx, @@ -1185,11 +1185,11 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, 1); break; - case Rayleigh1: + case Rayleigh1://MIMO Test uses Rayleigh1 nb_taps = 1; Td = 0; channel_length = 1; - ricean_factor = 1; + ricean_factor = 0.0; aoa = .03; maxDoppler = 0; fill_channel_desc(chan_desc,nb_tx, @@ -1632,7 +1632,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, void free_channel_desc_scm(channel_desc_t *ch) { // Must be made cleanly, a lot of leaks... - defined_channels[ch->chan_idx]=NULL; + if (max_chan != 0) defined_channels[ch->chan_idx]=NULL; if(ch->free_flags&CHANMODEL_FREE_AMPS) free(ch->amps); for (int i = 0; inb_tx*ch->nb_rx; i++) { From 5d6863ddd2952c568cfb2e93f5b6ac0b0707e8b6 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 17 Mar 2021 17:01:42 +0100 Subject: [PATCH 31/40] NR_UE: fix memory allocations in phy_init_nr_ue__PDSCH() --- openair1/PHY/INIT/nr_init_ue.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 2d3ca4d5e4..e18a9e7f94 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -74,7 +74,7 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch, pdsch->rxdataF_ext = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); pdsch->rxdataF_uespec_pilots = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); pdsch->rxdataF_comp0 = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->rho = (int32_t ***)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->rho = (int32_t ***)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t **) ); pdsch->dl_ch_estimates = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); pdsch->dl_ch_estimates_ext = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); pdsch->dl_bf_ch_estimates = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); @@ -90,17 +90,20 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch, // the allocated memory size is fixed: AssertFatal( fp->nb_antennas_rx <= 4, "nb_antennas_rx > 4" );//Extend the max number of UE Rx antennas to 4 + const size_t num = 7*2*fp->N_RB_DL*12; for (int i=0; inb_antennas_rx; i++) { - pdsch->rho[i] = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS*sizeof(int32_t) ); + pdsch->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + pdsch->rxdataF_uespec_pilots[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12); + pdsch->ptrs_phase_per_slot[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * 14 ); + pdsch->ptrs_re_per_slot[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * 14); + pdsch->dl_ch_ptrs_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * num); + pdsch->rho[i] = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS*sizeof(int32_t *) ); for (int j=0; jnb_antennas_rx)+i; - const size_t num = 7*2*fp->N_RB_DL*12; for (int k=0; krho[i][j*NR_MAX_NB_LAYERS+k] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + pdsch->rho[i][j*NR_MAX_NB_LAYERS+k] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); } - pdsch->rxdataF_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); - pdsch->rxdataF_uespec_pilots[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12); pdsch->rxdataF_comp0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); pdsch->dl_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2); pdsch->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); @@ -111,9 +114,6 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch, pdsch->dl_ch_mag0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); pdsch->dl_ch_magb0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); pdsch->dl_ch_magr0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); - pdsch->ptrs_re_per_slot[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * 14); - pdsch->ptrs_phase_per_slot[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * 14 ); - pdsch->dl_ch_ptrs_estimates_ext[idx]= (int32_t *)malloc16_clear( sizeof(int32_t) * num); } } } From decd654ad0e0520ec74c4e787415655769f6e79e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 18 Mar 2021 09:16:36 +0100 Subject: [PATCH 32/40] Change initial{D,U}LBWPlocationAndBandwidth for quectel to connect in testing_gnb.conf files --- targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf | 4 ++-- targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf index c46ea98ec2..17e5e948e8 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf @@ -48,7 +48,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=84,L=13 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -90,7 +90,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf index 6a3f008ec1..cc6d182d1e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf @@ -46,7 +46,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=84,L=13 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -88,7 +88,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; From d7f89ae686bdfd7c24aabfae26d640f7f5036a83 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 18 Mar 2021 13:23:37 +0100 Subject: [PATCH 33/40] NR: allocate memory for 2 slots of OFDM symbols in txdataF_precoding --- openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 9e2fd929f0..d69de105ff 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -155,7 +155,7 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, } dlsch->txdataF[layer] = (int32_t *)malloc16((NR_MAX_PDSCH_ENCODED_LENGTH/NR_MAX_NB_LAYERS)*sizeof(int32_t)); // NR_MAX_NB_LAYERS is already included in NR_MAX_PDSCH_ENCODED_LENGTH - dlsch->txdataF_precoding[layer] = (int32_t *)malloc16((14*frame_parms->ofdm_symbol_size)*sizeof(int32_t)); + dlsch->txdataF_precoding[layer] = (int32_t *)malloc16(2*14*frame_parms->ofdm_symbol_size*sizeof(int32_t)); } for (int q=0; q Date: Thu, 18 Mar 2021 13:25:18 +0100 Subject: [PATCH 34/40] NR: initialize t_nrLDPC_time_stats structure --- openair1/PHY/CODING/TESTBENCH/ldpctest.c | 2 +- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c index b42ac6e4c8..e16c909835 100644 --- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c +++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c @@ -144,7 +144,7 @@ int test_ldpc(short No_iteration, t_nrLDPC_procBuf nrLDPC_procBuf; t_nrLDPC_procBuf* p_nrLDPC_procBuf = &nrLDPC_procBuf; - t_nrLDPC_time_stats decoder_profiler; + t_nrLDPC_time_stats decoder_profiler = {0}; t_nrLDPC_time_stats* p_decoder_profiler =&decoder_profiler ; int32_t n_iter = 0; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 1fef23d642..ca997d95f3 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -320,7 +320,7 @@ void nr_processULSegment(void* arg) { Kr_bytes = Kr>>3; K_bits_F = Kr-ulsch_harq->F; - t_nrLDPC_time_stats procTime; + t_nrLDPC_time_stats procTime = {0}; t_nrLDPC_time_stats* p_procTime = &procTime ; //start_meas(&phy_vars_gNB->ulsch_deinterleaving_stats); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 429bd9a836..eded12b3d2 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -261,7 +261,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))); t_nrLDPC_dec_params decParams; t_nrLDPC_dec_params* p_decParams = &decParams; - t_nrLDPC_time_stats procTime; + t_nrLDPC_time_stats procTime = {0}; t_nrLDPC_time_stats* p_procTime =&procTime ; if (!harq_process) { From 58af72a640dfc59e2c04953727e63a02022a3090 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 18 Mar 2021 13:27:56 +0100 Subject: [PATCH 35/40] fix nr_dlsim for CI: use AWGN instead of Rayleigh1 channel by default --- openair1/SIMULATION/NR_PHY/dlsim.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 03fbbdc260..76ee5a09cc 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -297,7 +297,7 @@ int main(int argc, char **argv) //uint8_t frame_mod4,num_pdcch_symbols = 0; - SCM_t channel_model=Rayleigh1;//AWGN Rayleigh1 Rayleigh1_anticorr; + SCM_t channel_model = AWGN; // AWGN Rayleigh1 Rayleigh1_anticorr; NB_UE_INST = 1; //double pbch_sinr; @@ -601,7 +601,8 @@ int main(int argc, char **argv) InitSinLUT(); get_softmodem_params()->phy_test = 1; - + get_softmodem_params()->do_ra = 0; + if (snr1set==0) snr1 = snr0+10; init_dlsch_tpool(dlsch_threads); @@ -874,7 +875,7 @@ int main(int argc, char **argv) scheduled_response.CC_id = 0; scheduled_response.frame = frame; scheduled_response.slot = slot; - scheduled_response.thread_id = UE_proc.thread_id; + scheduled_response.thread_id = 0; nr_ue_phy_config_request(&UE_mac->phy_config); //NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels; From 2a73b2d0c46db5262be54a7b13169121df11d599 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 18 Mar 2021 14:02:22 +0100 Subject: [PATCH 36/40] NR_UE: fix typo in nr_dlsch_decoding() --- openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index eded12b3d2..d5c0245fdc 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -678,7 +678,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, memcpy(harq_process->b+offset, harq_process->c[r], - Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0)); + Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) From ccee372aa5f235edc83f024e6e8c17b120e19b75 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 18 Mar 2021 14:06:51 +0100 Subject: [PATCH 37/40] NR: don't enable PRINT_CRC_CHECK by default in nr_ulsch_decoding.c --- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index ca997d95f3..b572a6e5bb 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -50,7 +50,7 @@ //#define gNB_DEBUG_TRACE #define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384 -#define PRINT_CRC_CHECK +//#define PRINT_CRC_CHECK //extern double cpuf; From 14f3d6a77adb40725c9ccd2c7f113e15f2571931 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Fri, 19 Mar 2021 11:40:21 +0100 Subject: [PATCH 38/40] gNB: fix memory allocations in fix_scc() and prepare_scd() issues found by valgrind --- openair2/GNB_APP/gnb_config.c | 40 ++++++++++++++--------------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 48176943a7..c25ddaab29 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -297,7 +297,7 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) { void prepare_scd(NR_ServingCellConfig_t *scd) { // Allocate downlink structures - scd->downlinkBWP_ToAddModList = CALLOC(1, sizeof(scd->downlinkBWP_ToAddModList)); + scd->downlinkBWP_ToAddModList = CALLOC(1, sizeof(*scd->downlinkBWP_ToAddModList)); // Downlink bandwidth part NR_BWP_Downlink_t *bwp = calloc(1, sizeof(*bwp)); @@ -318,29 +318,25 @@ void prepare_scd(NR_ServingCellConfig_t *scd) { NR_DMRS_DownlinkCfg->phaseTrackingRS->present = NR_SetupRelease_PTRS_DownlinkConfig_PR_setup; NR_DMRS_DownlinkCfg->phaseTrackingRS->choice.setup = CALLOC(1, sizeof(*NR_DMRS_DownlinkCfg->phaseTrackingRS->choice.setup)); NR_PTRS_DownlinkConfig_t *NR_PTRS_DownlinkCfg = NR_DMRS_DownlinkCfg->phaseTrackingRS->choice.setup; - NR_PTRS_DownlinkCfg->frequencyDensity = CALLOC(1, sizeof(NR_PTRS_DownlinkCfg->frequencyDensity)); - int *dl_rbs[2]; + NR_PTRS_DownlinkCfg->frequencyDensity = CALLOC(1, sizeof(*NR_PTRS_DownlinkCfg->frequencyDensity)); + long *dl_rbs = CALLOC(2, sizeof(long)); for (int i=0;i<2;i++) { - dl_rbs[i] = CALLOC(1, sizeof(*dl_rbs[i])); - *dl_rbs[i] = 0; - ASN_SEQUENCE_ADD(&NR_PTRS_DownlinkCfg->frequencyDensity->list, dl_rbs[i]); + ASN_SEQUENCE_ADD(&NR_PTRS_DownlinkCfg->frequencyDensity->list, &dl_rbs[i]); } - NR_PTRS_DownlinkCfg->timeDensity = CALLOC(1, sizeof(NR_PTRS_DownlinkCfg->timeDensity)); - int *dl_mcs[3]; + NR_PTRS_DownlinkCfg->timeDensity = CALLOC(1, sizeof(*NR_PTRS_DownlinkCfg->timeDensity)); + long *dl_mcs = CALLOC(3, sizeof(long)); for (int i=0;i<3;i++) { - dl_mcs[i] = CALLOC(1, sizeof(*dl_mcs[i])); - *dl_mcs[i] = 0; - ASN_SEQUENCE_ADD(&NR_PTRS_DownlinkCfg->timeDensity->list, dl_mcs[i]); + ASN_SEQUENCE_ADD(&NR_PTRS_DownlinkCfg->timeDensity->list, &dl_mcs[i]); } - NR_PTRS_DownlinkCfg->epre_Ratio = CALLOC(1, sizeof(NR_PTRS_DownlinkCfg->epre_Ratio)); - NR_PTRS_DownlinkCfg->resourceElementOffset = CALLOC(1, sizeof(NR_PTRS_DownlinkCfg->resourceElementOffset)); + NR_PTRS_DownlinkCfg->epre_Ratio = CALLOC(1, sizeof(*NR_PTRS_DownlinkCfg->epre_Ratio)); + NR_PTRS_DownlinkCfg->resourceElementOffset = CALLOC(1, sizeof(*NR_PTRS_DownlinkCfg->resourceElementOffset)); *NR_PTRS_DownlinkCfg->resourceElementOffset = 0; ASN_SEQUENCE_ADD(&scd->downlinkBWP_ToAddModList->list,bwp); // Allocate uplink structures - scd->uplinkConfig = CALLOC(1, sizeof(NR_UplinkConfig_t)); - scd->uplinkConfig->uplinkBWP_ToAddModList = CALLOC(1, sizeof(scd->uplinkConfig->uplinkBWP_ToAddModList)); + scd->uplinkConfig = CALLOC(1, sizeof(*scd->uplinkConfig)); + scd->uplinkConfig->uplinkBWP_ToAddModList = CALLOC(1, sizeof(*scd->uplinkConfig->uplinkBWP_ToAddModList)); NR_PUSCH_Config_t *pusch_Config = CALLOC(1, sizeof(*pusch_Config)); @@ -355,20 +351,16 @@ void prepare_scd(NR_ServingCellConfig_t *scd) { NR_PTRS_UplinkConfig_t *NR_PTRS_UplinkConfig = NR_DMRS_UplinkConfig->phaseTrackingRS->choice.setup; NR_PTRS_UplinkConfig->transformPrecoderDisabled = CALLOC(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled)); NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity = CALLOC(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity)); - int *n_rbs[2]; + long *n_rbs = CALLOC(2, sizeof(long)); for (int i=0;i<2;i++) { - n_rbs[i] = CALLOC(1, sizeof(*n_rbs[i])); - *n_rbs[i] = 0; - ASN_SEQUENCE_ADD(&NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity->list, n_rbs[i]); + ASN_SEQUENCE_ADD(&NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity->list, &n_rbs[i]); } NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity = CALLOC(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity)); - int *ptrs_mcs[3]; + long *ptrs_mcs = CALLOC(3, sizeof(long)); for (int i = 0; i < 3; i++) { - ptrs_mcs[i] = CALLOC(1, sizeof(*ptrs_mcs[i])); - *ptrs_mcs[i] = 0; - ASN_SEQUENCE_ADD(&NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity->list, ptrs_mcs[i]); + ASN_SEQUENCE_ADD(&NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity->list, &ptrs_mcs[i]); } - NR_PTRS_UplinkConfig->transformPrecoderDisabled->resourceElementOffset = CALLOC(1, sizeof(NR_PTRS_UplinkConfig->transformPrecoderDisabled->resourceElementOffset)); + NR_PTRS_UplinkConfig->transformPrecoderDisabled->resourceElementOffset = CALLOC(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled->resourceElementOffset)); *NR_PTRS_UplinkConfig->transformPrecoderDisabled->resourceElementOffset = 0; // UL bandwidth part From bc041092c83b166f8e071cbb2eb7669c7ec5ec08 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Fri, 19 Mar 2021 17:45:14 +0100 Subject: [PATCH 39/40] NR_UE: always break out of MAC PDU processing after pdu_len Bytes In case of false positive PDSCH CRC check, a random MAC PDU is processed. Currently pdu_len is unsigned 16 Bit, so we did break out of the processing loop only if we _exactly_ hit a residual pdu_len of 0, or we hit a LCID of DL_SCH_LCID_PADDING. If we didn't hit either of these, pdu_len wrapped to a very positive value, and we continued processing the PDU even beyond its bounds! This behavior was observed with SNR 1 dB and MCS 9. So better make pdu_len signed and break out of the loop after processing at max. pdu_len Bytes! --- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index f7085c4555..e11eec6b28 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -881,7 +881,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, int harq_pid = dlsch0->current_harq_pid; int frame_rx = proc->frame_rx; int nr_slot_rx = proc->nr_slot_rx; - int ret=0, ret1=0; + uint32_t ret = UINT32_MAX, ret1 = UINT32_MAX; NR_UE_PDSCH *pdsch_vars; uint16_t dmrs_len = get_num_dmrs(dlsch0->harq_processes[dlsch0->current_harq_pid]->dlDmrsSymbPos); nr_downlink_indication_t dl_indication; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index cb104092f1..80ee97798a 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -1746,7 +1746,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, frame_t frameP = dl_info->frame; int slot = dl_info->slot; uint8_t *pduP = (dl_info->rx_ind->rx_indication_body + pdu_id)->pdsch_pdu.pdu; - uint16_t pdu_len = (dl_info->rx_ind->rx_indication_body + pdu_id)->pdsch_pdu.pdu_length; + int32_t pdu_len = (dl_info->rx_ind->rx_indication_body + pdu_id)->pdsch_pdu.pdu_length; uint8_t gNB_index = dl_info->gNB_index; uint8_t CC_id = dl_info->cc_id; uint8_t done = 0; @@ -1757,7 +1757,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, return; } - LOG_D(MAC, "In %s [%d.%d]: processing PDU %d of %d total number of PDUs...\n", __FUNCTION__, frameP, slot, pdu_id, dl_info->rx_ind->number_pdus); + LOG_D(MAC, "In %s [%d.%d]: processing PDU %d (with length %d) of %d total number of PDUs...\n", __FUNCTION__, frameP, slot, pdu_id, pdu_len, dl_info->rx_ind->number_pdus); while (!done && pdu_len > 0){ mac_ce_len = 0x0000; @@ -1961,7 +1961,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, pduP += ( mac_subheader_len + mac_ce_len + mac_sdu_len ); pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len ); if (pdu_len < 0) - LOG_E(MAC, "[MAC] nr_ue_process_mac_pdu, residual mac pdu length %d < 0!\n", pdu_len); + LOG_E(MAC, "[UE %d][%d.%d] nr_ue_process_mac_pdu, residual mac pdu length %d < 0!\n", module_idP, frameP, slot, pdu_len); } } From e7da2c88b3e48743c0cbf72cc89c96c3f1d47ded Mon Sep 17 00:00:00 2001 From: sfn Date: Mon, 22 Mar 2021 18:23:06 +0100 Subject: [PATCH 40/40] skip the precoding lines of the code if there is no precoding info from nfapi --- openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 130 ++++++++++++++++----------- 1 file changed, 79 insertions(+), 51 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 088f6393de..d6b8a41a0e 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -418,64 +418,92 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, // The Precoding matrix: // The Codebook Type I and Type II are not supported yet. // We adopt the precoding matrices of PUSCH for 4 layers. - uint8_t pmi; - for (int ap=0; apnb_antennas_tx; ap++) { + if ((frame_parms->nb_antennas_tx == 1 && rel15->nrOfLayers == 1) || rel15->precodingAndBeamforming.prgSize == 0) {//No precoding if precoding info is not available + for (int ap=0; apnb_antennas_tx; ap++) {//frame_parms->nb_antennas_tx rel15->nrOfLayers + if(apnrOfLayers) + memcpy((void*)&txdataF[ap][rel15->StartSymbolIndex*frame_parms->ofdm_symbol_size + txdataF_offset], + (void*)&txdataF_precoding[ap][2*(rel15->StartSymbolIndex*frame_parms->ofdm_symbol_size + txdataF_offset)], + rel15->NrOfSymbols*frame_parms->ofdm_symbol_size*sizeof(int32_t)); + else + memset((void*)&txdataF[ap][rel15->StartSymbolIndex*frame_parms->ofdm_symbol_size + txdataF_offset], + 0, + rel15->NrOfSymbols*frame_parms->ofdm_symbol_size*sizeof(int32_t)); + } + } else {//apply precoding + uint8_t pmi; + for (int ap=0; apnb_antennas_tx; ap++) { - for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { - uint16_t k = start_sc; + for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { + uint16_t k = start_sc; - for (int rb=0; rbrbSize; rb++) { - //get pmi info - if (rel15->precodingAndBeamforming.prgSize > 0) - pmi = rel15->precodingAndBeamforming.PMIdx[(int)rb/rel15->precodingAndBeamforming.prgSize]; - else - pmi = 0;//no precoding + for (int rb=0; rbrbSize; rb++) { + //get pmi info + if (rel15->precodingAndBeamforming.prgSize > 0) + pmi = rel15->precodingAndBeamforming.PMIdx[(int)rb/rel15->precodingAndBeamforming.prgSize]; + else + pmi = 0;//no precoding - //get the precoding matrix weights: - char *W_prec; - switch (frame_parms->nb_antennas_tx) { - case 1://1 antenna port - W_prec = nr_W_1l_2p[pmi][ap]; - break; - case 2://2 antenna ports - if (rel15->nrOfLayers == 1)//1 layer - W_prec = nr_W_1l_2p[pmi][ap]; - else//2 layers - W_prec = nr_W_2l_2p[pmi][ap]; + //get the precoding matrix weights: + char *W_prec; + switch (frame_parms->nb_antennas_tx) { + case 1://1 antenna port + W_prec = nr_W_1l_2p[pmi][ap]; break; - case 4://4 antenna ports + case 2://2 antenna ports if (rel15->nrOfLayers == 1)//1 layer - W_prec = nr_W_1l_4p[pmi][ap]; - else if (rel15->nrOfLayers == 2)//2 layers - W_prec = nr_W_2l_4p[pmi][ap]; - else if (rel15->nrOfLayers == 3)//3 layers - W_prec = nr_W_3l_4p[pmi][ap]; - else//4 layers - W_prec = nr_W_4l_4p[pmi][ap]; + W_prec = nr_W_1l_2p[pmi][ap]; + else//2 layers + W_prec = nr_W_2l_2p[pmi][ap]; break; - default: - LOG_D(PHY,"Precoding 1,2, or 4 antenna ports are currently supported\n"); - W_prec = nr_W_1l_2p[pmi][ap]; - break; - } - - for (int i=0; iofdm_symbol_size + k; - int32_t precodatatx_F = nr_layer_precoder(txdataF_precoding, W_prec, rel15->nrOfLayers, re_offset+txdataF_offset); - ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[0]; - ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[1]; - #ifdef DEBUG_DLSCH_MAPPING - printf("antenna %d\t l %d \t k %d \t txdataF: %d %d\n", - ap, l, k, ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)], - ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)]); - #endif - if (++k >= frame_parms->ofdm_symbol_size) { - k -= frame_parms->ofdm_symbol_size; + case 4://4 antenna ports + if (rel15->nrOfLayers == 1)//1 layer + W_prec = nr_W_1l_4p[pmi][ap]; + else if (rel15->nrOfLayers == 2)//2 layers + W_prec = nr_W_2l_4p[pmi][ap]; + else if (rel15->nrOfLayers == 3)//3 layers + W_prec = nr_W_3l_4p[pmi][ap]; + else//4 layers + W_prec = nr_W_4l_4p[pmi][ap]; + break; + default: + LOG_D(PHY,"Precoding 1,2, or 4 antenna ports are currently supported\n"); + W_prec = nr_W_1l_2p[pmi][ap]; + break; } - } - } //RE loop - } // symbol loop - }// port loop + if (pmi == 0) {//unitary Precoding + if(apnrOfLayers) + memcpy((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + txdataF_offset + k], + (void*)&txdataF_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + txdataF_offset+ k)], + NR_NB_SC_PER_RB*sizeof(int32_t)); + else + memset((void*)&txdataF[ap][rel15->StartSymbolIndex*frame_parms->ofdm_symbol_size + txdataF_offset +k], + 0, + NR_NB_SC_PER_RB*sizeof(int32_t)); + k += NR_NB_SC_PER_RB; + if (k >= frame_parms->ofdm_symbol_size) { + k -= frame_parms->ofdm_symbol_size; + } + } + else { + for (int i=0; iofdm_symbol_size + k; + int32_t precodatatx_F = nr_layer_precoder(txdataF_precoding, W_prec, rel15->nrOfLayers, re_offset+txdataF_offset); + ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[0]; + ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[1]; +#ifdef DEBUG_DLSCH_MAPPING + printf("antenna %d\t l %d \t k %d \t txdataF: %d %d\n", + ap, l, k, ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)], + ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)]); +#endif + if (++k >= frame_parms->ofdm_symbol_size) { + k -= frame_parms->ofdm_symbol_size; + } + } + } + } //RB loop + } // symbol loop + }// port loop + } dlsch->slot_tx[slot]=0; }// dlsch loop