From e4a7eda96878e2e43c90926619f3333429cbdc0c Mon Sep 17 00:00:00 2001 From: yihz Date: Tue, 7 Dec 2021 10:43:28 +0800 Subject: [PATCH 01/49] base on 2021.w48, diff_1206_2.diff, UL_NR_MIMO 4*4 --- diff_1206_2.txt | 4257 +++++++++++++++++ executables/nr-softmodem-common.h | 1 + executables/nr-softmodem.h | 2 + executables/nr-ue.c | 5 +- executables/nr-uesoftmodem.c | 7 +- .../nfapi/public_inc/fapi_nr_ue_interface.h | 3 +- .../nfapi/public_inc/nfapi_nr_interface_scf.h | 3 +- nfapi/open-nFAPI/nfapi/src/nfapi_p7.c | 6 +- openair1/PHY/INIT/nr_init.c | 20 +- openair1/PHY/INIT/nr_init_ru.c | 2 +- openair1/PHY/INIT/nr_init_ue.c | 5 +- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 9 +- .../PHY/NR_TRANSPORT/nr_transport_proto.h | 30 +- openair1/PHY/NR_TRANSPORT/nr_ulsch.c | 32 + openair1/PHY/NR_TRANSPORT/nr_ulsch.h | 6 + .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 1363 +++++- .../NR_TRANSPORT/nr_ulsch_llr_computation.c | 28 +- openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c | 6 +- .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 9 + openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 357 +- openair1/PHY/defs_gNB.h | 6 +- openair1/PHY/defs_nr_UE.h | 3 + openair1/PHY/defs_nr_common.h | 8 +- openair1/SCHED_NR/nr_ru_procedures.c | 3 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 20 +- openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 4 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 9 +- openair1/SIMULATION/NR_PHY/dlsim.c | 2 +- openair1/SIMULATION/NR_PHY/ulschsim.c | 32 +- openair1/SIMULATION/NR_PHY/ulsim.c | 271 +- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 3 + openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 109 +- openair2/LAYER2/NR_MAC_gNB/config.c | 2 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 4 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 3 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 14 +- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 28 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 34 +- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 1 + openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 3 +- openair2/RRC/NR/MESSAGES/asn1_msg.c | 1 + openair2/RRC/NR/nr_rrc_proto.h | 2 + openair2/RRC/NR/rrc_gNB_nsa.c | 4 +- openair2/RRC/NR/rrc_gNB_reconfig.c | 13 +- targets/ARCH/rfsimulator/simulator.c | 17 +- ....sa.band78.fr1.106PRB.usrpb210.4layer.conf | 320 ++ 46 files changed, 6444 insertions(+), 623 deletions(-) create mode 100644 diff_1206_2.txt create mode 100644 targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf diff --git a/diff_1206_2.txt b/diff_1206_2.txt new file mode 100644 index 0000000000..ff352f4157 --- /dev/null +++ b/diff_1206_2.txt @@ -0,0 +1,4257 @@ +diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h +index c02155326b..1238b43c27 100644 +--- a/executables/nr-softmodem-common.h ++++ b/executables/nr-softmodem-common.h +@@ -67,6 +67,7 @@ + #define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n" + #define CONFIG_HLP_DLMCS_PHYTEST "Set the downlink MCS for PHYTEST mode\n" + #define CONFIG_HLP_DLNL_PHYTEST "Set the downlink nrOfLayers for PHYTEST mode\n" ++#define CONFIG_HLP_ULNL_PHYTEST "Set the uplink nrOfLayers for PHYTEST mode\n" + #define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n" + #define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n" + #define CONFIG_HLP_ULMCS_PHYTEST "Set the uplink MCS for PHYTEST mode\n" +diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h +index 896c363cbf..a11572c0e1 100644 +--- a/executables/nr-softmodem.h ++++ b/executables/nr-softmodem.h +@@ -23,6 +23,7 @@ + {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \ + {"m" , CONFIG_HLP_DLMCS_PHYTEST,0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ + {"l" , CONFIG_HLP_DLNL_PHYTEST,0, uptr:&target_dl_Nl, defintval:0, TYPE_UINT, 0}, \ ++ {"L" , CONFIG_HLP_ULNL_PHYTEST,0, uptr:&target_ul_Nl, defintval:0, TYPE_UINT, 0}, \ + {"t" , CONFIG_HLP_ULMCS_PHYTEST,0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ + {"M" , CONFIG_HLP_DLBW_PHYTEST,0, uptr:&target_dl_bw, defintval:0, TYPE_UINT, 0}, \ + {"T" , CONFIG_HLP_ULBW_PHYTEST,0, uptr:&target_ul_bw, defintval:0, TYPE_UINT, 0}, \ +@@ -36,6 +37,7 @@ + extern threads_t threads; + extern uint32_t target_dl_mcs; + extern uint32_t target_dl_Nl; ++extern uint32_t target_ul_Nl; + extern uint32_t target_ul_mcs; + extern uint32_t target_dl_bw; + extern uint32_t target_ul_bw; +diff --git a/executables/nr-ue.c b/executables/nr-ue.c +index 60ff40abeb..a23f91b1dd 100644 +--- a/executables/nr-ue.c ++++ b/executables/nr-ue.c +@@ -278,7 +278,7 @@ void processSlotTX(void *arg) { + int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_slot_tx); + uint8_t gNB_id = 0; + +- LOG_D(PHY,"%d.%d => slot type %d\n",proc->frame_tx,proc->nr_slot_tx,tx_slot_type); ++ LOG_D(PHY,"processSlotTX %d.%d => slot type %d\n",proc->frame_tx,proc->nr_slot_tx,tx_slot_type); + if (tx_slot_type == NR_UPLINK_SLOT || tx_slot_type == NR_MIXED_SLOT){ + + // trigger L2 to run ue_scheduler thru IF module +@@ -372,7 +372,8 @@ void processSlotRX(void *arg) { + LOG_D(PHY, "Sending Uplink data \n"); + nr_ue_pusch_common_procedures(UE, + proc->nr_slot_tx, +- &UE->frame_parms,1); ++ &UE->frame_parms, ++ UE->frame_parms.nb_antennas_tx); + } + + if (UE->UE_mode[gNB_id] > NOT_SYNCHED && UE->UE_mode[gNB_id] < PUSCH) { +diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c +index ad5ea982c9..57fd284601 100644 +--- a/executables/nr-uesoftmodem.c ++++ b/executables/nr-uesoftmodem.c +@@ -465,8 +465,11 @@ int main( int argc, char **argv ) { + memset(UE[CC_id],0,sizeof(PHY_VARS_NR_UE)); + + set_options(CC_id, UE[CC_id]); +- NR_UE_MAC_INST_t *mac = get_mac_inst(0); +- ++ NR_DL_FRAME_PARMS *fp = &UE[CC_id]->frame_parms; ++ NR_UE_MAC_INST_t *mac = get_mac_inst(0); ++ ++ mac->phy_config.config_req.carrier_config.num_tx_ant = fp->nb_antennas_tx; ++ + if (get_softmodem_params()->sa) { + uint16_t nr_band = get_band(downlink_frequency[CC_id][0],uplink_frequency_offset[CC_id][0]); + mac->nr_band = nr_band; +diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +index 0e923931ad..8b93417cb0 100644 +--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h ++++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +@@ -298,9 +298,10 @@ typedef struct + uint8_t qam_mod_order; + uint8_t mcs_index; + uint8_t mcs_table; +- uint8_t transform_precoding; ++ uint8_t transformPrecoder; + uint16_t data_scrambling_id; + uint8_t nrOfLayers; ++ uint8_t Tpmi; + //DMRS + uint16_t ul_dmrs_symb_pos; + uint8_t dmrs_config_type; +diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +index 9d245446c8..58ff9037ce 100644 +--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h ++++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +@@ -1208,9 +1208,10 @@ typedef struct + uint8_t qam_mod_order; + uint8_t mcs_index; + uint8_t mcs_table; +- uint8_t transform_precoding; ++ uint8_t transformPrecoder; + uint16_t data_scrambling_id; + uint8_t nrOfLayers; ++ uint8_t Tpmi; + //DMRS + uint16_t ul_dmrs_symb_pos; + uint8_t dmrs_config_type; +diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +index 7cb74f8562..473b0900bc 100644 +--- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c ++++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +@@ -941,9 +941,10 @@ static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, ui + push8(pusch_pdu->qam_mod_order, ppWritePackedMsg, end) && + push8(pusch_pdu->mcs_index, ppWritePackedMsg, end) && + push8(pusch_pdu->mcs_table, ppWritePackedMsg, end) && +- push8(pusch_pdu->transform_precoding, ppWritePackedMsg, end) && ++ push8(pusch_pdu->transformPrecoder, ppWritePackedMsg, end) && + push16(pusch_pdu->data_scrambling_id, ppWritePackedMsg, end) && + push8(pusch_pdu->nrOfLayers, ppWritePackedMsg, end) && ++ push8(pusch_pdu->Tpmi, ppWritePackedMsg, end) && + push16(pusch_pdu->ul_dmrs_symb_pos, ppWritePackedMsg, end) && + push8(pusch_pdu->dmrs_config_type, ppWritePackedMsg, end) && + push16(pusch_pdu->ul_dmrs_scrambling_id, ppWritePackedMsg, end) && +@@ -4445,9 +4446,10 @@ static uint8_t unpack_ul_tti_request_pusch_pdu(void *tlv, uint8_t **ppReadPacked + pull8(ppReadPackedMsg, &pusch_pdu->qam_mod_order, end) && + pull8(ppReadPackedMsg, &pusch_pdu->mcs_index, end) && + pull8(ppReadPackedMsg, &pusch_pdu->mcs_table, end) && +- pull8(ppReadPackedMsg, &pusch_pdu->transform_precoding, end) && ++ pull8(ppReadPackedMsg, &pusch_pdu->transformPrecoder, end) && + pull16(ppReadPackedMsg, &pusch_pdu->data_scrambling_id, end) && + pull8(ppReadPackedMsg, &pusch_pdu->nrOfLayers, end) && ++ pull8(ppReadPackedMsg, &pusch_pdu->Tpmi, end) && + pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_symb_pos, end) && + pull8(ppReadPackedMsg, &pusch_pdu->dmrs_config_type, end) && + pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_scrambling_id, end) && +diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c +index cd4848ea8c..2ac3230215 100644 +--- a/openair1/PHY/INIT/nr_init.c ++++ b/openair1/PHY/INIT/nr_init.c +@@ -276,11 +276,21 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, + pusch_vars[ULSCH_id]->ul_ch_magb0 = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->ul_ch_mag = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->ul_ch_magb = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); +- pusch_vars[ULSCH_id]->rho = (int32_t **)malloc16_clear(n_buf*sizeof(int32_t*) ); ++ pusch_vars[ULSCH_id]->rho = (int32_t ***)malloc16_clear(Prx*sizeof(int32_t**) ); ++ pusch_vars[ULSCH_id]->llr_layers = (int16_t **)malloc16(max_ul_mimo_layers*sizeof(int32_t *) ); + + for (i=0; irxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); + pusch_vars[ULSCH_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); ++ pusch_vars[ULSCH_id]->rho[i] = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS*sizeof(int32_t*)); ++ ++ for (int j=0; j< max_ul_mimo_layers; j++) ++ { ++ for (int k=0; krho[i][j*max_ul_mimo_layers+k]=(int32_t *)malloc16_clear( sizeof(int32_t) * fp->N_RB_UL*12*7*2 ); ++ } ++ } + } + for (i=0; iul_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot ); +@@ -293,8 +303,12 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, + pusch_vars[ULSCH_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); + pusch_vars[ULSCH_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); + pusch_vars[ULSCH_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); +- pusch_vars[ULSCH_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); +- pusch_vars[ULSCH_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) ); ++ pusch_vars[ULSCH_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); ++ } ++ ++ for (i=0; i< max_ul_mimo_layers; i++) ++ { ++ pusch_vars[ULSCH_id]->llr_layers[i] = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear + } + pusch_vars[ULSCH_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear + pusch_vars[ULSCH_id]->ul_valid_re_per_slot = (int16_t *)malloc16_clear( sizeof(int16_t)*fp->symbols_per_slot); +diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c +index 4024ed1617..169db48e69 100644 +--- a/openair1/PHY/INIT/nr_init_ru.c ++++ b/openair1/PHY/INIT/nr_init_ru.c +@@ -41,7 +41,7 @@ int nr_phy_init_RU(RU_t *ru) { + int p; + int re; + +- LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d\n",ru_if_types[ru->if_south],ru->nb_tx); ++ LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d, nb_rx %d\n",ru_if_types[ru->if_south],ru->nb_tx, ru->nb_rx); + + nfapi_nr_config_request_scf_t *cfg; + ru->nb_log_antennas=0; +diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c +index b60e77e814..11fb6e7d61 100644 +--- a/openair1/PHY/INIT/nr_init_ue.c ++++ b/openair1/PHY/INIT/nr_init_ue.c +@@ -124,7 +124,8 @@ void phy_init_nr_ue_PUSCH(NR_UE_PUSCH *const pusch, + AssertFatal( pusch, "pusch==0" ); + + for (int i=0; itxdataF_layers[i] = (int32_t *)malloc16_clear(NR_MAX_PUSCH_ENCODED_LENGTH*sizeof(int32_t)); ++ pusch->txdataF_layers[i] = (int32_t *)malloc16_clear((NR_MAX_PUSCH_ENCODED_LENGTH)*sizeof(int32_t *)); ++ pusch->txdataF_precoding[i] = (int32_t *)malloc16_clear((NR_MAX_PUSCH_ENCODED_LENGTH)*sizeof(int32_t *)); + } + } + +@@ -143,7 +144,7 @@ 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; +- 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_I(PHY, "Initializing UE vars (abstraction %u) for UE 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_gNB_INST); + phy_init_nr_top(ue); + // many memory allocation sizes are hard coded +diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +index 1f164748bf..9a432e8615 100644 +--- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c ++++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +@@ -110,7 +110,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, + fr = filt8_r1; + fmm = filt8_mm1; + fml = filt8_ml1; +- fmr = filt8_m1; ++ fmr = filt8_mm1; + fdcl = filt8_dcl1; + fdcr = filt8_dcr1; + fdclh = filt8_dcl1_h; +@@ -129,9 +129,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, + + //------------------generate DMRS------------------// + +- // transform precoding = 1 means disabled +- if (pusch_pdu->transform_precoding == 1) { +- nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, ++ if (pusch_pdu->transformPrecoder == transformPrecoder_disabled) { ++ nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], (1000+p), 0, nb_rb_pusch, + (pusch_pdu->bwp_start + pusch_pdu->rb_start)*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type); + } + else { // if transform precoding or SC-FDMA is enabled in Uplink +@@ -291,7 +290,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, + printf("pilot %u : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]); + printf("data %u : rxF - > (%d,%d) (%d)\n",pilot_cnt,rxF[2],rxF[3],dBc(rxF[2],rxF[3])); + #endif +- multadd_real_vector_complex_scalar(fml, ++ multadd_real_vector_complex_scalar(fm, + ch, + ul_ch, + 8); +diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +index 4fed3a468f..87e4d57362 100644 +--- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h ++++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +@@ -137,21 +137,22 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, + @param nb_rb_pusch The number of RBs allocated (used for Resource Allocation Type 1 in NR) + @param frame_parms, Pointer to frame descriptor structure + */ +-void nr_ulsch_extract_rbs_single(int32_t **rxdataF, +- NR_gNB_PUSCH *pusch_vars, +- int slot, +- unsigned char symbol, +- uint8_t is_dmrs_symbol, +- nfapi_nr_pusch_pdu_t *pusch_pdu, +- NR_DL_FRAME_PARMS *frame_parms); ++void nr_ulsch_extract_rbs(int32_t **rxdataF, ++ NR_gNB_PUSCH *pusch_vars, ++ int slot, ++ unsigned char symbol, ++ uint8_t is_dmrs_symbol, ++ nfapi_nr_pusch_pdu_t *pusch_pdu, ++ NR_DL_FRAME_PARMS *frame_parms); + + void nr_ulsch_scale_channel(int32_t **ul_ch_estimates_ext, + NR_DL_FRAME_PARMS *frame_parms, + NR_gNB_ULSCH_t **ulsch_gNB, +- uint8_t symbol, +- uint8_t start_symbol, +- uint16_t nb_rb, +- pusch_dmrs_type_t pusch_dmrs_type); ++ uint8_t symbol, ++ uint8_t is_dmrs_symbol, ++ uint32_t len, ++ uint8_t nrOfLayers, ++ uint16_t nb_rb); + + /** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal + @param ul_ch_estimates_ext Channel estimates in allocated RBs +@@ -185,9 +186,10 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, + int **ul_ch_mag, + int **ul_ch_magb, + int **rxdataF_comp, +- int **rho, ++ int ***rho, + NR_DL_FRAME_PARMS *frame_parms, + unsigned char symbol, ++ int length, + uint8_t is_dmrs_symbol, + unsigned char mod_order, + uint8_t nrOfLayers, +@@ -255,8 +257,8 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, + @param mod_order modulation order + */ + void nr_ulsch_compute_llr(int32_t *rxdataF_comp, +- int32_t **ul_ch_mag, +- int32_t **ul_ch_magb, ++ int32_t *ul_ch_mag, ++ int32_t *ul_ch_magb, + int16_t *ulsch_llr, + uint32_t nb_rb, + uint32_t nb_re, +diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c +index 4278338dbc..3ea19a9970 100644 +--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c ++++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c +@@ -137,6 +137,38 @@ void nr_ulsch_unscrambling_optim(int16_t* llr, + #endif + } + ++void nr_ulsch_layer_demapping(int16_t *llr_cw, ++ uint8_t Nl, ++ uint8_t mod_order, ++ uint32_t length, ++ int16_t **llr_layers) ++{ ++ ++ switch (Nl) { ++ ++ case 1: ++ memcpy((void*)llr_cw, (void*)llr_layers[0], (length)*sizeof(int16_t)); ++ break; ++ ++ case 2: ++ case 3: ++ case 4: ++ for (int i=0; i<(length/Nl/mod_order); i++) ++ { ++ for (int l=0; lnumber_of_nr_ulsch_max;i++) { +diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h +index 80c10d74b1..0e660351ae 100644 +--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h ++++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h +@@ -82,6 +82,12 @@ void nr_ulsch_unscrambling_optim(int16_t* llr, + uint32_t Nid, + uint32_t n_RNTI); + ++void nr_ulsch_layer_demapping(int16_t *llr_cw, ++ uint8_t Nl, ++ uint8_t mod_order, ++ uint32_t length, ++ int16_t **llr_layers); ++ + void nr_ulsch_procedures(PHY_VARS_gNB *gNB, + int frame_rx, + int slot_rx, +diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +index 28dd5ab219..8314c83ad9 100644 +--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c ++++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +@@ -302,26 +302,27 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) + } + + +-void nr_ulsch_extract_rbs_single(int32_t **rxdataF, +- NR_gNB_PUSCH *pusch_vars, +- int slot, +- unsigned char symbol, +- uint8_t is_dmrs_symbol, +- nfapi_nr_pusch_pdu_t *pusch_pdu, +- NR_DL_FRAME_PARMS *frame_parms) ++void nr_ulsch_extract_rbs(int32_t **rxdataF, ++ NR_gNB_PUSCH *pusch_vars, ++ int slot, ++ unsigned char symbol, ++ uint8_t is_dmrs_symbol, ++ nfapi_nr_pusch_pdu_t *pusch_pdu, ++ NR_DL_FRAME_PARMS *frame_parms) + { + + unsigned short start_re, re, nb_re_pusch; +- unsigned char aarx; ++ unsigned char aarx, aatx; + uint32_t rxF_ext_index = 0; + uint32_t ul_ch0_ext_index = 0; + uint32_t ul_ch0_index = 0; +- uint8_t k_prime; +- uint16_t n; ++ //uint8_t k_prime; ++ //uint16_t n; + int16_t *rxF,*rxF_ext; + int *ul_ch0,*ul_ch0_ext; +- uint8_t delta = 0; ++ //uint8_t delta = 0; + int soffset = (slot&3)*frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size; ++ + #ifdef DEBUG_RB_EXT + + printf("--------------------symbol = %d-----------------------\n", symbol); +@@ -329,7 +330,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, + + #endif + +- uint8_t is_dmrs_re; ++ uint8_t is_data_re; + start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start + pusch_pdu->bwp_start) * NR_NB_SC_PER_RB)%frame_parms->ofdm_symbol_size; + nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size; + #ifdef __AVX2__ +@@ -338,64 +339,95 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, + int nb_re_pusch2 = nb_re_pusch; + #endif + +- for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { ++ for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) ++ { + + rxF = (int16_t *)&rxdataF[aarx][soffset+(symbol * frame_parms->ofdm_symbol_size)]; + rxF_ext = (int16_t *)&pusch_vars->rxdataF_ext[aarx][symbol * nb_re_pusch2]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6 +- +- ul_ch0 = &pusch_vars->ul_ch_estimates[aarx][pusch_vars->dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available +- +- ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aarx][symbol*nb_re_pusch2]; +- +- n = 0; +- k_prime = 0; +- rxF_ext_index = 0; +- ul_ch0_ext_index = 0; +- ul_ch0_index = 0; +- +- if (is_dmrs_symbol == 0) { ++ ++ if (is_dmrs_symbol == 0) ++ { + // + //rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]); +- if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size) { ++ if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size) ++ { + memcpy1((void*)rxF_ext, + (void*)&rxF[start_re*2], + nb_re_pusch*sizeof(int32_t)); +- } else { +- int neg_length = frame_parms->ofdm_symbol_size-start_re; +- int pos_length = nb_re_pusch-neg_length; ++ } ++ else ++ { ++ int neg_length = frame_parms->ofdm_symbol_size-start_re; ++ int pos_length = nb_re_pusch-neg_length; ++ memcpy1((void*)rxF_ext,(void*)&rxF[start_re*2],neg_length*sizeof(int32_t)); ++ memcpy1((void*)&rxF_ext[2*neg_length],(void*)rxF,pos_length*sizeof(int32_t)); ++ } + +- memcpy1((void*)rxF_ext,(void*)&rxF[start_re*2],neg_length*sizeof(int32_t)); +- memcpy1((void*)&rxF_ext[2*neg_length],(void*)rxF,pos_length*sizeof(int32_t)); ++ #ifdef SUPPORT_PMI_MATRIC ++ for (aatx = 0; aatx < pusch_pdu->nrOfLayers; aatx++) ++ #else ++ aatx = aarx; ++ #endif ++ { ++ ul_ch0 = &pusch_vars->ul_ch_estimates[aatx*frame_parms->nb_antennas_rx+aarx][pusch_vars->dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available ++ ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_re_pusch2]; ++ ++ memcpy1((void*)ul_ch0_ext,(void*)ul_ch0,nb_re_pusch*sizeof(int32_t)); + } +- memcpy1((void*)ul_ch0_ext,(void*)ul_ch0,nb_re_pusch*sizeof(int32_t)); + } +- else { +- for (re = 0; re < nb_re_pusch; re++) { +- +- is_dmrs_re = (re == get_dmrs_freq_idx_ul(n, k_prime, delta, pusch_pdu->dmrs_config_type)); +- +-#ifdef DEBUG_RB_EXT +- printf("re = %d, kprime %d, n %d, is_dmrs_symbol = %d, symbol = %d\n", re, k_prime, n, is_dmrs_symbol, symbol); +-#endif +- +- /* save only data and respective channel estimates */ +- if (is_dmrs_re == 0) { +- rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]); +- rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]); +- ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index]; ++ else ++ { ++ #ifdef SUPPORT_PMI_MATRIC ++ for (aatx = 0; aatx < pusch_pdu->nrOfLayers; aatx++) ++ #else ++ aatx = aarx; ++ #endif ++ { ++ ul_ch0 = &pusch_vars->ul_ch_estimates[aatx*frame_parms->nb_antennas_rx+aarx][pusch_vars->dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available ++ ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_re_pusch2]; ++ ++ //n = 0; ++ //k_prime = 0; ++ rxF_ext_index = 0; ++ ul_ch0_ext_index = 0; ++ ul_ch0_index = 0; ++ ++ for (re = 0; re < nb_re_pusch; re++) ++ { ++ uint16_t k= start_re+re; ++ ++ is_data_re = allowed_xlsch_re_in_dmrs_symbol(k, start_re, frame_parms->ofdm_symbol_size, pusch_pdu->num_dmrs_cdm_grps_no_data, pusch_pdu->dmrs_config_type); ++ ++ if (++k >= frame_parms->ofdm_symbol_size) ++ { ++ k -= frame_parms->ofdm_symbol_size; ++ } + +-#ifdef DEBUG_RB_EXT +- printf("dmrs symb %d: rxF_ext[%d] = (%d,%d), ul_ch0_ext[%d] = (%d,%d)\n", ++ #ifdef DEBUG_RB_EXT ++ printf("re = %d, kprime %d, n %d, is_dmrs_symbol = %d, symbol = %d\n", re, k_prime, n, is_dmrs_symbol, symbol); ++ #endif ++ ++ /* save only data and respective channel estimates */ ++ if (is_data_re == 1) ++ { ++ if (aatx == aarx) ++ { ++ rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]); ++ rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]); ++ rxF_ext_index +=2; ++ } ++ ++ ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index]; ++ ul_ch0_ext_index++; ++ ++ #ifdef DEBUG_RB_EXT ++ printf("dmrs symb %d: rxF_ext[%d] = (%d,%d), ul_ch0_ext[%d] = (%d,%d)\n", + is_dmrs_symbol,rxF_ext_index>>1, rxF_ext[rxF_ext_index],rxF_ext[rxF_ext_index+1], + ul_ch0_ext_index, ((int16_t*)&ul_ch0_ext[ul_ch0_ext_index])[0], ((int16_t*)&ul_ch0_ext[ul_ch0_ext_index])[1]); +-#endif +- ul_ch0_ext_index++; +- rxF_ext_index +=2; +- } else { +- n += k_prime; +- k_prime ^= 1; ++ #endif ++ } ++ ul_ch0_index++; + } +- ul_ch0_index++; + } + } + } +@@ -406,16 +438,19 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, + NR_gNB_ULSCH_t **ulsch_gNB, + uint8_t symbol, + uint8_t is_dmrs_symbol, +- unsigned short nb_rb, +- pusch_dmrs_type_t pusch_dmrs_type) ++ uint32_t len, ++ uint8_t nrOfLayers, ++ unsigned short nb_rb) + { + + #if defined(__x86_64__)||defined(__i386__) + + short rb, ch_amp; +- unsigned char aarx; ++ unsigned char aarx,aatx; + __m128i *ul_ch128, ch_amp128; + ++ uint32_t nb_rb_0 = len/12 + ((len%12)?1:0); ++ + // Determine scaling amplitude based the symbol + + ch_amp = 1024*8; //((pilots) ? (ulsch_gNB[0]->sqrt_rho_b) : (ulsch_gNB[0]->sqrt_rho_a)); +@@ -431,35 +466,26 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, + int off = 0; + #endif + +- 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))]; +- +- if (is_dmrs_symbol==1){ +- if (pusch_dmrs_type == pusch_dmrs_type1) +- nb_rb = nb_rb>>1; +- else +- nb_rb = (2*nb_rb)/3; +- } +- +- for (rb=0;rbnb_antennas_rx; aarx++) ++ { ++ ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*NR_NB_SC_PER_RB))]; + ++ for (rb=0;rb < nb_rb_0;rb++) ++ { + ul_ch128[0] = _mm_mulhi_epi16(ul_ch128[0], ch_amp128); + ul_ch128[0] = _mm_slli_epi16(ul_ch128[0], 3); + + ul_ch128[1] = _mm_mulhi_epi16(ul_ch128[1], ch_amp128); + ul_ch128[1] = _mm_slli_epi16(ul_ch128[1], 3); + +- if (is_dmrs_symbol) { +- ul_ch128+=2; +- } else { +- ul_ch128[2] = _mm_mulhi_epi16(ul_ch128[2], ch_amp128); +- ul_ch128[2] = _mm_slli_epi16(ul_ch128[2], 3); +- ul_ch128+=3; +- +- } ++ ul_ch128[2] = _mm_mulhi_epi16(ul_ch128[2], ch_amp128); ++ ul_ch128[2] = _mm_slli_epi16(ul_ch128[2], 3); ++ ul_ch128+=3; + } +- } ++ } ++} + #endif + } + +@@ -481,6 +507,8 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, + + int16_t x = factor2(len); + int16_t y = (len)>>x; ++ ++ uint32_t nb_rb_0 = len/12 + ((len%12)?1:0); + + #ifdef __AVX2__ + int off = ((nb_rb&1) == 1)? 4:0; +@@ -489,13 +517,16 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, + #endif + + for (aatx = 0; aatx < nrOfLayers; aatx++) +- for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { ++ { ++ for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) ++ { + //clear average level + avg128U = _mm_setzero_si128(); + + ul_ch128=(__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; + +- for (rb = 0; rb < len/12; rb++) { ++ for (rb = 0; rb < nb_rb_0; rb++) ++ { + avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[0], ul_ch128[0]), x)); + avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[1], ul_ch128[1]), x)); + avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[2], ul_ch128[2]), x)); +@@ -508,7 +539,8 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, + ((int32_t*)&avg128U)[3]) / y; + + } +- ++ } ++ + _mm_empty(); + _m_empty(); + +@@ -520,7 +552,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, + int16x4_t *ul_ch128; + + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; +- ++ uint32_t nb_rb_0 = len/12 + ((len%12)?1:0); + for (aatx=0; aatxnb_antennas_rx; aarx++) { + //clear average level +@@ -529,7 +561,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, + + ul_ch128 = (int16x4_t *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*frame_parms->N_RB_UL*12]; + +- for (rb = 0; rb < nb_rb; rb++) { ++ for (rb = 0; rb < nb_rb_0; rb++) { + // printf("rb %d : ",rb); + // print_shorts("ch",&ul_ch128[0]); + avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[0], ul_ch128[0])); +@@ -568,14 +600,20 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, + #endif + } + ++ ++ ++//============================================================================================== ++// Pre-processing for LLR computation ++//============================================================================================== + void nr_ulsch_channel_compensation(int **rxdataF_ext, + int **ul_ch_estimates_ext, + int **ul_ch_mag, + int **ul_ch_magb, + int **rxdataF_comp, +- int **rho, ++ int ***rho, + NR_DL_FRAME_PARMS *frame_parms, + unsigned char symbol, ++ int length, + uint8_t is_dmrs_symbol, + unsigned char mod_order, + uint8_t nrOfLayers, +@@ -637,20 +675,24 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, + __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128={0},QAM_amp128b={0}; + QAM_amp128b = _mm_setzero_si128(); + +- for (aatx=0; aatxnb_antennas_rx; aarx++) { +- ++ for (aarx=0; aarxnb_antennas_rx; aarx++) ++ { + ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; + ul_ch_mag128 = (__m128i *)&ul_ch_mag[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; + ul_ch_mag128b = (__m128i *)&ul_ch_magb[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; +@@ -658,8 +700,10 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, + rxdataF_comp128 = (__m128i *)&rxdataF_comp[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; + + +- for (rb=0; rb2) { ++ for (rb=0; rb2) ++ { + // get channel amplitude if not QPSK + + //print_shorts("ch:",(int16_t*)&ul_ch128[0]); +@@ -679,6 +723,8 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, + ul_ch_mag128[0] = _mm_mulhi_epi16(ul_ch_mag128[0],QAM_amp128); + ul_ch_mag128[0] = _mm_slli_epi16(ul_ch_mag128[0],1); + ++ ul_ch_mag128b[0] = _mm_mulhi_epi16(ul_ch_mag128b[0],QAM_amp128b); ++ ul_ch_mag128b[0] = _mm_slli_epi16(ul_ch_mag128b[0],1); + // print_ints("ch: = ",(int32_t*)&mmtmpD0); + // print_shorts("QAM_amp:",(int16_t*)&QAM_amp128); + // print_shorts("mag:",(int16_t*)&ul_ch_mag128[0]); +@@ -687,30 +733,24 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, + ul_ch_mag128b[1] = ul_ch_mag128[1]; + ul_ch_mag128[1] = _mm_mulhi_epi16(ul_ch_mag128[1],QAM_amp128); + ul_ch_mag128[1] = _mm_slli_epi16(ul_ch_mag128[1],1); ++ ++ ul_ch_mag128b[1] = _mm_mulhi_epi16(ul_ch_mag128b[1],QAM_amp128); ++ ul_ch_mag128b[1] = _mm_slli_epi16(ul_ch_mag128b[1],1); + +- if (is_dmrs_symbol==0) { +- mmtmpD0 = _mm_madd_epi16(ul_ch128[2],ul_ch128[2]); +- mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); +- mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); +- +- ul_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); +- ul_ch_mag128b[2] = ul_ch_mag128[2]; ++ mmtmpD0 = _mm_madd_epi16(ul_ch128[2],ul_ch128[2]); ++ mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); ++ mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); + +- ul_ch_mag128[2] = _mm_mulhi_epi16(ul_ch_mag128[2],QAM_amp128); +- ul_ch_mag128[2] = _mm_slli_epi16(ul_ch_mag128[2],1); +- } ++ ul_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); ++ ul_ch_mag128b[2] = ul_ch_mag128[2]; + +- ul_ch_mag128b[0] = _mm_mulhi_epi16(ul_ch_mag128b[0],QAM_amp128b); +- ul_ch_mag128b[0] = _mm_slli_epi16(ul_ch_mag128b[0],1); ++ ul_ch_mag128[2] = _mm_mulhi_epi16(ul_ch_mag128[2],QAM_amp128); ++ ul_ch_mag128[2] = _mm_slli_epi16(ul_ch_mag128[2],1); + + +- ul_ch_mag128b[1] = _mm_mulhi_epi16(ul_ch_mag128b[1],QAM_amp128b); +- ul_ch_mag128b[1] = _mm_slli_epi16(ul_ch_mag128b[1],1); ++ ul_ch_mag128b[2] = _mm_mulhi_epi16(ul_ch_mag128b[2],QAM_amp128b); ++ ul_ch_mag128b[2] = _mm_slli_epi16(ul_ch_mag128b[2],1); + +- if (is_dmrs_symbol==0) { +- ul_ch_mag128b[2] = _mm_mulhi_epi16(ul_ch_mag128b[2],QAM_amp128b); +- ul_ch_mag128b[2] = _mm_slli_epi16(ul_ch_mag128b[2],1); +- } + } + + // multiply by conjugated channel +@@ -755,117 +795,157 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, + // print_shorts("ch:",ul_ch128+1); + // print_shorts("pack:",rxdataF_comp128+1); + +- if (is_dmrs_symbol==0) { +- // multiply by conjugated channel +- mmtmpD0 = _mm_madd_epi16(ul_ch128[2],rxdataF128[2]); +- // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) +- mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[2],_MM_SHUFFLE(2,3,0,1)); +- mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); +- mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); +- mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); +- // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) +- mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); +- mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); +- mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); +- mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); +- +- rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); +- // print_shorts("rx:",rxdataF128+2); +- // print_shorts("ch:",ul_ch128+2); +- // print_shorts("pack:",rxdataF_comp128+2); +- +- ul_ch128+=3; +- ul_ch_mag128+=3; +- ul_ch_mag128b+=3; +- rxdataF128+=3; +- rxdataF_comp128+=3; +- } else { // we have a smaller PUSCH in symbols with pilots so skip last group of 4 REs and increment less +- ul_ch128+=2; +- ul_ch_mag128+=2; +- ul_ch_mag128b+=2; +- rxdataF128+=2; +- rxdataF_comp128+=2; +- } +- +- } +- } +- } +- +- if (rho) { +- +- for (aarx=0; aarxnb_antennas_rx; aarx++) { +- rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_UL*12]; +- ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_UL*12]; +- ul_ch128_2 = (__m128i *)&ul_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_UL*12]; +- +- for (rb=0; rbnb_antennas_rx][nrOfLayers*nrOfLayers]; ++ int avg_rho_im[frame_parms->nb_antennas_rx][nrOfLayers*nrOfLayers]; ++ ++ for (aarx=0; aarxnb_antennas_rx; aarx++) ++ { ++ for (aatx=0; aatx < nrOfLayers; aatx++) ++ { ++ ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; ++ ++ for (int atx=0; atx< nrOfLayers; atx++) ++ { ++ avg_rho_re[aarx][aatx*nrOfLayers+atx] = 0; ++ avg_rho_im[aarx][aatx*nrOfLayers+atx] = 0; ++ rho128 = (__m128i *)&rho[aarx][aatx*nrOfLayers+atx][symbol*(off+(nb_rb*12))]; ++ ul_ch128_2 = (__m128i *)&ul_ch_estimates_ext[atx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; ++ ++ 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*nrOfLayers+atx] = 16*avg_rho_re[aarx][aatx*nrOfLayers+atx]/(nb_rb*12); ++ avg_rho_im[aarx][aatx*nrOfLayers+atx] = 16*avg_rho_im[aarx][aatx*nrOfLayers+atx]/(nb_rb*12); ++ //printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, aatx,atx, avg_rho_re[aarx][aatx*nb_aatx+atx], avg_rho_im[aarx][aatx*nb_aatx+atx]); ++ } ++ } ++ } + } + } + +@@ -1105,19 +1185,23 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, + } + + void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, +- int32_t **rxdataF_comp, +- int32_t **ul_ch_mag, +- int32_t **ul_ch_magb, +- uint8_t symbol, +- uint16_t nb_rb) { ++ int32_t **rxdataF_comp, ++ int32_t **ul_ch_mag, ++ int32_t **ul_ch_magb, ++ int32_t ***rho, ++ uint8_t nrOfLayers, ++ uint8_t symbol, ++ uint16_t nb_rb, ++ int length) { + int n_rx = frame_parms->nb_antennas_rx; + #if defined(__x86_64__) || defined(__i386__) +- __m128i *rxdataF_comp128[1+n_rx],*ul_ch_mag128[1+n_rx],*ul_ch_mag128b[1+n_rx]; ++ __m128i *rxdataF_comp128[2],*ul_ch_mag128[2],*ul_ch_mag128b[2]; + #elif defined(__arm__) + int16x8_t *rxdataF_comp128_0,*ul_ch_mag128_0,*ul_ch_mag128_0b; + int16x8_t *rxdataF_comp128_1,*ul_ch_mag128_1,*ul_ch_mag128_1b; + #endif + int32_t i; ++ uint32_t nb_rb_0 = length/12 + ((length%12)?1:0); + + #ifdef __AVX2__ + int off = ((nb_rb&1) == 1)? 4:0; +@@ -1125,23 +1209,34 @@ void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, + int off = 0; + #endif + +- if (frame_parms->nb_antennas_rx>1) { +-#if defined(__x86_64__) || defined(__i386__) +- int nb_re = nb_rb*12; +- for (int aa=0;aanb_antennas_rx;aa++) { +- rxdataF_comp128[aa] = (__m128i *)&rxdataF_comp[aa][(symbol*(nb_re + off))]; +- ul_ch_mag128[aa] = (__m128i *)&ul_ch_mag[aa][(symbol*(nb_re + off))]; +- ul_ch_mag128b[aa] = (__m128i *)&ul_ch_magb[aa][(symbol*(nb_re + off))]; +- } +- for (int aa=1;aanb_antennas_rx;aa++) { +- // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) +- for (i=0; i 1) ++ { ++ #if defined(__x86_64__) || defined(__i386__) ++ for (int aatx=0; aatxnb_antennas_rx][(symbol*(nb_re + off))]; ++ ul_ch_mag128[0] = (__m128i *)&ul_ch_mag[aatx*frame_parms->nb_antennas_rx][(symbol*(nb_re + off))]; ++ ul_ch_mag128b[0] = (__m128i *)&ul_ch_magb[aatx*frame_parms->nb_antennas_rx][(symbol*(nb_re + off))]; ++ ++ for (int aa=1;aa < n_rx;aa++) ++ { ++ rxdataF_comp128[1] = (__m128i *)&rxdataF_comp[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))]; ++ ul_ch_mag128[1] = (__m128i *)&ul_ch_mag[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))]; ++ ul_ch_mag128b[1] = (__m128i *)&ul_ch_magb[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))]; ++ ++ // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) ++ for (i=0; iN_RB_DL*12]; + rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12]; + ul_ch_mag128_0 = (int16x8_t *)&ul_ch_mag[0][symbol*frame_parms->N_RB_DL*12]; +@@ -1156,7 +1251,7 @@ void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, + ul_ch_mag128_0b[i] = vhaddq_s16(ul_ch_mag128_0b[i],ul_ch_mag128_1b[i]); + rxdataF_comp128_0[i] = vqaddq_s16(rxdataF_comp128_0[i],(*(int16x8_t *)&jitterc[0])); + } +-#endif ++ #endif + } + + #if defined(__x86_64__) || defined(__i386__) +@@ -1165,6 +1260,696 @@ void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, + #endif + } + ++/* Zero Forcing Rx function: nr_det_HhH() ++ * ++ * ++ * */ ++void nr_ulsch_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, ++ int32_t shift) ++{ ++ 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); ++ ++ //det in Q30 format ++ det_fin_128[0] = _mm_abs_epi32(det_re_128); ++ ++ ++#ifdef DEBUG_DLSCH_DEMOD ++ 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]); ++#endif ++ 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_ulsch_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_ulsch_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(); ++} ++__m128i nr_ulsch_comp_muli_sum(__m128i input_x, ++ __m128i input_y, ++ __m128i input_w, ++ __m128i input_z, ++ __m128i det) ++{ ++ int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ; ++ ++ __m128i xy_re_128, xy_im_128, wz_re_128, wz_im_128; ++ __m128i output, 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) ++ ++ // complex multiplication (w_re + jw_im)*(z_re + jz_im) = (w_re*z_re - w_im*z_im) + j(w_im*z_re + w_re*z_im) ++ // the real part ++ wz_re_128 = _mm_sign_epi16(input_w,*(__m128i*)&nr_conjug2[0]); ++ wz_re_128 = _mm_madd_epi16(wz_re_128,input_z); //Re: (w_re*z_re - w_im*z_im) ++ ++ // the imag part ++ wz_im_128 = _mm_shufflelo_epi16(input_w,_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 ++ wz_im_128 = _mm_shufflehi_epi16(wz_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 ++ wz_im_128 = _mm_madd_epi16(wz_im_128,input_z);//Im: (w_im*z_re + w_re*z_im) ++ ++ ++ xy_re_128 = _mm_sub_epi32(xy_re_128, wz_re_128); ++ xy_im_128 = _mm_sub_epi32(xy_im_128, wz_im_128); ++ //print_ints("rx_re:",(int32_t*)&xy_re_128[0]); ++ //print_ints("rx_Img:",(int32_t*)&xy_im_128[0]); ++ //divide by matrix det and convert back to Q15 before packing ++ int sum_det =0; ++ for (int k=0; k<4;k++) { ++ sum_det += ((((int *)&det[0])[k])>>2); ++ //printf("det_%d = %d log2 =%d \n",k,(((int *)&det[0])[k]),log2_approx(((int *)&det[0])[k])); ++ } ++ ++ xy_re_128 = _mm_slli_epi32(xy_re_128,5); ++ xy_re_128 = _mm_srai_epi32(xy_re_128,log2_approx(sum_det)); ++ xy_re_128 = _mm_slli_epi32(xy_re_128,5); ++ ++ xy_im_128 = _mm_slli_epi32(xy_im_128,5); ++ xy_im_128 = _mm_srai_epi32(xy_im_128,log2_approx(sum_det)); ++ xy_im_128 = _mm_slli_epi32(xy_im_128,5); ++ ++ 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 = _mm_packs_epi32(tmp_z0,tmp_z1); ++ ++ _mm_empty(); ++ _m_empty(); ++ return(output); ++} ++/* Zero Forcing Rx function: nr_construct_HhH_elements() ++ * ++ * ++ * */ ++void nr_ulsch_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]); ++ ++#ifdef DEBUG_DLSCH_DEMOD ++ if ((rb<=30)) ++ { ++ 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]); ++ } ++#endif ++ 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_ulsch_zero_forcing_rx_2layers() ++ * ++ * ++ * */ ++uint8_t nr_ulsch_zero_forcing_rx_2layers(int **rxdataF_comp, ++ int **ul_ch_mag, ++ int **ul_ch_magb, ++ int **ul_ch_estimates_ext, ++ unsigned short nb_rb, ++ unsigned char n_rx, ++ unsigned char mod_order, ++ int shift, ++ unsigned char symbol, ++ int length) ++{ ++ int *ch00, *ch01, *ch10, *ch11; ++ int *ch20, *ch30, *ch21, *ch31; ++ uint32_t nb_rb_0 = length/12 + ((length%12)?1:0); ++ ++ #ifdef __AVX2__ ++ int off = ((nb_rb&1) == 1)? 4:0; ++ #else ++ int off = 0; ++ #endif ++ ++ /* 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 *)&ul_ch_estimates_ext[0][symbol*(off+nb_rb*12)]; ++ ch01 = (int *)&ul_ch_estimates_ext[2][symbol*(off+nb_rb*12)]; ++ ch10 = (int *)&ul_ch_estimates_ext[1][symbol*(off+nb_rb*12)]; ++ ch11 = (int *)&ul_ch_estimates_ext[3][symbol*(off+nb_rb*12)]; ++ ch20 = NULL; ++ ch21 = NULL; ++ ch30 = NULL; ++ ch31 = NULL; ++ break; ++ ++ case 4:// ++ ch00 = (int *)&ul_ch_estimates_ext[0][symbol*(off+nb_rb*12)]; ++ ch01 = (int *)&ul_ch_estimates_ext[4][symbol*(off+nb_rb*12)]; ++ ch10 = (int *)&ul_ch_estimates_ext[1][symbol*(off+nb_rb*12)]; ++ ch11 = (int *)&ul_ch_estimates_ext[5][symbol*(off+nb_rb*12)]; ++ ch20 = (int *)&ul_ch_estimates_ext[2][symbol*(off+nb_rb*12)]; ++ ch21 = (int *)&ul_ch_estimates_ext[6][symbol*(off+nb_rb*12)]; ++ ch30 = (int *)&ul_ch_estimates_ext[3][symbol*(off+nb_rb*12)]; ++ ch31 = (int *)&ul_ch_estimates_ext[7][symbol*(off+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_ulsch_conjch0_mult_ch1(ch00, ++ ch00, ++ conjch00_ch00, ++ nb_rb_0, ++ shift); ++ // (1/2^log2_maxh)*conj_H_10xH_10: (1/(64*2))conjH_10*H_10*2^15 ++ nr_ulsch_conjch0_mult_ch1(ch10, ++ ch10, ++ conjch10_ch10, ++ nb_rb_0, ++ shift); ++ // conj_H_00xH_01 ++ nr_ulsch_conjch0_mult_ch1(ch00, ++ ch01, ++ conjch00_ch01, ++ nb_rb_0, ++ shift); // this shift is equal to the channel level log2_maxh ++ // conj_H_10xH_11 ++ nr_ulsch_conjch0_mult_ch1(ch10, ++ ch11, ++ conjch10_ch11, ++ nb_rb_0, ++ shift); ++ // conj_H_01xH_01 ++ nr_ulsch_conjch0_mult_ch1(ch01, ++ ch01, ++ conjch01_ch01, ++ nb_rb_0, ++ shift); ++ // conj_H_11xH_11 ++ nr_ulsch_conjch0_mult_ch1(ch11, ++ ch11, ++ conjch11_ch11, ++ nb_rb_0, ++ shift); ++ // conj_H_01xH_00 ++ nr_ulsch_conjch0_mult_ch1(ch01, ++ ch00, ++ conjch01_ch00, ++ nb_rb_0, ++ shift); ++ // conj_H_11xH_10 ++ nr_ulsch_conjch0_mult_ch1(ch11, ++ ch10, ++ conjch11_ch10, ++ nb_rb_0, ++ shift); ++ } ++ if (n_rx==4){ ++ // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2*16))conjH_20*H_20*2^15 ++ nr_ulsch_conjch0_mult_ch1(ch20, ++ ch20, ++ conjch20_ch20, ++ nb_rb_0, ++ shift); ++ ++ // (1/2^log2_maxh)*conj_H_30xH_30: (1/(64*2*4))conjH_30*H_30*2^15 ++ nr_ulsch_conjch0_mult_ch1(ch30, ++ ch30, ++ conjch30_ch30, ++ nb_rb_0, ++ shift); ++ ++ // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15 ++ nr_ulsch_conjch0_mult_ch1(ch20, ++ ch21, ++ conjch20_ch21, ++ nb_rb_0, ++ shift); ++ ++ nr_ulsch_conjch0_mult_ch1(ch30, ++ ch31, ++ conjch30_ch31, ++ nb_rb_0, ++ shift); ++ ++ nr_ulsch_conjch0_mult_ch1(ch21, ++ ch21, ++ conjch21_ch21, ++ nb_rb_0, ++ shift); ++ ++ nr_ulsch_conjch0_mult_ch1(ch31, ++ ch31, ++ conjch31_ch31, ++ nb_rb_0, ++ shift); ++ ++ // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15 ++ nr_ulsch_conjch0_mult_ch1(ch21, ++ ch20, ++ conjch21_ch20, ++ nb_rb_0, ++ shift); ++ ++ nr_ulsch_conjch0_mult_ch1(ch31, ++ ch30, ++ conjch31_ch30, ++ nb_rb_0, ++ shift); ++ ++ nr_ulsch_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_0, ++ symbol); ++ } ++ if (n_rx==2){ ++ nr_ulsch_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_0, ++ symbol); ++ } ++ //det_HhH = ad -bc ++ nr_ulsch_det_HhH(af_mf_00,//a ++ af_mf_01,//b ++ af_mf_10,//c ++ af_mf_11,//d ++ determ_fin, ++ nb_rb_0, ++ symbol, ++ shift); ++ /* 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,*ul_ch_mag128_0=NULL,*ul_ch_mag128b_0=NULL,*determ_fin_128;//*dl_ch_mag128_1,*dl_ch_mag128b_1,*dl_ch_mag128r_1 ++ __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; ++ __m128i *after_mf_a_128,*after_mf_b_128, *after_mf_c_128, *after_mf_d_128; ++ __m128i QAM_amp128={0},QAM_amp128b={0}; ++ ++ determ_fin_128 = (__m128i *)&determ_fin[0]; ++ ++ rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][symbol*(off+nb_rb*12)];//aatx=0 @ aarx =0 ++ rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[n_rx][symbol*(off+nb_rb*12)];//aatx=1 @ aarx =0 ++ ++ 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; ++ ++ if (mod_order>2) { ++ 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); //4/sqrt{42} ++ QAM_amp128b = _mm_set1_epi16(QAM64_n2); //2/sqrt{42} ++ } ++ ul_ch_mag128_0 = (__m128i *)&ul_ch_mag[0][symbol*(off+nb_rb*12)]; ++ ul_ch_mag128b_0 = (__m128i *)&ul_ch_magb[0][symbol*(off+nb_rb*12)]; ++ } ++ ++ for (int rb=0; rb<3*nb_rb_0; rb++) { ++ if (mod_order>2) { ++ int sum_det =0; ++ for (int k=0; k<4;k++) { ++ sum_det += ((((int *)&determ_fin_128[0])[k])>>2); ++ //printf("det_%d = %d\n",k,sum_det); ++ } ++ ++ mmtmpD2 = _mm_slli_epi32(determ_fin_128[0],5); ++ mmtmpD2 = _mm_srai_epi32(mmtmpD2,log2_approx(sum_det)); ++ mmtmpD2 = _mm_slli_epi32(mmtmpD2,5); ++ ++ mmtmpD3 = _mm_unpacklo_epi32(mmtmpD2,mmtmpD2); ++ ++ mmtmpD2 = _mm_unpackhi_epi32(mmtmpD2,mmtmpD2); ++ ++ mmtmpD2 = _mm_packs_epi32(mmtmpD3,mmtmpD2); ++ ++ ul_ch_mag128_0[0] = mmtmpD2; ++ ul_ch_mag128b_0[0] = mmtmpD2; ++ ++ ul_ch_mag128_0[0] = _mm_mulhi_epi16(ul_ch_mag128_0[0],QAM_amp128); ++ ul_ch_mag128_0[0] = _mm_slli_epi16(ul_ch_mag128_0[0],1); ++ ++ ul_ch_mag128b_0[0] = _mm_mulhi_epi16(ul_ch_mag128b_0[0],QAM_amp128b); ++ ul_ch_mag128b_0[0] = _mm_slli_epi16(ul_ch_mag128b_0[0],1); ++ ++ //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]); ++ //print_shorts("magr layer 1:",(int16_t*)&dl_ch_mag128r_0[0]); ++ //print_shorts("magr layer 2:",(int16_t*)&dl_ch_mag128r_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 ++ //printf("layer_1 \n"); ++ mmtmpD0 = nr_ulsch_comp_muli_sum(rxdataF_comp128_0[0], ++ after_mf_d_128[0], ++ rxdataF_comp128_1[0], ++ after_mf_b_128[0], ++ determ_fin_128[0]); ++ ++ //printf("layer_2 \n"); ++ mmtmpD1 = nr_ulsch_comp_muli_sum(rxdataF_comp128_1[0], ++ after_mf_a_128[0], ++ rxdataF_comp128_0[0], ++ after_mf_c_128[0], ++ determ_fin_128[0]); ++ ++ rxdataF_comp128_0[0] = mmtmpD0; ++ rxdataF_comp128_1[0] = mmtmpD1; ++#ifdef DEBUG_DLSCH_DEMOD ++ printf("\n Rx signal after ZF l%d rb%d\n",symbol,rb); ++ print_shorts(" Rx layer 1:",(int16_t*)&rxdataF_comp128_0[0]); ++ print_shorts(" Rx layer 2:",(int16_t*)&rxdataF_comp128_1[0]); ++#endif ++ determ_fin_128 += 1; ++ ul_ch_mag128_0 += 1; ++ ul_ch_mag128b_0 += 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); ++} ++ ++//============================================================================================== ++ ++/* Main Function */ + int nr_rx_pusch(PHY_VARS_gNB *gNB, + uint8_t ulsch_id, + uint32_t frame, +@@ -1184,21 +1969,29 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, + gNB->pusch_vars[ulsch_id]->cl_done = 0; + + bwp_start_subcarrier = ((rel15_ul->rb_start + rel15_ul->bwp_start)*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size; +- LOG_D(PHY,"pusch %d.%d : bwp_start_subcarrier %d, rb_start %d, first_carrier_offset %d\n", frame,slot,bwp_start_subcarrier, rel15_ul->rb_start, frame_parms->first_carrier_offset); +- LOG_D(PHY,"pusch %d.%d : ul_dmrs_symb_pos %x\n",frame,slot,rel15_ul->ul_dmrs_symb_pos); +- ++ LOG_I(PHY,"pusch %d.%d : bwp_start_subcarrier %d, rb_start %d, first_carrier_offset %d\n", frame,slot,bwp_start_subcarrier, rel15_ul->rb_start, frame_parms->first_carrier_offset); ++ LOG_I(PHY,"pusch %d.%d : ul_dmrs_symb_pos %x\n",frame,slot,rel15_ul->ul_dmrs_symb_pos); ++ LOG_I(PHY,"ulsch RX %x : start_rb %d nb_rb %d mcs %d Nl %d Tpmi %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_ports %d\n", ++ rel15_ul->rnti,rel15_ul->rb_start,rel15_ul->rb_size,rel15_ul->mcs_index, ++ rel15_ul->nrOfLayers,0,rel15_ul->bwp_start,0,rel15_ul->start_symbol_index,rel15_ul->nr_of_symbols, ++ rel15_ul->num_dmrs_cdm_grps_no_data,rel15_ul->ul_dmrs_symb_pos,rel15_ul->dmrs_ports); + //---------------------------------------------------------- + //--------------------- Channel estimation --------------------- + //---------------------------------------------------------- + start_meas(&gNB->ulsch_channel_estimation_stats); +- for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) { ++ for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) ++ { + uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01; + LOG_D(PHY, "symbol %d, dmrs_symbol_flag :%d\n", symbol, dmrs_symbol_flag); +- if (dmrs_symbol_flag == 1) { ++ ++ if (dmrs_symbol_flag == 1) ++ { + if (gNB->pusch_vars[ulsch_id]->dmrs_symbol == INVALID_VALUE) + gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol; + + for (int nl=0; nlnrOfLayers; nl++) ++ { ++ + nr_pusch_channel_estimation(gNB, + slot, + get_dmrs_port(nl,rel15_ul->dmrs_ports), +@@ -1206,6 +1999,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, + ulsch_id, + bwp_start_subcarrier, + rel15_ul); ++ } + + nr_gnb_measurements(gNB, ulsch_id, harq_pid, symbol,rel15_ul->nrOfLayers); + +@@ -1214,9 +2008,12 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, + gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] = 0; + gNB->pusch_vars[ulsch_id]->ulsch_noise_power[aarx] = 0; + } +- gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] += signal_energy_nodc( +- &gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aarx][symbol * frame_parms->ofdm_symbol_size], ++ for (aatx = 0; aatx < rel15_ul->nrOfLayers; aatx++) ++ { ++ gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] += signal_energy_nodc( ++ &gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aatx*gNB->frame_parms.nb_antennas_rx+aarx][symbol * frame_parms->ofdm_symbol_size], + rel15_ul->rb_size * 12); ++ } + for (int rb = 0; rb < rel15_ul->rb_size; rb++) { + gNB->pusch_vars[ulsch_id]->ulsch_noise_power[aarx] += + gNB->measurements.n0_subband_power[aarx][rel15_ul->bwp_start + rel15_ul->rb_start + rb] / +@@ -1234,23 +2031,29 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, + #endif + uint32_t rxdataF_ext_offset = 0; + +- for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) { ++ for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) ++ { + uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01; +- if (dmrs_symbol_flag == 1) { ++ if (dmrs_symbol_flag == 1) ++ { + if ((rel15_ul->ul_dmrs_symb_pos >> ((symbol + 1) % frame_parms->symbols_per_slot)) & 0x01) + AssertFatal(1==0,"Double DMRS configuration is not yet supported\n"); + + gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol; + +- if (rel15_ul->dmrs_config_type == 0) { ++ if (rel15_ul->dmrs_config_type == 0) ++ { + // if no data in dmrs cdm group is 1 only even REs have no data + // if no data in dmrs cdm group is 2 both odd and even REs have no data + nb_re_pusch = rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*6)); + } +- else { ++ else ++ { + nb_re_pusch = rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*4)); + } +- } else { ++ } ++ else ++ { + nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB; + } + +@@ -1260,16 +2063,16 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, + //---------------------------------------------------------- + //--------------------- RBs extraction --------------------- + //---------------------------------------------------------- +- if (nb_re_pusch > 0) { +- ++ if (nb_re_pusch > 0) ++ { + start_meas(&gNB->ulsch_rbs_extraction_stats); +- nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF, +- gNB->pusch_vars[ulsch_id], +- slot, +- symbol, +- dmrs_symbol_flag, +- rel15_ul, +- frame_parms); ++ nr_ulsch_extract_rbs(gNB->common_vars.rxdataF, ++ gNB->pusch_vars[ulsch_id], ++ slot, ++ symbol, ++ dmrs_symbol_flag, ++ rel15_ul, ++ frame_parms); + stop_meas(&gNB->ulsch_rbs_extraction_stats); + + //---------------------------------------------------------- +@@ -1280,8 +2083,9 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, + gNB->ulsch[ulsch_id], + symbol, + dmrs_symbol_flag, +- rel15_ul->rb_size, +- rel15_ul->dmrs_config_type); ++ nb_re_pusch, ++ rel15_ul->nrOfLayers, ++ rel15_ul->rb_size); + + if (gNB->pusch_vars[ulsch_id]->cl_done==0) { + nr_ulsch_channel_level(gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext, +@@ -1312,9 +2116,14 @@ 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, ++ #ifdef SUPPORT_PMI_MATRIC + (rel15_ul->nrOfLayers>1) ? gNB->pusch_vars[ulsch_id]->rho : NULL, ++ #else ++ NULL, ++ #endif + frame_parms, + symbol, ++ nb_re_pusch, + dmrs_symbol_flag, + rel15_ul->qam_mod_order, + rel15_ul->nrOfLayers, +@@ -1327,19 +2136,37 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, + gNB->pusch_vars[ulsch_id]->rxdataF_comp, + gNB->pusch_vars[ulsch_id]->ul_ch_mag0, + gNB->pusch_vars[ulsch_id]->ul_ch_magb0, ++ #ifdef SUPPORT_PMI_MATRIC ++ (rel15_ul->nrOfLayers>1) ? gNB->pusch_vars[ulsch_id]->rho : NULL, ++ #else ++ NULL, ++ #endif ++ rel15_ul->nrOfLayers, + symbol, +- rel15_ul->rb_size); ++ rel15_ul->rb_size, ++ nb_re_pusch); ++ ++ if (rel15_ul->nrOfLayers == 2)//Apply zero forcing for 2 Tx layers ++ nr_ulsch_zero_forcing_rx_2layers(gNB->pusch_vars[ulsch_id]->rxdataF_comp, ++ gNB->pusch_vars[ulsch_id]->ul_ch_mag0, ++ gNB->pusch_vars[ulsch_id]->ul_ch_magb0, ++ gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext, ++ rel15_ul->rb_size, ++ frame_parms->nb_antennas_rx, ++ rel15_ul->qam_mod_order, ++ gNB->pusch_vars[ulsch_id]->log2_maxh, ++ symbol, ++ nb_re_pusch); + stop_meas(&gNB->ulsch_mrc_stats); + +- // transform precoding = 0 means enabled +- if (rel15_ul->transform_precoding == 0) { +- +- #ifdef __AVX2__ ++ if (rel15_ul->transformPrecoder == transformPrecoder_enabled) ++ { ++ #ifdef __AVX2__ + // For odd number of resource blocks need byte alignment to multiple of 8 + int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7); +- #else ++ #else + int nb_re_pusch2 = nb_re_pusch; +- #endif ++ #endif + + // perform IDFT operation on the compensated rxdata if transform precoding is enabled + nr_idft(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][symbol * nb_re_pusch2], nb_re_pusch); +@@ -1351,7 +2178,8 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, + //---------------------------------------------------------- + /* In case PTRS is enabled then LLR will be calculated after PTRS symbols are processed * + * otherwise LLR are calculated for each symbol based upon DMRS channel estimates only. */ +- if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { ++ if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) ++ { + start_meas(&gNB->ulsch_ptrs_processing_stats); + nr_pusch_ptrs_processing(gNB, + frame_parms, +@@ -1370,14 +2198,17 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, + /*-------------------- LLRs computation -------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------------------------------*/ + start_meas(&gNB->ulsch_llr_stats); +- nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][symbol * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)], +- gNB->pusch_vars[ulsch_id]->ul_ch_mag0, +- gNB->pusch_vars[ulsch_id]->ul_ch_magb0, +- &gNB->pusch_vars[ulsch_id]->llr[rxdataF_ext_offset * rel15_ul->qam_mod_order], +- rel15_ul->rb_size, +- gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol], +- symbol, +- rel15_ul->qam_mod_order); ++ for (aatx=0; aatx < rel15_ul->nrOfLayers; aatx++) ++ { ++ nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aatx*frame_parms->nb_antennas_rx][symbol * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)], ++ gNB->pusch_vars[ulsch_id]->ul_ch_mag0[aatx*frame_parms->nb_antennas_rx], ++ gNB->pusch_vars[ulsch_id]->ul_ch_magb0[aatx*frame_parms->nb_antennas_rx], ++ &gNB->pusch_vars[ulsch_id]->llr_layers[aatx][rxdataF_ext_offset * rel15_ul->qam_mod_order], ++ rel15_ul->rb_size, ++ gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol], ++ symbol, ++ rel15_ul->qam_mod_order); ++ } + stop_meas(&gNB->ulsch_llr_stats); + rxdataF_ext_offset += gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol]; + } +diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c +index bf96a76106..ad41ebf3d6 100644 +--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c ++++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c +@@ -64,7 +64,7 @@ void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp, + //---------------------------------------------------------------------------------------------- + + void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, +- int32_t **ul_ch_mag, ++ int32_t *ul_ch_mag, + int16_t *ulsch_llr, + uint32_t nb_rb, + uint32_t nb_re, +@@ -110,12 +110,12 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, + + #if defined(__x86_64__) || defined(__i386__) + #ifdef __AVX2__ +- ch_mag = (__m256i*)&ul_ch_mag[0][(symbol*(off+(nb_rb*12)))]; ++ ch_mag = (__m256i*)&ul_ch_mag[(symbol*(off+(nb_rb*12)))]; + #else +- ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*(off+(nb_rb*12)))]; ++ ch_mag = (__m128i*)&ul_ch_mag[(symbol*(off+(nb_rb*12)))]; + #endif + #elif defined(__arm__) +- ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)]; ++ ch_mag = (int16x8_t*)&ul_ch_mag[(symbol*nb_rb*12)]; + #endif + + #ifdef __AVX2__ +@@ -231,8 +231,8 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, + //---------------------------------------------------------------------------------------------- + + void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, +- int32_t **ul_ch_mag, +- int32_t **ul_ch_magb, ++ int32_t *ul_ch_mag, ++ int32_t *ul_ch_magb, + int16_t *ulsch_llr, + uint32_t nb_rb, + uint32_t nb_re, +@@ -265,15 +265,15 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, + + #if defined(__x86_64__) || defined(__i386__) + #ifdef __AVX2__ +- ch_mag = (__m256i*)&ul_ch_mag[0][(symbol*(off+(nb_rb*12)))]; +- ch_magb = (__m256i*)&ul_ch_magb[0][(symbol*(off+(nb_rb*12)))]; ++ ch_mag = (__m256i*)&ul_ch_mag[(symbol*(off+(nb_rb*12)))]; ++ ch_magb = (__m256i*)&ul_ch_magb[(symbol*(off+(nb_rb*12)))]; + #else +- ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*nb_rb*12)]; +- ch_magb = (__m128i*)&ul_ch_magb[0][(symbol*nb_rb*12)]; ++ ch_mag = (__m128i*)&ul_ch_mag[(symbol*nb_rb*12)]; ++ ch_magb = (__m128i*)&ul_ch_magb[(symbol*nb_rb*12)]; + #endif + #elif defined(__arm__) +- ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)]; +- ch_magb = (int16x8_t*)&ul_ch_magb[0][(symbol*nb_rb*12)]; ++ ch_mag = (int16x8_t*)&ul_ch_mag[(symbol*nb_rb*12)]; ++ ch_magb = (int16x8_t*)&ul_ch_magb[(symbol*nb_rb*12)]; + #endif + + #ifdef __AVX2__ +@@ -471,8 +471,8 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, + + + void nr_ulsch_compute_llr(int32_t *rxdataF_comp, +- int32_t **ul_ch_mag, +- int32_t **ul_ch_magb, ++ int32_t *ul_ch_mag, ++ int32_t *ul_ch_magb, + int16_t *ulsch_llr, + uint32_t nb_rb, + uint32_t nb_re, +diff --git a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c +index 65ae288252..2cb7609d62 100644 +--- a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c ++++ b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c +@@ -148,7 +148,7 @@ short filt8_dcr0_h[8]= { + 0,4096,8192,12288,16384,0,0,0}; + + short filt8_l1[8] = { +-24576,16384,0,0,0,0,0,0}; ++24576,16384,8192,0,0,0,0,0}; + + short filt8_ml1[8] = { + -8192,0,8192,16384,8192,0,0,0}; +@@ -163,10 +163,10 @@ short filt8_mm1[8]= { + 0,0,0,0,8192,16384,8192,0}; + + short filt8_dcl1[8]= { +-0,0,0,16384,12288,8192,4096,0}; ++0,0,16384,12288,8192,4096,0,0}; + + short filt8_dcr1[8]= { +-0,0,0,0,4096,8192,12288,16384}; ++0,0,0,4096,8192,12288,16384,0}; + + short filt8_dcl1_h[8]= { + 0,16384,12288,8192,4096,0,0,0}; +diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +index 945dc51673..a293eec6d8 100644 +--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c ++++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +@@ -258,6 +258,15 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, + Ilbrm = 0; + Tbslbrm = 950984; //max tbs + Coderate = 0.0; ++ ++ #if 0 ++ harq_process->a[0] = 0x31; ++ for (int i = 1; i < harq_process->pusch_pdu.pusch_data.tb_size; i++) ++ { ++ harq_process->a[i] = (i&0xff); ++ } ++ #endif ++ + trace_NRpdu(DIRECTION_UPLINK, harq_process->a, harq_process->pusch_pdu.pusch_data.tb_size, 0, WS_C_RNTI, 0, 0, 0,0, 0); + /////////// + ///////////////////////////////////////////////////////////////////////////////////////// +diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +index 99dc2b658e..5d76e654ba 100644 +--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c ++++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +@@ -98,13 +98,12 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, + uint8_t thread_id, + int gNB_id) { + +- LOG_D(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot); ++ LOG_I(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot); + + uint32_t available_bits; + uint8_t cwd_index, l; + uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5]; +- int16_t **tx_layers; +- int32_t **txdataF; ++ + int8_t Wf[2], Wt[2], l_prime[2], delta; + uint8_t nb_dmrs_re_per_rb; + int ap, i; +@@ -112,6 +111,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, + + NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms; + NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id]; ++ int16_t **tx_layers = (int16_t **)pusch_ue->txdataF_layers; ++ int16_t **tx_precoding = (int16_t **)pusch_ue->txdataF_precoding; ++ int32_t **txdataF = UE->common_vars.txdataF; + + uint8_t num_of_codewords = 1; // tmp assumption + int Nid_cell = 0; +@@ -148,9 +150,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, + + nb_dmrs_re_per_rb = ((dmrs_type == pusch_dmrs_type1) ? 6:4)*cdm_grps_no_data; + +- LOG_D(PHY,"ulsch %x : start_rb %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_re_per_rb %d\n", +- rnti,start_rb,pusch_pdu->bwp_start,start_sc,start_symbol,number_of_symbols,cdm_grps_no_data,number_dmrs_symbols,nb_dmrs_re_per_rb); +- ++ LOG_I(PHY,"ulsch TX %x : start_rb %d nb_rb %d mod_order %d Nl %d Tpmi %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_re_per_rb %d\n", ++ rnti,start_rb,nb_rb,mod_order,Nl,pusch_pdu->Tpmi,pusch_pdu->bwp_start,start_sc,start_symbol,number_of_symbols,cdm_grps_no_data,number_dmrs_symbols,nb_dmrs_re_per_rb); ++ + // TbD num_of_mod_symbols is set but never used + N_RE_prime = NR_NB_SC_PER_RB*number_of_symbols - nb_dmrs_re_per_rb*number_dmrs_symbols - N_PRB_oh; + harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb*num_of_codewords; +@@ -236,8 +238,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, + /////////////////////////ULSCH layer mapping///////////////////////// + /////////// + +- tx_layers = (int16_t **)pusch_ue->txdataF_layers; +- + nr_ue_layer_mapping(UE->ulsch[thread_id][gNB_id], + Nl, + available_bits/mod_order, +@@ -257,7 +257,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, + int16_t *dmrs_seq = NULL; + + // if transform precoding is enbaled (value 0) +- if (pusch_pdu->transform_precoding == 0) { ++ if (pusch_pdu->transformPrecoder == transformPrecoder_enabled) { + + uint32_t nb_re_pusch=nb_rb * NR_NB_SC_PER_RB; + uint32_t y_offset = 0; +@@ -315,10 +315,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, + LOG_M("UE_DMRS_SEQ.m","UE_DMRS_SEQ", dmrs_seq,nb_re_pusch,1,1); + #endif + +- } +- else +- memcpy(ulsch_ue->y, tx_layers[0], (available_bits/mod_order)*sizeof(int32_t)); +- ++ } + + /////////// + //////////////////////////////////////////////////////////////////////// +@@ -328,145 +325,233 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, + /////////////////////////ULSCH RE mapping///////////////////////// + /////////// + +- txdataF = UE->common_vars.txdataF; +- +- for (ap=0; ap< Nl; ap++) { +- +- uint8_t k_prime = 0; +- uint16_t m = 0; +- +- +- #ifdef DEBUG_PUSCH_MAPPING ++ for (ap=0; ap< Nl; ap++) ++ { ++ uint8_t k_prime = 0; ++ uint16_t m = 0; ++ ++ #ifdef DEBUG_PUSCH_MAPPING + printf("NR_ULSCH_UE: Value of CELL ID %d /t, u %d \n", frame_parms->Nid_cell, u); +- #endif +- +- +- +- // DMRS params for this ap +- get_Wt(Wt, ap, dmrs_type); +- get_Wf(Wf, ap, dmrs_type); +- delta = get_delta(ap, dmrs_type); +- +- for (l=start_symbol; l> l) & 0x01) { +- is_dmrs_sym = 1; +- +- // transform precoding disabled (value 1) +- if (pusch_pdu->transform_precoding == 1){ +- +- if (dmrs_type == pusch_dmrs_type1) +- dmrs_idx = (pusch_pdu->bwp_start + start_rb)*6; +- else +- dmrs_idx = (pusch_pdu->bwp_start + start_rb)*4; +- +- // TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part +- // Perform this on gold sequence, not required when SC FDMA operation is done, +- LOG_D(PHY,"DMRS in symbol %d\n",l); +- nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated +- +- } else { +- dmrs_idx = 0; +- } +- +- +- } else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { +- +- AssertFatal(pusch_pdu->transform_precoding == 1, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); ++ #endif + +- if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) { +- is_ptrs_sym = 1; +- nr_modulation(pusch_dmrs[l][0], nb_rb, DMRS_MOD_ORDER, mod_ptrs); ++ // DMRS params for this ap ++ get_Wt(Wt, ap, dmrs_type); ++ get_Wf(Wf, ap, dmrs_type); ++ delta = get_delta(ap, dmrs_type); ++ ++ for (l=start_symbol; l> l) & 0x01) ++ { ++ is_dmrs_sym = 1; ++ if (pusch_pdu->transformPrecoder == transformPrecoder_disabled) ++ { ++ if (dmrs_type == pusch_dmrs_type1) ++ dmrs_idx = (pusch_pdu->bwp_start + start_rb)*6; ++ else ++ dmrs_idx = (pusch_pdu->bwp_start + start_rb)*4; ++ ++ // TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part ++ // Perform this on gold sequence, not required when SC FDMA operation is done, ++ LOG_D(PHY,"DMRS in symbol %d\n",l); ++ nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated ++ } ++ else ++ { ++ dmrs_idx = 0; ++ } ++ } ++ else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) ++ { ++ AssertFatal(pusch_pdu->transformPrecoder == transformPrecoder_disabled, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); ++ ++ if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) ++ { ++ is_ptrs_sym = 1; ++ nr_modulation(pusch_dmrs[l][0], nb_rb, DMRS_MOD_ORDER, mod_ptrs); ++ } + } +- } + +- for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) { ++ for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) ++ { ++ uint8_t is_dmrs = 0; ++ uint8_t is_ptrs = 0; + +- uint8_t is_dmrs = 0; +- uint8_t is_ptrs = 0; ++ sample_offsetF = l*frame_parms->ofdm_symbol_size + k; + +- sample_offsetF = l*frame_parms->ofdm_symbol_size + k; +- +- if (is_dmrs_sym) { +- if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%frame_parms->ofdm_symbol_size)) +- is_dmrs = 1; +- } else if (is_ptrs_sym) { ++ if (is_dmrs_sym) ++ { ++ if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%frame_parms->ofdm_symbol_size)) ++ is_dmrs = 1; ++ } ++ else if (is_ptrs_sym) ++ { + is_ptrs = is_ptrs_subcarrier(k, +- rnti, +- ap, +- dmrs_type, +- K_ptrs, +- nb_rb, +- pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset, +- start_sc, +- frame_parms->ofdm_symbol_size); +- } +- +- if (is_dmrs == 1) { +- // if transform precoding is enabled +- if (pusch_pdu->transform_precoding == 0) { +- +- ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15; +- ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15; ++ rnti, ++ ap, ++ dmrs_type, ++ K_ptrs, ++ nb_rb, ++ pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset, ++ start_sc, ++ frame_parms->ofdm_symbol_size); ++ } ++ ++ if (is_dmrs == 1) ++ { ++ if (pusch_pdu->transformPrecoder == transformPrecoder_enabled) ++ { ++ ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15; ++ ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15; ++ } ++ else ++ { ++ ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15; ++ ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; ++ } ++ ++ #ifdef DEBUG_PUSCH_MAPPING ++ printf("DMRS: Layer: %d\t, dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n", ++ ap, dmrs_idx, l, k, k_prime, n, ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1], ++ ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1]); ++ #endif ++ ++ dmrs_idx++; ++ k_prime++; ++ k_prime&=1; ++ n+=(k_prime)?0:1; ++ } ++ else if (is_ptrs == 1) ++ { ++ ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15; ++ ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15; ++ ++ ptrs_idx++; ++ } ++ else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) ++ { ++ if (pusch_pdu->transformPrecoder == transformPrecoder_disabled) ++ { ++ ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = ((int16_t *)tx_layers[ap])[m<<1]; ++ ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *)tx_layers[ap])[(m<<1) + 1]; ++ } ++ else ++ { ++ ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1]; ++ ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1]; ++ } ++ ++ #ifdef DEBUG_PUSCH_MAPPING ++ printf("DATA: layer %d\t m %d\t l %d \t k %d \t txdataF: %d %d\n", ++ ap, m, l, k, ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1], ++ ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1]); ++ #endif ++ ++ m++; ++ } ++ else ++ { ++ ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = 0; ++ ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = 0; ++ } ++ ++ if (++k >= frame_parms->ofdm_symbol_size) ++ { ++ k -= frame_parms->ofdm_symbol_size; ++ } ++ } //for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) ++ }//for (l=start_symbol; lnb_antennas_tx; ap++) ++ { ++ for (int l=start_symbol; lTpmi; + +- } else { +- +- ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15; +- ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; +- ++ if (pmi == 0) {//unitary Precoding ++ if(ap< pusch_pdu->nrOfLayers) ++ memcpy((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + k], ++ (void*)&tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)], ++ NR_NB_SC_PER_RB*sizeof(int32_t)); ++ else ++ memset((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + 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 ++ { ++ //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 (pusch_pdu->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 (pusch_pdu->nrOfLayers == 1)//1 layer ++ W_prec = nr_W_1l_4p[pmi][ap]; ++ else if (pusch_pdu->nrOfLayers == 2)//2 layers ++ W_prec = nr_W_2l_4p[pmi][ap]; ++ else if (pusch_pdu->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; + } + +- #ifdef DEBUG_PUSCH_MAPPING +- printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n", +- dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1], +- ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1]); +- #endif +- +- +- dmrs_idx++; +- k_prime++; +- k_prime&=1; +- n+=(k_prime)?0:1; +- +- } else if (is_ptrs == 1) { +- +- ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15; +- ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15; +- +- ptrs_idx++; +- +- } else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) { +- +- ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1]; +- ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1]; +- +- #ifdef DEBUG_PUSCH_MAPPING +- printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", +- m, l, k, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1], +- ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1]); +- #endif +- +- m++; +- +- } else { +- +- ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = 0; +- ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = 0; +- +- } ++ for (int i=0; iofdm_symbol_size + k; ++ int32_t precodatatx_F = nr_layer_precoder(tx_precoding, W_prec, pusch_pdu->nrOfLayers, re_offset); ++ ((int16_t*)txdataF[ap])[(re_offset<<1)] = ((int16_t *) &precodatatx_F)[0]; ++ ((int16_t*)txdataF[ap])[(re_offset<<1) + 1] = ((int16_t *) &precodatatx_F)[1]; ++ ++ if (++k >= frame_parms->ofdm_symbol_size) ++ { ++ k -= frame_parms->ofdm_symbol_size; ++ } ++ } ++ } ++ } //RB loop ++ } // symbol loop ++ }// port loop + +- if (++k >= frame_parms->ofdm_symbol_size) +- k -= frame_parms->ofdm_symbol_size; +- } +- } +- } +- } ++ } //for (cwd_index = 0;cwd_index < num_of_codewords; cwd_index++) + + NR_UL_UE_HARQ_t *harq_process_ulsch=NULL; + harq_process_ulsch = UE->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid]; +diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h +index 11b5112a6c..600ba07cb3 100644 +--- a/openair1/PHY/defs_gNB.h ++++ b/openair1/PHY/defs_gNB.h +@@ -479,7 +479,7 @@ typedef struct { + /// \brief Cross-correlation of two UE signals. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: symbol [0..] +- int32_t **rho; ++ int32_t ***rho; + /// \f$\log_2(\max|H_i|^2)\f$ + int16_t log2_maxh; + /// \brief Magnitude of Uplink Channel first layer (16QAM level/First 64QAM level). +@@ -509,6 +509,10 @@ typedef struct { + /// \brief llr values. + /// - first index: ? [0..1179743] (hard coded) + int16_t *llr; ++ /// \brief llr values per layer. ++ /// - first index: ? [0..3] (hard coded) ++ /// - first index: ? [0..1179743] (hard coded) ++ int16_t **llr_layers; + /// DMRS symbol index, to be updated every DMRS symbol within a slot. + uint8_t dmrs_symbol; + // PTRS symbol index, to be updated every PTRS symbol within a slot. +diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h +index 69978f5548..02988b590a 100644 +--- a/openair1/PHY/defs_nr_UE.h ++++ b/openair1/PHY/defs_nr_UE.h +@@ -229,6 +229,9 @@ typedef struct { + typedef struct { + /// TX buffers for multiple layers + int32_t *txdataF_layers[NR_MAX_NB_LAYERS]; ++ ++ /// TX buffers for UE-spec transmission ++ int32_t *txdataF_precoding[NR_MAX_NB_LAYERS]; + } NR_UE_PUSCH; + + typedef struct { +diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h +index c385d323e3..fbe094f41c 100644 +--- a/openair1/PHY/defs_nr_common.h ++++ b/openair1/PHY/defs_nr_common.h +@@ -93,7 +93,7 @@ + #define NR_MAX_CSET_DURATION 3 + + #define NR_MAX_NB_RBG 18 +-#define NR_MAX_NB_LAYERS 2 // 8 // SU-MIMO (3GPP TS 38.211 V15.4.0 section 7.3.1.3) ++#define NR_MAX_NB_LAYERS 4 // 8 // SU-MIMO (3GPP TS 38.211 V15.4.0 section 7.3.1.3) + #define NR_MAX_NB_CODEWORDS 2 + #define NR_MAX_NB_HARQ_PROCESSES 16 + #define NR_MAX_PDSCH_ENCODED_LENGTH (NR_MAX_NB_RB*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8*NR_MAX_NB_LAYERS) // 8 is the maximum modulation order (it was 950984 before !!) +@@ -104,11 +104,11 @@ + #define MAX_NUM_NR_DLSCH_SEGMENTS (NR_MAX_NB_LAYERS*34) + #define MAX_NR_DLSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056) + +-#define MAX_NUM_NR_ULSCH_SEGMENTS 34 ++#define MAX_NUM_NR_ULSCH_SEGMENTS (NR_MAX_NB_LAYERS*34) + #define MAX_NR_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_ULSCH_SEGMENTS*1056) + +-#define MAX_NUM_NR_CHANNEL_BITS (14*273*12*8) // 14 symbols, 273 RB +-#define MAX_NUM_NR_RE (14*273*12) ++#define MAX_NUM_NR_CHANNEL_BITS (4*14*273*12*8) // 14 symbols, 273 RB ++#define MAX_NUM_NR_RE (4*14*273*12) + #define NR_RX_NB_TH 1 + #define NR_NB_TH_SLOT 2 + +diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c +index d8fa11d157..640a0740ef 100644 +--- a/openair1/SCHED_NR/nr_ru_procedures.c ++++ b/openair1/SCHED_NR/nr_ru_procedures.c +@@ -526,7 +526,8 @@ void nr_fep0(RU_t *ru, int first_half) { + end_symbol = NR_SYMBOLS_PER_SLOT; + } + +- LOG_D(PHY,"In fep0 for slot = %d, first_half = %d, start_symbol = %d, end_symbol = %d\n", proc->tti_rx, first_half, start_symbol, end_symbol); ++ LOG_D(PHY,"In fep0 for slot = %d, first_half = %d, start_symbol = %d, end_symbol = %d, nb_antennas_rx = %d,N_TA_offset = %d\n", ++ proc->tti_rx, first_half, start_symbol, end_symbol,fp->nb_antennas_rx,ru->N_TA_offset); + // printf("fep0: slot %d\n",slot); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+proc->tti_rx, 1); +diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c +index 1685e206ae..63c708e565 100644 +--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c ++++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c +@@ -253,13 +253,13 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { + // if all segments are done + if (rdata->nbSegments == ulsch_harq->processedSegments) { + if (decodeSuccess) { +- LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for SFN/SF %d.%d (pid %d, ndi %d, status %d, round %d, TBS %d, Max interation (all seg) %d)\n", ++ LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for SFN/SF %d.%d (pid %d, ndi %d, status %d, round %d, TBS %d, Max interation (all seg) %d)\n", + gNB->Mod_id,ulsch_harq->frame,ulsch_harq->slot,rdata->harq_pid,pusch_pdu->pusch_data.new_data_indicator,ulsch_harq->status,ulsch_harq->round,ulsch_harq->TBS,rdata->decodeIterations); + ulsch_harq->status = SCH_IDLE; + ulsch_harq->round = 0; + ulsch->harq_mask &= ~(1 << rdata->harq_pid); + +- LOG_D(PHY, "ULSCH received ok \n"); ++ LOG_I(PHY, "ULSCH received ok \n"); + nr_fill_indication(gNB,ulsch_harq->frame, ulsch_harq->slot, rdata->ulsch_id, rdata->harq_pid, 0,0); + //dumpsig=1; + } else { +@@ -281,7 +281,7 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { + } + ulsch_harq->handled = 1; + +- LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id); ++ LOG_I(PHY, "ULSCH %d in error\n",rdata->ulsch_id); + nr_fill_indication(gNB,ulsch_harq->frame, ulsch_harq->slot, rdata->ulsch_id, rdata->harq_pid, 1,0); + } + /* +@@ -365,6 +365,14 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH + number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs + pusch_pdu->qam_mod_order, + pusch_pdu->nrOfLayers); ++ ++ ++ nr_ulsch_layer_demapping(gNB->pusch_vars[ULSCH_id]->llr, ++ pusch_pdu->nrOfLayers, ++ pusch_pdu->qam_mod_order, ++ G, ++ gNB->pusch_vars[ULSCH_id]->llr_layers); ++ + //---------------------------------------------------------- + //------------------- ULSCH unscrambling ------------------- + //---------------------------------------------------------- +@@ -731,7 +739,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { + (ulsch_harq->slot == slot_rx) && + (ulsch_harq->handled == 0)){ + +- LOG_D(PHY, "PUSCH detection started in frame %d slot %d\n", ++ LOG_I(PHY, "PUSCH detection started in frame %d slot %d\n", + frame_rx,slot_rx); + int num_dmrs=0; + for (int s=0;srx_pusch_stats); + no_sig = nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, harq_pid); + if (no_sig) { +- LOG_D(PHY, "PUSCH not detected in frame %d, slot %d\n", frame_rx, slot_rx); ++ LOG_I(PHY, "PUSCH not detected in frame %d, slot %d\n", frame_rx, slot_rx); + nr_fill_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid, 1,1); + return 1; + } +@@ -783,7 +791,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { + dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot) + gNB->pusch_thres) { + NR_gNB_SCH_STATS_t *stats=get_ulsch_stats(gNB,ulsch); + +- LOG_D(PHY, "PUSCH not detected in %d.%d (%d,%d,%d)\n",frame_rx,slot_rx, ++ LOG_I(PHY, "PUSCH not detected in %d.%d (%d,%d,%d)\n",frame_rx,slot_rx, + dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot), + dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot),gNB->pusch_thres); + gNB->pusch_vars[ULSCH_id]->ulsch_power_tot = gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot; +diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +index f6e4d90bee..8e1df435c3 100644 +--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c ++++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +@@ -157,7 +157,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ + for (i = 0; i < ul_config->number_pdus; ++i){ + + AssertFatal(ul_config->ul_config_list[i].pdu_type <= FAPI_NR_UL_CONFIG_TYPES,"pdu_type %d out of bounds\n",ul_config->ul_config_list[i].pdu_type); +- LOG_D(PHY, "In %s: processing %s PDU of %d total UL PDUs (ul_config %p) \n", __FUNCTION__, ul_pdu_type[ul_config->ul_config_list[i].pdu_type - 1], ul_config->number_pdus, ul_config); ++ LOG_I(PHY, "In %s i %d: processing %s PDU of %d total UL PDUs (ul_config %p) \n", __FUNCTION__, i, ul_pdu_type[ul_config->ul_config_list[i].pdu_type - 1], ul_config->number_pdus, ul_config); + + uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type, current_harq_pid, gNB_id = 0; + /* PRACH */ +@@ -180,6 +180,8 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ + if (harq_process_ul_ue){ + + nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &harq_process_ul_ue->pusch_pdu; ++ ++ LOG_I(PHY, "In %s i %d: copy pusch_config_pdu nrOfLayers:%d, num_dmrs_cdm_grps_no_data:%d \n", __FUNCTION__, i, pusch_config_pdu->nrOfLayers,pusch_config_pdu->num_dmrs_cdm_grps_no_data); + + memcpy(pusch_pdu, pusch_config_pdu, sizeof(nfapi_nr_ue_pusch_pdu_t)); + +diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +index 940931694c..0a0a9cc2f9 100644 +--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c ++++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +@@ -270,9 +270,12 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, + AssertFatal(ue->CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN); +- +- memset(ue->common_vars.txdataF[0], 0, sizeof(int)*14*ue->frame_parms.ofdm_symbol_size); +- ++ ++ for(int i=0; i< ue->frame_parms.nb_antennas_tx; ++i) ++ { ++ memset(ue->common_vars.txdataF[i], 0, sizeof(int)*14*ue->frame_parms.ofdm_symbol_size); ++ } ++ + LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx); + + +diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c +index 1eb6027936..d5a1054654 100644 +--- a/openair1/SIMULATION/NR_PHY/dlsim.c ++++ b/openair1/SIMULATION/NR_PHY/dlsim.c +@@ -768,7 +768,7 @@ int main(int argc, char **argv) + + prepare_scd(scd); + +- fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, 0, 0, 0); ++ fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, n_rx, 0, 0, 0); + + /* RRC parameter validation for secondaryCellGroup */ + fix_scd(scd); +diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c +index 94aea36a67..fb8b4295ae 100644 +--- a/openair1/SIMULATION/NR_PHY/ulschsim.c ++++ b/openair1/SIMULATION/NR_PHY/ulschsim.c +@@ -137,6 +137,7 @@ int main(int argc, char **argv) + uint16_t nb_symb_sch = 12; + uint16_t nb_rb = 50; + uint8_t Imcs = 9; ++ uint8_t Nl = 1; + + double DS_TDL = .03; + +@@ -150,7 +151,7 @@ int main(int argc, char **argv) + randominit(0); + + //while ((c = getopt(argc, argv, "df:hpg:i:j:n:l:m:r:s:S:y:z:M:N:F:R:P:")) != -1) { +- while ((c = getopt(argc, argv, "hg:n:s:S:py:z:M:N:R:F:m:l:r:")) != -1) { ++ while ((c = getopt(argc, argv, "hg:n:s:S:py:z:M:N:R:F:m:l:r:W:")) != -1) { + switch (c) { + /*case 'f': + write_output_file = 1; +@@ -251,7 +252,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)) { + printf("Unsupported number of TX antennas %d. Exiting.\n", n_tx); + exit(-1); + } +@@ -261,7 +262,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)) { + printf("Unsupported number of RX antennas %d. Exiting.\n", n_rx); + exit(-1); + } +@@ -299,6 +300,10 @@ int main(int argc, char **argv) + printf("Illegal PBCH phase (0-3) got %d\n", pbch_phase); + break;*/ + ++ case 'W': ++ Nl = atoi(optarg); ++ break; ++ + case 'm': + Imcs = atoi(optarg); + #ifdef DEBUG_NR_ULSCHSIM +@@ -335,13 +340,14 @@ int main(int argc, char **argv) + printf("-z Number of RX antennas used in UE\n"); + //printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); + //printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); ++ printf("-W number of layer\n"); + printf("-M Multiple SSB positions in burst\n"); + printf("-N Nid_cell\n"); + printf("-R N_RB_UL\n"); + printf("-F Input filename (.txt format) for RX conformance testing\n"); +- printf("-m\n"); +- printf("-l\n"); +- printf("-r\n"); ++ printf("-m MCS\n"); ++ printf("-l number of symbol\n"); ++ printf("-r number of RB\n"); + //printf("-O oversampling factor (1,2,4,8,16)\n"); + //printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); + //printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); +@@ -359,8 +365,8 @@ int main(int argc, char **argv) + snr1 = snr0 + 10; + + gNB2UE = new_channel_desc_scm(n_tx, +- n_rx, +- channel_model, ++ n_rx, ++ channel_model, + 61.44e6, //N_RB2sampling_rate(N_RB_DL), + 40e6, //N_RB2channel_bandwidth(N_RB_DL), + DS_TDL, +@@ -426,8 +432,7 @@ int main(int argc, char **argv) + uint8_t length_dmrs = 1; + uint8_t N_PRB_oh; + uint16_t N_RE_prime,code_rate; +- unsigned char mod_order; +- uint8_t Nl = 1; ++ unsigned char mod_order; + uint8_t rvidx = 0; + uint8_t UE_id = 0; + +@@ -437,9 +442,14 @@ int main(int argc, char **argv) + + NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[0][0][0]; + ++ if ((Nl==4)||(Nl==3)) ++ { ++ nb_re_dmrs = nb_re_dmrs*2; ++ } ++ + mod_order = nr_get_Qm_ul(Imcs, 0); + code_rate = nr_get_code_rate_ul(Imcs, 0); +- available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1); ++ available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, Nl); + TBS = nr_compute_tbs(mod_order,code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, 0, Nl); + + printf("\nAvailable bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order); +diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c +index 69316d6b88..b6cfae3fe1 100644 +--- a/openair1/SIMULATION/NR_PHY/ulsim.c ++++ b/openair1/SIMULATION/NR_PHY/ulsim.c +@@ -282,7 +282,7 @@ int main(int argc, char **argv) + int gNB_id = 0; + int ap; + int tx_offset; +- int32_t txlev=0; ++ int32_t txlev_sum = 0, atxlev[4]; + int start_rb = 0; + int UE_id =0; // [hna] only works for UE_id = 0 because NUMBER_OF_NR_UE_MAX is set to 1 (phy_init_nr_gNB causes segmentation fault) + float target_error_rate = 0.01; +@@ -307,7 +307,7 @@ int main(int argc, char **argv) + uint16_t ptrsSymbPerSlot = 0; + uint16_t ptrsRePerSymb = 0; + +- uint8_t transform_precoding = 1; // 0 - ENABLE, 1 - DISABLE ++ uint8_t transformPrecoder = transformPrecoder_disabled; // 0 - ENABLE, 1 - DISABLE + uint8_t num_dmrs_cdm_grps_no_data = 1; + uint8_t mcs_table = 0; + +@@ -329,7 +329,7 @@ int main(int argc, char **argv) + /* initialize the sin-cos table */ + InitSinLUT(); + +- while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:ikl:m:n:p:r:s:u:w:y:z:F:G:H:M:N:PR:S:T:U:L:Z")) != -1) { ++ while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:kl:m:n:p:r:s:u:w:y:z:F:G:H:M:N:PR:S:T:U:L:Z:W:")) != -1) { + printf("handling optarg %c\n",c); + switch (c) { + +@@ -363,8 +363,8 @@ int main(int argc, char **argv) + scg_fd = fopen(optarg, "r"); + + if (scg_fd == NULL) { +- printf("Error opening %s\n", optarg); +- exit(-1); ++ printf("Error opening %s\n", optarg); ++ exit(-1); + } + + break; +@@ -437,6 +437,10 @@ int main(int argc, char **argv) + case 'm': + Imcs = atoi(optarg); + break; ++ ++ case 'W': ++ precod_nbr_layers = atoi(optarg); ++ break; + + case 'n': + n_trials = atoi(optarg); +@@ -485,9 +489,9 @@ int main(int argc, char **argv) + case 'y': + n_tx = atoi(optarg); + +- if ((n_tx == 0) || (n_tx > 2)) { +- printf("Unsupported number of tx antennas %d\n", n_tx); +- exit(-1); ++ if ((n_tx == 0) || (n_tx > 4)) { ++ printf("Unsupported number of tx antennas %d\n", n_tx); ++ exit(-1); + } + + break; +@@ -496,8 +500,8 @@ int main(int argc, char **argv) + n_rx = atoi(optarg); + + if ((n_rx == 0) || (n_rx > 8)) { +- printf("Unsupported number of rx antennas %d\n", n_rx); +- exit(-1); ++ printf("Unsupported number of rx antennas %d\n", n_rx); ++ exit(-1); + } + + break; +@@ -506,8 +510,8 @@ int main(int argc, char **argv) + input_fd = fopen(optarg, "r"); + + if (input_fd == NULL) { +- printf("Problem with filename %s\n", optarg); +- exit(-1); ++ printf("Problem with filename %s\n", optarg); ++ exit(-1); + } + + break; +@@ -568,11 +572,11 @@ int main(int argc, char **argv) + + case 'Z': + +- transform_precoding = 0; // enabled ++ transformPrecoder = transformPrecoder_enabled; + num_dmrs_cdm_grps_no_data = 2; + mcs_table = 3; + +- printf("NOTE: TRANSFORM PRECODING (SC-FDMA) is ENABLED in UPLINK (0 - ENABLE, 1 - DISABLE) : %d \n", transform_precoding); ++ printf("NOTE: TRANSFORM PRECODING (SC-FDMA) is ENABLED in UPLINK (0 - ENABLE, 1 - DISABLE) : %d \n", transformPrecoder); + + break; + +@@ -611,6 +615,7 @@ int main(int argc, char **argv) + printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:3}, e.g. -U 2 0 2 \n"); + printf("-Q If -F used, read parameters from file\n"); + printf("-Z If -Z is used, SC-FDMA or transform precoding is enabled in Uplink \n"); ++ printf("-W Num of layer for PUSCH\n"); + exit(-1); + break; + +@@ -713,7 +718,7 @@ int main(int argc, char **argv) + + prepare_scd(scd); + +- fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, 0, 0, 0); ++ fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, n_rx, 0, 0, 0); + + // xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup); + +@@ -724,9 +729,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, n_tx, n_rx, 0, scc, &rrc.carrier.mib,0, 0, NULL); ++ rrc_mac_config_req_gNB(0,0, n_tx, n_rx, n_tx, scc, &rrc.carrier.mib,0, 0, NULL); + // UE dedicated configuration +- rrc_mac_config_req_gNB(0,0, n_tx, n_rx, 0, scc, &rrc.carrier.mib,1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); ++ rrc_mac_config_req_gNB(0,0, n_tx, n_rx, n_tx, scc, &rrc.carrier.mib,1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); + frame_parms->nb_antennas_tx = n_tx; + frame_parms->nb_antennas_rx = n_rx; + nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; +@@ -870,14 +875,18 @@ int main(int argc, char **argv) + uint16_t number_dmrs_symbols = get_dmrs_symbols_in_slot(l_prime_mask, nb_symb_sch); + printf("num dmrs sym %d\n",number_dmrs_symbols); + uint8_t nb_re_dmrs = (dmrs_config_type == pusch_dmrs_type1) ? 6 : 4; +- +- // if transform precoding is enabled +- if (transform_precoding == 0) { ++ ++ if ((frame_parms->nb_antennas_tx==4)&&(precod_nbr_layers==4)) ++ { ++ num_dmrs_cdm_grps_no_data = 2; ++ } ++ ++ if (transformPrecoder == transformPrecoder_enabled) { + + AssertFatal(enable_ptrs == 0, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); + + int8_t index = get_index_for_dmrs_lowpapr_seq((NR_NB_SC_PER_RB/2) * nb_rb); +- AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); ++ AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); + + dmrs_config_type = pusch_dmrs_type1; + +@@ -886,7 +895,7 @@ int main(int argc, char **argv) + + nb_re_dmrs = nb_re_dmrs * num_dmrs_cdm_grps_no_data; + +- unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, 1); ++ unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, precod_nbr_layers); + unsigned int TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, 0, precod_nbr_layers); + + +@@ -1082,14 +1091,14 @@ int main(int argc, char **argv) + pusch_pdu->mcs_table = mcs_table; + pusch_pdu->target_code_rate = code_rate; + pusch_pdu->qam_mod_order = mod_order; +- pusch_pdu->transform_precoding = transform_precoding; ++ pusch_pdu->transformPrecoder = transformPrecoder; + pusch_pdu->data_scrambling_id = *scc->physCellId; +- pusch_pdu->nrOfLayers = 1; ++ pusch_pdu->nrOfLayers = precod_nbr_layers; + pusch_pdu->ul_dmrs_symb_pos = l_prime_mask; + pusch_pdu->dmrs_config_type = dmrs_config_type; + pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; + pusch_pdu->scid = 0; +- pusch_pdu->dmrs_ports = 1; ++ pusch_pdu->dmrs_ports = ((1<num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data; + pusch_pdu->resource_alloc = 1; + pusch_pdu->rb_start = start_rb; +@@ -1109,7 +1118,7 @@ int main(int argc, char **argv) + pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0; + + // if transform precoding is enabled +- if (transform_precoding == 0) { ++ if (transformPrecoder == transformPrecoder_enabled) { + + pusch_pdu->dfts_ofdm.low_papr_group_number = *scc->physCellId % 30; // U as defined in 38.211 section 6.4.1.1.1.2 + pusch_pdu->dfts_ofdm.low_papr_sequence_number = 0; // V as defined in 38.211 section 6.4.1.1.1.2 +@@ -1167,10 +1176,10 @@ int main(int argc, char **argv) + ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t)); + ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0; + +- ul_config.ul_config_list[0].pusch_config_pdu.transform_precoding = transform_precoding; ++ ul_config.ul_config_list[0].pusch_config_pdu.transformPrecoder = transformPrecoder; + + // if transform precoding is enabled +- if (transform_precoding == 0) { ++ if (transformPrecoder == transformPrecoder_enabled) { + + ul_config.ul_config_list[0].pusch_config_pdu.dfts_ofdm.low_papr_group_number = *scc->physCellId % 30;// U as defined in 38.211 section 6.4.1.1.1.2 + ul_config.ul_config_list[0].pusch_config_pdu.dfts_ofdm.low_papr_sequence_number = 0;// V as defined in 38.211 section 6.4.1.1.1.2 +@@ -1198,28 +1207,54 @@ int main(int argc, char **argv) + LOG_D(PHY, "Sending Uplink data \n"); + nr_ue_pusch_common_procedures(UE, + slot, +- &UE->frame_parms,1); +- +- if (n_trials==1) { +- LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_parms->samples_per_subframe*10,1,1); ++ &UE->frame_parms, ++ frame_parms->nb_antennas_tx); ++ ++ ++ if (n_trials==1) ++ { ++ LOG_M("txsig0.m","txs0", &UE->common_vars.txdata[0][slot_offset],slot_length,1,1); + LOG_M("txsig0F.m","txs0F", UE->common_vars.txdataF[0],frame_parms->ofdm_symbol_size*14,1,1); ++ if (precod_nbr_layers > 1) ++ { ++ LOG_M("txsig1.m","txs1", &UE->common_vars.txdata[1][slot_offset],slot_length,1,1); ++ LOG_M("txsig1F.m","txs1F", UE->common_vars.txdataF[1],frame_parms->ofdm_symbol_size*14,1,1); ++ if (precod_nbr_layers==4) ++ { ++ LOG_M("txsig2.m","txs2", &UE->common_vars.txdata[2][slot_offset],slot_length,1,1); ++ LOG_M("txsig3.m","txs3", &UE->common_vars.txdata[3][slot_offset],slot_length,1,1); ++ ++ LOG_M("txsig2F.m","txs2F", UE->common_vars.txdataF[2],frame_parms->ofdm_symbol_size*14,1,1); ++ LOG_M("txsig3F.m","txs3F", UE->common_vars.txdataF[3],frame_parms->ofdm_symbol_size*14,1,1); ++ } ++ } + } + /////////// + //////////////////////////////////////////////////// + tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); +- +- txlev = signal_energy(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], ++ txlev_sum = 0; ++ for (int aa=0; aanb_antennas_tx; aa++) ++ { ++ atxlev[aa] = signal_energy(&UE->common_vars.txdata[aa][tx_offset + 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); +- } +- else n_trials = 1; +- +- if (input_fd == NULL ) { ++ ++ txlev_sum += atxlev[aa]; ++ ++ if (n_trials==1) printf("txlev[%d] = %d (%f dB) txlev_sum %d\n",aa,atxlev[aa],10*log10((double)atxlev[aa]),txlev_sum); ++ } ++ } ++ else ++ { ++ n_trials = 1; ++ } + +- sigma_dB = 10 * log10((double)txlev * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;; ++ if (input_fd == NULL ) ++ { ++ sigma_dB = 10 * log10((double)txlev_sum * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;; + sigma = pow(10,sigma_dB/10); + + +- if(n_trials==1) printf("sigma %f (%f dB), txlev %f (factor %f)\n",sigma,sigma_dB,10*log10((double)txlev),(double)(double) ++ if(n_trials==1) printf("sigma %f (%f dB), txlev_sum %f (factor %f)\n",sigma,sigma_dB,10*log10((double)txlev_sum),(double)(double) + frame_parms->ofdm_symbol_size/(12*nb_rb)); + + for (i=0; imax_Doppler == 0) { ++ if (UE2gNB->max_Doppler == 0) ++ { + multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials==1)?1:0); + } else { + multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, 2*slot_length, 0); + } +- for (i=0; inb_antennas_rx; ap++) { ++ for (i=0; inb_antennas_rx; ap++) ++ { ++ if (channel_model == AWGN) ++ { ++ double H_awgn[4][4] ={{1.0, 0.0, 0.0, 0.0},//rx 0 ++ {0.0, 1.0, 0.0, 0.0}, //rx 1 ++ {0.0, 0.0, 1.0, 0.0}, //rx 2 ++ {0.0, 0.0, 0.0, 1.0}};//rx 3 ++ #if 0 ++ double H_awgn_mimo[4][4] ={{1.0, 0.5, 0.25, 0.125},//rx 0 ++ {0.5, 1.0, 0.5, 0.25}, //rx 1 ++ {0.25, 0.5, 1.0, 0.5}, //rx 2 ++ {0.125, 0.25, 0.5, 1.0}};//rx 3 ++ #endif ++ // sum up signals from different Tx antennas ++ r_re[ap][i] = 0; ++ r_im[ap][i] = 0; ++ ++ for (int aa=0; aaofdm_symbol_size/(12*nb_rb))) - SNR;; ++ sigma = pow(10,sigma_dB/10); ++ + ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point + ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); ++ ++ #if 0 ++ ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((r_re[ap][i])); // convert to fixed point ++ ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((r_im[ap][i])); ++ ++ ++ ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) ] = ((int16_t*) &UE->common_vars.txdata[ap][slot_offset])[(2*i) ]; // convert to fixed point ++ ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1] = ((int16_t*) &UE->common_vars.txdata[ap][slot_offset])[(2*i)+1 ]; ++ #endif ++ + /* Add phase noise if enabled */ + if (pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { + phase_noise(ts, &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)], +@@ -1250,7 +1324,8 @@ int main(int argc, char **argv) + } /*End input_fd */ + + +- if(pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { ++ if(pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) ++ { + set_ptrs_symb_idx(&ptrsSymPos, + pusch_pdu->nr_of_symbols, + pusch_pdu->start_symbol_index, +@@ -1268,24 +1343,37 @@ int main(int argc, char **argv) + gNB->UL_INFO.rx_ind.number_of_pdus = 0; + gNB->UL_INFO.crc_ind.number_crcs = 0; + +- phy_procedures_gNB_common_RX(gNB, frame, slot); ++ phy_procedures_gNB_common_RX(gNB, frame, slot); + +- ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot); ++ ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot); + +- if (n_trials==1 && round==0) { ++ if (n_trials==1 && round==0) ++ { + LOG_M("rxsig0.m","rx0",&gNB->common_vars.rxdata[0][slot_offset],slot_length,1,1); + +- LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0]+start_symbol*frame_parms->ofdm_symbol_size,nb_symb_sch*frame_parms->ofdm_symbol_size,1,1); +- ++ LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0],14*frame_parms->ofdm_symbol_size,1,1); ++ if (precod_nbr_layers > 1) ++ { ++ LOG_M("rxsig1.m","rx1",&gNB->common_vars.rxdata[1][slot_offset],slot_length,1,1); ++ LOG_M("rxsigF1.m","rxsF1",gNB->common_vars.rxdataF[1],14*frame_parms->ofdm_symbol_size,1,1); ++ if (precod_nbr_layers==4) ++ { ++ LOG_M("rxsig2.m","rx2",&gNB->common_vars.rxdata[2][slot_offset],slot_length,1,1); ++ LOG_M("rxsig3.m","rx3",&gNB->common_vars.rxdata[3][slot_offset],slot_length,1,1); ++ ++ LOG_M("rxsigF2.m","rxsF2",gNB->common_vars.rxdataF[2],14*frame_parms->ofdm_symbol_size,1,1); ++ LOG_M("rxsigF3.m","rxsF3",gNB->common_vars.rxdataF[3],14*frame_parms->ofdm_symbol_size,1,1); ++ } ++ } + } + + + if (n_trials == 1 && round==0) { +-#ifdef __AVX2__ ++ #ifdef __AVX2__ + int off = ((nb_rb&1) == 1)? 4:0; +-#else ++ #else + int off = 0; +-#endif ++ #endif + + LOG_M("rxsigF0_ext.m","rxsF0_ext", + &gNB->pusch_vars[0]->rxdataF_ext[0][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); +@@ -1298,11 +1386,77 @@ int main(int argc, char **argv) + (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + LOG_M("rxsigF0_comp.m","rxsF0_comp", + &gNB->pusch_vars[0]->rxdataF_comp[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); +- LOG_M("chmagF0.m","chmF0", +- &gNB->pusch_vars[0]->ul_ch_mag[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); +- LOG_M("chmagbF0.m","chmbF0", +- &gNB->pusch_vars[0]->ul_ch_magb[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); +- if (n_rx == 2) { ++ LOG_M("chmagF0.m","chmF0", ++ &gNB->pusch_vars[0]->ul_ch_mag[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); ++ LOG_M("chmagbF0.m","chmbF0", ++ &gNB->pusch_vars[0]->ul_ch_magb[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); ++ LOG_M("rxsigF0_llrlayers0.m","rxsF0_llrlayers0", ++ &gNB->pusch_vars[0]->llr_layers[0][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); ++ ++ if (precod_nbr_layers==2) ++ { ++ LOG_M("rxsigF1_ext.m","rxsF1_ext", ++ &gNB->pusch_vars[0]->rxdataF_ext[1][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); ++ ++ LOG_M("chestF3.m","chF3", ++ &gNB->pusch_vars[0]->ul_ch_estimates[3][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); ++ ++ LOG_M("chestF3_ext.m","chF3_ext", ++ &gNB->pusch_vars[0]->ul_ch_estimates_ext[3][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], ++ (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); ++ ++ LOG_M("rxsigF2_comp.m","rxsF2_comp", ++ &gNB->pusch_vars[0]->rxdataF_comp[2][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); ++ ++ LOG_M("rxsigF0_llrlayers1.m","rxsF0_llrlayers1", ++ &gNB->pusch_vars[0]->llr_layers[1][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); ++ ++ } ++ ++ if (precod_nbr_layers==4) ++ { ++ LOG_M("rxsigF1_ext.m","rxsF1_ext", ++ &gNB->pusch_vars[0]->rxdataF_ext[1][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); ++ LOG_M("rxsigF2_ext.m","rxsF2_ext", ++ &gNB->pusch_vars[0]->rxdataF_ext[2][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); ++ LOG_M("rxsigF3_ext.m","rxsF3_ext", ++ &gNB->pusch_vars[0]->rxdataF_ext[3][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); ++ ++ LOG_M("chestF5.m","chF5", ++ &gNB->pusch_vars[0]->ul_ch_estimates[5][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); ++ LOG_M("chestF10.m","chF10", ++ &gNB->pusch_vars[0]->ul_ch_estimates[10][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); ++ LOG_M("chestF15.m","chF15", ++ &gNB->pusch_vars[0]->ul_ch_estimates[15][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); ++ ++ ++ LOG_M("chestF5_ext.m","chF5_ext", ++ &gNB->pusch_vars[0]->ul_ch_estimates_ext[5][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], ++ (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); ++ LOG_M("chestF10_ext.m","chF10_ext", ++ &gNB->pusch_vars[0]->ul_ch_estimates_ext[10][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], ++ (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); ++ LOG_M("chestF15_ext.m","chF15_ext", ++ &gNB->pusch_vars[0]->ul_ch_estimates_ext[15][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], ++ (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); ++ ++ ++ LOG_M("rxsigF4_comp.m","rxsF4_comp", ++ &gNB->pusch_vars[0]->rxdataF_comp[4][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); ++ LOG_M("rxsigF8_comp.m","rxsF8_comp", ++ &gNB->pusch_vars[0]->rxdataF_comp[8][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); ++ LOG_M("rxsigF12_comp.m","rxsF12_comp", ++ &gNB->pusch_vars[0]->rxdataF_comp[12][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); ++ LOG_M("rxsigF0_llrlayers1.m","rxsF0_llrlayers1", ++ &gNB->pusch_vars[0]->llr_layers[1][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); ++ LOG_M("rxsigF0_llrlayers2.m","rxsF0_llrlayers2", ++ &gNB->pusch_vars[0]->llr_layers[2][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); ++ LOG_M("rxsigF0_llrlayers3.m","rxsF0_llrlayers3", ++ &gNB->pusch_vars[0]->llr_layers[3][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); ++ } ++ ++ #if 0 ++ if (n_rx == 2) { + LOG_MM("rxsigF0_comp.m","rxsF1_comp", + &gNB->pusch_vars[0]->rxdataF_comp[1][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + LOG_MM("rxsigF0_ext.m","rxsF1_ext", +@@ -1349,9 +1503,10 @@ int main(int argc, char **argv) + LOG_MM("chmagbF0.m","chmbF3", + &gNB->pusch_vars[0]->ul_ch_magb[3][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + } ++ #endif + + LOG_M("rxsigF0_llr.m","rxsF0_llr", +- &gNB->pusch_vars[0]->llr[0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); ++ &gNB->pusch_vars[0]->llr[0],precod_nbr_layers*(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); + } + //////////////////////////////////////////////////////////// + +diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +index 3f4be9dd58..7e5be9eeba 100644 +--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c ++++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +@@ -2708,6 +2708,9 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP, + LOG_D(NR_MAC,"dci_pdu->srs_resource_indicator.nbits %d\n",dci_pdu->srs_resource_indicator.nbits); + // Precoding info and number of layers + long transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, ubwpd, (uint8_t*)&format, rnti_type, 0); ++ ++ pusch_antenna_ports = *pusch_Config->maxRank; ++ + dci_pdu->precoding_information.nbits=0; + if (pusch_Config && + pusch_Config->txConfig != NULL){ +diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +index c23d4bb073..963723725f 100644 +--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c ++++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +@@ -190,7 +190,7 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con + else + transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled; + } +- ++ pusch_config_pdu->transformPrecoder = transformPrecoder; + + /* PRECOD_NBR_LAYERS */ + if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_nonCodebook)); +@@ -198,11 +198,12 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con + + if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook)){ + +- uint8_t n_antenna_port = 0; //FIXME!!! ++ uint8_t n_antenna_port = mac->phy_config.config_req.carrier_config.num_tx_ant; + + if (n_antenna_port == 1); // 1 antenna port and the higher layer parameter txConfig = codebook 0 bits + +- if (n_antenna_port == 4){ // 4 antenna port and the higher layer parameter txConfig = codebook ++ if (n_antenna_port == 4) ++ { // 4 antenna port and the higher layer parameter txConfig = codebook + + // Table 7.3.1.1.2-2: transformPrecoder=disabled and maxRank = 2 or 3 or 4 + if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) +@@ -212,54 +213,56 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con + + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][0]; +- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][1]; ++ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][1]; + } + + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_partialAndNonCoherent){ + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][2]; +- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][3]; ++ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][3]; + } + + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){ + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][4]; +- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][5]; ++ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][5]; + } + } + + // Table 7.3.1.1.2-3: transformPrecoder= enabled, or transformPrecoder=disabled and maxRank = 1 + if (((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) + || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled)) +- && (*pusch_Config->maxRank == 1)){ ++ && (*pusch_Config->maxRank == 1)) ++ { + + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][6]; +- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][7]; ++ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][7]; + } + + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_partialAndNonCoherent){ + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][8]; +- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][9]; ++ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][9]; + } + + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){ + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][10]; +- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][11]; ++ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][11]; + } + } + } + +- if (n_antenna_port == 4){ // 2 antenna port and the higher layer parameter txConfig = codebook ++ if (n_antenna_port == 2) ++ { // 2 antenna port and the higher layer parameter txConfig = codebook + // Table 7.3.1.1.2-4: transformPrecoder=disabled and maxRank = 2 +- if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (*pusch_Config->maxRank == 2)){ +- ++ if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (*pusch_Config->maxRank == 2)) ++ { + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][12]; +- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][13]; ++ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][13]; + } + + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){ + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][14]; +- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][15]; ++ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][15]; + } + + } +@@ -267,16 +270,17 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con + // Table 7.3.1.1.2-5: transformPrecoder= enabled, or transformPrecoder= disabled and maxRank = 1 + if (((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) + || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled)) +- && (*pusch_Config->maxRank == 1)){ ++ && (*pusch_Config->maxRank == 1)) ++ { + + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][16]; +- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][17]; ++ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][17]; + } + + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){ + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][18]; +- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][19]; ++ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][19]; + } + + } +@@ -285,9 +289,9 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con + + /*-------------------- Changed to enable Transform precoding in RF SIM------------------------------------------------*/ + +- /*if (pusch_config_pdu->transform_precoding == transform_precoder_enabled) { ++ /*if (pusch_config_pdu->transformPrecoder == transformPrecoder_enabled) { + +- pusch_config_dedicated->transform_precoder = transform_precoder_enabled; ++ pusch_config_dedicated->transform_precoder = transformPrecoder_enabled; + + if(pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL) { + +@@ -309,7 +313,7 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con + + } + } else +- pusch_config_dedicated->transform_precoder = transform_precoder_disabled;*/ ++ pusch_config_dedicated->transformPrecoder = ttransformPrecoder_disabled;*/ + } + + // todo: this function shall be reviewed completely because of the many comments left by the author +@@ -342,7 +346,7 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf + } + long *max_length = NULL; + long *dmrs_type = NULL; +- LOG_D(NR_MAC,"transformPrecoder %s\n",transformPrecoder==NR_PUSCH_Config__transformPrecoder_disabled?"disabled":"enabled"); ++ LOG_I(NR_MAC,"transformPrecoder %s\n",transformPrecoder==NR_PUSCH_Config__transformPrecoder_disabled?"disabled":"enabled"); + + if (pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA) { + max_length = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup->maxLength; +@@ -353,7 +357,7 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf + dmrs_type = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->dmrs_Type; + } + +- LOG_D(NR_MAC,"MappingType%s max_length %s, dmrs_type %s, antenna_ports %d\n",pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA?"A":"B",max_length?"len2":"len1",dmrs_type?"type2":"type1",dci->antenna_ports.val); ++ LOG_I(NR_MAC,"MappingType%s max_length %s, dmrs_type %s, antenna_ports %d\n",pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA?"A":"B",max_length?"len2":"len1",dmrs_type?"type2":"type1",dci->antenna_ports.val); + if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) && + (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-6 + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC +@@ -369,35 +373,32 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf + } + + if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && +- (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-8/9/10/11 ++ (dmrs_type == NULL) && (max_length == NULL)) ++ { // tables 7.3.1.1.2-8/9/10/11 ++ ++ if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook)) ++ { ++ rank = pusch_config_pdu->nrOfLayers; ++ } + + if (rank == 1) { +- pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; //TBC +- pusch_config_pdu->dmrs_ports = (dci->antenna_ports.val > 1)?(dci->antenna_ports.val-2):(dci->antenna_ports.val); //TBC ++ pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; ++ pusch_config_pdu->dmrs_ports =1<<((dci->antenna_ports.val > 1)?(dci->antenna_ports.val-2):(dci->antenna_ports.val)); + } + + if (rank == 2){ +- pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 0)?2:1; //TBC +- pusch_config_pdu->dmrs_ports = 0; //FIXME +- //pusch_config_pdu->dmrs_ports[0] = (dci->antenna_ports > 1)?(dci->antenna_ports > 2 ?0:2):0; +- //pusch_config_pdu->dmrs_ports[1] = (dci->antenna_ports > 1)?(dci->antenna_ports > 2 ?2:3):1; ++ pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 0)?2:1; ++ pusch_config_pdu->dmrs_ports = (dci->antenna_ports.val > 1)?((dci->antenna_ports.val> 2)?0x5:0xc):0x3; + } + + if (rank == 3){ +- pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC +- pusch_config_pdu->dmrs_ports = 0; //FIXME +- //pusch_config_pdu->dmrs_ports[0] = 0; +- //pusch_config_pdu->dmrs_ports[1] = 1; +- //pusch_config_pdu->dmrs_ports[2] = 2; ++ pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; ++ pusch_config_pdu->dmrs_ports = ((1<num_dmrs_cdm_grps_no_data = 2; //TBC +- pusch_config_pdu->dmrs_ports = 0; //FIXME +- //pusch_config_pdu->dmrs_ports[0] = 0; +- //pusch_config_pdu->dmrs_ports[1] = 1; +- //pusch_config_pdu->dmrs_ports[2] = 2; +- //pusch_config_pdu->dmrs_ports[3] = 3; ++ pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; ++ pusch_config_pdu->dmrs_ports = ((1<n_front_load_symb = table_7_3_1_1_2_23[dci->antenna_ports.val][5]; //FIXME + } + } +- LOG_D(NR_MAC,"num_dmrs_cdm_grps_no_data %d, dmrs_ports %d\n",pusch_config_pdu->num_dmrs_cdm_grps_no_data,pusch_config_pdu->dmrs_ports); ++ LOG_I(NR_MAC,"num_dmrs_cdm_grps_no_data %d, dmrs_ports %d\n",pusch_config_pdu->num_dmrs_cdm_grps_no_data,pusch_config_pdu->dmrs_ports); + } + + // Configuration of Msg3 PDU according to clauses: +@@ -542,6 +543,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, + pusch_config_pdu->dmrs_config_type = pusch_dmrs_type1; + pusch_config_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; + pusch_config_pdu->nrOfLayers = 1; ++ pusch_config_pdu->Tpmi = 0; + pusch_config_pdu->rnti = rnti; + NR_BWP_UplinkCommon_t *initialUplinkBWP; + if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP; +@@ -634,7 +636,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, + pusch_config_pdu->scid = 0; + + // Transform precoding according to 6.1.3 UE procedure for applying transform precoding on PUSCH in 38.214 +- pusch_config_pdu->transform_precoding = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, NULL, NR_RNTI_TC, 0); // TBR fix rnti and take out ++ pusch_config_pdu->transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, NULL, NR_RNTI_TC, 0); // TBR fix rnti and take out + + // Resource allocation in frequency domain according to 6.1.2.2 in TS 38.214 + pusch_config_pdu->resource_alloc = (mac->cg) ? pusch_Config->resourceAllocation : 1; +@@ -680,7 +682,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, + + /* Transform precoding */ + if (rnti_type != NR_RNTI_CS || (rnti_type == NR_RNTI_CS && dci->ndi == 1)) { +- pusch_config_pdu->transform_precoding = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, dci_format, rnti_type, 0); ++ pusch_config_pdu->transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, dci_format, rnti_type, 0); + } + + /*DCI format-related configuration*/ +@@ -716,7 +718,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, + + /* TRANSFORM PRECODING ------------------------------------------------------------------------------------------*/ + +- if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled) { ++ if (pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) { + + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; + +@@ -761,7 +763,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, + pusch_config_pdu->mcs_index = dci->mcs; + + /* MCS TABLE */ +- if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) { ++ if (pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) { + pusch_config_pdu->mcs_table = get_pusch_mcs_table(pusch_Config ? pusch_Config->mcs_Table : NULL, 0, *dci_format, rnti_type, target_ss, false); + } else { + pusch_config_pdu->mcs_table = get_pusch_mcs_table(pusch_Config ? pusch_Config->mcs_TableTransformPrecoder : NULL, 1, *dci_format, rnti_type, target_ss, false); +@@ -798,9 +800,14 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, + mappingtype, add_pos, dmrslength, + pusch_config_pdu->start_symbol_index, + mac->scc ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position); +- if ((mac->ULbwp[0] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled)) +- pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1; +- else if (*dci_format == NR_UL_DCI_FORMAT_0_0 || (mac->ULbwp[0] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled)) ++ if (mac->ULbwp[0] && pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) ++ { ++ if (*dci_format != NR_UL_DCI_FORMAT_0_1) ++ { ++ pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1; ++ } ++ } ++ else if (*dci_format == NR_UL_DCI_FORMAT_0_0 || (mac->ULbwp[0] && pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled)) + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; + + // Num PRB Overhead from PUSCH-ServingCellConfig +@@ -821,7 +828,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, + mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup && + mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB && + mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) { +- if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) { ++ if (pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) { + nfapi_nr_ue_ptrs_ports_t ptrs_ports_list; + pusch_config_pdu->pusch_ptrs.ptrs_ports_list = &ptrs_ports_list; + valid_ptrs_setup = set_ul_ptrs_values(mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup, +@@ -909,6 +916,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in + + fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id); + if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) ++ LOG_I(NR_MAC,"1# scheduled_response transmitted, %d, %d\n", rx_frame, rx_slot); + mac->if_module->scheduled_response(&scheduled_response); + } + else { +@@ -1022,6 +1030,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in + + fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, rx_frame, rx_slot, ul_info->thread_id); + if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ ++ LOG_I(NR_MAC,"3# scheduled_response transmitted,%d, %d\n", frame_tx, slot_tx); + mac->if_module->scheduled_response(&scheduled_response); + } + pthread_mutex_lock(&ul_config->mutex_ul_config); +diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c +index 1cb3fdb708..d9c98852a3 100644 +--- a/openair2/LAYER2/NR_MAC_gNB/config.c ++++ b/openair2/LAYER2/NR_MAC_gNB/config.c +@@ -388,7 +388,7 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts + 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(NR_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); ++ LOG_I(NR_MAC,"Set RX antenna number to %d, Set TX antenna number to %d (num ssb %d: %x,%x)\n",cfg->carrier_config.num_tx_ant.value,cfg->carrier_config.num_rx_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 ); + cfg->num_tlv++; + cfg->num_tlv++; +diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +index 6ac7f3f82e..5de36bb2db 100644 +--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c ++++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +@@ -977,9 +977,9 @@ void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, + pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); + pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) +- pusch_pdu->transform_precoding = 1; ++ pusch_pdu->transformPrecoder = 1; + else +- pusch_pdu->transform_precoding = 0; ++ pusch_pdu->transformPrecoder = 0; + pusch_pdu->data_scrambling_id = *scc->physCellId; + pusch_pdu->nrOfLayers = 1; + pusch_pdu->ul_dmrs_symb_pos = get_l_prime(nr_of_symbols,mappingtype,pusch_dmrs_pos2,pusch_len1,start_symbol_index, scc->dmrs_TypeA_Position); +diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +index abc007197d..9cbbe7d9a1 100644 +--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c ++++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +@@ -1139,13 +1139,14 @@ void nr_schedule_ue_spec(module_id_t module_id, + dci_payload.dmrs_sequence_initialization.val = pdsch_pdu->SCID; + LOG_D(NR_MAC, + "%4d.%2d DCI type 1 payload: freq_alloc %d (%d,%d,%d), " +- "time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d tpc %d ti %d\n", ++ "nrOfLayers %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d tpc %d ti %d\n", + frame, + slot, + dci_payload.frequency_domain_assignment.val, + pdsch_pdu->rbStart, + pdsch_pdu->rbSize, + pdsch_pdu->BWPSize, ++ pdsch_pdu->nrOfLayers, + dci_payload.time_domain_assignment.val, + dci_payload.vrb_to_prb_mapping.val, + dci_payload.mcs, +diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +index f1005cea70..8f7c856a30 100644 +--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c ++++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +@@ -405,6 +405,7 @@ void nr_preprocessor_phytest(module_id_t module_id, + + uint32_t target_ul_mcs = 9; + uint32_t target_ul_bw = 50; ++uint32_t target_ul_Nl = 1; + uint64_t ulsch_slot_bitmap = (1 << 8); + bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_t slot) + { +@@ -446,15 +447,21 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ + + const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats; + const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0; +- const uint8_t num_dmrs_cdm_grps_no_data = 1; ++ uint8_t num_dmrs_cdm_grps_no_data = 1; ++ if ((target_ul_Nl==4)||(target_ul_Nl==3)) ++ { ++ num_dmrs_cdm_grps_no_data = 2; ++ } ++ + /* we want to avoid a lengthy deduction of DMRS and other parameters in + * every TTI if we can save it, so check whether dci_format, TDA, or + * num_dmrs_cdm_grps_no_data has changed and only then recompute */ + NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; + if (ps->time_domain_allocation != tda + || ps->dci_format != dci_format ++ || ps->nrOfLayers != target_ul_Nl + || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) +- nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, NULL,dci_format, tda, num_dmrs_cdm_grps_no_data, ps); ++ nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, NULL,dci_format, tda, num_dmrs_cdm_grps_no_data,target_ul_Nl,ps); + + uint16_t rbStart = 0; + uint16_t rbSize; +@@ -525,6 +532,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ + sched_pusch->ul_harq_pid = sched_ctrl->retrans_ul_harq.head; + + /* Calculate TBS from MCS */ ++ ps->nrOfLayers = target_ul_Nl; + sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table); + sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table); + if (ps->pusch_Config->tp_pi2BPSK +@@ -539,7 +547,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ + ps->N_PRB_DMRS * ps->num_dmrs_symb, + 0, // nb_rb_oh + 0, +- 1 /* NrOfLayers */) ++ ps->nrOfLayers /* NrOfLayers */) + >> 3; + + /* mark the corresponding RBs as used */ +diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +index 1c0cb0353e..4583da876f 100644 +--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c ++++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +@@ -355,6 +355,7 @@ void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc, + long dci_format, + int tda, + uint8_t num_dmrs_cdm_grps_no_data, ++ uint8_t nrOfLayers, + NR_pusch_semi_static_t *ps) + { + ps->dci_format = dci_format; +@@ -371,11 +372,11 @@ void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc, + + ps->pusch_Config = ubwp?ubwp->bwp_Dedicated->pusch_Config->choice.setup:(ubwpd ? ubwpd->pusch_Config->choice.setup : NULL); + if (ps->pusch_Config == NULL || !ps->pusch_Config->transformPrecoder) +- ps->transform_precoding = !scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder; ++ ps->transformPrecoder = !scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder; + else +- ps->transform_precoding = *ps->pusch_Config->transformPrecoder; ++ ps->transformPrecoder = *ps->pusch_Config->transformPrecoder; + const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; +- if (ps->transform_precoding) ++ if (ps->transformPrecoder) + ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config ? ps->pusch_Config->mcs_Table : NULL, + 0, + ps->dci_format, +@@ -392,6 +393,7 @@ void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc, + num_dmrs_cdm_grps_no_data = 2; // in case of transform precoding - no Data sent in DMRS symbol + } + ++ ps->nrOfLayers = nrOfLayers; + ps->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data; + + /* DMRS calculations */ +@@ -689,8 +691,21 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp, + "Non Codebook configuration non supported\n"); + dci_pdu_rel15->srs_resource_indicator.val = 0; // taking resource 0 for SRS + } ++ AssertFatal((pusch_pdu->Tpmi==0), "unsupport Tpmi\n"); ++ dci_pdu_rel15->precoding_information.val= 0; ++ if (pusch_pdu->nrOfLayers == 2) ++ { ++ dci_pdu_rel15->precoding_information.val = 4; ++ } ++ else if (pusch_pdu->nrOfLayers == 4) ++ { ++ dci_pdu_rel15->precoding_information.val = 11; ++ } ++ ++ // antenna_ports.val = 0 for transform precoder is disabled, dmrs-Type=1, maxLength=1, Rank=1/2/3/4 + // Antenna Ports +- dci_pdu_rel15->antenna_ports.val = 0; // TODO for now it is hardcoded, it should depends on cdm group no data and rank ++ dci_pdu_rel15->antenna_ports.val = 0; ++ + // DMRS sequence initialization + dci_pdu_rel15->dmrs_sequence_initialization.val = pusch_pdu->scid; + break; +@@ -699,11 +714,14 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp, + } + + LOG_D(NR_MAC, +- "%s() ULDCI type 0 payload: freq_alloc %d, time_alloc %d, freq_hop_flag %d, mcs %d tpc %d ndi %d rv %d\n", ++ "%s() ULDCI type 0 payload: dci_format %d, freq_alloc %d, time_alloc %d, freq_hop_flag %d, precoding_information.val %d antenna_ports.val %d mcs %d tpc %d ndi %d rv %d\n", + __func__, ++ dci_format, + dci_pdu_rel15->frequency_domain_assignment.val, + dci_pdu_rel15->time_domain_assignment.val, + dci_pdu_rel15->frequency_hopping_flag.val, ++ dci_pdu_rel15->precoding_information.val, ++ dci_pdu_rel15->antenna_ports.val, + dci_pdu_rel15->mcs, + dci_pdu_rel15->tpc, + dci_pdu_rel15->ndi, +diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +index 9a6fa32b5f..269d6c5359 100644 +--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c ++++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +@@ -905,7 +905,7 @@ bool allocate_ul_retransmission(module_id_t module_id, + NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; + int rbStart = 0; // wrt BWP start + const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); +- ++ const uint8_t nrOfLayers = 1; + const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_bwp || ubwpd) ? 1 : 2; + const int tda = sched_ctrl->active_ubwp ? RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0; + LOG_D(NR_MAC,"retInfo->time_domain_allocation = %d, tda = %d\n", retInfo->time_domain_allocation, tda); +@@ -926,8 +926,9 @@ bool allocate_ul_retransmission(module_id_t module_id, + + if (ps->time_domain_allocation != tda + || ps->dci_format != dci_format ++ || ps->nrOfLayers != nrOfLayers + || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) +- nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps); ++ nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, nrOfLayers,ps); + LOG_D(NR_MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size); + } else { + /* the retransmission will use a different time domain allocation, check +@@ -939,7 +940,7 @@ bool allocate_ul_retransmission(module_id_t module_id, + rbSize++; + NR_pusch_semi_static_t temp_ps; + int dci_format = get_dci_format(sched_ctrl); +- nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp,ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, &temp_ps); ++ nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp,ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, nrOfLayers, &temp_ps); + uint32_t new_tbs; + uint16_t new_rbSize; + bool success = nr_find_nb_rb(retInfo->Qm, +@@ -1094,7 +1095,7 @@ void pf_ul(module_id_t module_id, + if (max_num_ue < 0) + return; + +- LOG_D(NR_MAC,"Looking for min_rb %d RBs, starting at %d\n", min_rb, rbStart); ++ LOG_D(NR_MAC,"Looking for min_rb %d RBs, starting at %d num_dmrs_cdm_grps_no_data %d\n", min_rb, rbStart, ps->num_dmrs_cdm_grps_no_data); + while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++; + if (rbStart + min_rb >= bwpSize) { + LOG_W(NR_MAC, "cannot allocate continuous UL data for UE %d/RNTI %04x: no resources (rbStart %d, min_rb %d, bwpSize %d\n", +@@ -1106,13 +1107,15 @@ void pf_ul(module_id_t module_id, + /* we want to avoid a lengthy deduction of DMRS and other parameters in + * every TTI if we can save it, so check whether dci_format, TDA, or + * num_dmrs_cdm_grps_no_data has changed and only then recompute */ ++ const uint8_t nrOfLayers = 1; + const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_ubwp || ubwpd) ? 1 : 2; + int dci_format = get_dci_format(sched_ctrl); + const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0; + if (ps->time_domain_allocation != tda + || ps->dci_format != dci_format ++ || ps->nrOfLayers != nrOfLayers + || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) +- nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps); ++ nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data,nrOfLayers, ps); + NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; + sched_pusch->mcs = 9; + update_ul_ue_R_Qm(sched_pusch, ps); +@@ -1125,7 +1128,7 @@ void pf_ul(module_id_t module_id, + ps->N_PRB_DMRS * ps->num_dmrs_symb, + 0, // nb_rb_oh + 0, +- 1 /* NrOfLayers */) ++ ps->nrOfLayers) + >> 3; + + /* Mark the corresponding RBs as used */ +@@ -1205,13 +1208,15 @@ void pf_ul(module_id_t module_id, + /* we want to avoid a lengthy deduction of DMRS and other parameters in + * every TTI if we can save it, so check whether dci_format, TDA, or + * num_dmrs_cdm_grps_no_data has changed and only then recompute */ ++ const uint8_t nrOfLayers = 1; + const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_ubwp || ubwpd) ? 1 : 2; + int dci_format = get_dci_format(sched_ctrl); + const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0; + if (ps->time_domain_allocation != tda + || ps->dci_format != dci_format ++ || ps->nrOfLayers != nrOfLayers + || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) +- nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps); ++ nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, nrOfLayers,ps); + update_ul_ue_R_Qm(sched_pusch, ps); + + /* Calculate the current scheduling bytes and the necessary RBs */ +@@ -1473,7 +1478,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) + sched_ctrl->last_ul_slot = sched_pusch->slot; + + LOG_D(NR_MAC, +- "ULSCH/PUSCH: %4d.%2d RNTI %04x UL sched %4d.%2d DCI L %d start %2d RBS %3d startSymbol %2d nb_symbol %2d dmrs_pos %x MCS %2d TBS %4d HARQ PID %2d round %d RV %d NDI %d est %6d sched %6d est BSR %6d TPC %d\n", ++ "ULSCH/PUSCH: %4d.%2d RNTI %04x UL sched %4d.%2d DCI L %d start %2d RBS %3d startSymbol %2d nb_symbol %2d dmrs_pos %x MCS %2d nrOfLayers %2d num_dmrs_cdm_grps_no_data %2d TBS %4d HARQ PID %2d round %d RV %d NDI %d est %6d sched %6d est BSR %6d TPC %d\n", + frame, + slot, + rnti, +@@ -1486,6 +1491,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) + ps->nrOfSymbols, + ps->ul_dmrs_symb_pos, + sched_pusch->mcs, ++ ps->nrOfLayers, ++ ps->num_dmrs_cdm_grps_no_data, + sched_pusch->tb_size, + harq_id, + cur_harq->round, +@@ -1532,17 +1539,18 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) + pusch_pdu->qam_mod_order = sched_pusch->Qm; + pusch_pdu->mcs_index = sched_pusch->mcs; + pusch_pdu->mcs_table = ps->mcs_table; +- pusch_pdu->transform_precoding = ps->transform_precoding; ++ pusch_pdu->transformPrecoder = ps->transformPrecoder; + if (ps->pusch_Config && ps->pusch_Config->dataScramblingIdentityPUSCH) + pusch_pdu->data_scrambling_id = *ps->pusch_Config->dataScramblingIdentityPUSCH; + else + pusch_pdu->data_scrambling_id = *scc->physCellId; +- pusch_pdu->nrOfLayers = 1; ++ pusch_pdu->nrOfLayers = ps->nrOfLayers; ++ pusch_pdu->num_dmrs_cdm_grps_no_data = ps->num_dmrs_cdm_grps_no_data; + + /* FAPI: DMRS */ + pusch_pdu->ul_dmrs_symb_pos = ps->ul_dmrs_symb_pos; + pusch_pdu->dmrs_config_type = ps->dmrs_config_type; +- if (pusch_pdu->transform_precoding) { // transform precoding disabled ++ if (pusch_pdu->transformPrecoder) { // transform precoding disabled + long *scramblingid=NULL; + if (ps->NR_DMRS_UplinkConfig && pusch_pdu->scid == 0) + scramblingid = ps->NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0; +@@ -1562,7 +1570,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) + } + pusch_pdu->scid = 0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1] + pusch_pdu->num_dmrs_cdm_grps_no_data = ps->num_dmrs_cdm_grps_no_data; +- pusch_pdu->dmrs_ports = 1; ++ pusch_pdu->dmrs_ports = ((1<nrOfLayers) - 1); + + /* FAPI: Pusch Allocation in frequency domain */ + pusch_pdu->resource_alloc = 1; //type 1 +@@ -1588,7 +1596,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) + LOG_D(NR_MAC,"PUSCH PDU : data_scrambling_identity %x, dmrs_scrambling_id %x\n",pusch_pdu->data_scrambling_id,pusch_pdu->ul_dmrs_scrambling_id); + /* TRANSFORM PRECODING --------------------------------------------------------*/ + +- if (pusch_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled){ ++ if (pusch_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled){ + + // U as specified in section 6.4.1.1.1.2 in 38.211, if sequence hopping and group hopping are disabled + pusch_pdu->dfts_ofdm.low_papr_group_number = pusch_pdu->pusch_identity % 30; +diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +index 91221276b0..8a560580c9 100644 +--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h ++++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +@@ -298,6 +298,7 @@ void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc, + long dci_format, + int tda, + uint8_t num_dmrs_cdm_grps_no_data, ++ uint8_t nrOfLayers, + NR_pusch_semi_static_t *ps); + + uint8_t nr_get_tpc(int target, uint8_t cqi, int incr); +diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +index 27f42f4b1d..66b10dad42 100644 +--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h ++++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +@@ -318,13 +318,14 @@ typedef struct NR_sched_pucch { + typedef struct NR_pusch_semi_static_t { + int dci_format; + int time_domain_allocation; ++ uint8_t nrOfLayers; + uint8_t num_dmrs_cdm_grps_no_data; + + int startSymbolIndex; + int nrOfSymbols; + + NR_PUSCH_Config_t *pusch_Config; +- uint8_t transform_precoding; ++ uint8_t transformPrecoder; + uint8_t mcs_table; + + long mapping_type; +diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c +index ff6923429e..52d03b5e56 100755 +--- a/openair2/RRC/NR/MESSAGES/asn1_msg.c ++++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c +@@ -1867,6 +1867,7 @@ int16_t do_RRCReconfiguration( + // 1, + // 1, + // carrier->pdsch_AntennaPorts, ++ // carrier->pusch_AntennaPorts, + // carrier->initial_csi_index[ue_context_p->local_uid + 1], + // ue_context_pP->local_uid); + +diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h +index 9465b9b4b0..6a94450450 100644 +--- a/openair2/RRC/NR/nr_rrc_proto.h ++++ b/openair2/RRC/NR/nr_rrc_proto.h +@@ -79,6 +79,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco + int scg_id, + int servCellIndex, + int dl_antenna_ports, ++ int ul_antenna_ports, + int do_csirs, + int initial_csi_index, + int uid); +@@ -90,6 +91,7 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon + NR_RRCReconfiguration_IEs_t *reconfig, + NR_CellGroupConfig_t *secondaryCellGroup, + int dl_antenna_ports, ++ int ul_antenna_ports, + int do_csirs, + int initial_csi_index, + int uid); +diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c +index f9fce48f41..22e43cbb6a 100644 +--- a/openair2/RRC/NR/rrc_gNB_nsa.c ++++ b/openair2/RRC/NR/rrc_gNB_nsa.c +@@ -241,6 +241,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ + reconfig_ies, + ue_context_p->ue_context.secondaryCellGroup, + carrier->pdsch_AntennaPorts, ++ carrier->pusch_AntennaPorts, + carrier->do_CSIRS, + carrier->initial_csi_index[ue_context_p->local_uid + 1], + ue_context_p->local_uid); +@@ -250,6 +251,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ + reconfig_ies, + ue_context_p->ue_context.secondaryCellGroup, + carrier->pdsch_AntennaPorts, ++ carrier->pusch_AntennaPorts, + carrier->do_CSIRS, + carrier->initial_csi_index[ue_context_p->local_uid + 1], + ue_context_p->local_uid); +@@ -348,7 +350,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_AntennaPorts, + rrc->carrier.sib1_tda, + rrc->carrier.servingcellconfigcommon, + &rrc->carrier.mib, +diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c +index 980bd39c37..d03f361502 100644 +--- a/openair2/RRC/NR/rrc_gNB_reconfig.c ++++ b/openair2/RRC/NR/rrc_gNB_reconfig.c +@@ -55,6 +55,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco + int scg_id, + int servCellIndex, + int dl_antenna_ports, ++ int ul_antenna_ports, + int do_csirs, + int initial_csi_index, + int uid) { +@@ -745,14 +746,14 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco + pusch_Config->codebookSubset=calloc(1,sizeof(*pusch_Config->codebookSubset)); + *pusch_Config->codebookSubset = NR_PUSCH_Config__codebookSubset_nonCoherent; + pusch_Config->maxRank=calloc(1,sizeof(*pusch_Config->maxRank)); +- *pusch_Config->maxRank= 1; ++ *pusch_Config->maxRank= ul_antenna_ports; + pusch_Config->rbg_Size=NULL; + pusch_Config->uci_OnPUSCH=NULL; + pusch_Config->tp_pi2BPSK=NULL; + + /*------------------------------TRANSFORM PRECODING- -----------------------------------------------------------------------*/ + +- uint8_t transform_precoding = NR_PUSCH_Config__transformPrecoder_disabled; ++ uint8_t transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled; + + // TBD: configure this from .conf file, Dedicated params cannot yet be configured in .conf file. + // Enable this to test transform precoding enabled from dedicated config. +@@ -764,13 +765,13 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco + + if (pusch_Config->transformPrecoder == NULL) { + if (servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder != NULL) +- transform_precoding = NR_PUSCH_Config__transformPrecoder_enabled; ++ transformPrecoder = NR_PUSCH_Config__transformPrecoder_enabled; + } + else +- transform_precoding = *pusch_Config->transformPrecoder; ++ transformPrecoder = *pusch_Config->transformPrecoder; + + +- if (transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled ) { ++ if (transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled ) { + /* Enable DMRS uplink config for transform precoding enabled */ + NR_DMRS_UplinkConfig->transformPrecodingEnabled = calloc(1,sizeof(*NR_DMRS_UplinkConfig->transformPrecodingEnabled)); + NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity = NULL; +@@ -1348,6 +1349,7 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon + NR_RRCReconfiguration_IEs_t *reconfig, + NR_CellGroupConfig_t *secondaryCellGroup, + int dl_antenna_ports, ++ int ul_antenna_ports, + int do_csirs, + int initial_csi_index, + int uid) { +@@ -1363,6 +1365,7 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon + 1, + 1, + dl_antenna_ports, ++ ul_antenna_ports, + do_csirs, + initial_csi_index, + uid); +diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c +index 13945998d7..20faa86591 100644 +--- a/targets/ARCH/rfsimulator/simulator.c ++++ b/targets/ARCH/rfsimulator/simulator.c +@@ -429,7 +429,7 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp + if (!alreadyLocked) + pthread_mutex_lock(&Sockmutex); + +- LOG_D(HW,"sending %d samples at time: %ld\n", nsamps, timestamp); ++ LOG_D(HW,"sending %d samples at time: %ld, nbAnt %d\n", nsamps, timestamp, nbAnt); + + for (int i=0; ibuf[i]; +@@ -623,7 +623,7 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest + } + + rfsimulator_state_t *t = device->priv; +- LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextTimestamp+nsamps); ++ LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld, nbAnt %d\n", nsamps, t->nextTimestamp+nsamps, nbAnt); + // deliver data from received data + // check if a UE is connected + int first_sock; +@@ -728,6 +728,7 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest + + for (int a=0; achannel_model != NULL ) // apply a channel model ++ { + rxAddInput( ptr->circularBuf, (struct complex16 *) samplesVoid[a], + a, + ptr->channel_model, +@@ -735,11 +736,21 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest + t->nextTimestamp, + CirSize + ); +- else { // no channel modeling ++ } ++ else ++ { // no channel modeling ++ ++ #if 0 + double H_awgn_mimo[4][4] ={{1.0, 0.5, 0.25, 0.125},//rx 0 + {0.5, 1.0, 0.5, 0.25}, //rx 1 + {0.25, 0.5, 1.0, 0.5}, //rx 2 + {0.125, 0.25, 0.5, 1.0}};//rx 3 ++ #else ++ double H_awgn_mimo[4][4] ={{1.0, 0.0, 0.0, 0.0},//rx 0 ++ {0.0, 1.0, 0.0, 0.0},//rx 1 ++ {0.0, 0.0, 1.0, 0.0},//rx 2 ++ {0.0, 0.0, 0.0, 1.0}};//rx 3 ++ #endif + + sample_t *out=(sample_t *)samplesVoid[a]; + int nbAnt_tx = ptr->th.nbAnt;//number of Tx antennas diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h index c02155326b..1238b43c27 100644 --- a/executables/nr-softmodem-common.h +++ b/executables/nr-softmodem-common.h @@ -67,6 +67,7 @@ #define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n" #define CONFIG_HLP_DLMCS_PHYTEST "Set the downlink MCS for PHYTEST mode\n" #define CONFIG_HLP_DLNL_PHYTEST "Set the downlink nrOfLayers for PHYTEST mode\n" +#define CONFIG_HLP_ULNL_PHYTEST "Set the uplink nrOfLayers for PHYTEST mode\n" #define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n" #define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n" #define CONFIG_HLP_ULMCS_PHYTEST "Set the uplink MCS for PHYTEST mode\n" diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h index 896c363cbf..a11572c0e1 100644 --- a/executables/nr-softmodem.h +++ b/executables/nr-softmodem.h @@ -23,6 +23,7 @@ {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \ {"m" , CONFIG_HLP_DLMCS_PHYTEST,0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ {"l" , CONFIG_HLP_DLNL_PHYTEST,0, uptr:&target_dl_Nl, defintval:0, TYPE_UINT, 0}, \ + {"L" , CONFIG_HLP_ULNL_PHYTEST,0, uptr:&target_ul_Nl, defintval:0, TYPE_UINT, 0}, \ {"t" , CONFIG_HLP_ULMCS_PHYTEST,0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ {"M" , CONFIG_HLP_DLBW_PHYTEST,0, uptr:&target_dl_bw, defintval:0, TYPE_UINT, 0}, \ {"T" , CONFIG_HLP_ULBW_PHYTEST,0, uptr:&target_ul_bw, defintval:0, TYPE_UINT, 0}, \ @@ -36,6 +37,7 @@ extern threads_t threads; extern uint32_t target_dl_mcs; extern uint32_t target_dl_Nl; +extern uint32_t target_ul_Nl; extern uint32_t target_ul_mcs; extern uint32_t target_dl_bw; extern uint32_t target_ul_bw; diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 60ff40abeb..a23f91b1dd 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -278,7 +278,7 @@ void processSlotTX(void *arg) { int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_slot_tx); uint8_t gNB_id = 0; - LOG_D(PHY,"%d.%d => slot type %d\n",proc->frame_tx,proc->nr_slot_tx,tx_slot_type); + LOG_D(PHY,"processSlotTX %d.%d => slot type %d\n",proc->frame_tx,proc->nr_slot_tx,tx_slot_type); if (tx_slot_type == NR_UPLINK_SLOT || tx_slot_type == NR_MIXED_SLOT){ // trigger L2 to run ue_scheduler thru IF module @@ -372,7 +372,8 @@ void processSlotRX(void *arg) { LOG_D(PHY, "Sending Uplink data \n"); nr_ue_pusch_common_procedures(UE, proc->nr_slot_tx, - &UE->frame_parms,1); + &UE->frame_parms, + UE->frame_parms.nb_antennas_tx); } if (UE->UE_mode[gNB_id] > NOT_SYNCHED && UE->UE_mode[gNB_id] < PUSCH) { diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index ad5ea982c9..57fd284601 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -465,8 +465,11 @@ int main( int argc, char **argv ) { memset(UE[CC_id],0,sizeof(PHY_VARS_NR_UE)); set_options(CC_id, UE[CC_id]); - NR_UE_MAC_INST_t *mac = get_mac_inst(0); - + NR_DL_FRAME_PARMS *fp = &UE[CC_id]->frame_parms; + NR_UE_MAC_INST_t *mac = get_mac_inst(0); + + mac->phy_config.config_req.carrier_config.num_tx_ant = fp->nb_antennas_tx; + if (get_softmodem_params()->sa) { uint16_t nr_band = get_band(downlink_frequency[CC_id][0],uplink_frequency_offset[CC_id][0]); mac->nr_band = nr_band; diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 0e923931ad..8b93417cb0 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -298,9 +298,10 @@ typedef struct uint8_t qam_mod_order; uint8_t mcs_index; uint8_t mcs_table; - uint8_t transform_precoding; + uint8_t transformPrecoder; uint16_t data_scrambling_id; uint8_t nrOfLayers; + uint8_t Tpmi; //DMRS uint16_t ul_dmrs_symb_pos; uint8_t dmrs_config_type; diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index 9d245446c8..58ff9037ce 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -1208,9 +1208,10 @@ typedef struct uint8_t qam_mod_order; uint8_t mcs_index; uint8_t mcs_table; - uint8_t transform_precoding; + uint8_t transformPrecoder; uint16_t data_scrambling_id; uint8_t nrOfLayers; + uint8_t Tpmi; //DMRS uint16_t ul_dmrs_symb_pos; uint8_t dmrs_config_type; diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c index 7cb74f8562..473b0900bc 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -941,9 +941,10 @@ static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, ui push8(pusch_pdu->qam_mod_order, ppWritePackedMsg, end) && push8(pusch_pdu->mcs_index, ppWritePackedMsg, end) && push8(pusch_pdu->mcs_table, ppWritePackedMsg, end) && - push8(pusch_pdu->transform_precoding, ppWritePackedMsg, end) && + push8(pusch_pdu->transformPrecoder, ppWritePackedMsg, end) && push16(pusch_pdu->data_scrambling_id, ppWritePackedMsg, end) && push8(pusch_pdu->nrOfLayers, ppWritePackedMsg, end) && + push8(pusch_pdu->Tpmi, ppWritePackedMsg, end) && push16(pusch_pdu->ul_dmrs_symb_pos, ppWritePackedMsg, end) && push8(pusch_pdu->dmrs_config_type, ppWritePackedMsg, end) && push16(pusch_pdu->ul_dmrs_scrambling_id, ppWritePackedMsg, end) && @@ -4445,9 +4446,10 @@ static uint8_t unpack_ul_tti_request_pusch_pdu(void *tlv, uint8_t **ppReadPacked pull8(ppReadPackedMsg, &pusch_pdu->qam_mod_order, end) && pull8(ppReadPackedMsg, &pusch_pdu->mcs_index, end) && pull8(ppReadPackedMsg, &pusch_pdu->mcs_table, end) && - pull8(ppReadPackedMsg, &pusch_pdu->transform_precoding, end) && + pull8(ppReadPackedMsg, &pusch_pdu->transformPrecoder, end) && pull16(ppReadPackedMsg, &pusch_pdu->data_scrambling_id, end) && pull8(ppReadPackedMsg, &pusch_pdu->nrOfLayers, end) && + pull8(ppReadPackedMsg, &pusch_pdu->Tpmi, end) && pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_symb_pos, end) && pull8(ppReadPackedMsg, &pusch_pdu->dmrs_config_type, end) && pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_scrambling_id, end) && diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index cd4848ea8c..2ac3230215 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -276,11 +276,21 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, pusch_vars[ULSCH_id]->ul_ch_magb0 = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); pusch_vars[ULSCH_id]->ul_ch_mag = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); pusch_vars[ULSCH_id]->ul_ch_magb = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); - pusch_vars[ULSCH_id]->rho = (int32_t **)malloc16_clear(n_buf*sizeof(int32_t*) ); + pusch_vars[ULSCH_id]->rho = (int32_t ***)malloc16_clear(Prx*sizeof(int32_t**) ); + pusch_vars[ULSCH_id]->llr_layers = (int16_t **)malloc16(max_ul_mimo_layers*sizeof(int32_t *) ); for (i=0; irxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); pusch_vars[ULSCH_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); + pusch_vars[ULSCH_id]->rho[i] = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS*sizeof(int32_t*)); + + for (int j=0; j< max_ul_mimo_layers; j++) + { + for (int k=0; krho[i][j*max_ul_mimo_layers+k]=(int32_t *)malloc16_clear( sizeof(int32_t) * fp->N_RB_UL*12*7*2 ); + } + } } for (i=0; iul_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot ); @@ -293,8 +303,12 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, pusch_vars[ULSCH_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); pusch_vars[ULSCH_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); pusch_vars[ULSCH_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); - pusch_vars[ULSCH_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); - pusch_vars[ULSCH_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) ); + pusch_vars[ULSCH_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); + } + + for (i=0; i< max_ul_mimo_layers; i++) + { + pusch_vars[ULSCH_id]->llr_layers[i] = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear } pusch_vars[ULSCH_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear pusch_vars[ULSCH_id]->ul_valid_re_per_slot = (int16_t *)malloc16_clear( sizeof(int16_t)*fp->symbols_per_slot); diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index 4024ed1617..169db48e69 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -41,7 +41,7 @@ int nr_phy_init_RU(RU_t *ru) { int p; int re; - LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d\n",ru_if_types[ru->if_south],ru->nb_tx); + LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d, nb_rx %d\n",ru_if_types[ru->if_south],ru->nb_tx, ru->nb_rx); nfapi_nr_config_request_scf_t *cfg; ru->nb_log_antennas=0; diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index b60e77e814..11fb6e7d61 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -124,7 +124,8 @@ void phy_init_nr_ue_PUSCH(NR_UE_PUSCH *const pusch, AssertFatal( pusch, "pusch==0" ); for (int i=0; itxdataF_layers[i] = (int32_t *)malloc16_clear(NR_MAX_PUSCH_ENCODED_LENGTH*sizeof(int32_t)); + pusch->txdataF_layers[i] = (int32_t *)malloc16_clear((NR_MAX_PUSCH_ENCODED_LENGTH)*sizeof(int32_t *)); + pusch->txdataF_precoding[i] = (int32_t *)malloc16_clear((NR_MAX_PUSCH_ENCODED_LENGTH)*sizeof(int32_t *)); } } @@ -143,7 +144,7 @@ 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; - 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_I(PHY, "Initializing UE vars (abstraction %u) for UE 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_gNB_INST); phy_init_nr_top(ue); // many memory allocation sizes are hard coded diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 1f164748bf..9a432e8615 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -110,7 +110,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, fr = filt8_r1; fmm = filt8_mm1; fml = filt8_ml1; - fmr = filt8_m1; + fmr = filt8_mm1; fdcl = filt8_dcl1; fdcr = filt8_dcr1; fdclh = filt8_dcl1_h; @@ -129,9 +129,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, //------------------generate DMRS------------------// - // transform precoding = 1 means disabled - if (pusch_pdu->transform_precoding == 1) { - nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, + if (pusch_pdu->transformPrecoder == transformPrecoder_disabled) { + nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], (1000+p), 0, nb_rb_pusch, (pusch_pdu->bwp_start + pusch_pdu->rb_start)*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type); } else { // if transform precoding or SC-FDMA is enabled in Uplink @@ -291,7 +290,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, printf("pilot %u : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]); printf("data %u : rxF - > (%d,%d) (%d)\n",pilot_cnt,rxF[2],rxF[3],dBc(rxF[2],rxF[3])); #endif - multadd_real_vector_complex_scalar(fml, + multadd_real_vector_complex_scalar(fm, ch, ul_ch, 8); diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 4fed3a468f..87e4d57362 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -137,21 +137,22 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, @param nb_rb_pusch The number of RBs allocated (used for Resource Allocation Type 1 in NR) @param frame_parms, Pointer to frame descriptor structure */ -void nr_ulsch_extract_rbs_single(int32_t **rxdataF, - NR_gNB_PUSCH *pusch_vars, - int slot, - unsigned char symbol, - uint8_t is_dmrs_symbol, - nfapi_nr_pusch_pdu_t *pusch_pdu, - NR_DL_FRAME_PARMS *frame_parms); +void nr_ulsch_extract_rbs(int32_t **rxdataF, + NR_gNB_PUSCH *pusch_vars, + int slot, + unsigned char symbol, + uint8_t is_dmrs_symbol, + nfapi_nr_pusch_pdu_t *pusch_pdu, + NR_DL_FRAME_PARMS *frame_parms); void nr_ulsch_scale_channel(int32_t **ul_ch_estimates_ext, NR_DL_FRAME_PARMS *frame_parms, NR_gNB_ULSCH_t **ulsch_gNB, - uint8_t symbol, - uint8_t start_symbol, - uint16_t nb_rb, - pusch_dmrs_type_t pusch_dmrs_type); + uint8_t symbol, + uint8_t is_dmrs_symbol, + uint32_t len, + uint8_t nrOfLayers, + uint16_t nb_rb); /** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal @param ul_ch_estimates_ext Channel estimates in allocated RBs @@ -185,9 +186,10 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, int **ul_ch_mag, int **ul_ch_magb, int **rxdataF_comp, - int **rho, + int ***rho, NR_DL_FRAME_PARMS *frame_parms, unsigned char symbol, + int length, uint8_t is_dmrs_symbol, unsigned char mod_order, uint8_t nrOfLayers, @@ -255,8 +257,8 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, @param mod_order modulation order */ void nr_ulsch_compute_llr(int32_t *rxdataF_comp, - int32_t **ul_ch_mag, - int32_t **ul_ch_magb, + int32_t *ul_ch_mag, + int32_t *ul_ch_magb, int16_t *ulsch_llr, uint32_t nb_rb, uint32_t nb_re, diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c index 4278338dbc..3ea19a9970 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c @@ -137,6 +137,38 @@ void nr_ulsch_unscrambling_optim(int16_t* llr, #endif } +void nr_ulsch_layer_demapping(int16_t *llr_cw, + uint8_t Nl, + uint8_t mod_order, + uint32_t length, + int16_t **llr_layers) +{ + + switch (Nl) { + + case 1: + memcpy((void*)llr_cw, (void*)llr_layers[0], (length)*sizeof(int16_t)); + break; + + case 2: + case 3: + case 4: + for (int i=0; i<(length/Nl/mod_order); i++) + { + for (int l=0; lnumber_of_nr_ulsch_max;i++) { diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h index 80c10d74b1..0e660351ae 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h @@ -82,6 +82,12 @@ void nr_ulsch_unscrambling_optim(int16_t* llr, uint32_t Nid, uint32_t n_RNTI); +void nr_ulsch_layer_demapping(int16_t *llr_cw, + uint8_t Nl, + uint8_t mod_order, + uint32_t length, + int16_t **llr_layers); + void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 28dd5ab219..8314c83ad9 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -302,26 +302,27 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) } -void nr_ulsch_extract_rbs_single(int32_t **rxdataF, - NR_gNB_PUSCH *pusch_vars, - int slot, - unsigned char symbol, - uint8_t is_dmrs_symbol, - nfapi_nr_pusch_pdu_t *pusch_pdu, - NR_DL_FRAME_PARMS *frame_parms) +void nr_ulsch_extract_rbs(int32_t **rxdataF, + NR_gNB_PUSCH *pusch_vars, + int slot, + unsigned char symbol, + uint8_t is_dmrs_symbol, + nfapi_nr_pusch_pdu_t *pusch_pdu, + NR_DL_FRAME_PARMS *frame_parms) { unsigned short start_re, re, nb_re_pusch; - unsigned char aarx; + unsigned char aarx, aatx; uint32_t rxF_ext_index = 0; uint32_t ul_ch0_ext_index = 0; uint32_t ul_ch0_index = 0; - uint8_t k_prime; - uint16_t n; + //uint8_t k_prime; + //uint16_t n; int16_t *rxF,*rxF_ext; int *ul_ch0,*ul_ch0_ext; - uint8_t delta = 0; + //uint8_t delta = 0; int soffset = (slot&3)*frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size; + #ifdef DEBUG_RB_EXT printf("--------------------symbol = %d-----------------------\n", symbol); @@ -329,7 +330,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, #endif - uint8_t is_dmrs_re; + uint8_t is_data_re; start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start + pusch_pdu->bwp_start) * NR_NB_SC_PER_RB)%frame_parms->ofdm_symbol_size; nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size; #ifdef __AVX2__ @@ -338,64 +339,95 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, int nb_re_pusch2 = nb_re_pusch; #endif - for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { + for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) + { rxF = (int16_t *)&rxdataF[aarx][soffset+(symbol * frame_parms->ofdm_symbol_size)]; rxF_ext = (int16_t *)&pusch_vars->rxdataF_ext[aarx][symbol * nb_re_pusch2]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6 - - ul_ch0 = &pusch_vars->ul_ch_estimates[aarx][pusch_vars->dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available - - ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aarx][symbol*nb_re_pusch2]; - - n = 0; - k_prime = 0; - rxF_ext_index = 0; - ul_ch0_ext_index = 0; - ul_ch0_index = 0; - - if (is_dmrs_symbol == 0) { + + if (is_dmrs_symbol == 0) + { // //rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]); - if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size) { + if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size) + { memcpy1((void*)rxF_ext, (void*)&rxF[start_re*2], nb_re_pusch*sizeof(int32_t)); - } else { - int neg_length = frame_parms->ofdm_symbol_size-start_re; - int pos_length = nb_re_pusch-neg_length; + } + else + { + int neg_length = frame_parms->ofdm_symbol_size-start_re; + int pos_length = nb_re_pusch-neg_length; + memcpy1((void*)rxF_ext,(void*)&rxF[start_re*2],neg_length*sizeof(int32_t)); + memcpy1((void*)&rxF_ext[2*neg_length],(void*)rxF,pos_length*sizeof(int32_t)); + } - memcpy1((void*)rxF_ext,(void*)&rxF[start_re*2],neg_length*sizeof(int32_t)); - memcpy1((void*)&rxF_ext[2*neg_length],(void*)rxF,pos_length*sizeof(int32_t)); + #ifdef SUPPORT_PMI_MATRIC + for (aatx = 0; aatx < pusch_pdu->nrOfLayers; aatx++) + #else + aatx = aarx; + #endif + { + ul_ch0 = &pusch_vars->ul_ch_estimates[aatx*frame_parms->nb_antennas_rx+aarx][pusch_vars->dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available + ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_re_pusch2]; + + memcpy1((void*)ul_ch0_ext,(void*)ul_ch0,nb_re_pusch*sizeof(int32_t)); } - memcpy1((void*)ul_ch0_ext,(void*)ul_ch0,nb_re_pusch*sizeof(int32_t)); } - else { - for (re = 0; re < nb_re_pusch; re++) { + else + { + #ifdef SUPPORT_PMI_MATRIC + for (aatx = 0; aatx < pusch_pdu->nrOfLayers; aatx++) + #else + aatx = aarx; + #endif + { + ul_ch0 = &pusch_vars->ul_ch_estimates[aatx*frame_parms->nb_antennas_rx+aarx][pusch_vars->dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available + ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_re_pusch2]; - is_dmrs_re = (re == get_dmrs_freq_idx_ul(n, k_prime, delta, pusch_pdu->dmrs_config_type)); + //n = 0; + //k_prime = 0; + rxF_ext_index = 0; + ul_ch0_ext_index = 0; + ul_ch0_index = 0; + + for (re = 0; re < nb_re_pusch; re++) + { + uint16_t k= start_re+re; + + is_data_re = allowed_xlsch_re_in_dmrs_symbol(k, start_re, frame_parms->ofdm_symbol_size, pusch_pdu->num_dmrs_cdm_grps_no_data, pusch_pdu->dmrs_config_type); + + if (++k >= frame_parms->ofdm_symbol_size) + { + k -= frame_parms->ofdm_symbol_size; + } -#ifdef DEBUG_RB_EXT - printf("re = %d, kprime %d, n %d, is_dmrs_symbol = %d, symbol = %d\n", re, k_prime, n, is_dmrs_symbol, symbol); -#endif + #ifdef DEBUG_RB_EXT + printf("re = %d, kprime %d, n %d, is_dmrs_symbol = %d, symbol = %d\n", re, k_prime, n, is_dmrs_symbol, symbol); + #endif - /* save only data and respective channel estimates */ - if (is_dmrs_re == 0) { - rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]); - rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]); - ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index]; + /* save only data and respective channel estimates */ + if (is_data_re == 1) + { + if (aatx == aarx) + { + rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]); + rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]); + rxF_ext_index +=2; + } + + ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index]; + ul_ch0_ext_index++; -#ifdef DEBUG_RB_EXT - printf("dmrs symb %d: rxF_ext[%d] = (%d,%d), ul_ch0_ext[%d] = (%d,%d)\n", + #ifdef DEBUG_RB_EXT + printf("dmrs symb %d: rxF_ext[%d] = (%d,%d), ul_ch0_ext[%d] = (%d,%d)\n", is_dmrs_symbol,rxF_ext_index>>1, rxF_ext[rxF_ext_index],rxF_ext[rxF_ext_index+1], ul_ch0_ext_index, ((int16_t*)&ul_ch0_ext[ul_ch0_ext_index])[0], ((int16_t*)&ul_ch0_ext[ul_ch0_ext_index])[1]); -#endif - ul_ch0_ext_index++; - rxF_ext_index +=2; - } else { - n += k_prime; - k_prime ^= 1; + #endif + } + ul_ch0_index++; } - ul_ch0_index++; } } } @@ -406,16 +438,19 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, NR_gNB_ULSCH_t **ulsch_gNB, uint8_t symbol, uint8_t is_dmrs_symbol, - unsigned short nb_rb, - pusch_dmrs_type_t pusch_dmrs_type) + uint32_t len, + uint8_t nrOfLayers, + unsigned short nb_rb) { #if defined(__x86_64__)||defined(__i386__) short rb, ch_amp; - unsigned char aarx; + unsigned char aarx,aatx; __m128i *ul_ch128, ch_amp128; + uint32_t nb_rb_0 = len/12 + ((len%12)?1:0); + // Determine scaling amplitude based the symbol ch_amp = 1024*8; //((pilots) ? (ulsch_gNB[0]->sqrt_rho_b) : (ulsch_gNB[0]->sqrt_rho_a)); @@ -431,35 +466,26 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, int off = 0; #endif - 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))]; - - if (is_dmrs_symbol==1){ - if (pusch_dmrs_type == pusch_dmrs_type1) - nb_rb = nb_rb>>1; - else - nb_rb = (2*nb_rb)/3; - } - - for (rb=0;rbnb_antennas_rx; aarx++) + { + ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*NR_NB_SC_PER_RB))]; + for (rb=0;rb < nb_rb_0;rb++) + { ul_ch128[0] = _mm_mulhi_epi16(ul_ch128[0], ch_amp128); ul_ch128[0] = _mm_slli_epi16(ul_ch128[0], 3); ul_ch128[1] = _mm_mulhi_epi16(ul_ch128[1], ch_amp128); ul_ch128[1] = _mm_slli_epi16(ul_ch128[1], 3); - if (is_dmrs_symbol) { - ul_ch128+=2; - } else { - ul_ch128[2] = _mm_mulhi_epi16(ul_ch128[2], ch_amp128); - ul_ch128[2] = _mm_slli_epi16(ul_ch128[2], 3); - ul_ch128+=3; - - } + ul_ch128[2] = _mm_mulhi_epi16(ul_ch128[2], ch_amp128); + ul_ch128[2] = _mm_slli_epi16(ul_ch128[2], 3); + ul_ch128+=3; } - } + } +} #endif } @@ -481,6 +507,8 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, int16_t x = factor2(len); int16_t y = (len)>>x; + + uint32_t nb_rb_0 = len/12 + ((len%12)?1:0); #ifdef __AVX2__ int off = ((nb_rb&1) == 1)? 4:0; @@ -489,13 +517,16 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, #endif for (aatx = 0; aatx < nrOfLayers; aatx++) - for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { + { + for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) + { //clear average level avg128U = _mm_setzero_si128(); ul_ch128=(__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; - for (rb = 0; rb < len/12; rb++) { + for (rb = 0; rb < nb_rb_0; rb++) + { avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[0], ul_ch128[0]), x)); avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[1], ul_ch128[1]), x)); avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[2], ul_ch128[2]), x)); @@ -508,7 +539,8 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, ((int32_t*)&avg128U)[3]) / y; } - + } + _mm_empty(); _m_empty(); @@ -520,7 +552,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, int16x4_t *ul_ch128; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - + uint32_t nb_rb_0 = len/12 + ((len%12)?1:0); for (aatx=0; aatxnb_antennas_rx; aarx++) { //clear average level @@ -529,7 +561,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, ul_ch128 = (int16x4_t *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*frame_parms->N_RB_UL*12]; - for (rb = 0; rb < nb_rb; rb++) { + for (rb = 0; rb < nb_rb_0; rb++) { // printf("rb %d : ",rb); // print_shorts("ch",&ul_ch128[0]); avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[0], ul_ch128[0])); @@ -568,14 +600,20 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, #endif } + + +//============================================================================================== +// Pre-processing for LLR computation +//============================================================================================== void nr_ulsch_channel_compensation(int **rxdataF_ext, int **ul_ch_estimates_ext, int **ul_ch_mag, int **ul_ch_magb, int **rxdataF_comp, - int **rho, + int ***rho, NR_DL_FRAME_PARMS *frame_parms, unsigned char symbol, + int length, uint8_t is_dmrs_symbol, unsigned char mod_order, uint8_t nrOfLayers, @@ -637,20 +675,24 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128={0},QAM_amp128b={0}; QAM_amp128b = _mm_setzero_si128(); - for (aatx=0; aatxnb_antennas_rx; aarx++) { - + for (aarx=0; aarxnb_antennas_rx; aarx++) + { ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; ul_ch_mag128 = (__m128i *)&ul_ch_mag[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; ul_ch_mag128b = (__m128i *)&ul_ch_magb[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; @@ -658,8 +700,10 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, rxdataF_comp128 = (__m128i *)&rxdataF_comp[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; - for (rb=0; rb2) { + for (rb=0; rb2) + { // get channel amplitude if not QPSK //print_shorts("ch:",(int16_t*)&ul_ch128[0]); @@ -679,6 +723,8 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, ul_ch_mag128[0] = _mm_mulhi_epi16(ul_ch_mag128[0],QAM_amp128); ul_ch_mag128[0] = _mm_slli_epi16(ul_ch_mag128[0],1); + ul_ch_mag128b[0] = _mm_mulhi_epi16(ul_ch_mag128b[0],QAM_amp128b); + ul_ch_mag128b[0] = _mm_slli_epi16(ul_ch_mag128b[0],1); // print_ints("ch: = ",(int32_t*)&mmtmpD0); // print_shorts("QAM_amp:",(int16_t*)&QAM_amp128); // print_shorts("mag:",(int16_t*)&ul_ch_mag128[0]); @@ -687,30 +733,24 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, ul_ch_mag128b[1] = ul_ch_mag128[1]; ul_ch_mag128[1] = _mm_mulhi_epi16(ul_ch_mag128[1],QAM_amp128); ul_ch_mag128[1] = _mm_slli_epi16(ul_ch_mag128[1],1); - - if (is_dmrs_symbol==0) { - mmtmpD0 = _mm_madd_epi16(ul_ch128[2],ul_ch128[2]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); - - ul_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); - ul_ch_mag128b[2] = ul_ch_mag128[2]; - - ul_ch_mag128[2] = _mm_mulhi_epi16(ul_ch_mag128[2],QAM_amp128); - ul_ch_mag128[2] = _mm_slli_epi16(ul_ch_mag128[2],1); - } - - ul_ch_mag128b[0] = _mm_mulhi_epi16(ul_ch_mag128b[0],QAM_amp128b); - ul_ch_mag128b[0] = _mm_slli_epi16(ul_ch_mag128b[0],1); - - - ul_ch_mag128b[1] = _mm_mulhi_epi16(ul_ch_mag128b[1],QAM_amp128b); + + ul_ch_mag128b[1] = _mm_mulhi_epi16(ul_ch_mag128b[1],QAM_amp128); ul_ch_mag128b[1] = _mm_slli_epi16(ul_ch_mag128b[1],1); - if (is_dmrs_symbol==0) { - ul_ch_mag128b[2] = _mm_mulhi_epi16(ul_ch_mag128b[2],QAM_amp128b); - ul_ch_mag128b[2] = _mm_slli_epi16(ul_ch_mag128b[2],1); - } + mmtmpD0 = _mm_madd_epi16(ul_ch128[2],ul_ch128[2]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); + + ul_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); + ul_ch_mag128b[2] = ul_ch_mag128[2]; + + ul_ch_mag128[2] = _mm_mulhi_epi16(ul_ch_mag128[2],QAM_amp128); + ul_ch_mag128[2] = _mm_slli_epi16(ul_ch_mag128[2],1); + + + ul_ch_mag128b[2] = _mm_mulhi_epi16(ul_ch_mag128b[2],QAM_amp128b); + ul_ch_mag128b[2] = _mm_slli_epi16(ul_ch_mag128b[2],1); + } // multiply by conjugated channel @@ -755,117 +795,157 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, // print_shorts("ch:",ul_ch128+1); // print_shorts("pack:",rxdataF_comp128+1); - if (is_dmrs_symbol==0) { - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(ul_ch128[2],rxdataF128[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[2],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(ul_ch128[2],rxdataF128[2]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[2],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",ul_ch128+2); - // print_shorts("pack:",rxdataF_comp128+2); - - ul_ch128+=3; - ul_ch_mag128+=3; - ul_ch_mag128b+=3; - rxdataF128+=3; - rxdataF_comp128+=3; - } else { // we have a smaller PUSCH in symbols with pilots so skip last group of 4 REs and increment less - ul_ch128+=2; - ul_ch_mag128+=2; - ul_ch_mag128b+=2; - rxdataF128+=2; - rxdataF_comp128+=2; - } + rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + //print_shorts("rx:",rxdataF128+2); + //print_shorts("ch:",ul_ch128+2); + //print_shorts("pack:",rxdataF_comp128+2); + ul_ch128+=3; + ul_ch_mag128+=3; + ul_ch_mag128b+=3; + rxdataF128+=3; + rxdataF_comp128+=3; } } } if (rho) { + //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 - for (aarx=0; aarxnb_antennas_rx; aarx++) { - rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_UL*12]; - ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_UL*12]; - ul_ch128_2 = (__m128i *)&ul_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_UL*12]; + int avg_rho_re[frame_parms->nb_antennas_rx][nrOfLayers*nrOfLayers]; + int avg_rho_im[frame_parms->nb_antennas_rx][nrOfLayers*nrOfLayers]; - for (rb=0; rbnb_antennas_rx; aarx++) + { + for (aatx=0; aatx < nrOfLayers; aatx++) + { + ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; + + for (int atx=0; atx< nrOfLayers; atx++) + { + avg_rho_re[aarx][aatx*nrOfLayers+atx] = 0; + avg_rho_im[aarx][aatx*nrOfLayers+atx] = 0; + rho128 = (__m128i *)&rho[aarx][aatx*nrOfLayers+atx][symbol*(off+(nb_rb*12))]; + ul_ch128_2 = (__m128i *)&ul_ch_estimates_ext[atx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[0],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); - // print_ints("im",&mmtmpD1); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,ul_ch128_2[0]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - // print_ints("im(shift)",&mmtmpD1); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); - rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + 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*nrOfLayers+atx] = 16*avg_rho_re[aarx][aatx*nrOfLayers+atx]/(nb_rb*12); + avg_rho_im[aarx][aatx*nrOfLayers+atx] = 16*avg_rho_im[aarx][aatx*nrOfLayers+atx]/(nb_rb*12); + //printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, aatx,atx, avg_rho_re[aarx][aatx*nb_aatx+atx], avg_rho_im[aarx][aatx*nb_aatx+atx]); + } + } } - } } @@ -1105,19 +1185,23 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, } void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, - int32_t **ul_ch_mag, - int32_t **ul_ch_magb, - uint8_t symbol, - uint16_t nb_rb) { + int32_t **rxdataF_comp, + int32_t **ul_ch_mag, + int32_t **ul_ch_magb, + int32_t ***rho, + uint8_t nrOfLayers, + uint8_t symbol, + uint16_t nb_rb, + int length) { int n_rx = frame_parms->nb_antennas_rx; #if defined(__x86_64__) || defined(__i386__) - __m128i *rxdataF_comp128[1+n_rx],*ul_ch_mag128[1+n_rx],*ul_ch_mag128b[1+n_rx]; + __m128i *rxdataF_comp128[2],*ul_ch_mag128[2],*ul_ch_mag128b[2]; #elif defined(__arm__) int16x8_t *rxdataF_comp128_0,*ul_ch_mag128_0,*ul_ch_mag128_0b; int16x8_t *rxdataF_comp128_1,*ul_ch_mag128_1,*ul_ch_mag128_1b; #endif int32_t i; + uint32_t nb_rb_0 = length/12 + ((length%12)?1:0); #ifdef __AVX2__ int off = ((nb_rb&1) == 1)? 4:0; @@ -1125,23 +1209,34 @@ void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, int off = 0; #endif - if (frame_parms->nb_antennas_rx>1) { -#if defined(__x86_64__) || defined(__i386__) - int nb_re = nb_rb*12; - for (int aa=0;aanb_antennas_rx;aa++) { - rxdataF_comp128[aa] = (__m128i *)&rxdataF_comp[aa][(symbol*(nb_re + off))]; - ul_ch_mag128[aa] = (__m128i *)&ul_ch_mag[aa][(symbol*(nb_re + off))]; - ul_ch_mag128b[aa] = (__m128i *)&ul_ch_magb[aa][(symbol*(nb_re + off))]; - } - for (int aa=1;aanb_antennas_rx;aa++) { - // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) - for (i=0; i 1) + { + #if defined(__x86_64__) || defined(__i386__) + for (int aatx=0; aatxnb_antennas_rx][(symbol*(nb_re + off))]; + ul_ch_mag128[0] = (__m128i *)&ul_ch_mag[aatx*frame_parms->nb_antennas_rx][(symbol*(nb_re + off))]; + ul_ch_mag128b[0] = (__m128i *)&ul_ch_magb[aatx*frame_parms->nb_antennas_rx][(symbol*(nb_re + off))]; + + for (int aa=1;aa < n_rx;aa++) + { + rxdataF_comp128[1] = (__m128i *)&rxdataF_comp[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))]; + ul_ch_mag128[1] = (__m128i *)&ul_ch_mag[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))]; + ul_ch_mag128b[1] = (__m128i *)&ul_ch_magb[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))]; + + // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) + for (i=0; iN_RB_DL*12]; rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12]; ul_ch_mag128_0 = (int16x8_t *)&ul_ch_mag[0][symbol*frame_parms->N_RB_DL*12]; @@ -1156,7 +1251,7 @@ void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, ul_ch_mag128_0b[i] = vhaddq_s16(ul_ch_mag128_0b[i],ul_ch_mag128_1b[i]); rxdataF_comp128_0[i] = vqaddq_s16(rxdataF_comp128_0[i],(*(int16x8_t *)&jitterc[0])); } -#endif + #endif } #if defined(__x86_64__) || defined(__i386__) @@ -1165,6 +1260,696 @@ void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, #endif } +/* Zero Forcing Rx function: nr_det_HhH() + * + * + * */ +void nr_ulsch_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, + int32_t shift) +{ + 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); + + //det in Q30 format + det_fin_128[0] = _mm_abs_epi32(det_re_128); + + +#ifdef DEBUG_DLSCH_DEMOD + 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]); +#endif + 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_ulsch_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_ulsch_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(); +} +__m128i nr_ulsch_comp_muli_sum(__m128i input_x, + __m128i input_y, + __m128i input_w, + __m128i input_z, + __m128i det) +{ + int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ; + + __m128i xy_re_128, xy_im_128, wz_re_128, wz_im_128; + __m128i output, 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) + + // complex multiplication (w_re + jw_im)*(z_re + jz_im) = (w_re*z_re - w_im*z_im) + j(w_im*z_re + w_re*z_im) + // the real part + wz_re_128 = _mm_sign_epi16(input_w,*(__m128i*)&nr_conjug2[0]); + wz_re_128 = _mm_madd_epi16(wz_re_128,input_z); //Re: (w_re*z_re - w_im*z_im) + + // the imag part + wz_im_128 = _mm_shufflelo_epi16(input_w,_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 + wz_im_128 = _mm_shufflehi_epi16(wz_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 + wz_im_128 = _mm_madd_epi16(wz_im_128,input_z);//Im: (w_im*z_re + w_re*z_im) + + + xy_re_128 = _mm_sub_epi32(xy_re_128, wz_re_128); + xy_im_128 = _mm_sub_epi32(xy_im_128, wz_im_128); + //print_ints("rx_re:",(int32_t*)&xy_re_128[0]); + //print_ints("rx_Img:",(int32_t*)&xy_im_128[0]); + //divide by matrix det and convert back to Q15 before packing + int sum_det =0; + for (int k=0; k<4;k++) { + sum_det += ((((int *)&det[0])[k])>>2); + //printf("det_%d = %d log2 =%d \n",k,(((int *)&det[0])[k]),log2_approx(((int *)&det[0])[k])); + } + + xy_re_128 = _mm_slli_epi32(xy_re_128,5); + xy_re_128 = _mm_srai_epi32(xy_re_128,log2_approx(sum_det)); + xy_re_128 = _mm_slli_epi32(xy_re_128,5); + + xy_im_128 = _mm_slli_epi32(xy_im_128,5); + xy_im_128 = _mm_srai_epi32(xy_im_128,log2_approx(sum_det)); + xy_im_128 = _mm_slli_epi32(xy_im_128,5); + + 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 = _mm_packs_epi32(tmp_z0,tmp_z1); + + _mm_empty(); + _m_empty(); + return(output); +} +/* Zero Forcing Rx function: nr_construct_HhH_elements() + * + * + * */ +void nr_ulsch_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]); + +#ifdef DEBUG_DLSCH_DEMOD + if ((rb<=30)) + { + 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]); + } +#endif + 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_ulsch_zero_forcing_rx_2layers() + * + * + * */ +uint8_t nr_ulsch_zero_forcing_rx_2layers(int **rxdataF_comp, + int **ul_ch_mag, + int **ul_ch_magb, + int **ul_ch_estimates_ext, + unsigned short nb_rb, + unsigned char n_rx, + unsigned char mod_order, + int shift, + unsigned char symbol, + int length) +{ + int *ch00, *ch01, *ch10, *ch11; + int *ch20, *ch30, *ch21, *ch31; + uint32_t nb_rb_0 = length/12 + ((length%12)?1:0); + + #ifdef __AVX2__ + int off = ((nb_rb&1) == 1)? 4:0; + #else + int off = 0; + #endif + + /* 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 *)&ul_ch_estimates_ext[0][symbol*(off+nb_rb*12)]; + ch01 = (int *)&ul_ch_estimates_ext[2][symbol*(off+nb_rb*12)]; + ch10 = (int *)&ul_ch_estimates_ext[1][symbol*(off+nb_rb*12)]; + ch11 = (int *)&ul_ch_estimates_ext[3][symbol*(off+nb_rb*12)]; + ch20 = NULL; + ch21 = NULL; + ch30 = NULL; + ch31 = NULL; + break; + + case 4:// + ch00 = (int *)&ul_ch_estimates_ext[0][symbol*(off+nb_rb*12)]; + ch01 = (int *)&ul_ch_estimates_ext[4][symbol*(off+nb_rb*12)]; + ch10 = (int *)&ul_ch_estimates_ext[1][symbol*(off+nb_rb*12)]; + ch11 = (int *)&ul_ch_estimates_ext[5][symbol*(off+nb_rb*12)]; + ch20 = (int *)&ul_ch_estimates_ext[2][symbol*(off+nb_rb*12)]; + ch21 = (int *)&ul_ch_estimates_ext[6][symbol*(off+nb_rb*12)]; + ch30 = (int *)&ul_ch_estimates_ext[3][symbol*(off+nb_rb*12)]; + ch31 = (int *)&ul_ch_estimates_ext[7][symbol*(off+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_ulsch_conjch0_mult_ch1(ch00, + ch00, + conjch00_ch00, + nb_rb_0, + shift); + // (1/2^log2_maxh)*conj_H_10xH_10: (1/(64*2))conjH_10*H_10*2^15 + nr_ulsch_conjch0_mult_ch1(ch10, + ch10, + conjch10_ch10, + nb_rb_0, + shift); + // conj_H_00xH_01 + nr_ulsch_conjch0_mult_ch1(ch00, + ch01, + conjch00_ch01, + nb_rb_0, + shift); // this shift is equal to the channel level log2_maxh + // conj_H_10xH_11 + nr_ulsch_conjch0_mult_ch1(ch10, + ch11, + conjch10_ch11, + nb_rb_0, + shift); + // conj_H_01xH_01 + nr_ulsch_conjch0_mult_ch1(ch01, + ch01, + conjch01_ch01, + nb_rb_0, + shift); + // conj_H_11xH_11 + nr_ulsch_conjch0_mult_ch1(ch11, + ch11, + conjch11_ch11, + nb_rb_0, + shift); + // conj_H_01xH_00 + nr_ulsch_conjch0_mult_ch1(ch01, + ch00, + conjch01_ch00, + nb_rb_0, + shift); + // conj_H_11xH_10 + nr_ulsch_conjch0_mult_ch1(ch11, + ch10, + conjch11_ch10, + nb_rb_0, + shift); + } + if (n_rx==4){ + // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2*16))conjH_20*H_20*2^15 + nr_ulsch_conjch0_mult_ch1(ch20, + ch20, + conjch20_ch20, + nb_rb_0, + shift); + + // (1/2^log2_maxh)*conj_H_30xH_30: (1/(64*2*4))conjH_30*H_30*2^15 + nr_ulsch_conjch0_mult_ch1(ch30, + ch30, + conjch30_ch30, + nb_rb_0, + shift); + + // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15 + nr_ulsch_conjch0_mult_ch1(ch20, + ch21, + conjch20_ch21, + nb_rb_0, + shift); + + nr_ulsch_conjch0_mult_ch1(ch30, + ch31, + conjch30_ch31, + nb_rb_0, + shift); + + nr_ulsch_conjch0_mult_ch1(ch21, + ch21, + conjch21_ch21, + nb_rb_0, + shift); + + nr_ulsch_conjch0_mult_ch1(ch31, + ch31, + conjch31_ch31, + nb_rb_0, + shift); + + // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15 + nr_ulsch_conjch0_mult_ch1(ch21, + ch20, + conjch21_ch20, + nb_rb_0, + shift); + + nr_ulsch_conjch0_mult_ch1(ch31, + ch30, + conjch31_ch30, + nb_rb_0, + shift); + + nr_ulsch_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_0, + symbol); + } + if (n_rx==2){ + nr_ulsch_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_0, + symbol); + } + //det_HhH = ad -bc + nr_ulsch_det_HhH(af_mf_00,//a + af_mf_01,//b + af_mf_10,//c + af_mf_11,//d + determ_fin, + nb_rb_0, + symbol, + shift); + /* 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,*ul_ch_mag128_0=NULL,*ul_ch_mag128b_0=NULL,*determ_fin_128;//*dl_ch_mag128_1,*dl_ch_mag128b_1,*dl_ch_mag128r_1 + __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; + __m128i *after_mf_a_128,*after_mf_b_128, *after_mf_c_128, *after_mf_d_128; + __m128i QAM_amp128={0},QAM_amp128b={0}; + + determ_fin_128 = (__m128i *)&determ_fin[0]; + + rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][symbol*(off+nb_rb*12)];//aatx=0 @ aarx =0 + rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[n_rx][symbol*(off+nb_rb*12)];//aatx=1 @ aarx =0 + + 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; + + if (mod_order>2) { + 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); //4/sqrt{42} + QAM_amp128b = _mm_set1_epi16(QAM64_n2); //2/sqrt{42} + } + ul_ch_mag128_0 = (__m128i *)&ul_ch_mag[0][symbol*(off+nb_rb*12)]; + ul_ch_mag128b_0 = (__m128i *)&ul_ch_magb[0][symbol*(off+nb_rb*12)]; + } + + for (int rb=0; rb<3*nb_rb_0; rb++) { + if (mod_order>2) { + int sum_det =0; + for (int k=0; k<4;k++) { + sum_det += ((((int *)&determ_fin_128[0])[k])>>2); + //printf("det_%d = %d\n",k,sum_det); + } + + mmtmpD2 = _mm_slli_epi32(determ_fin_128[0],5); + mmtmpD2 = _mm_srai_epi32(mmtmpD2,log2_approx(sum_det)); + mmtmpD2 = _mm_slli_epi32(mmtmpD2,5); + + mmtmpD3 = _mm_unpacklo_epi32(mmtmpD2,mmtmpD2); + + mmtmpD2 = _mm_unpackhi_epi32(mmtmpD2,mmtmpD2); + + mmtmpD2 = _mm_packs_epi32(mmtmpD3,mmtmpD2); + + ul_ch_mag128_0[0] = mmtmpD2; + ul_ch_mag128b_0[0] = mmtmpD2; + + ul_ch_mag128_0[0] = _mm_mulhi_epi16(ul_ch_mag128_0[0],QAM_amp128); + ul_ch_mag128_0[0] = _mm_slli_epi16(ul_ch_mag128_0[0],1); + + ul_ch_mag128b_0[0] = _mm_mulhi_epi16(ul_ch_mag128b_0[0],QAM_amp128b); + ul_ch_mag128b_0[0] = _mm_slli_epi16(ul_ch_mag128b_0[0],1); + + //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]); + //print_shorts("magr layer 1:",(int16_t*)&dl_ch_mag128r_0[0]); + //print_shorts("magr layer 2:",(int16_t*)&dl_ch_mag128r_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 + //printf("layer_1 \n"); + mmtmpD0 = nr_ulsch_comp_muli_sum(rxdataF_comp128_0[0], + after_mf_d_128[0], + rxdataF_comp128_1[0], + after_mf_b_128[0], + determ_fin_128[0]); + + //printf("layer_2 \n"); + mmtmpD1 = nr_ulsch_comp_muli_sum(rxdataF_comp128_1[0], + after_mf_a_128[0], + rxdataF_comp128_0[0], + after_mf_c_128[0], + determ_fin_128[0]); + + rxdataF_comp128_0[0] = mmtmpD0; + rxdataF_comp128_1[0] = mmtmpD1; +#ifdef DEBUG_DLSCH_DEMOD + printf("\n Rx signal after ZF l%d rb%d\n",symbol,rb); + print_shorts(" Rx layer 1:",(int16_t*)&rxdataF_comp128_0[0]); + print_shorts(" Rx layer 2:",(int16_t*)&rxdataF_comp128_1[0]); +#endif + determ_fin_128 += 1; + ul_ch_mag128_0 += 1; + ul_ch_mag128b_0 += 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); +} + +//============================================================================================== + +/* Main Function */ int nr_rx_pusch(PHY_VARS_gNB *gNB, uint8_t ulsch_id, uint32_t frame, @@ -1184,21 +1969,29 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, gNB->pusch_vars[ulsch_id]->cl_done = 0; bwp_start_subcarrier = ((rel15_ul->rb_start + rel15_ul->bwp_start)*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size; - LOG_D(PHY,"pusch %d.%d : bwp_start_subcarrier %d, rb_start %d, first_carrier_offset %d\n", frame,slot,bwp_start_subcarrier, rel15_ul->rb_start, frame_parms->first_carrier_offset); - LOG_D(PHY,"pusch %d.%d : ul_dmrs_symb_pos %x\n",frame,slot,rel15_ul->ul_dmrs_symb_pos); - + LOG_I(PHY,"pusch %d.%d : bwp_start_subcarrier %d, rb_start %d, first_carrier_offset %d\n", frame,slot,bwp_start_subcarrier, rel15_ul->rb_start, frame_parms->first_carrier_offset); + LOG_I(PHY,"pusch %d.%d : ul_dmrs_symb_pos %x\n",frame,slot,rel15_ul->ul_dmrs_symb_pos); + LOG_I(PHY,"ulsch RX %x : start_rb %d nb_rb %d mcs %d Nl %d Tpmi %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_ports %d\n", + rel15_ul->rnti,rel15_ul->rb_start,rel15_ul->rb_size,rel15_ul->mcs_index, + rel15_ul->nrOfLayers,0,rel15_ul->bwp_start,0,rel15_ul->start_symbol_index,rel15_ul->nr_of_symbols, + rel15_ul->num_dmrs_cdm_grps_no_data,rel15_ul->ul_dmrs_symb_pos,rel15_ul->dmrs_ports); //---------------------------------------------------------- //--------------------- Channel estimation --------------------- //---------------------------------------------------------- start_meas(&gNB->ulsch_channel_estimation_stats); - for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) { + for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) + { uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01; LOG_D(PHY, "symbol %d, dmrs_symbol_flag :%d\n", symbol, dmrs_symbol_flag); - if (dmrs_symbol_flag == 1) { + + if (dmrs_symbol_flag == 1) + { if (gNB->pusch_vars[ulsch_id]->dmrs_symbol == INVALID_VALUE) gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol; for (int nl=0; nlnrOfLayers; nl++) + { + nr_pusch_channel_estimation(gNB, slot, get_dmrs_port(nl,rel15_ul->dmrs_ports), @@ -1206,6 +1999,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, ulsch_id, bwp_start_subcarrier, rel15_ul); + } nr_gnb_measurements(gNB, ulsch_id, harq_pid, symbol,rel15_ul->nrOfLayers); @@ -1214,9 +2008,12 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] = 0; gNB->pusch_vars[ulsch_id]->ulsch_noise_power[aarx] = 0; } - gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] += signal_energy_nodc( - &gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aarx][symbol * frame_parms->ofdm_symbol_size], + for (aatx = 0; aatx < rel15_ul->nrOfLayers; aatx++) + { + gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] += signal_energy_nodc( + &gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aatx*gNB->frame_parms.nb_antennas_rx+aarx][symbol * frame_parms->ofdm_symbol_size], rel15_ul->rb_size * 12); + } for (int rb = 0; rb < rel15_ul->rb_size; rb++) { gNB->pusch_vars[ulsch_id]->ulsch_noise_power[aarx] += gNB->measurements.n0_subband_power[aarx][rel15_ul->bwp_start + rel15_ul->rb_start + rb] / @@ -1234,23 +2031,29 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, #endif uint32_t rxdataF_ext_offset = 0; - for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) { + for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) + { uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01; - if (dmrs_symbol_flag == 1) { + if (dmrs_symbol_flag == 1) + { if ((rel15_ul->ul_dmrs_symb_pos >> ((symbol + 1) % frame_parms->symbols_per_slot)) & 0x01) AssertFatal(1==0,"Double DMRS configuration is not yet supported\n"); gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol; - if (rel15_ul->dmrs_config_type == 0) { + if (rel15_ul->dmrs_config_type == 0) + { // if no data in dmrs cdm group is 1 only even REs have no data // if no data in dmrs cdm group is 2 both odd and even REs have no data nb_re_pusch = rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*6)); } - else { + else + { nb_re_pusch = rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*4)); } - } else { + } + else + { nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB; } @@ -1260,16 +2063,16 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, //---------------------------------------------------------- //--------------------- RBs extraction --------------------- //---------------------------------------------------------- - if (nb_re_pusch > 0) { - + if (nb_re_pusch > 0) + { start_meas(&gNB->ulsch_rbs_extraction_stats); - nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF, - gNB->pusch_vars[ulsch_id], - slot, - symbol, - dmrs_symbol_flag, - rel15_ul, - frame_parms); + nr_ulsch_extract_rbs(gNB->common_vars.rxdataF, + gNB->pusch_vars[ulsch_id], + slot, + symbol, + dmrs_symbol_flag, + rel15_ul, + frame_parms); stop_meas(&gNB->ulsch_rbs_extraction_stats); //---------------------------------------------------------- @@ -1280,8 +2083,9 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, gNB->ulsch[ulsch_id], symbol, dmrs_symbol_flag, - rel15_ul->rb_size, - rel15_ul->dmrs_config_type); + nb_re_pusch, + rel15_ul->nrOfLayers, + rel15_ul->rb_size); if (gNB->pusch_vars[ulsch_id]->cl_done==0) { nr_ulsch_channel_level(gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext, @@ -1312,9 +2116,14 @@ 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, + #ifdef SUPPORT_PMI_MATRIC (rel15_ul->nrOfLayers>1) ? gNB->pusch_vars[ulsch_id]->rho : NULL, + #else + NULL, + #endif frame_parms, symbol, + nb_re_pusch, dmrs_symbol_flag, rel15_ul->qam_mod_order, rel15_ul->nrOfLayers, @@ -1327,19 +2136,37 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, gNB->pusch_vars[ulsch_id]->rxdataF_comp, gNB->pusch_vars[ulsch_id]->ul_ch_mag0, gNB->pusch_vars[ulsch_id]->ul_ch_magb0, + #ifdef SUPPORT_PMI_MATRIC + (rel15_ul->nrOfLayers>1) ? gNB->pusch_vars[ulsch_id]->rho : NULL, + #else + NULL, + #endif + rel15_ul->nrOfLayers, symbol, - rel15_ul->rb_size); + rel15_ul->rb_size, + nb_re_pusch); + + if (rel15_ul->nrOfLayers == 2)//Apply zero forcing for 2 Tx layers + nr_ulsch_zero_forcing_rx_2layers(gNB->pusch_vars[ulsch_id]->rxdataF_comp, + gNB->pusch_vars[ulsch_id]->ul_ch_mag0, + gNB->pusch_vars[ulsch_id]->ul_ch_magb0, + gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext, + rel15_ul->rb_size, + frame_parms->nb_antennas_rx, + rel15_ul->qam_mod_order, + gNB->pusch_vars[ulsch_id]->log2_maxh, + symbol, + nb_re_pusch); stop_meas(&gNB->ulsch_mrc_stats); - // transform precoding = 0 means enabled - if (rel15_ul->transform_precoding == 0) { - - #ifdef __AVX2__ + if (rel15_ul->transformPrecoder == transformPrecoder_enabled) + { + #ifdef __AVX2__ // For odd number of resource blocks need byte alignment to multiple of 8 int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7); - #else + #else int nb_re_pusch2 = nb_re_pusch; - #endif + #endif // perform IDFT operation on the compensated rxdata if transform precoding is enabled nr_idft(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][symbol * nb_re_pusch2], nb_re_pusch); @@ -1351,7 +2178,8 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, //---------------------------------------------------------- /* In case PTRS is enabled then LLR will be calculated after PTRS symbols are processed * * otherwise LLR are calculated for each symbol based upon DMRS channel estimates only. */ - if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { + if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) + { start_meas(&gNB->ulsch_ptrs_processing_stats); nr_pusch_ptrs_processing(gNB, frame_parms, @@ -1370,14 +2198,17 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, /*-------------------- LLRs computation -------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------------------------*/ start_meas(&gNB->ulsch_llr_stats); - nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][symbol * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)], - gNB->pusch_vars[ulsch_id]->ul_ch_mag0, - gNB->pusch_vars[ulsch_id]->ul_ch_magb0, - &gNB->pusch_vars[ulsch_id]->llr[rxdataF_ext_offset * rel15_ul->qam_mod_order], - rel15_ul->rb_size, - gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol], - symbol, - rel15_ul->qam_mod_order); + for (aatx=0; aatx < rel15_ul->nrOfLayers; aatx++) + { + nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aatx*frame_parms->nb_antennas_rx][symbol * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)], + gNB->pusch_vars[ulsch_id]->ul_ch_mag0[aatx*frame_parms->nb_antennas_rx], + gNB->pusch_vars[ulsch_id]->ul_ch_magb0[aatx*frame_parms->nb_antennas_rx], + &gNB->pusch_vars[ulsch_id]->llr_layers[aatx][rxdataF_ext_offset * rel15_ul->qam_mod_order], + rel15_ul->rb_size, + gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol], + symbol, + rel15_ul->qam_mod_order); + } stop_meas(&gNB->ulsch_llr_stats); rxdataF_ext_offset += gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol]; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c index bf96a76106..ad41ebf3d6 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c @@ -64,7 +64,7 @@ void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp, //---------------------------------------------------------------------------------------------- void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, - int32_t **ul_ch_mag, + int32_t *ul_ch_mag, int16_t *ulsch_llr, uint32_t nb_rb, uint32_t nb_re, @@ -110,12 +110,12 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, #if defined(__x86_64__) || defined(__i386__) #ifdef __AVX2__ - ch_mag = (__m256i*)&ul_ch_mag[0][(symbol*(off+(nb_rb*12)))]; + ch_mag = (__m256i*)&ul_ch_mag[(symbol*(off+(nb_rb*12)))]; #else - ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*(off+(nb_rb*12)))]; + ch_mag = (__m128i*)&ul_ch_mag[(symbol*(off+(nb_rb*12)))]; #endif #elif defined(__arm__) - ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)]; + ch_mag = (int16x8_t*)&ul_ch_mag[(symbol*nb_rb*12)]; #endif #ifdef __AVX2__ @@ -231,8 +231,8 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, //---------------------------------------------------------------------------------------------- void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, - int32_t **ul_ch_mag, - int32_t **ul_ch_magb, + int32_t *ul_ch_mag, + int32_t *ul_ch_magb, int16_t *ulsch_llr, uint32_t nb_rb, uint32_t nb_re, @@ -265,15 +265,15 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, #if defined(__x86_64__) || defined(__i386__) #ifdef __AVX2__ - ch_mag = (__m256i*)&ul_ch_mag[0][(symbol*(off+(nb_rb*12)))]; - ch_magb = (__m256i*)&ul_ch_magb[0][(symbol*(off+(nb_rb*12)))]; + ch_mag = (__m256i*)&ul_ch_mag[(symbol*(off+(nb_rb*12)))]; + ch_magb = (__m256i*)&ul_ch_magb[(symbol*(off+(nb_rb*12)))]; #else - ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*nb_rb*12)]; - ch_magb = (__m128i*)&ul_ch_magb[0][(symbol*nb_rb*12)]; + ch_mag = (__m128i*)&ul_ch_mag[(symbol*nb_rb*12)]; + ch_magb = (__m128i*)&ul_ch_magb[(symbol*nb_rb*12)]; #endif #elif defined(__arm__) - ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)]; - ch_magb = (int16x8_t*)&ul_ch_magb[0][(symbol*nb_rb*12)]; + ch_mag = (int16x8_t*)&ul_ch_mag[(symbol*nb_rb*12)]; + ch_magb = (int16x8_t*)&ul_ch_magb[(symbol*nb_rb*12)]; #endif #ifdef __AVX2__ @@ -471,8 +471,8 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, void nr_ulsch_compute_llr(int32_t *rxdataF_comp, - int32_t **ul_ch_mag, - int32_t **ul_ch_magb, + int32_t *ul_ch_mag, + int32_t *ul_ch_magb, int16_t *ulsch_llr, uint32_t nb_rb, uint32_t nb_re, diff --git a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c index 65ae288252..2cb7609d62 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c +++ b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c @@ -148,7 +148,7 @@ short filt8_dcr0_h[8]= { 0,4096,8192,12288,16384,0,0,0}; short filt8_l1[8] = { -24576,16384,0,0,0,0,0,0}; +24576,16384,8192,0,0,0,0,0}; short filt8_ml1[8] = { -8192,0,8192,16384,8192,0,0,0}; @@ -163,10 +163,10 @@ short filt8_mm1[8]= { 0,0,0,0,8192,16384,8192,0}; short filt8_dcl1[8]= { -0,0,0,16384,12288,8192,4096,0}; +0,0,16384,12288,8192,4096,0,0}; short filt8_dcr1[8]= { -0,0,0,0,4096,8192,12288,16384}; +0,0,0,4096,8192,12288,16384,0}; short filt8_dcl1_h[8]= { 0,16384,12288,8192,4096,0,0,0}; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 945dc51673..a293eec6d8 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -258,6 +258,15 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, Ilbrm = 0; Tbslbrm = 950984; //max tbs Coderate = 0.0; + + #if 0 + harq_process->a[0] = 0x31; + for (int i = 1; i < harq_process->pusch_pdu.pusch_data.tb_size; i++) + { + harq_process->a[i] = (i&0xff); + } + #endif + trace_NRpdu(DIRECTION_UPLINK, harq_process->a, harq_process->pusch_pdu.pusch_data.tb_size, 0, WS_C_RNTI, 0, 0, 0,0, 0); /////////// ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 99dc2b658e..5d76e654ba 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -98,13 +98,12 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, uint8_t thread_id, int gNB_id) { - LOG_D(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot); + LOG_I(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot); uint32_t available_bits; uint8_t cwd_index, l; uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5]; - int16_t **tx_layers; - int32_t **txdataF; + int8_t Wf[2], Wt[2], l_prime[2], delta; uint8_t nb_dmrs_re_per_rb; int ap, i; @@ -112,6 +111,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms; NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id]; + int16_t **tx_layers = (int16_t **)pusch_ue->txdataF_layers; + int16_t **tx_precoding = (int16_t **)pusch_ue->txdataF_precoding; + int32_t **txdataF = UE->common_vars.txdataF; uint8_t num_of_codewords = 1; // tmp assumption int Nid_cell = 0; @@ -148,9 +150,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, nb_dmrs_re_per_rb = ((dmrs_type == pusch_dmrs_type1) ? 6:4)*cdm_grps_no_data; - LOG_D(PHY,"ulsch %x : start_rb %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_re_per_rb %d\n", - rnti,start_rb,pusch_pdu->bwp_start,start_sc,start_symbol,number_of_symbols,cdm_grps_no_data,number_dmrs_symbols,nb_dmrs_re_per_rb); - + LOG_I(PHY,"ulsch TX %x : start_rb %d nb_rb %d mod_order %d Nl %d Tpmi %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_re_per_rb %d\n", + rnti,start_rb,nb_rb,mod_order,Nl,pusch_pdu->Tpmi,pusch_pdu->bwp_start,start_sc,start_symbol,number_of_symbols,cdm_grps_no_data,number_dmrs_symbols,nb_dmrs_re_per_rb); + // TbD num_of_mod_symbols is set but never used N_RE_prime = NR_NB_SC_PER_RB*number_of_symbols - nb_dmrs_re_per_rb*number_dmrs_symbols - N_PRB_oh; harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb*num_of_codewords; @@ -236,8 +238,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////////////////////ULSCH layer mapping///////////////////////// /////////// - tx_layers = (int16_t **)pusch_ue->txdataF_layers; - nr_ue_layer_mapping(UE->ulsch[thread_id][gNB_id], Nl, available_bits/mod_order, @@ -257,7 +257,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, int16_t *dmrs_seq = NULL; // if transform precoding is enbaled (value 0) - if (pusch_pdu->transform_precoding == 0) { + if (pusch_pdu->transformPrecoder == transformPrecoder_enabled) { uint32_t nb_re_pusch=nb_rb * NR_NB_SC_PER_RB; uint32_t y_offset = 0; @@ -315,10 +315,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, LOG_M("UE_DMRS_SEQ.m","UE_DMRS_SEQ", dmrs_seq,nb_re_pusch,1,1); #endif - } - else - memcpy(ulsch_ue->y, tx_layers[0], (available_bits/mod_order)*sizeof(int32_t)); - + } /////////// //////////////////////////////////////////////////////////////////////// @@ -328,145 +325,233 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////////////////////ULSCH RE mapping///////////////////////// /////////// - txdataF = UE->common_vars.txdataF; - - for (ap=0; ap< Nl; ap++) { - - uint8_t k_prime = 0; - uint16_t m = 0; - - - #ifdef DEBUG_PUSCH_MAPPING + for (ap=0; ap< Nl; ap++) + { + uint8_t k_prime = 0; + uint16_t m = 0; + + #ifdef DEBUG_PUSCH_MAPPING printf("NR_ULSCH_UE: Value of CELL ID %d /t, u %d \n", frame_parms->Nid_cell, u); - #endif + #endif - + // DMRS params for this ap + get_Wt(Wt, ap, dmrs_type); + get_Wf(Wf, ap, dmrs_type); + delta = get_delta(ap, dmrs_type); - // DMRS params for this ap - get_Wt(Wt, ap, dmrs_type); - get_Wf(Wf, ap, dmrs_type); - delta = get_delta(ap, dmrs_type); + for (l=start_symbol; l> l) & 0x01) + { + is_dmrs_sym = 1; + if (pusch_pdu->transformPrecoder == transformPrecoder_disabled) + { + if (dmrs_type == pusch_dmrs_type1) + dmrs_idx = (pusch_pdu->bwp_start + start_rb)*6; + else + dmrs_idx = (pusch_pdu->bwp_start + start_rb)*4; - uint16_t k = start_sc; - uint16_t n = 0; - uint8_t is_dmrs_sym = 0; - uint8_t is_ptrs_sym = 0; - uint16_t dmrs_idx = 0, ptrs_idx = 0; + // TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part + // Perform this on gold sequence, not required when SC FDMA operation is done, + LOG_D(PHY,"DMRS in symbol %d\n",l); + nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated + } + else + { + dmrs_idx = 0; + } + } + else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) + { + AssertFatal(pusch_pdu->transformPrecoder == transformPrecoder_disabled, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); - if ((ul_dmrs_symb_pos >> l) & 0x01) { - is_dmrs_sym = 1; - - // transform precoding disabled (value 1) - if (pusch_pdu->transform_precoding == 1){ - - if (dmrs_type == pusch_dmrs_type1) - dmrs_idx = (pusch_pdu->bwp_start + start_rb)*6; - else - dmrs_idx = (pusch_pdu->bwp_start + start_rb)*4; - - // TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part - // Perform this on gold sequence, not required when SC FDMA operation is done, - LOG_D(PHY,"DMRS in symbol %d\n",l); - nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated - - } else { - dmrs_idx = 0; + if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) + { + is_ptrs_sym = 1; + nr_modulation(pusch_dmrs[l][0], nb_rb, DMRS_MOD_ORDER, mod_ptrs); + } } - - - } else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { - AssertFatal(pusch_pdu->transform_precoding == 1, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); + for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) + { + uint8_t is_dmrs = 0; + uint8_t is_ptrs = 0; - if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) { - is_ptrs_sym = 1; - nr_modulation(pusch_dmrs[l][0], nb_rb, DMRS_MOD_ORDER, mod_ptrs); - } - } + sample_offsetF = l*frame_parms->ofdm_symbol_size + k; - for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) { - - uint8_t is_dmrs = 0; - uint8_t is_ptrs = 0; - - sample_offsetF = l*frame_parms->ofdm_symbol_size + k; - - if (is_dmrs_sym) { - if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%frame_parms->ofdm_symbol_size)) - is_dmrs = 1; - } else if (is_ptrs_sym) { + if (is_dmrs_sym) + { + if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%frame_parms->ofdm_symbol_size)) + is_dmrs = 1; + } + else if (is_ptrs_sym) + { is_ptrs = is_ptrs_subcarrier(k, - rnti, - ap, - dmrs_type, - K_ptrs, - nb_rb, - pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset, - start_sc, - frame_parms->ofdm_symbol_size); - } + rnti, + ap, + dmrs_type, + K_ptrs, + nb_rb, + pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset, + start_sc, + frame_parms->ofdm_symbol_size); + } - if (is_dmrs == 1) { - // if transform precoding is enabled - if (pusch_pdu->transform_precoding == 0) { + if (is_dmrs == 1) + { + if (pusch_pdu->transformPrecoder == transformPrecoder_enabled) + { + ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15; + ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15; + } + else + { + ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15; + ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; + } + + #ifdef DEBUG_PUSCH_MAPPING + printf("DMRS: Layer: %d\t, dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n", + ap, dmrs_idx, l, k, k_prime, n, ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1], + ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1]); + #endif + + dmrs_idx++; + k_prime++; + k_prime&=1; + n+=(k_prime)?0:1; + } + else if (is_ptrs == 1) + { + ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15; + ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15; + + ptrs_idx++; + } + else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) + { + if (pusch_pdu->transformPrecoder == transformPrecoder_disabled) + { + ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = ((int16_t *)tx_layers[ap])[m<<1]; + ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *)tx_layers[ap])[(m<<1) + 1]; + } + else + { + ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1]; + ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1]; + } + + #ifdef DEBUG_PUSCH_MAPPING + printf("DATA: layer %d\t m %d\t l %d \t k %d \t txdataF: %d %d\n", + ap, m, l, k, ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1], + ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1]); + #endif + + m++; + } + else + { + ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = 0; + ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = 0; + } + + if (++k >= frame_parms->ofdm_symbol_size) + { + k -= frame_parms->ofdm_symbol_size; + } + } //for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) + }//for (l=start_symbol; lnb_antennas_tx; ap++) + { + for (int l=start_symbol; lTpmi; - ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15; - ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15; - - } else { - - ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15; - ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; - + if (pmi == 0) {//unitary Precoding + if(ap< pusch_pdu->nrOfLayers) + memcpy((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + k], + (void*)&tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)], + NR_NB_SC_PER_RB*sizeof(int32_t)); + else + memset((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + 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 + { + //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 (pusch_pdu->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 (pusch_pdu->nrOfLayers == 1)//1 layer + W_prec = nr_W_1l_4p[pmi][ap]; + else if (pusch_pdu->nrOfLayers == 2)//2 layers + W_prec = nr_W_2l_4p[pmi][ap]; + else if (pusch_pdu->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; } - #ifdef DEBUG_PUSCH_MAPPING - printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n", - dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1], - ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1]); - #endif + for (int i=0; iofdm_symbol_size + k; + int32_t precodatatx_F = nr_layer_precoder(tx_precoding, W_prec, pusch_pdu->nrOfLayers, re_offset); + ((int16_t*)txdataF[ap])[(re_offset<<1)] = ((int16_t *) &precodatatx_F)[0]; + ((int16_t*)txdataF[ap])[(re_offset<<1) + 1] = ((int16_t *) &precodatatx_F)[1]; + + if (++k >= frame_parms->ofdm_symbol_size) + { + k -= frame_parms->ofdm_symbol_size; + } + } + } + } //RB loop + } // symbol loop + }// port loop - - dmrs_idx++; - k_prime++; - k_prime&=1; - n+=(k_prime)?0:1; - - } else if (is_ptrs == 1) { - - ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15; - ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15; - - ptrs_idx++; - - } else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) { - - ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1]; - ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1]; - - #ifdef DEBUG_PUSCH_MAPPING - printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", - m, l, k, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1], - ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1]); - #endif - - m++; - - } else { - - ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = 0; - ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = 0; - - } - - if (++k >= frame_parms->ofdm_symbol_size) - k -= frame_parms->ofdm_symbol_size; - } - } - } - } + } //for (cwd_index = 0;cwd_index < num_of_codewords; cwd_index++) NR_UL_UE_HARQ_t *harq_process_ulsch=NULL; harq_process_ulsch = UE->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid]; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 11b5112a6c..600ba07cb3 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -479,7 +479,7 @@ typedef struct { /// \brief Cross-correlation of two UE signals. /// - first index: rx antenna [0..nb_antennas_rx[ /// - second index: symbol [0..] - int32_t **rho; + int32_t ***rho; /// \f$\log_2(\max|H_i|^2)\f$ int16_t log2_maxh; /// \brief Magnitude of Uplink Channel first layer (16QAM level/First 64QAM level). @@ -509,6 +509,10 @@ typedef struct { /// \brief llr values. /// - first index: ? [0..1179743] (hard coded) int16_t *llr; + /// \brief llr values per layer. + /// - first index: ? [0..3] (hard coded) + /// - first index: ? [0..1179743] (hard coded) + int16_t **llr_layers; /// DMRS symbol index, to be updated every DMRS symbol within a slot. uint8_t dmrs_symbol; // PTRS symbol index, to be updated every PTRS symbol within a slot. diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 69978f5548..02988b590a 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -229,6 +229,9 @@ typedef struct { typedef struct { /// TX buffers for multiple layers int32_t *txdataF_layers[NR_MAX_NB_LAYERS]; + + /// TX buffers for UE-spec transmission + int32_t *txdataF_precoding[NR_MAX_NB_LAYERS]; } NR_UE_PUSCH; typedef struct { diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index c385d323e3..fbe094f41c 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -93,7 +93,7 @@ #define NR_MAX_CSET_DURATION 3 #define NR_MAX_NB_RBG 18 -#define NR_MAX_NB_LAYERS 2 // 8 // SU-MIMO (3GPP TS 38.211 V15.4.0 section 7.3.1.3) +#define NR_MAX_NB_LAYERS 4 // 8 // SU-MIMO (3GPP TS 38.211 V15.4.0 section 7.3.1.3) #define NR_MAX_NB_CODEWORDS 2 #define NR_MAX_NB_HARQ_PROCESSES 16 #define NR_MAX_PDSCH_ENCODED_LENGTH (NR_MAX_NB_RB*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8*NR_MAX_NB_LAYERS) // 8 is the maximum modulation order (it was 950984 before !!) @@ -104,11 +104,11 @@ #define MAX_NUM_NR_DLSCH_SEGMENTS (NR_MAX_NB_LAYERS*34) #define MAX_NR_DLSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056) -#define MAX_NUM_NR_ULSCH_SEGMENTS 34 +#define MAX_NUM_NR_ULSCH_SEGMENTS (NR_MAX_NB_LAYERS*34) #define MAX_NR_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_ULSCH_SEGMENTS*1056) -#define MAX_NUM_NR_CHANNEL_BITS (14*273*12*8) // 14 symbols, 273 RB -#define MAX_NUM_NR_RE (14*273*12) +#define MAX_NUM_NR_CHANNEL_BITS (4*14*273*12*8) // 14 symbols, 273 RB +#define MAX_NUM_NR_RE (4*14*273*12) #define NR_RX_NB_TH 1 #define NR_NB_TH_SLOT 2 diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index d8fa11d157..640a0740ef 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -526,7 +526,8 @@ void nr_fep0(RU_t *ru, int first_half) { end_symbol = NR_SYMBOLS_PER_SLOT; } - LOG_D(PHY,"In fep0 for slot = %d, first_half = %d, start_symbol = %d, end_symbol = %d\n", proc->tti_rx, first_half, start_symbol, end_symbol); + LOG_D(PHY,"In fep0 for slot = %d, first_half = %d, start_symbol = %d, end_symbol = %d, nb_antennas_rx = %d,N_TA_offset = %d\n", + proc->tti_rx, first_half, start_symbol, end_symbol,fp->nb_antennas_rx,ru->N_TA_offset); // printf("fep0: slot %d\n",slot); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+proc->tti_rx, 1); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 1685e206ae..63c708e565 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -253,13 +253,13 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { // if all segments are done if (rdata->nbSegments == ulsch_harq->processedSegments) { if (decodeSuccess) { - LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for SFN/SF %d.%d (pid %d, ndi %d, status %d, round %d, TBS %d, Max interation (all seg) %d)\n", + LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for SFN/SF %d.%d (pid %d, ndi %d, status %d, round %d, TBS %d, Max interation (all seg) %d)\n", gNB->Mod_id,ulsch_harq->frame,ulsch_harq->slot,rdata->harq_pid,pusch_pdu->pusch_data.new_data_indicator,ulsch_harq->status,ulsch_harq->round,ulsch_harq->TBS,rdata->decodeIterations); ulsch_harq->status = SCH_IDLE; ulsch_harq->round = 0; ulsch->harq_mask &= ~(1 << rdata->harq_pid); - LOG_D(PHY, "ULSCH received ok \n"); + LOG_I(PHY, "ULSCH received ok \n"); nr_fill_indication(gNB,ulsch_harq->frame, ulsch_harq->slot, rdata->ulsch_id, rdata->harq_pid, 0,0); //dumpsig=1; } else { @@ -281,7 +281,7 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { } ulsch_harq->handled = 1; - LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id); + LOG_I(PHY, "ULSCH %d in error\n",rdata->ulsch_id); nr_fill_indication(gNB,ulsch_harq->frame, ulsch_harq->slot, rdata->ulsch_id, rdata->harq_pid, 1,0); } /* @@ -365,6 +365,14 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs pusch_pdu->qam_mod_order, pusch_pdu->nrOfLayers); + + + nr_ulsch_layer_demapping(gNB->pusch_vars[ULSCH_id]->llr, + pusch_pdu->nrOfLayers, + pusch_pdu->qam_mod_order, + G, + gNB->pusch_vars[ULSCH_id]->llr_layers); + //---------------------------------------------------------- //------------------- ULSCH unscrambling ------------------- //---------------------------------------------------------- @@ -731,7 +739,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { (ulsch_harq->slot == slot_rx) && (ulsch_harq->handled == 0)){ - LOG_D(PHY, "PUSCH detection started in frame %d slot %d\n", + LOG_I(PHY, "PUSCH detection started in frame %d slot %d\n", frame_rx,slot_rx); int num_dmrs=0; for (int s=0;srx_pusch_stats); no_sig = nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, harq_pid); if (no_sig) { - LOG_D(PHY, "PUSCH not detected in frame %d, slot %d\n", frame_rx, slot_rx); + LOG_I(PHY, "PUSCH not detected in frame %d, slot %d\n", frame_rx, slot_rx); nr_fill_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid, 1,1); return 1; } @@ -783,7 +791,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot) + gNB->pusch_thres) { NR_gNB_SCH_STATS_t *stats=get_ulsch_stats(gNB,ulsch); - LOG_D(PHY, "PUSCH not detected in %d.%d (%d,%d,%d)\n",frame_rx,slot_rx, + LOG_I(PHY, "PUSCH not detected in %d.%d (%d,%d,%d)\n",frame_rx,slot_rx, dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot), dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot),gNB->pusch_thres); gNB->pusch_vars[ULSCH_id]->ulsch_power_tot = gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot; diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index f6e4d90bee..8e1df435c3 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -157,7 +157,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ for (i = 0; i < ul_config->number_pdus; ++i){ AssertFatal(ul_config->ul_config_list[i].pdu_type <= FAPI_NR_UL_CONFIG_TYPES,"pdu_type %d out of bounds\n",ul_config->ul_config_list[i].pdu_type); - LOG_D(PHY, "In %s: processing %s PDU of %d total UL PDUs (ul_config %p) \n", __FUNCTION__, ul_pdu_type[ul_config->ul_config_list[i].pdu_type - 1], ul_config->number_pdus, ul_config); + LOG_I(PHY, "In %s i %d: processing %s PDU of %d total UL PDUs (ul_config %p) \n", __FUNCTION__, i, ul_pdu_type[ul_config->ul_config_list[i].pdu_type - 1], ul_config->number_pdus, ul_config); uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type, current_harq_pid, gNB_id = 0; /* PRACH */ @@ -180,6 +180,8 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ if (harq_process_ul_ue){ nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &harq_process_ul_ue->pusch_pdu; + + LOG_I(PHY, "In %s i %d: copy pusch_config_pdu nrOfLayers:%d, num_dmrs_cdm_grps_no_data:%d \n", __FUNCTION__, i, pusch_config_pdu->nrOfLayers,pusch_config_pdu->num_dmrs_cdm_grps_no_data); memcpy(pusch_pdu, pusch_config_pdu, sizeof(nfapi_nr_ue_pusch_pdu_t)); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 940931694c..0a0a9cc2f9 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -270,9 +270,12 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, AssertFatal(ue->CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN); - - memset(ue->common_vars.txdataF[0], 0, sizeof(int)*14*ue->frame_parms.ofdm_symbol_size); - + + for(int i=0; i< ue->frame_parms.nb_antennas_tx; ++i) + { + memset(ue->common_vars.txdataF[i], 0, sizeof(int)*14*ue->frame_parms.ofdm_symbol_size); + } + LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 1eb6027936..d5a1054654 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -768,7 +768,7 @@ int main(int argc, char **argv) prepare_scd(scd); - fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, 0, 0, 0); + fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, n_rx, 0, 0, 0); /* RRC parameter validation for secondaryCellGroup */ fix_scd(scd); diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 94aea36a67..fb8b4295ae 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -137,6 +137,7 @@ int main(int argc, char **argv) uint16_t nb_symb_sch = 12; uint16_t nb_rb = 50; uint8_t Imcs = 9; + uint8_t Nl = 1; double DS_TDL = .03; @@ -150,7 +151,7 @@ int main(int argc, char **argv) randominit(0); //while ((c = getopt(argc, argv, "df:hpg:i:j:n:l:m:r:s:S:y:z:M:N:F:R:P:")) != -1) { - while ((c = getopt(argc, argv, "hg:n:s:S:py:z:M:N:R:F:m:l:r:")) != -1) { + while ((c = getopt(argc, argv, "hg:n:s:S:py:z:M:N:R:F:m:l:r:W:")) != -1) { switch (c) { /*case 'f': write_output_file = 1; @@ -251,7 +252,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)) { printf("Unsupported number of TX antennas %d. Exiting.\n", n_tx); exit(-1); } @@ -261,7 +262,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)) { printf("Unsupported number of RX antennas %d. Exiting.\n", n_rx); exit(-1); } @@ -299,6 +300,10 @@ int main(int argc, char **argv) printf("Illegal PBCH phase (0-3) got %d\n", pbch_phase); break;*/ + case 'W': + Nl = atoi(optarg); + break; + case 'm': Imcs = atoi(optarg); #ifdef DEBUG_NR_ULSCHSIM @@ -335,13 +340,14 @@ int main(int argc, char **argv) printf("-z Number of RX antennas used in UE\n"); //printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); //printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); + printf("-W number of layer\n"); printf("-M Multiple SSB positions in burst\n"); printf("-N Nid_cell\n"); printf("-R N_RB_UL\n"); printf("-F Input filename (.txt format) for RX conformance testing\n"); - printf("-m\n"); - printf("-l\n"); - printf("-r\n"); + printf("-m MCS\n"); + printf("-l number of symbol\n"); + printf("-r number of RB\n"); //printf("-O oversampling factor (1,2,4,8,16)\n"); //printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); //printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); @@ -359,8 +365,8 @@ int main(int argc, char **argv) snr1 = snr0 + 10; gNB2UE = new_channel_desc_scm(n_tx, - n_rx, - channel_model, + n_rx, + channel_model, 61.44e6, //N_RB2sampling_rate(N_RB_DL), 40e6, //N_RB2channel_bandwidth(N_RB_DL), DS_TDL, @@ -426,8 +432,7 @@ int main(int argc, char **argv) uint8_t length_dmrs = 1; uint8_t N_PRB_oh; uint16_t N_RE_prime,code_rate; - unsigned char mod_order; - uint8_t Nl = 1; + unsigned char mod_order; uint8_t rvidx = 0; uint8_t UE_id = 0; @@ -437,9 +442,14 @@ int main(int argc, char **argv) NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[0][0][0]; + if ((Nl==4)||(Nl==3)) + { + nb_re_dmrs = nb_re_dmrs*2; + } + mod_order = nr_get_Qm_ul(Imcs, 0); code_rate = nr_get_code_rate_ul(Imcs, 0); - available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1); + available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, Nl); TBS = nr_compute_tbs(mod_order,code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, 0, Nl); printf("\nAvailable bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 69316d6b88..b6cfae3fe1 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -282,7 +282,7 @@ int main(int argc, char **argv) int gNB_id = 0; int ap; int tx_offset; - int32_t txlev=0; + int32_t txlev_sum = 0, atxlev[4]; int start_rb = 0; int UE_id =0; // [hna] only works for UE_id = 0 because NUMBER_OF_NR_UE_MAX is set to 1 (phy_init_nr_gNB causes segmentation fault) float target_error_rate = 0.01; @@ -307,7 +307,7 @@ int main(int argc, char **argv) uint16_t ptrsSymbPerSlot = 0; uint16_t ptrsRePerSymb = 0; - uint8_t transform_precoding = 1; // 0 - ENABLE, 1 - DISABLE + uint8_t transformPrecoder = transformPrecoder_disabled; // 0 - ENABLE, 1 - DISABLE uint8_t num_dmrs_cdm_grps_no_data = 1; uint8_t mcs_table = 0; @@ -329,7 +329,7 @@ int main(int argc, char **argv) /* initialize the sin-cos table */ InitSinLUT(); - while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:ikl:m:n:p:r:s:u:w:y:z:F:G:H:M:N:PR:S:T:U:L:Z")) != -1) { + while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:kl:m:n:p:r:s:u:w:y:z:F:G:H:M:N:PR:S:T:U:L:Z:W:")) != -1) { printf("handling optarg %c\n",c); switch (c) { @@ -363,8 +363,8 @@ int main(int argc, char **argv) scg_fd = fopen(optarg, "r"); if (scg_fd == NULL) { - printf("Error opening %s\n", optarg); - exit(-1); + printf("Error opening %s\n", optarg); + exit(-1); } break; @@ -437,6 +437,10 @@ int main(int argc, char **argv) case 'm': Imcs = atoi(optarg); break; + + case 'W': + precod_nbr_layers = atoi(optarg); + break; case 'n': n_trials = atoi(optarg); @@ -485,9 +489,9 @@ int main(int argc, char **argv) case 'y': n_tx = atoi(optarg); - if ((n_tx == 0) || (n_tx > 2)) { - printf("Unsupported number of tx antennas %d\n", n_tx); - exit(-1); + if ((n_tx == 0) || (n_tx > 4)) { + printf("Unsupported number of tx antennas %d\n", n_tx); + exit(-1); } break; @@ -496,8 +500,8 @@ int main(int argc, char **argv) n_rx = atoi(optarg); if ((n_rx == 0) || (n_rx > 8)) { - printf("Unsupported number of rx antennas %d\n", n_rx); - exit(-1); + printf("Unsupported number of rx antennas %d\n", n_rx); + exit(-1); } break; @@ -506,8 +510,8 @@ int main(int argc, char **argv) input_fd = fopen(optarg, "r"); if (input_fd == NULL) { - printf("Problem with filename %s\n", optarg); - exit(-1); + printf("Problem with filename %s\n", optarg); + exit(-1); } break; @@ -568,11 +572,11 @@ int main(int argc, char **argv) case 'Z': - transform_precoding = 0; // enabled + transformPrecoder = transformPrecoder_enabled; num_dmrs_cdm_grps_no_data = 2; mcs_table = 3; - printf("NOTE: TRANSFORM PRECODING (SC-FDMA) is ENABLED in UPLINK (0 - ENABLE, 1 - DISABLE) : %d \n", transform_precoding); + printf("NOTE: TRANSFORM PRECODING (SC-FDMA) is ENABLED in UPLINK (0 - ENABLE, 1 - DISABLE) : %d \n", transformPrecoder); break; @@ -611,6 +615,7 @@ int main(int argc, char **argv) printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:3}, e.g. -U 2 0 2 \n"); printf("-Q If -F used, read parameters from file\n"); printf("-Z If -Z is used, SC-FDMA or transform precoding is enabled in Uplink \n"); + printf("-W Num of layer for PUSCH\n"); exit(-1); break; @@ -713,7 +718,7 @@ int main(int argc, char **argv) prepare_scd(scd); - fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, 0, 0, 0); + fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, n_rx, 0, 0, 0); // xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup); @@ -724,9 +729,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, n_tx, n_rx, 0, scc, &rrc.carrier.mib,0, 0, NULL); + rrc_mac_config_req_gNB(0,0, n_tx, n_rx, n_tx, scc, &rrc.carrier.mib,0, 0, NULL); // UE dedicated configuration - rrc_mac_config_req_gNB(0,0, n_tx, n_rx, 0, scc, &rrc.carrier.mib,1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); + rrc_mac_config_req_gNB(0,0, n_tx, n_rx, n_tx, scc, &rrc.carrier.mib,1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); frame_parms->nb_antennas_tx = n_tx; frame_parms->nb_antennas_rx = n_rx; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; @@ -870,14 +875,18 @@ int main(int argc, char **argv) uint16_t number_dmrs_symbols = get_dmrs_symbols_in_slot(l_prime_mask, nb_symb_sch); printf("num dmrs sym %d\n",number_dmrs_symbols); uint8_t nb_re_dmrs = (dmrs_config_type == pusch_dmrs_type1) ? 6 : 4; - - // if transform precoding is enabled - if (transform_precoding == 0) { + + if ((frame_parms->nb_antennas_tx==4)&&(precod_nbr_layers==4)) + { + num_dmrs_cdm_grps_no_data = 2; + } + + if (transformPrecoder == transformPrecoder_enabled) { AssertFatal(enable_ptrs == 0, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); int8_t index = get_index_for_dmrs_lowpapr_seq((NR_NB_SC_PER_RB/2) * nb_rb); - AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); + AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); dmrs_config_type = pusch_dmrs_type1; @@ -886,7 +895,7 @@ int main(int argc, char **argv) nb_re_dmrs = nb_re_dmrs * num_dmrs_cdm_grps_no_data; - unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, 1); + unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, precod_nbr_layers); unsigned int TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, 0, precod_nbr_layers); @@ -1082,14 +1091,14 @@ int main(int argc, char **argv) pusch_pdu->mcs_table = mcs_table; pusch_pdu->target_code_rate = code_rate; pusch_pdu->qam_mod_order = mod_order; - pusch_pdu->transform_precoding = transform_precoding; + pusch_pdu->transformPrecoder = transformPrecoder; pusch_pdu->data_scrambling_id = *scc->physCellId; - pusch_pdu->nrOfLayers = 1; + pusch_pdu->nrOfLayers = precod_nbr_layers; pusch_pdu->ul_dmrs_symb_pos = l_prime_mask; pusch_pdu->dmrs_config_type = dmrs_config_type; pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; pusch_pdu->scid = 0; - pusch_pdu->dmrs_ports = 1; + pusch_pdu->dmrs_ports = ((1<num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data; pusch_pdu->resource_alloc = 1; pusch_pdu->rb_start = start_rb; @@ -1109,7 +1118,7 @@ int main(int argc, char **argv) pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0; // if transform precoding is enabled - if (transform_precoding == 0) { + if (transformPrecoder == transformPrecoder_enabled) { pusch_pdu->dfts_ofdm.low_papr_group_number = *scc->physCellId % 30; // U as defined in 38.211 section 6.4.1.1.1.2 pusch_pdu->dfts_ofdm.low_papr_sequence_number = 0; // V as defined in 38.211 section 6.4.1.1.1.2 @@ -1167,10 +1176,10 @@ int main(int argc, char **argv) ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t)); ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0; - ul_config.ul_config_list[0].pusch_config_pdu.transform_precoding = transform_precoding; + ul_config.ul_config_list[0].pusch_config_pdu.transformPrecoder = transformPrecoder; // if transform precoding is enabled - if (transform_precoding == 0) { + if (transformPrecoder == transformPrecoder_enabled) { ul_config.ul_config_list[0].pusch_config_pdu.dfts_ofdm.low_papr_group_number = *scc->physCellId % 30;// U as defined in 38.211 section 6.4.1.1.1.2 ul_config.ul_config_list[0].pusch_config_pdu.dfts_ofdm.low_papr_sequence_number = 0;// V as defined in 38.211 section 6.4.1.1.1.2 @@ -1198,28 +1207,54 @@ int main(int argc, char **argv) LOG_D(PHY, "Sending Uplink data \n"); nr_ue_pusch_common_procedures(UE, slot, - &UE->frame_parms,1); - - if (n_trials==1) { - LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_parms->samples_per_subframe*10,1,1); + &UE->frame_parms, + frame_parms->nb_antennas_tx); + + + if (n_trials==1) + { + LOG_M("txsig0.m","txs0", &UE->common_vars.txdata[0][slot_offset],slot_length,1,1); LOG_M("txsig0F.m","txs0F", UE->common_vars.txdataF[0],frame_parms->ofdm_symbol_size*14,1,1); + if (precod_nbr_layers > 1) + { + LOG_M("txsig1.m","txs1", &UE->common_vars.txdata[1][slot_offset],slot_length,1,1); + LOG_M("txsig1F.m","txs1F", UE->common_vars.txdataF[1],frame_parms->ofdm_symbol_size*14,1,1); + if (precod_nbr_layers==4) + { + LOG_M("txsig2.m","txs2", &UE->common_vars.txdata[2][slot_offset],slot_length,1,1); + LOG_M("txsig3.m","txs3", &UE->common_vars.txdata[3][slot_offset],slot_length,1,1); + + LOG_M("txsig2F.m","txs2F", UE->common_vars.txdataF[2],frame_parms->ofdm_symbol_size*14,1,1); + LOG_M("txsig3F.m","txs3F", UE->common_vars.txdataF[3],frame_parms->ofdm_symbol_size*14,1,1); + } + } } /////////// //////////////////////////////////////////////////// tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); - - txlev = signal_energy(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], + txlev_sum = 0; + for (int aa=0; aanb_antennas_tx; aa++) + { + atxlev[aa] = signal_energy(&UE->common_vars.txdata[aa][tx_offset + 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); - } - else n_trials = 1; + + txlev_sum += atxlev[aa]; + + if (n_trials==1) printf("txlev[%d] = %d (%f dB) txlev_sum %d\n",aa,atxlev[aa],10*log10((double)atxlev[aa]),txlev_sum); + } + } + else + { + n_trials = 1; + } - if (input_fd == NULL ) { - - sigma_dB = 10 * log10((double)txlev * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;; + if (input_fd == NULL ) + { + sigma_dB = 10 * log10((double)txlev_sum * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;; sigma = pow(10,sigma_dB/10); - if(n_trials==1) printf("sigma %f (%f dB), txlev %f (factor %f)\n",sigma,sigma_dB,10*log10((double)txlev),(double)(double) + if(n_trials==1) printf("sigma %f (%f dB), txlev_sum %f (factor %f)\n",sigma,sigma_dB,10*log10((double)txlev_sum),(double)(double) frame_parms->ofdm_symbol_size/(12*nb_rb)); for (i=0; imax_Doppler == 0) { + if (UE2gNB->max_Doppler == 0) + { multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials==1)?1:0); } else { multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, 2*slot_length, 0); } - for (i=0; inb_antennas_rx; ap++) { + for (i=0; inb_antennas_rx; ap++) + { + if (channel_model == AWGN) + { + double H_awgn[4][4] ={{1.0, 0.0, 0.0, 0.0},//rx 0 + {0.0, 1.0, 0.0, 0.0}, //rx 1 + {0.0, 0.0, 1.0, 0.0}, //rx 2 + {0.0, 0.0, 0.0, 1.0}};//rx 3 + #if 0 + double H_awgn_mimo[4][4] ={{1.0, 0.5, 0.25, 0.125},//rx 0 + {0.5, 1.0, 0.5, 0.25}, //rx 1 + {0.25, 0.5, 1.0, 0.5}, //rx 2 + {0.125, 0.25, 0.5, 1.0}};//rx 3 + #endif + // sum up signals from different Tx antennas + r_re[ap][i] = 0; + r_im[ap][i] = 0; + + for (int aa=0; aaofdm_symbol_size/(12*nb_rb))) - SNR;; + sigma = pow(10,sigma_dB/10); + ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); + + #if 0 + ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((r_re[ap][i])); // convert to fixed point + ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((r_im[ap][i])); + + + ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) ] = ((int16_t*) &UE->common_vars.txdata[ap][slot_offset])[(2*i) ]; // convert to fixed point + ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1] = ((int16_t*) &UE->common_vars.txdata[ap][slot_offset])[(2*i)+1 ]; + #endif + /* Add phase noise if enabled */ if (pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { phase_noise(ts, &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)], @@ -1250,7 +1324,8 @@ int main(int argc, char **argv) } /*End input_fd */ - if(pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { + if(pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) + { set_ptrs_symb_idx(&ptrsSymPos, pusch_pdu->nr_of_symbols, pusch_pdu->start_symbol_index, @@ -1268,24 +1343,37 @@ int main(int argc, char **argv) gNB->UL_INFO.rx_ind.number_of_pdus = 0; gNB->UL_INFO.crc_ind.number_crcs = 0; - phy_procedures_gNB_common_RX(gNB, frame, slot); + phy_procedures_gNB_common_RX(gNB, frame, slot); - ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot); + ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot); - if (n_trials==1 && round==0) { + if (n_trials==1 && round==0) + { LOG_M("rxsig0.m","rx0",&gNB->common_vars.rxdata[0][slot_offset],slot_length,1,1); - LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0]+start_symbol*frame_parms->ofdm_symbol_size,nb_symb_sch*frame_parms->ofdm_symbol_size,1,1); - + LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0],14*frame_parms->ofdm_symbol_size,1,1); + if (precod_nbr_layers > 1) + { + LOG_M("rxsig1.m","rx1",&gNB->common_vars.rxdata[1][slot_offset],slot_length,1,1); + LOG_M("rxsigF1.m","rxsF1",gNB->common_vars.rxdataF[1],14*frame_parms->ofdm_symbol_size,1,1); + if (precod_nbr_layers==4) + { + LOG_M("rxsig2.m","rx2",&gNB->common_vars.rxdata[2][slot_offset],slot_length,1,1); + LOG_M("rxsig3.m","rx3",&gNB->common_vars.rxdata[3][slot_offset],slot_length,1,1); + + LOG_M("rxsigF2.m","rxsF2",gNB->common_vars.rxdataF[2],14*frame_parms->ofdm_symbol_size,1,1); + LOG_M("rxsigF3.m","rxsF3",gNB->common_vars.rxdataF[3],14*frame_parms->ofdm_symbol_size,1,1); + } + } } if (n_trials == 1 && round==0) { -#ifdef __AVX2__ + #ifdef __AVX2__ int off = ((nb_rb&1) == 1)? 4:0; -#else + #else int off = 0; -#endif + #endif LOG_M("rxsigF0_ext.m","rxsF0_ext", &gNB->pusch_vars[0]->rxdataF_ext[0][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); @@ -1298,11 +1386,77 @@ int main(int argc, char **argv) (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); LOG_M("rxsigF0_comp.m","rxsF0_comp", &gNB->pusch_vars[0]->rxdataF_comp[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_M("chmagF0.m","chmF0", - &gNB->pusch_vars[0]->ul_ch_mag[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_M("chmagbF0.m","chmbF0", - &gNB->pusch_vars[0]->ul_ch_magb[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - if (n_rx == 2) { + LOG_M("chmagF0.m","chmF0", + &gNB->pusch_vars[0]->ul_ch_mag[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + LOG_M("chmagbF0.m","chmbF0", + &gNB->pusch_vars[0]->ul_ch_magb[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + LOG_M("rxsigF0_llrlayers0.m","rxsF0_llrlayers0", + &gNB->pusch_vars[0]->llr_layers[0][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); + + if (precod_nbr_layers==2) + { + LOG_M("rxsigF1_ext.m","rxsF1_ext", + &gNB->pusch_vars[0]->rxdataF_ext[1][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + + LOG_M("chestF3.m","chF3", + &gNB->pusch_vars[0]->ul_ch_estimates[3][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); + + LOG_M("chestF3_ext.m","chF3_ext", + &gNB->pusch_vars[0]->ul_ch_estimates_ext[3][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], + (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + + LOG_M("rxsigF2_comp.m","rxsF2_comp", + &gNB->pusch_vars[0]->rxdataF_comp[2][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + + LOG_M("rxsigF0_llrlayers1.m","rxsF0_llrlayers1", + &gNB->pusch_vars[0]->llr_layers[1][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); + + } + + if (precod_nbr_layers==4) + { + LOG_M("rxsigF1_ext.m","rxsF1_ext", + &gNB->pusch_vars[0]->rxdataF_ext[1][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + LOG_M("rxsigF2_ext.m","rxsF2_ext", + &gNB->pusch_vars[0]->rxdataF_ext[2][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + LOG_M("rxsigF3_ext.m","rxsF3_ext", + &gNB->pusch_vars[0]->rxdataF_ext[3][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + + LOG_M("chestF5.m","chF5", + &gNB->pusch_vars[0]->ul_ch_estimates[5][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); + LOG_M("chestF10.m","chF10", + &gNB->pusch_vars[0]->ul_ch_estimates[10][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); + LOG_M("chestF15.m","chF15", + &gNB->pusch_vars[0]->ul_ch_estimates[15][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); + + + LOG_M("chestF5_ext.m","chF5_ext", + &gNB->pusch_vars[0]->ul_ch_estimates_ext[5][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], + (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + LOG_M("chestF10_ext.m","chF10_ext", + &gNB->pusch_vars[0]->ul_ch_estimates_ext[10][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], + (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + LOG_M("chestF15_ext.m","chF15_ext", + &gNB->pusch_vars[0]->ul_ch_estimates_ext[15][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], + (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + + + LOG_M("rxsigF4_comp.m","rxsF4_comp", + &gNB->pusch_vars[0]->rxdataF_comp[4][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + LOG_M("rxsigF8_comp.m","rxsF8_comp", + &gNB->pusch_vars[0]->rxdataF_comp[8][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + LOG_M("rxsigF12_comp.m","rxsF12_comp", + &gNB->pusch_vars[0]->rxdataF_comp[12][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + LOG_M("rxsigF0_llrlayers1.m","rxsF0_llrlayers1", + &gNB->pusch_vars[0]->llr_layers[1][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); + LOG_M("rxsigF0_llrlayers2.m","rxsF0_llrlayers2", + &gNB->pusch_vars[0]->llr_layers[2][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); + LOG_M("rxsigF0_llrlayers3.m","rxsF0_llrlayers3", + &gNB->pusch_vars[0]->llr_layers[3][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); + } + + #if 0 + if (n_rx == 2) { LOG_MM("rxsigF0_comp.m","rxsF1_comp", &gNB->pusch_vars[0]->rxdataF_comp[1][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); LOG_MM("rxsigF0_ext.m","rxsF1_ext", @@ -1349,9 +1503,10 @@ int main(int argc, char **argv) LOG_MM("chmagbF0.m","chmbF3", &gNB->pusch_vars[0]->ul_ch_magb[3][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); } + #endif LOG_M("rxsigF0_llr.m","rxsF0_llr", - &gNB->pusch_vars[0]->llr[0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); + &gNB->pusch_vars[0]->llr[0],precod_nbr_layers*(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); } //////////////////////////////////////////////////////////// diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 3f4be9dd58..7e5be9eeba 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -2708,6 +2708,9 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP, LOG_D(NR_MAC,"dci_pdu->srs_resource_indicator.nbits %d\n",dci_pdu->srs_resource_indicator.nbits); // Precoding info and number of layers long transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, ubwpd, (uint8_t*)&format, rnti_type, 0); + + pusch_antenna_ports = *pusch_Config->maxRank; + dci_pdu->precoding_information.nbits=0; if (pusch_Config && pusch_Config->txConfig != NULL){ diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index c23d4bb073..963723725f 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -190,7 +190,7 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con else transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled; } - + pusch_config_pdu->transformPrecoder = transformPrecoder; /* PRECOD_NBR_LAYERS */ if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_nonCodebook)); @@ -198,11 +198,12 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook)){ - uint8_t n_antenna_port = 0; //FIXME!!! + uint8_t n_antenna_port = mac->phy_config.config_req.carrier_config.num_tx_ant; if (n_antenna_port == 1); // 1 antenna port and the higher layer parameter txConfig = codebook 0 bits - if (n_antenna_port == 4){ // 4 antenna port and the higher layer parameter txConfig = codebook + if (n_antenna_port == 4) + { // 4 antenna port and the higher layer parameter txConfig = codebook // Table 7.3.1.1.2-2: transformPrecoder=disabled and maxRank = 2 or 3 or 4 if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) @@ -212,54 +213,56 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][0]; - pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][1]; + pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][1]; } if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_partialAndNonCoherent){ pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][2]; - pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][3]; + pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][3]; } if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){ pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][4]; - pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][5]; + pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][5]; } } // Table 7.3.1.1.2-3: transformPrecoder= enabled, or transformPrecoder=disabled and maxRank = 1 if (((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled)) - && (*pusch_Config->maxRank == 1)){ + && (*pusch_Config->maxRank == 1)) + { if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][6]; - pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][7]; + pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][7]; } if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_partialAndNonCoherent){ pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][8]; - pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][9]; + pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][9]; } if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){ pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][10]; - pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][11]; + pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][11]; } } } - if (n_antenna_port == 4){ // 2 antenna port and the higher layer parameter txConfig = codebook + if (n_antenna_port == 2) + { // 2 antenna port and the higher layer parameter txConfig = codebook // Table 7.3.1.1.2-4: transformPrecoder=disabled and maxRank = 2 - if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (*pusch_Config->maxRank == 2)){ - + if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (*pusch_Config->maxRank == 2)) + { if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][12]; - pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][13]; + pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][13]; } if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){ pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][14]; - pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][15]; + pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][15]; } } @@ -267,16 +270,17 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con // Table 7.3.1.1.2-5: transformPrecoder= enabled, or transformPrecoder= disabled and maxRank = 1 if (((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled)) - && (*pusch_Config->maxRank == 1)){ + && (*pusch_Config->maxRank == 1)) + { if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][16]; - pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][17]; + pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][17]; } if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){ pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][18]; - pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][19]; + pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][19]; } } @@ -285,9 +289,9 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con /*-------------------- Changed to enable Transform precoding in RF SIM------------------------------------------------*/ - /*if (pusch_config_pdu->transform_precoding == transform_precoder_enabled) { + /*if (pusch_config_pdu->transformPrecoder == transformPrecoder_enabled) { - pusch_config_dedicated->transform_precoder = transform_precoder_enabled; + pusch_config_dedicated->transform_precoder = transformPrecoder_enabled; if(pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL) { @@ -309,7 +313,7 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con } } else - pusch_config_dedicated->transform_precoder = transform_precoder_disabled;*/ + pusch_config_dedicated->transformPrecoder = ttransformPrecoder_disabled;*/ } // todo: this function shall be reviewed completely because of the many comments left by the author @@ -342,7 +346,7 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf } long *max_length = NULL; long *dmrs_type = NULL; - LOG_D(NR_MAC,"transformPrecoder %s\n",transformPrecoder==NR_PUSCH_Config__transformPrecoder_disabled?"disabled":"enabled"); + LOG_I(NR_MAC,"transformPrecoder %s\n",transformPrecoder==NR_PUSCH_Config__transformPrecoder_disabled?"disabled":"enabled"); if (pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA) { max_length = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup->maxLength; @@ -353,7 +357,7 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf dmrs_type = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->dmrs_Type; } - LOG_D(NR_MAC,"MappingType%s max_length %s, dmrs_type %s, antenna_ports %d\n",pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA?"A":"B",max_length?"len2":"len1",dmrs_type?"type2":"type1",dci->antenna_ports.val); + LOG_I(NR_MAC,"MappingType%s max_length %s, dmrs_type %s, antenna_ports %d\n",pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA?"A":"B",max_length?"len2":"len1",dmrs_type?"type2":"type1",dci->antenna_ports.val); if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) && (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-6 pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC @@ -369,35 +373,32 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf } if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && - (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-8/9/10/11 + (dmrs_type == NULL) && (max_length == NULL)) + { // tables 7.3.1.1.2-8/9/10/11 + + if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook)) + { + rank = pusch_config_pdu->nrOfLayers; + } if (rank == 1) { - pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; //TBC - pusch_config_pdu->dmrs_ports = (dci->antenna_ports.val > 1)?(dci->antenna_ports.val-2):(dci->antenna_ports.val); //TBC + pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; + pusch_config_pdu->dmrs_ports =1<<((dci->antenna_ports.val > 1)?(dci->antenna_ports.val-2):(dci->antenna_ports.val)); } if (rank == 2){ - pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 0)?2:1; //TBC - pusch_config_pdu->dmrs_ports = 0; //FIXME - //pusch_config_pdu->dmrs_ports[0] = (dci->antenna_ports > 1)?(dci->antenna_ports > 2 ?0:2):0; - //pusch_config_pdu->dmrs_ports[1] = (dci->antenna_ports > 1)?(dci->antenna_ports > 2 ?2:3):1; + pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 0)?2:1; + pusch_config_pdu->dmrs_ports = (dci->antenna_ports.val > 1)?((dci->antenna_ports.val> 2)?0x5:0xc):0x3; } if (rank == 3){ - pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC - pusch_config_pdu->dmrs_ports = 0; //FIXME - //pusch_config_pdu->dmrs_ports[0] = 0; - //pusch_config_pdu->dmrs_ports[1] = 1; - //pusch_config_pdu->dmrs_ports[2] = 2; + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; + pusch_config_pdu->dmrs_ports = ((1<num_dmrs_cdm_grps_no_data = 2; //TBC - pusch_config_pdu->dmrs_ports = 0; //FIXME - //pusch_config_pdu->dmrs_ports[0] = 0; - //pusch_config_pdu->dmrs_ports[1] = 1; - //pusch_config_pdu->dmrs_ports[2] = 2; - //pusch_config_pdu->dmrs_ports[3] = 3; + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; + pusch_config_pdu->dmrs_ports = ((1<n_front_load_symb = table_7_3_1_1_2_23[dci->antenna_ports.val][5]; //FIXME } } - LOG_D(NR_MAC,"num_dmrs_cdm_grps_no_data %d, dmrs_ports %d\n",pusch_config_pdu->num_dmrs_cdm_grps_no_data,pusch_config_pdu->dmrs_ports); + LOG_I(NR_MAC,"num_dmrs_cdm_grps_no_data %d, dmrs_ports %d\n",pusch_config_pdu->num_dmrs_cdm_grps_no_data,pusch_config_pdu->dmrs_ports); } // Configuration of Msg3 PDU according to clauses: @@ -542,6 +543,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->dmrs_config_type = pusch_dmrs_type1; pusch_config_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; pusch_config_pdu->nrOfLayers = 1; + pusch_config_pdu->Tpmi = 0; pusch_config_pdu->rnti = rnti; NR_BWP_UplinkCommon_t *initialUplinkBWP; if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP; @@ -634,7 +636,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->scid = 0; // Transform precoding according to 6.1.3 UE procedure for applying transform precoding on PUSCH in 38.214 - pusch_config_pdu->transform_precoding = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, NULL, NR_RNTI_TC, 0); // TBR fix rnti and take out + pusch_config_pdu->transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, NULL, NR_RNTI_TC, 0); // TBR fix rnti and take out // Resource allocation in frequency domain according to 6.1.2.2 in TS 38.214 pusch_config_pdu->resource_alloc = (mac->cg) ? pusch_Config->resourceAllocation : 1; @@ -680,7 +682,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, /* Transform precoding */ if (rnti_type != NR_RNTI_CS || (rnti_type == NR_RNTI_CS && dci->ndi == 1)) { - pusch_config_pdu->transform_precoding = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, dci_format, rnti_type, 0); + pusch_config_pdu->transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, dci_format, rnti_type, 0); } /*DCI format-related configuration*/ @@ -716,7 +718,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, /* TRANSFORM PRECODING ------------------------------------------------------------------------------------------*/ - if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled) { + if (pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) { pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; @@ -761,7 +763,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->mcs_index = dci->mcs; /* MCS TABLE */ - if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) { + if (pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) { pusch_config_pdu->mcs_table = get_pusch_mcs_table(pusch_Config ? pusch_Config->mcs_Table : NULL, 0, *dci_format, rnti_type, target_ss, false); } else { pusch_config_pdu->mcs_table = get_pusch_mcs_table(pusch_Config ? pusch_Config->mcs_TableTransformPrecoder : NULL, 1, *dci_format, rnti_type, target_ss, false); @@ -798,9 +800,14 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, mappingtype, add_pos, dmrslength, pusch_config_pdu->start_symbol_index, mac->scc ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position); - if ((mac->ULbwp[0] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled)) - pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1; - else if (*dci_format == NR_UL_DCI_FORMAT_0_0 || (mac->ULbwp[0] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled)) + if (mac->ULbwp[0] && pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) + { + if (*dci_format != NR_UL_DCI_FORMAT_0_1) + { + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1; + } + } + else if (*dci_format == NR_UL_DCI_FORMAT_0_0 || (mac->ULbwp[0] && pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled)) pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; // Num PRB Overhead from PUSCH-ServingCellConfig @@ -821,7 +828,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup && mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB && mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) { - if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) { + if (pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) { nfapi_nr_ue_ptrs_ports_t ptrs_ports_list; pusch_config_pdu->pusch_ptrs.ptrs_ports_list = &ptrs_ports_list; valid_ptrs_setup = set_ul_ptrs_values(mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup, @@ -909,6 +916,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) + LOG_I(NR_MAC,"1# scheduled_response transmitted, %d, %d\n", rx_frame, rx_slot); mac->if_module->scheduled_response(&scheduled_response); } else { @@ -1022,6 +1030,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, rx_frame, rx_slot, ul_info->thread_id); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ + LOG_I(NR_MAC,"3# scheduled_response transmitted,%d, %d\n", frame_tx, slot_tx); mac->if_module->scheduled_response(&scheduled_response); } pthread_mutex_lock(&ul_config->mutex_ul_config); diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 1cb3fdb708..d9c98852a3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -388,7 +388,7 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts 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(NR_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); + LOG_I(NR_MAC,"Set RX antenna number to %d, Set TX antenna number to %d (num ssb %d: %x,%x)\n",cfg->carrier_config.num_tx_ant.value,cfg->carrier_config.num_rx_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 ); cfg->num_tlv++; cfg->num_tlv++; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 6ac7f3f82e..5de36bb2db 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -977,9 +977,9 @@ void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) - pusch_pdu->transform_precoding = 1; + pusch_pdu->transformPrecoder = 1; else - pusch_pdu->transform_precoding = 0; + pusch_pdu->transformPrecoder = 0; pusch_pdu->data_scrambling_id = *scc->physCellId; pusch_pdu->nrOfLayers = 1; pusch_pdu->ul_dmrs_symb_pos = get_l_prime(nr_of_symbols,mappingtype,pusch_dmrs_pos2,pusch_len1,start_symbol_index, scc->dmrs_TypeA_Position); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index abc007197d..9cbbe7d9a1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -1139,13 +1139,14 @@ void nr_schedule_ue_spec(module_id_t module_id, dci_payload.dmrs_sequence_initialization.val = pdsch_pdu->SCID; LOG_D(NR_MAC, "%4d.%2d DCI type 1 payload: freq_alloc %d (%d,%d,%d), " - "time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d tpc %d ti %d\n", + "nrOfLayers %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d tpc %d ti %d\n", frame, slot, dci_payload.frequency_domain_assignment.val, pdsch_pdu->rbStart, pdsch_pdu->rbSize, pdsch_pdu->BWPSize, + pdsch_pdu->nrOfLayers, dci_payload.time_domain_assignment.val, dci_payload.vrb_to_prb_mapping.val, dci_payload.mcs, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index f1005cea70..8f7c856a30 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -405,6 +405,7 @@ void nr_preprocessor_phytest(module_id_t module_id, uint32_t target_ul_mcs = 9; uint32_t target_ul_bw = 50; +uint32_t target_ul_Nl = 1; uint64_t ulsch_slot_bitmap = (1 << 8); bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_t slot) { @@ -446,15 +447,21 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats; const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0; - const uint8_t num_dmrs_cdm_grps_no_data = 1; + uint8_t num_dmrs_cdm_grps_no_data = 1; + if ((target_ul_Nl==4)||(target_ul_Nl==3)) + { + num_dmrs_cdm_grps_no_data = 2; + } + /* we want to avoid a lengthy deduction of DMRS and other parameters in * every TTI if we can save it, so check whether dci_format, TDA, or * num_dmrs_cdm_grps_no_data has changed and only then recompute */ NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; if (ps->time_domain_allocation != tda || ps->dci_format != dci_format + || ps->nrOfLayers != target_ul_Nl || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) - nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, NULL,dci_format, tda, num_dmrs_cdm_grps_no_data, ps); + nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, NULL,dci_format, tda, num_dmrs_cdm_grps_no_data,target_ul_Nl,ps); uint16_t rbStart = 0; uint16_t rbSize; @@ -525,6 +532,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ sched_pusch->ul_harq_pid = sched_ctrl->retrans_ul_harq.head; /* Calculate TBS from MCS */ + ps->nrOfLayers = target_ul_Nl; sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table); sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table); if (ps->pusch_Config->tp_pi2BPSK @@ -539,7 +547,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ ps->N_PRB_DMRS * ps->num_dmrs_symb, 0, // nb_rb_oh 0, - 1 /* NrOfLayers */) + ps->nrOfLayers /* NrOfLayers */) >> 3; /* mark the corresponding RBs as used */ diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 1c0cb0353e..4583da876f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -355,6 +355,7 @@ void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc, long dci_format, int tda, uint8_t num_dmrs_cdm_grps_no_data, + uint8_t nrOfLayers, NR_pusch_semi_static_t *ps) { ps->dci_format = dci_format; @@ -371,11 +372,11 @@ void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc, ps->pusch_Config = ubwp?ubwp->bwp_Dedicated->pusch_Config->choice.setup:(ubwpd ? ubwpd->pusch_Config->choice.setup : NULL); if (ps->pusch_Config == NULL || !ps->pusch_Config->transformPrecoder) - ps->transform_precoding = !scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder; + ps->transformPrecoder = !scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder; else - ps->transform_precoding = *ps->pusch_Config->transformPrecoder; + ps->transformPrecoder = *ps->pusch_Config->transformPrecoder; const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - if (ps->transform_precoding) + if (ps->transformPrecoder) ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config ? ps->pusch_Config->mcs_Table : NULL, 0, ps->dci_format, @@ -392,6 +393,7 @@ void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc, num_dmrs_cdm_grps_no_data = 2; // in case of transform precoding - no Data sent in DMRS symbol } + ps->nrOfLayers = nrOfLayers; ps->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data; /* DMRS calculations */ @@ -689,8 +691,21 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp, "Non Codebook configuration non supported\n"); dci_pdu_rel15->srs_resource_indicator.val = 0; // taking resource 0 for SRS } + AssertFatal((pusch_pdu->Tpmi==0), "unsupport Tpmi\n"); + dci_pdu_rel15->precoding_information.val= 0; + if (pusch_pdu->nrOfLayers == 2) + { + dci_pdu_rel15->precoding_information.val = 4; + } + else if (pusch_pdu->nrOfLayers == 4) + { + dci_pdu_rel15->precoding_information.val = 11; + } + + // antenna_ports.val = 0 for transform precoder is disabled, dmrs-Type=1, maxLength=1, Rank=1/2/3/4 // Antenna Ports - dci_pdu_rel15->antenna_ports.val = 0; // TODO for now it is hardcoded, it should depends on cdm group no data and rank + dci_pdu_rel15->antenna_ports.val = 0; + // DMRS sequence initialization dci_pdu_rel15->dmrs_sequence_initialization.val = pusch_pdu->scid; break; @@ -699,11 +714,14 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp, } LOG_D(NR_MAC, - "%s() ULDCI type 0 payload: freq_alloc %d, time_alloc %d, freq_hop_flag %d, mcs %d tpc %d ndi %d rv %d\n", + "%s() ULDCI type 0 payload: dci_format %d, freq_alloc %d, time_alloc %d, freq_hop_flag %d, precoding_information.val %d antenna_ports.val %d mcs %d tpc %d ndi %d rv %d\n", __func__, + dci_format, dci_pdu_rel15->frequency_domain_assignment.val, dci_pdu_rel15->time_domain_assignment.val, dci_pdu_rel15->frequency_hopping_flag.val, + dci_pdu_rel15->precoding_information.val, + dci_pdu_rel15->antenna_ports.val, dci_pdu_rel15->mcs, dci_pdu_rel15->tpc, dci_pdu_rel15->ndi, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 9a6fa32b5f..269d6c5359 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -905,7 +905,7 @@ bool allocate_ul_retransmission(module_id_t module_id, NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; int rbStart = 0; // wrt BWP start const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - + const uint8_t nrOfLayers = 1; const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_bwp || ubwpd) ? 1 : 2; const int tda = sched_ctrl->active_ubwp ? RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0; LOG_D(NR_MAC,"retInfo->time_domain_allocation = %d, tda = %d\n", retInfo->time_domain_allocation, tda); @@ -926,8 +926,9 @@ bool allocate_ul_retransmission(module_id_t module_id, if (ps->time_domain_allocation != tda || ps->dci_format != dci_format + || ps->nrOfLayers != nrOfLayers || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) - nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps); + nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, nrOfLayers,ps); LOG_D(NR_MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size); } else { /* the retransmission will use a different time domain allocation, check @@ -939,7 +940,7 @@ bool allocate_ul_retransmission(module_id_t module_id, rbSize++; NR_pusch_semi_static_t temp_ps; int dci_format = get_dci_format(sched_ctrl); - nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp,ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, &temp_ps); + nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp,ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, nrOfLayers, &temp_ps); uint32_t new_tbs; uint16_t new_rbSize; bool success = nr_find_nb_rb(retInfo->Qm, @@ -1094,7 +1095,7 @@ void pf_ul(module_id_t module_id, if (max_num_ue < 0) return; - LOG_D(NR_MAC,"Looking for min_rb %d RBs, starting at %d\n", min_rb, rbStart); + LOG_D(NR_MAC,"Looking for min_rb %d RBs, starting at %d num_dmrs_cdm_grps_no_data %d\n", min_rb, rbStart, ps->num_dmrs_cdm_grps_no_data); while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++; if (rbStart + min_rb >= bwpSize) { LOG_W(NR_MAC, "cannot allocate continuous UL data for UE %d/RNTI %04x: no resources (rbStart %d, min_rb %d, bwpSize %d\n", @@ -1106,13 +1107,15 @@ void pf_ul(module_id_t module_id, /* we want to avoid a lengthy deduction of DMRS and other parameters in * every TTI if we can save it, so check whether dci_format, TDA, or * num_dmrs_cdm_grps_no_data has changed and only then recompute */ + const uint8_t nrOfLayers = 1; const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_ubwp || ubwpd) ? 1 : 2; int dci_format = get_dci_format(sched_ctrl); const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0; if (ps->time_domain_allocation != tda || ps->dci_format != dci_format + || ps->nrOfLayers != nrOfLayers || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) - nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps); + nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data,nrOfLayers, ps); NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; sched_pusch->mcs = 9; update_ul_ue_R_Qm(sched_pusch, ps); @@ -1125,7 +1128,7 @@ void pf_ul(module_id_t module_id, ps->N_PRB_DMRS * ps->num_dmrs_symb, 0, // nb_rb_oh 0, - 1 /* NrOfLayers */) + ps->nrOfLayers) >> 3; /* Mark the corresponding RBs as used */ @@ -1205,13 +1208,15 @@ void pf_ul(module_id_t module_id, /* we want to avoid a lengthy deduction of DMRS and other parameters in * every TTI if we can save it, so check whether dci_format, TDA, or * num_dmrs_cdm_grps_no_data has changed and only then recompute */ + const uint8_t nrOfLayers = 1; const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_ubwp || ubwpd) ? 1 : 2; int dci_format = get_dci_format(sched_ctrl); const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0; if (ps->time_domain_allocation != tda || ps->dci_format != dci_format + || ps->nrOfLayers != nrOfLayers || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) - nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps); + nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, nrOfLayers,ps); update_ul_ue_R_Qm(sched_pusch, ps); /* Calculate the current scheduling bytes and the necessary RBs */ @@ -1473,7 +1478,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) sched_ctrl->last_ul_slot = sched_pusch->slot; LOG_D(NR_MAC, - "ULSCH/PUSCH: %4d.%2d RNTI %04x UL sched %4d.%2d DCI L %d start %2d RBS %3d startSymbol %2d nb_symbol %2d dmrs_pos %x MCS %2d TBS %4d HARQ PID %2d round %d RV %d NDI %d est %6d sched %6d est BSR %6d TPC %d\n", + "ULSCH/PUSCH: %4d.%2d RNTI %04x UL sched %4d.%2d DCI L %d start %2d RBS %3d startSymbol %2d nb_symbol %2d dmrs_pos %x MCS %2d nrOfLayers %2d num_dmrs_cdm_grps_no_data %2d TBS %4d HARQ PID %2d round %d RV %d NDI %d est %6d sched %6d est BSR %6d TPC %d\n", frame, slot, rnti, @@ -1486,6 +1491,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) ps->nrOfSymbols, ps->ul_dmrs_symb_pos, sched_pusch->mcs, + ps->nrOfLayers, + ps->num_dmrs_cdm_grps_no_data, sched_pusch->tb_size, harq_id, cur_harq->round, @@ -1532,17 +1539,18 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) pusch_pdu->qam_mod_order = sched_pusch->Qm; pusch_pdu->mcs_index = sched_pusch->mcs; pusch_pdu->mcs_table = ps->mcs_table; - pusch_pdu->transform_precoding = ps->transform_precoding; + pusch_pdu->transformPrecoder = ps->transformPrecoder; if (ps->pusch_Config && ps->pusch_Config->dataScramblingIdentityPUSCH) pusch_pdu->data_scrambling_id = *ps->pusch_Config->dataScramblingIdentityPUSCH; else pusch_pdu->data_scrambling_id = *scc->physCellId; - pusch_pdu->nrOfLayers = 1; + pusch_pdu->nrOfLayers = ps->nrOfLayers; + pusch_pdu->num_dmrs_cdm_grps_no_data = ps->num_dmrs_cdm_grps_no_data; /* FAPI: DMRS */ pusch_pdu->ul_dmrs_symb_pos = ps->ul_dmrs_symb_pos; pusch_pdu->dmrs_config_type = ps->dmrs_config_type; - if (pusch_pdu->transform_precoding) { // transform precoding disabled + if (pusch_pdu->transformPrecoder) { // transform precoding disabled long *scramblingid=NULL; if (ps->NR_DMRS_UplinkConfig && pusch_pdu->scid == 0) scramblingid = ps->NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0; @@ -1562,7 +1570,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) } pusch_pdu->scid = 0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1] pusch_pdu->num_dmrs_cdm_grps_no_data = ps->num_dmrs_cdm_grps_no_data; - pusch_pdu->dmrs_ports = 1; + pusch_pdu->dmrs_ports = ((1<nrOfLayers) - 1); /* FAPI: Pusch Allocation in frequency domain */ pusch_pdu->resource_alloc = 1; //type 1 @@ -1588,7 +1596,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) LOG_D(NR_MAC,"PUSCH PDU : data_scrambling_identity %x, dmrs_scrambling_id %x\n",pusch_pdu->data_scrambling_id,pusch_pdu->ul_dmrs_scrambling_id); /* TRANSFORM PRECODING --------------------------------------------------------*/ - if (pusch_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled){ + if (pusch_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled){ // U as specified in section 6.4.1.1.1.2 in 38.211, if sequence hopping and group hopping are disabled pusch_pdu->dfts_ofdm.low_papr_group_number = pusch_pdu->pusch_identity % 30; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 91221276b0..8a560580c9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -298,6 +298,7 @@ void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc, long dci_format, int tda, uint8_t num_dmrs_cdm_grps_no_data, + uint8_t nrOfLayers, NR_pusch_semi_static_t *ps); uint8_t nr_get_tpc(int target, uint8_t cqi, int incr); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 27f42f4b1d..66b10dad42 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -318,13 +318,14 @@ typedef struct NR_sched_pucch { typedef struct NR_pusch_semi_static_t { int dci_format; int time_domain_allocation; + uint8_t nrOfLayers; uint8_t num_dmrs_cdm_grps_no_data; int startSymbolIndex; int nrOfSymbols; NR_PUSCH_Config_t *pusch_Config; - uint8_t transform_precoding; + uint8_t transformPrecoder; uint8_t mcs_table; long mapping_type; diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index ff6923429e..52d03b5e56 100755 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -1867,6 +1867,7 @@ int16_t do_RRCReconfiguration( // 1, // 1, // carrier->pdsch_AntennaPorts, + // carrier->pusch_AntennaPorts, // carrier->initial_csi_index[ue_context_p->local_uid + 1], // ue_context_pP->local_uid); diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 9465b9b4b0..6a94450450 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -79,6 +79,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco int scg_id, int servCellIndex, int dl_antenna_ports, + int ul_antenna_ports, int do_csirs, int initial_csi_index, int uid); @@ -90,6 +91,7 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon NR_RRCReconfiguration_IEs_t *reconfig, NR_CellGroupConfig_t *secondaryCellGroup, int dl_antenna_ports, + int ul_antenna_ports, int do_csirs, int initial_csi_index, int uid); diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index f9fce48f41..22e43cbb6a 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -241,6 +241,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ reconfig_ies, ue_context_p->ue_context.secondaryCellGroup, carrier->pdsch_AntennaPorts, + carrier->pusch_AntennaPorts, carrier->do_CSIRS, carrier->initial_csi_index[ue_context_p->local_uid + 1], ue_context_p->local_uid); @@ -250,6 +251,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ reconfig_ies, ue_context_p->ue_context.secondaryCellGroup, carrier->pdsch_AntennaPorts, + carrier->pusch_AntennaPorts, carrier->do_CSIRS, carrier->initial_csi_index[ue_context_p->local_uid + 1], ue_context_p->local_uid); @@ -348,7 +350,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_AntennaPorts, rrc->carrier.sib1_tda, rrc->carrier.servingcellconfigcommon, &rrc->carrier.mib, diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 980bd39c37..d03f361502 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -55,6 +55,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco int scg_id, int servCellIndex, int dl_antenna_ports, + int ul_antenna_ports, int do_csirs, int initial_csi_index, int uid) { @@ -745,14 +746,14 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco pusch_Config->codebookSubset=calloc(1,sizeof(*pusch_Config->codebookSubset)); *pusch_Config->codebookSubset = NR_PUSCH_Config__codebookSubset_nonCoherent; pusch_Config->maxRank=calloc(1,sizeof(*pusch_Config->maxRank)); - *pusch_Config->maxRank= 1; + *pusch_Config->maxRank= ul_antenna_ports; pusch_Config->rbg_Size=NULL; pusch_Config->uci_OnPUSCH=NULL; pusch_Config->tp_pi2BPSK=NULL; /*------------------------------TRANSFORM PRECODING- -----------------------------------------------------------------------*/ - uint8_t transform_precoding = NR_PUSCH_Config__transformPrecoder_disabled; + uint8_t transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled; // TBD: configure this from .conf file, Dedicated params cannot yet be configured in .conf file. // Enable this to test transform precoding enabled from dedicated config. @@ -764,13 +765,13 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco if (pusch_Config->transformPrecoder == NULL) { if (servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder != NULL) - transform_precoding = NR_PUSCH_Config__transformPrecoder_enabled; + transformPrecoder = NR_PUSCH_Config__transformPrecoder_enabled; } else - transform_precoding = *pusch_Config->transformPrecoder; + transformPrecoder = *pusch_Config->transformPrecoder; - if (transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled ) { + if (transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled ) { /* Enable DMRS uplink config for transform precoding enabled */ NR_DMRS_UplinkConfig->transformPrecodingEnabled = calloc(1,sizeof(*NR_DMRS_UplinkConfig->transformPrecodingEnabled)); NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity = NULL; @@ -1348,6 +1349,7 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon NR_RRCReconfiguration_IEs_t *reconfig, NR_CellGroupConfig_t *secondaryCellGroup, int dl_antenna_ports, + int ul_antenna_ports, int do_csirs, int initial_csi_index, int uid) { @@ -1363,6 +1365,7 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon 1, 1, dl_antenna_ports, + ul_antenna_ports, do_csirs, initial_csi_index, uid); diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 13945998d7..20faa86591 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -429,7 +429,7 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp if (!alreadyLocked) pthread_mutex_lock(&Sockmutex); - LOG_D(HW,"sending %d samples at time: %ld\n", nsamps, timestamp); + LOG_D(HW,"sending %d samples at time: %ld, nbAnt %d\n", nsamps, timestamp, nbAnt); for (int i=0; ibuf[i]; @@ -623,7 +623,7 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest } rfsimulator_state_t *t = device->priv; - LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextTimestamp+nsamps); + LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld, nbAnt %d\n", nsamps, t->nextTimestamp+nsamps, nbAnt); // deliver data from received data // check if a UE is connected int first_sock; @@ -728,6 +728,7 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest for (int a=0; achannel_model != NULL ) // apply a channel model + { rxAddInput( ptr->circularBuf, (struct complex16 *) samplesVoid[a], a, ptr->channel_model, @@ -735,11 +736,21 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest t->nextTimestamp, CirSize ); - else { // no channel modeling + } + else + { // no channel modeling + + #if 0 double H_awgn_mimo[4][4] ={{1.0, 0.5, 0.25, 0.125},//rx 0 {0.5, 1.0, 0.5, 0.25}, //rx 1 {0.25, 0.5, 1.0, 0.5}, //rx 2 {0.125, 0.25, 0.5, 1.0}};//rx 3 + #else + double H_awgn_mimo[4][4] ={{1.0, 0.0, 0.0, 0.0},//rx 0 + {0.0, 1.0, 0.0, 0.0},//rx 1 + {0.0, 0.0, 1.0, 0.0},//rx 2 + {0.0, 0.0, 0.0, 1.0}};//rx 3 + #endif sample_t *out=(sample_t *)samplesVoid[a]; int nbAnt_tx = ptr->th.nbAnt;//number of Tx antennas diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf new file mode 100644 index 0000000000..74f2f9c11c --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf @@ -0,0 +1,320 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ + mcc = 208; + mnc = 99; + mnc_length = 2; + snssaiList = ( + { + sst = 1; + sd = 0x1; // 0 false, else true + }, + { + sst = 1; + sd = 0x112233; // 0 false, else true + } + ); + + }); + + nr_cellid = 12345678L; + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 4; + pusch_AntennaPorts = 4; + sib1_tda = 0; + + pdcch_ConfigSIB1 = ( + { + controlResourceSetZero = 12; + searchSpaceZero = 0; + } + ); + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641280; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640008; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=27,L=48 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952 +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 28875; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -96; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 6; # used for UL slot + initialULBWPmappingType_0 = 1 + initialULBWPstartSymbolAndLength_0 = 41; # this is SS=0 L=13 + + initialULBWPk2_1 = 6; # used for mixed slot + initialULBWPmappingType_1 = 1; + initialULBWPstartSymbolAndLength_1 = 52; # this is SS=10 L=4 + + initialULBWPk2_2 = 7; # used for Msg.3 during RA + initialULBWPmappingType_2 = 1; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -25; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + amf_ip_address = ( { ipv4 = "192.168.70.132"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + + NETWORK_INTERFACES : + { + GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai"; + GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24"; + GNB_INTERFACE_NAME_FOR_NGU = "demo-oai"; + GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 150; + pucch_TargetSNRx10 = 200; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + pusch_proc_threads = 8; + prach_dtx_threshold = 120; + pucch0_dtx_threshold = 150; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 4 + nb_rx = 4 + att_tx = 0 + att_rx = 0; + bands = [78]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; + clock_src = "internal"; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +rfsimulator : +{ + serveraddr = "server"; + serverport = "4043"; + options = (); #("saviq"); or/and "chanmod" + modelname = "AWGN"; + IQfile = "/tmp/rfsimulator.iqs"; +}; + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + ngap_log_level ="info"; + ngap_log_verbosity ="medium"; + }; + From 2aa8a438f2af6765d042c3024e2208085b806c5c Mon Sep 17 00:00:00 2001 From: Fang Date: Tue, 7 Dec 2021 13:47:15 +0800 Subject: [PATCH 02/49] add mimo doc --- doc/UL_MIMO.txt | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 doc/UL_MIMO.txt diff --git a/doc/UL_MIMO.txt b/doc/UL_MIMO.txt new file mode 100644 index 0000000000..c06bc78c4c --- /dev/null +++ b/doc/UL_MIMO.txt @@ -0,0 +1,31 @@ +# how to build phy sim +cd cmake_targets/ +sudo ./build_oai --phy_simulators -c + +cd phy_simulators/build/ +# ULSCH sim +# bit level validation +# PUSCH encoding and decoding for 4 layers 2 CMD without data +sudo ./nr_ulschsim -R 106 -m9 -s13 -n100 -y4 -z4 -W4 + +# UL sim +# Uplink chain validation +# PUSCH on UE side and gNB side,whole chain for PUSCH +# No channel model on data domain signal +# No cross-path connection +# PMI = 0 is only unitary prcoding matrix +sudo ./nr_ulsim -n100 -m9 -r106 -s13 -W4 -y4 -z4 + +# How to build rfsim +sudo ./build_oai -c --gNB --nrUE -w SIMU + +# How to run with rfsim +# 4x4 RANK 4 +sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf --rfsim --phy-test --l 2 --L 4 +sudo ./nr-uesoftmodem --rfsim --phy-test --ue-nb-ant-rx 4 --ue-nb-ant-tx 4 +# 4x4 RANK 2 +sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf --rfsim --phy-test --l 2 --L 2 +sudo ./nr-uesoftmodem --rfsim --phy-test --ue-nb-ant-rx 4 --ue-nb-ant-tx 4 + + + From 79002c119057c7a37fda5d17e9359bae71eadc4c Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 9 Dec 2021 17:37:16 +0100 Subject: [PATCH 03/49] phy-sim test cases for UL-MIMO --- cmake_targets/autotests/test_case_list.xml | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 3472b14efc..00fcfc4140 100755 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1182,9 +1182,10 @@ execution - nr_ulschsim Test cases. (Test1: 106 PRB), - (Test2: 217 PRB), - (Test3: 273 PRB) + nr_ulschsim Test cases. (Test1: 106 PRBs), + (Test2: 217 PRBs), + (Test3: 273 PRBs) + (Test4: 106 PRBs 4-layer MIMO) $OPENAIR_DIR/cmake_targets/build_oai --phy_simulators -c @@ -1193,8 +1194,9 @@ $OPENAIR_DIR/targets/bin/nr_ulschsim.Rel15 -R 106 -m9 -s13 -n100 -R 217 -m15 -s15 -n100 - -R 273 -m19 -s20 -n100 - nr_ulschsim.test1 nr_ulschsim.test2 nr_ulschsim.test3 + -R 273 -m19 -s20 -n100 + -R 106 -m9 -s13 -n100 -y4 -z4 -W4 + nr_ulschsim.test1 nr_ulschsim.test2 nr_ulschsim.test3 nr_ulschsim.test4 PUSCH test OK segmentation fault|assertion|exiting|fatal 3 @@ -1302,7 +1304,9 @@ (Test12: SC-FDMA, 216 PRBs), (Test13: SC-FDMA, 273 PRBs), (Test14: SC-FDMA, 3 DMRS), - (Test15: MCS 16 50 PRBs 2 RX_Antenna) + (Test15: MCS 16 50 PRBs 2 RX_Antenna) + (Test16: MCS 9 106 PRBs MIMO 2 layers) + (Test17: MCS 9 106 PRBs MIMO 4 layers) $OPENAIR_DIR/cmake_targets/build_oai --phy_simulators -c @@ -1323,9 +1327,11 @@ -n50 -s5 -Z -r216 -R217 -n50 -s5 -Z -r270 -R273 -n100 -s5 -Z -U 2 0 2 - -n100 -m16 -s10 -z2 + -n100 -m16 -s10 -z2 + -n100 -m9 -r106 -s10 -W2 -y2 -z2 + -n100 -m9 -r106 -s13 -W4 -y4 -z4 - nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15 + nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15 nr_ulsim.test16 nr_ulsim.test16 PUSCH test OK segmentation fault|assertion|exiting|fatal 3 From dbdf38133e3f99320f01ac54a3e398802981f35e Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 9 Dec 2021 17:37:55 +0100 Subject: [PATCH 04/49] reducing log levels --- diff_1206_2.txt | 4257 ----------------- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 6 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 4 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 14 +- openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 4 +- 5 files changed, 14 insertions(+), 4271 deletions(-) delete mode 100644 diff_1206_2.txt diff --git a/diff_1206_2.txt b/diff_1206_2.txt deleted file mode 100644 index ff352f4157..0000000000 --- a/diff_1206_2.txt +++ /dev/null @@ -1,4257 +0,0 @@ -diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h -index c02155326b..1238b43c27 100644 ---- a/executables/nr-softmodem-common.h -+++ b/executables/nr-softmodem-common.h -@@ -67,6 +67,7 @@ - #define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n" - #define CONFIG_HLP_DLMCS_PHYTEST "Set the downlink MCS for PHYTEST mode\n" - #define CONFIG_HLP_DLNL_PHYTEST "Set the downlink nrOfLayers for PHYTEST mode\n" -+#define CONFIG_HLP_ULNL_PHYTEST "Set the uplink nrOfLayers for PHYTEST mode\n" - #define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n" - #define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n" - #define CONFIG_HLP_ULMCS_PHYTEST "Set the uplink MCS for PHYTEST mode\n" -diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h -index 896c363cbf..a11572c0e1 100644 ---- a/executables/nr-softmodem.h -+++ b/executables/nr-softmodem.h -@@ -23,6 +23,7 @@ - {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \ - {"m" , CONFIG_HLP_DLMCS_PHYTEST,0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ - {"l" , CONFIG_HLP_DLNL_PHYTEST,0, uptr:&target_dl_Nl, defintval:0, TYPE_UINT, 0}, \ -+ {"L" , CONFIG_HLP_ULNL_PHYTEST,0, uptr:&target_ul_Nl, defintval:0, TYPE_UINT, 0}, \ - {"t" , CONFIG_HLP_ULMCS_PHYTEST,0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ - {"M" , CONFIG_HLP_DLBW_PHYTEST,0, uptr:&target_dl_bw, defintval:0, TYPE_UINT, 0}, \ - {"T" , CONFIG_HLP_ULBW_PHYTEST,0, uptr:&target_ul_bw, defintval:0, TYPE_UINT, 0}, \ -@@ -36,6 +37,7 @@ - extern threads_t threads; - extern uint32_t target_dl_mcs; - extern uint32_t target_dl_Nl; -+extern uint32_t target_ul_Nl; - extern uint32_t target_ul_mcs; - extern uint32_t target_dl_bw; - extern uint32_t target_ul_bw; -diff --git a/executables/nr-ue.c b/executables/nr-ue.c -index 60ff40abeb..a23f91b1dd 100644 ---- a/executables/nr-ue.c -+++ b/executables/nr-ue.c -@@ -278,7 +278,7 @@ void processSlotTX(void *arg) { - int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_slot_tx); - uint8_t gNB_id = 0; - -- LOG_D(PHY,"%d.%d => slot type %d\n",proc->frame_tx,proc->nr_slot_tx,tx_slot_type); -+ LOG_D(PHY,"processSlotTX %d.%d => slot type %d\n",proc->frame_tx,proc->nr_slot_tx,tx_slot_type); - if (tx_slot_type == NR_UPLINK_SLOT || tx_slot_type == NR_MIXED_SLOT){ - - // trigger L2 to run ue_scheduler thru IF module -@@ -372,7 +372,8 @@ void processSlotRX(void *arg) { - LOG_D(PHY, "Sending Uplink data \n"); - nr_ue_pusch_common_procedures(UE, - proc->nr_slot_tx, -- &UE->frame_parms,1); -+ &UE->frame_parms, -+ UE->frame_parms.nb_antennas_tx); - } - - if (UE->UE_mode[gNB_id] > NOT_SYNCHED && UE->UE_mode[gNB_id] < PUSCH) { -diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c -index ad5ea982c9..57fd284601 100644 ---- a/executables/nr-uesoftmodem.c -+++ b/executables/nr-uesoftmodem.c -@@ -465,8 +465,11 @@ int main( int argc, char **argv ) { - memset(UE[CC_id],0,sizeof(PHY_VARS_NR_UE)); - - set_options(CC_id, UE[CC_id]); -- NR_UE_MAC_INST_t *mac = get_mac_inst(0); -- -+ NR_DL_FRAME_PARMS *fp = &UE[CC_id]->frame_parms; -+ NR_UE_MAC_INST_t *mac = get_mac_inst(0); -+ -+ mac->phy_config.config_req.carrier_config.num_tx_ant = fp->nb_antennas_tx; -+ - if (get_softmodem_params()->sa) { - uint16_t nr_band = get_band(downlink_frequency[CC_id][0],uplink_frequency_offset[CC_id][0]); - mac->nr_band = nr_band; -diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h -index 0e923931ad..8b93417cb0 100644 ---- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h -+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h -@@ -298,9 +298,10 @@ typedef struct - uint8_t qam_mod_order; - uint8_t mcs_index; - uint8_t mcs_table; -- uint8_t transform_precoding; -+ uint8_t transformPrecoder; - uint16_t data_scrambling_id; - uint8_t nrOfLayers; -+ uint8_t Tpmi; - //DMRS - uint16_t ul_dmrs_symb_pos; - uint8_t dmrs_config_type; -diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h -index 9d245446c8..58ff9037ce 100644 ---- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h -+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h -@@ -1208,9 +1208,10 @@ typedef struct - uint8_t qam_mod_order; - uint8_t mcs_index; - uint8_t mcs_table; -- uint8_t transform_precoding; -+ uint8_t transformPrecoder; - uint16_t data_scrambling_id; - uint8_t nrOfLayers; -+ uint8_t Tpmi; - //DMRS - uint16_t ul_dmrs_symb_pos; - uint8_t dmrs_config_type; -diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c -index 7cb74f8562..473b0900bc 100644 ---- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c -+++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c -@@ -941,9 +941,10 @@ static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, ui - push8(pusch_pdu->qam_mod_order, ppWritePackedMsg, end) && - push8(pusch_pdu->mcs_index, ppWritePackedMsg, end) && - push8(pusch_pdu->mcs_table, ppWritePackedMsg, end) && -- push8(pusch_pdu->transform_precoding, ppWritePackedMsg, end) && -+ push8(pusch_pdu->transformPrecoder, ppWritePackedMsg, end) && - push16(pusch_pdu->data_scrambling_id, ppWritePackedMsg, end) && - push8(pusch_pdu->nrOfLayers, ppWritePackedMsg, end) && -+ push8(pusch_pdu->Tpmi, ppWritePackedMsg, end) && - push16(pusch_pdu->ul_dmrs_symb_pos, ppWritePackedMsg, end) && - push8(pusch_pdu->dmrs_config_type, ppWritePackedMsg, end) && - push16(pusch_pdu->ul_dmrs_scrambling_id, ppWritePackedMsg, end) && -@@ -4445,9 +4446,10 @@ static uint8_t unpack_ul_tti_request_pusch_pdu(void *tlv, uint8_t **ppReadPacked - pull8(ppReadPackedMsg, &pusch_pdu->qam_mod_order, end) && - pull8(ppReadPackedMsg, &pusch_pdu->mcs_index, end) && - pull8(ppReadPackedMsg, &pusch_pdu->mcs_table, end) && -- pull8(ppReadPackedMsg, &pusch_pdu->transform_precoding, end) && -+ pull8(ppReadPackedMsg, &pusch_pdu->transformPrecoder, end) && - pull16(ppReadPackedMsg, &pusch_pdu->data_scrambling_id, end) && - pull8(ppReadPackedMsg, &pusch_pdu->nrOfLayers, end) && -+ pull8(ppReadPackedMsg, &pusch_pdu->Tpmi, end) && - pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_symb_pos, end) && - pull8(ppReadPackedMsg, &pusch_pdu->dmrs_config_type, end) && - pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_scrambling_id, end) && -diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c -index cd4848ea8c..2ac3230215 100644 ---- a/openair1/PHY/INIT/nr_init.c -+++ b/openair1/PHY/INIT/nr_init.c -@@ -276,11 +276,21 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, - pusch_vars[ULSCH_id]->ul_ch_magb0 = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); - pusch_vars[ULSCH_id]->ul_ch_mag = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); - pusch_vars[ULSCH_id]->ul_ch_magb = (int32_t **)malloc16(n_buf*sizeof(int32_t *) ); -- pusch_vars[ULSCH_id]->rho = (int32_t **)malloc16_clear(n_buf*sizeof(int32_t*) ); -+ pusch_vars[ULSCH_id]->rho = (int32_t ***)malloc16_clear(Prx*sizeof(int32_t**) ); -+ pusch_vars[ULSCH_id]->llr_layers = (int16_t **)malloc16(max_ul_mimo_layers*sizeof(int32_t *) ); - - for (i=0; irxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); - pusch_vars[ULSCH_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); -+ pusch_vars[ULSCH_id]->rho[i] = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS*sizeof(int32_t*)); -+ -+ for (int j=0; j< max_ul_mimo_layers; j++) -+ { -+ for (int k=0; krho[i][j*max_ul_mimo_layers+k]=(int32_t *)malloc16_clear( sizeof(int32_t) * fp->N_RB_UL*12*7*2 ); -+ } -+ } - } - for (i=0; iul_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot ); -@@ -293,8 +303,12 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, - pusch_vars[ULSCH_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); - pusch_vars[ULSCH_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); - pusch_vars[ULSCH_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); -- pusch_vars[ULSCH_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); -- pusch_vars[ULSCH_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) ); -+ pusch_vars[ULSCH_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); -+ } -+ -+ for (i=0; i< max_ul_mimo_layers; i++) -+ { -+ pusch_vars[ULSCH_id]->llr_layers[i] = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear - } - pusch_vars[ULSCH_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear - pusch_vars[ULSCH_id]->ul_valid_re_per_slot = (int16_t *)malloc16_clear( sizeof(int16_t)*fp->symbols_per_slot); -diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c -index 4024ed1617..169db48e69 100644 ---- a/openair1/PHY/INIT/nr_init_ru.c -+++ b/openair1/PHY/INIT/nr_init_ru.c -@@ -41,7 +41,7 @@ int nr_phy_init_RU(RU_t *ru) { - int p; - int re; - -- LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d\n",ru_if_types[ru->if_south],ru->nb_tx); -+ LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d, nb_rx %d\n",ru_if_types[ru->if_south],ru->nb_tx, ru->nb_rx); - - nfapi_nr_config_request_scf_t *cfg; - ru->nb_log_antennas=0; -diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c -index b60e77e814..11fb6e7d61 100644 ---- a/openair1/PHY/INIT/nr_init_ue.c -+++ b/openair1/PHY/INIT/nr_init_ue.c -@@ -124,7 +124,8 @@ void phy_init_nr_ue_PUSCH(NR_UE_PUSCH *const pusch, - AssertFatal( pusch, "pusch==0" ); - - for (int i=0; itxdataF_layers[i] = (int32_t *)malloc16_clear(NR_MAX_PUSCH_ENCODED_LENGTH*sizeof(int32_t)); -+ pusch->txdataF_layers[i] = (int32_t *)malloc16_clear((NR_MAX_PUSCH_ENCODED_LENGTH)*sizeof(int32_t *)); -+ pusch->txdataF_precoding[i] = (int32_t *)malloc16_clear((NR_MAX_PUSCH_ENCODED_LENGTH)*sizeof(int32_t *)); - } - } - -@@ -143,7 +144,7 @@ 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; -- 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_I(PHY, "Initializing UE vars (abstraction %u) for UE 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_gNB_INST); - phy_init_nr_top(ue); - // many memory allocation sizes are hard coded -diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c -index 1f164748bf..9a432e8615 100644 ---- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c -+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c -@@ -110,7 +110,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, - fr = filt8_r1; - fmm = filt8_mm1; - fml = filt8_ml1; -- fmr = filt8_m1; -+ fmr = filt8_mm1; - fdcl = filt8_dcl1; - fdcr = filt8_dcr1; - fdclh = filt8_dcl1_h; -@@ -129,9 +129,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, - - //------------------generate DMRS------------------// - -- // transform precoding = 1 means disabled -- if (pusch_pdu->transform_precoding == 1) { -- nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, -+ if (pusch_pdu->transformPrecoder == transformPrecoder_disabled) { -+ nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], (1000+p), 0, nb_rb_pusch, - (pusch_pdu->bwp_start + pusch_pdu->rb_start)*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type); - } - else { // if transform precoding or SC-FDMA is enabled in Uplink -@@ -291,7 +290,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, - printf("pilot %u : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]); - printf("data %u : rxF - > (%d,%d) (%d)\n",pilot_cnt,rxF[2],rxF[3],dBc(rxF[2],rxF[3])); - #endif -- multadd_real_vector_complex_scalar(fml, -+ multadd_real_vector_complex_scalar(fm, - ch, - ul_ch, - 8); -diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h -index 4fed3a468f..87e4d57362 100644 ---- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h -+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h -@@ -137,21 +137,22 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, - @param nb_rb_pusch The number of RBs allocated (used for Resource Allocation Type 1 in NR) - @param frame_parms, Pointer to frame descriptor structure - */ --void nr_ulsch_extract_rbs_single(int32_t **rxdataF, -- NR_gNB_PUSCH *pusch_vars, -- int slot, -- unsigned char symbol, -- uint8_t is_dmrs_symbol, -- nfapi_nr_pusch_pdu_t *pusch_pdu, -- NR_DL_FRAME_PARMS *frame_parms); -+void nr_ulsch_extract_rbs(int32_t **rxdataF, -+ NR_gNB_PUSCH *pusch_vars, -+ int slot, -+ unsigned char symbol, -+ uint8_t is_dmrs_symbol, -+ nfapi_nr_pusch_pdu_t *pusch_pdu, -+ NR_DL_FRAME_PARMS *frame_parms); - - void nr_ulsch_scale_channel(int32_t **ul_ch_estimates_ext, - NR_DL_FRAME_PARMS *frame_parms, - NR_gNB_ULSCH_t **ulsch_gNB, -- uint8_t symbol, -- uint8_t start_symbol, -- uint16_t nb_rb, -- pusch_dmrs_type_t pusch_dmrs_type); -+ uint8_t symbol, -+ uint8_t is_dmrs_symbol, -+ uint32_t len, -+ uint8_t nrOfLayers, -+ uint16_t nb_rb); - - /** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal - @param ul_ch_estimates_ext Channel estimates in allocated RBs -@@ -185,9 +186,10 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, - int **ul_ch_mag, - int **ul_ch_magb, - int **rxdataF_comp, -- int **rho, -+ int ***rho, - NR_DL_FRAME_PARMS *frame_parms, - unsigned char symbol, -+ int length, - uint8_t is_dmrs_symbol, - unsigned char mod_order, - uint8_t nrOfLayers, -@@ -255,8 +257,8 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, - @param mod_order modulation order - */ - void nr_ulsch_compute_llr(int32_t *rxdataF_comp, -- int32_t **ul_ch_mag, -- int32_t **ul_ch_magb, -+ int32_t *ul_ch_mag, -+ int32_t *ul_ch_magb, - int16_t *ulsch_llr, - uint32_t nb_rb, - uint32_t nb_re, -diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c -index 4278338dbc..3ea19a9970 100644 ---- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c -+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c -@@ -137,6 +137,38 @@ void nr_ulsch_unscrambling_optim(int16_t* llr, - #endif - } - -+void nr_ulsch_layer_demapping(int16_t *llr_cw, -+ uint8_t Nl, -+ uint8_t mod_order, -+ uint32_t length, -+ int16_t **llr_layers) -+{ -+ -+ switch (Nl) { -+ -+ case 1: -+ memcpy((void*)llr_cw, (void*)llr_layers[0], (length)*sizeof(int16_t)); -+ break; -+ -+ case 2: -+ case 3: -+ case 4: -+ for (int i=0; i<(length/Nl/mod_order); i++) -+ { -+ for (int l=0; lnumber_of_nr_ulsch_max;i++) { -diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h -index 80c10d74b1..0e660351ae 100644 ---- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h -+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h -@@ -82,6 +82,12 @@ void nr_ulsch_unscrambling_optim(int16_t* llr, - uint32_t Nid, - uint32_t n_RNTI); - -+void nr_ulsch_layer_demapping(int16_t *llr_cw, -+ uint8_t Nl, -+ uint8_t mod_order, -+ uint32_t length, -+ int16_t **llr_layers); -+ - void nr_ulsch_procedures(PHY_VARS_gNB *gNB, - int frame_rx, - int slot_rx, -diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c -index 28dd5ab219..8314c83ad9 100644 ---- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c -+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c -@@ -302,26 +302,27 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) - } - - --void nr_ulsch_extract_rbs_single(int32_t **rxdataF, -- NR_gNB_PUSCH *pusch_vars, -- int slot, -- unsigned char symbol, -- uint8_t is_dmrs_symbol, -- nfapi_nr_pusch_pdu_t *pusch_pdu, -- NR_DL_FRAME_PARMS *frame_parms) -+void nr_ulsch_extract_rbs(int32_t **rxdataF, -+ NR_gNB_PUSCH *pusch_vars, -+ int slot, -+ unsigned char symbol, -+ uint8_t is_dmrs_symbol, -+ nfapi_nr_pusch_pdu_t *pusch_pdu, -+ NR_DL_FRAME_PARMS *frame_parms) - { - - unsigned short start_re, re, nb_re_pusch; -- unsigned char aarx; -+ unsigned char aarx, aatx; - uint32_t rxF_ext_index = 0; - uint32_t ul_ch0_ext_index = 0; - uint32_t ul_ch0_index = 0; -- uint8_t k_prime; -- uint16_t n; -+ //uint8_t k_prime; -+ //uint16_t n; - int16_t *rxF,*rxF_ext; - int *ul_ch0,*ul_ch0_ext; -- uint8_t delta = 0; -+ //uint8_t delta = 0; - int soffset = (slot&3)*frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size; -+ - #ifdef DEBUG_RB_EXT - - printf("--------------------symbol = %d-----------------------\n", symbol); -@@ -329,7 +330,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, - - #endif - -- uint8_t is_dmrs_re; -+ uint8_t is_data_re; - start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start + pusch_pdu->bwp_start) * NR_NB_SC_PER_RB)%frame_parms->ofdm_symbol_size; - nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size; - #ifdef __AVX2__ -@@ -338,64 +339,95 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, - int nb_re_pusch2 = nb_re_pusch; - #endif - -- for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { -+ for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) -+ { - - rxF = (int16_t *)&rxdataF[aarx][soffset+(symbol * frame_parms->ofdm_symbol_size)]; - rxF_ext = (int16_t *)&pusch_vars->rxdataF_ext[aarx][symbol * nb_re_pusch2]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6 -- -- ul_ch0 = &pusch_vars->ul_ch_estimates[aarx][pusch_vars->dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available -- -- ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aarx][symbol*nb_re_pusch2]; -- -- n = 0; -- k_prime = 0; -- rxF_ext_index = 0; -- ul_ch0_ext_index = 0; -- ul_ch0_index = 0; -- -- if (is_dmrs_symbol == 0) { -+ -+ if (is_dmrs_symbol == 0) -+ { - // - //rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]); -- if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size) { -+ if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size) -+ { - memcpy1((void*)rxF_ext, - (void*)&rxF[start_re*2], - nb_re_pusch*sizeof(int32_t)); -- } else { -- int neg_length = frame_parms->ofdm_symbol_size-start_re; -- int pos_length = nb_re_pusch-neg_length; -+ } -+ else -+ { -+ int neg_length = frame_parms->ofdm_symbol_size-start_re; -+ int pos_length = nb_re_pusch-neg_length; -+ memcpy1((void*)rxF_ext,(void*)&rxF[start_re*2],neg_length*sizeof(int32_t)); -+ memcpy1((void*)&rxF_ext[2*neg_length],(void*)rxF,pos_length*sizeof(int32_t)); -+ } - -- memcpy1((void*)rxF_ext,(void*)&rxF[start_re*2],neg_length*sizeof(int32_t)); -- memcpy1((void*)&rxF_ext[2*neg_length],(void*)rxF,pos_length*sizeof(int32_t)); -+ #ifdef SUPPORT_PMI_MATRIC -+ for (aatx = 0; aatx < pusch_pdu->nrOfLayers; aatx++) -+ #else -+ aatx = aarx; -+ #endif -+ { -+ ul_ch0 = &pusch_vars->ul_ch_estimates[aatx*frame_parms->nb_antennas_rx+aarx][pusch_vars->dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available -+ ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_re_pusch2]; -+ -+ memcpy1((void*)ul_ch0_ext,(void*)ul_ch0,nb_re_pusch*sizeof(int32_t)); - } -- memcpy1((void*)ul_ch0_ext,(void*)ul_ch0,nb_re_pusch*sizeof(int32_t)); - } -- else { -- for (re = 0; re < nb_re_pusch; re++) { -- -- is_dmrs_re = (re == get_dmrs_freq_idx_ul(n, k_prime, delta, pusch_pdu->dmrs_config_type)); -- --#ifdef DEBUG_RB_EXT -- printf("re = %d, kprime %d, n %d, is_dmrs_symbol = %d, symbol = %d\n", re, k_prime, n, is_dmrs_symbol, symbol); --#endif -- -- /* save only data and respective channel estimates */ -- if (is_dmrs_re == 0) { -- rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]); -- rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]); -- ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index]; -+ else -+ { -+ #ifdef SUPPORT_PMI_MATRIC -+ for (aatx = 0; aatx < pusch_pdu->nrOfLayers; aatx++) -+ #else -+ aatx = aarx; -+ #endif -+ { -+ ul_ch0 = &pusch_vars->ul_ch_estimates[aatx*frame_parms->nb_antennas_rx+aarx][pusch_vars->dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available -+ ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_re_pusch2]; -+ -+ //n = 0; -+ //k_prime = 0; -+ rxF_ext_index = 0; -+ ul_ch0_ext_index = 0; -+ ul_ch0_index = 0; -+ -+ for (re = 0; re < nb_re_pusch; re++) -+ { -+ uint16_t k= start_re+re; -+ -+ is_data_re = allowed_xlsch_re_in_dmrs_symbol(k, start_re, frame_parms->ofdm_symbol_size, pusch_pdu->num_dmrs_cdm_grps_no_data, pusch_pdu->dmrs_config_type); -+ -+ if (++k >= frame_parms->ofdm_symbol_size) -+ { -+ k -= frame_parms->ofdm_symbol_size; -+ } - --#ifdef DEBUG_RB_EXT -- printf("dmrs symb %d: rxF_ext[%d] = (%d,%d), ul_ch0_ext[%d] = (%d,%d)\n", -+ #ifdef DEBUG_RB_EXT -+ printf("re = %d, kprime %d, n %d, is_dmrs_symbol = %d, symbol = %d\n", re, k_prime, n, is_dmrs_symbol, symbol); -+ #endif -+ -+ /* save only data and respective channel estimates */ -+ if (is_data_re == 1) -+ { -+ if (aatx == aarx) -+ { -+ rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]); -+ rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]); -+ rxF_ext_index +=2; -+ } -+ -+ ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index]; -+ ul_ch0_ext_index++; -+ -+ #ifdef DEBUG_RB_EXT -+ printf("dmrs symb %d: rxF_ext[%d] = (%d,%d), ul_ch0_ext[%d] = (%d,%d)\n", - is_dmrs_symbol,rxF_ext_index>>1, rxF_ext[rxF_ext_index],rxF_ext[rxF_ext_index+1], - ul_ch0_ext_index, ((int16_t*)&ul_ch0_ext[ul_ch0_ext_index])[0], ((int16_t*)&ul_ch0_ext[ul_ch0_ext_index])[1]); --#endif -- ul_ch0_ext_index++; -- rxF_ext_index +=2; -- } else { -- n += k_prime; -- k_prime ^= 1; -+ #endif -+ } -+ ul_ch0_index++; - } -- ul_ch0_index++; - } - } - } -@@ -406,16 +438,19 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, - NR_gNB_ULSCH_t **ulsch_gNB, - uint8_t symbol, - uint8_t is_dmrs_symbol, -- unsigned short nb_rb, -- pusch_dmrs_type_t pusch_dmrs_type) -+ uint32_t len, -+ uint8_t nrOfLayers, -+ unsigned short nb_rb) - { - - #if defined(__x86_64__)||defined(__i386__) - - short rb, ch_amp; -- unsigned char aarx; -+ unsigned char aarx,aatx; - __m128i *ul_ch128, ch_amp128; - -+ uint32_t nb_rb_0 = len/12 + ((len%12)?1:0); -+ - // Determine scaling amplitude based the symbol - - ch_amp = 1024*8; //((pilots) ? (ulsch_gNB[0]->sqrt_rho_b) : (ulsch_gNB[0]->sqrt_rho_a)); -@@ -431,35 +466,26 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, - int off = 0; - #endif - -- 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))]; -- -- if (is_dmrs_symbol==1){ -- if (pusch_dmrs_type == pusch_dmrs_type1) -- nb_rb = nb_rb>>1; -- else -- nb_rb = (2*nb_rb)/3; -- } -- -- for (rb=0;rbnb_antennas_rx; aarx++) -+ { -+ ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*NR_NB_SC_PER_RB))]; - -+ for (rb=0;rb < nb_rb_0;rb++) -+ { - ul_ch128[0] = _mm_mulhi_epi16(ul_ch128[0], ch_amp128); - ul_ch128[0] = _mm_slli_epi16(ul_ch128[0], 3); - - ul_ch128[1] = _mm_mulhi_epi16(ul_ch128[1], ch_amp128); - ul_ch128[1] = _mm_slli_epi16(ul_ch128[1], 3); - -- if (is_dmrs_symbol) { -- ul_ch128+=2; -- } else { -- ul_ch128[2] = _mm_mulhi_epi16(ul_ch128[2], ch_amp128); -- ul_ch128[2] = _mm_slli_epi16(ul_ch128[2], 3); -- ul_ch128+=3; -- -- } -+ ul_ch128[2] = _mm_mulhi_epi16(ul_ch128[2], ch_amp128); -+ ul_ch128[2] = _mm_slli_epi16(ul_ch128[2], 3); -+ ul_ch128+=3; - } -- } -+ } -+} - #endif - } - -@@ -481,6 +507,8 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, - - int16_t x = factor2(len); - int16_t y = (len)>>x; -+ -+ uint32_t nb_rb_0 = len/12 + ((len%12)?1:0); - - #ifdef __AVX2__ - int off = ((nb_rb&1) == 1)? 4:0; -@@ -489,13 +517,16 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, - #endif - - for (aatx = 0; aatx < nrOfLayers; aatx++) -- for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { -+ { -+ for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) -+ { - //clear average level - avg128U = _mm_setzero_si128(); - - ul_ch128=(__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; - -- for (rb = 0; rb < len/12; rb++) { -+ for (rb = 0; rb < nb_rb_0; rb++) -+ { - avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[0], ul_ch128[0]), x)); - avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[1], ul_ch128[1]), x)); - avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[2], ul_ch128[2]), x)); -@@ -508,7 +539,8 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, - ((int32_t*)&avg128U)[3]) / y; - - } -- -+ } -+ - _mm_empty(); - _m_empty(); - -@@ -520,7 +552,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, - int16x4_t *ul_ch128; - - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; -- -+ uint32_t nb_rb_0 = len/12 + ((len%12)?1:0); - for (aatx=0; aatxnb_antennas_rx; aarx++) { - //clear average level -@@ -529,7 +561,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, - - ul_ch128 = (int16x4_t *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*frame_parms->N_RB_UL*12]; - -- for (rb = 0; rb < nb_rb; rb++) { -+ for (rb = 0; rb < nb_rb_0; rb++) { - // printf("rb %d : ",rb); - // print_shorts("ch",&ul_ch128[0]); - avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[0], ul_ch128[0])); -@@ -568,14 +600,20 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, - #endif - } - -+ -+ -+//============================================================================================== -+// Pre-processing for LLR computation -+//============================================================================================== - void nr_ulsch_channel_compensation(int **rxdataF_ext, - int **ul_ch_estimates_ext, - int **ul_ch_mag, - int **ul_ch_magb, - int **rxdataF_comp, -- int **rho, -+ int ***rho, - NR_DL_FRAME_PARMS *frame_parms, - unsigned char symbol, -+ int length, - uint8_t is_dmrs_symbol, - unsigned char mod_order, - uint8_t nrOfLayers, -@@ -637,20 +675,24 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, - __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128={0},QAM_amp128b={0}; - QAM_amp128b = _mm_setzero_si128(); - -- for (aatx=0; aatxnb_antennas_rx; aarx++) { -- -+ for (aarx=0; aarxnb_antennas_rx; aarx++) -+ { - ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; - ul_ch_mag128 = (__m128i *)&ul_ch_mag[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; - ul_ch_mag128b = (__m128i *)&ul_ch_magb[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; -@@ -658,8 +700,10 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, - rxdataF_comp128 = (__m128i *)&rxdataF_comp[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; - - -- for (rb=0; rb2) { -+ for (rb=0; rb2) -+ { - // get channel amplitude if not QPSK - - //print_shorts("ch:",(int16_t*)&ul_ch128[0]); -@@ -679,6 +723,8 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, - ul_ch_mag128[0] = _mm_mulhi_epi16(ul_ch_mag128[0],QAM_amp128); - ul_ch_mag128[0] = _mm_slli_epi16(ul_ch_mag128[0],1); - -+ ul_ch_mag128b[0] = _mm_mulhi_epi16(ul_ch_mag128b[0],QAM_amp128b); -+ ul_ch_mag128b[0] = _mm_slli_epi16(ul_ch_mag128b[0],1); - // print_ints("ch: = ",(int32_t*)&mmtmpD0); - // print_shorts("QAM_amp:",(int16_t*)&QAM_amp128); - // print_shorts("mag:",(int16_t*)&ul_ch_mag128[0]); -@@ -687,30 +733,24 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, - ul_ch_mag128b[1] = ul_ch_mag128[1]; - ul_ch_mag128[1] = _mm_mulhi_epi16(ul_ch_mag128[1],QAM_amp128); - ul_ch_mag128[1] = _mm_slli_epi16(ul_ch_mag128[1],1); -+ -+ ul_ch_mag128b[1] = _mm_mulhi_epi16(ul_ch_mag128b[1],QAM_amp128); -+ ul_ch_mag128b[1] = _mm_slli_epi16(ul_ch_mag128b[1],1); - -- if (is_dmrs_symbol==0) { -- mmtmpD0 = _mm_madd_epi16(ul_ch128[2],ul_ch128[2]); -- mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); -- mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); -- -- ul_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); -- ul_ch_mag128b[2] = ul_ch_mag128[2]; -+ mmtmpD0 = _mm_madd_epi16(ul_ch128[2],ul_ch128[2]); -+ mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); -+ mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); - -- ul_ch_mag128[2] = _mm_mulhi_epi16(ul_ch_mag128[2],QAM_amp128); -- ul_ch_mag128[2] = _mm_slli_epi16(ul_ch_mag128[2],1); -- } -+ ul_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); -+ ul_ch_mag128b[2] = ul_ch_mag128[2]; - -- ul_ch_mag128b[0] = _mm_mulhi_epi16(ul_ch_mag128b[0],QAM_amp128b); -- ul_ch_mag128b[0] = _mm_slli_epi16(ul_ch_mag128b[0],1); -+ ul_ch_mag128[2] = _mm_mulhi_epi16(ul_ch_mag128[2],QAM_amp128); -+ ul_ch_mag128[2] = _mm_slli_epi16(ul_ch_mag128[2],1); - - -- ul_ch_mag128b[1] = _mm_mulhi_epi16(ul_ch_mag128b[1],QAM_amp128b); -- ul_ch_mag128b[1] = _mm_slli_epi16(ul_ch_mag128b[1],1); -+ ul_ch_mag128b[2] = _mm_mulhi_epi16(ul_ch_mag128b[2],QAM_amp128b); -+ ul_ch_mag128b[2] = _mm_slli_epi16(ul_ch_mag128b[2],1); - -- if (is_dmrs_symbol==0) { -- ul_ch_mag128b[2] = _mm_mulhi_epi16(ul_ch_mag128b[2],QAM_amp128b); -- ul_ch_mag128b[2] = _mm_slli_epi16(ul_ch_mag128b[2],1); -- } - } - - // multiply by conjugated channel -@@ -755,117 +795,157 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, - // print_shorts("ch:",ul_ch128+1); - // print_shorts("pack:",rxdataF_comp128+1); - -- if (is_dmrs_symbol==0) { -- // multiply by conjugated channel -- mmtmpD0 = _mm_madd_epi16(ul_ch128[2],rxdataF128[2]); -- // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) -- mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[2],_MM_SHUFFLE(2,3,0,1)); -- mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); -- mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); -- mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); -- // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) -- mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); -- mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); -- mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); -- mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); -- -- rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); -- // print_shorts("rx:",rxdataF128+2); -- // print_shorts("ch:",ul_ch128+2); -- // print_shorts("pack:",rxdataF_comp128+2); -- -- ul_ch128+=3; -- ul_ch_mag128+=3; -- ul_ch_mag128b+=3; -- rxdataF128+=3; -- rxdataF_comp128+=3; -- } else { // we have a smaller PUSCH in symbols with pilots so skip last group of 4 REs and increment less -- ul_ch128+=2; -- ul_ch_mag128+=2; -- ul_ch_mag128b+=2; -- rxdataF128+=2; -- rxdataF_comp128+=2; -- } -- -- } -- } -- } -- -- if (rho) { -- -- for (aarx=0; aarxnb_antennas_rx; aarx++) { -- rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_UL*12]; -- ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_UL*12]; -- ul_ch128_2 = (__m128i *)&ul_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_UL*12]; -- -- for (rb=0; rbnb_antennas_rx][nrOfLayers*nrOfLayers]; -+ int avg_rho_im[frame_parms->nb_antennas_rx][nrOfLayers*nrOfLayers]; -+ -+ for (aarx=0; aarxnb_antennas_rx; aarx++) -+ { -+ for (aatx=0; aatx < nrOfLayers; aatx++) -+ { -+ ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; -+ -+ for (int atx=0; atx< nrOfLayers; atx++) -+ { -+ avg_rho_re[aarx][aatx*nrOfLayers+atx] = 0; -+ avg_rho_im[aarx][aatx*nrOfLayers+atx] = 0; -+ rho128 = (__m128i *)&rho[aarx][aatx*nrOfLayers+atx][symbol*(off+(nb_rb*12))]; -+ ul_ch128_2 = (__m128i *)&ul_ch_estimates_ext[atx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; -+ -+ 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*nrOfLayers+atx] = 16*avg_rho_re[aarx][aatx*nrOfLayers+atx]/(nb_rb*12); -+ avg_rho_im[aarx][aatx*nrOfLayers+atx] = 16*avg_rho_im[aarx][aatx*nrOfLayers+atx]/(nb_rb*12); -+ //printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, aatx,atx, avg_rho_re[aarx][aatx*nb_aatx+atx], avg_rho_im[aarx][aatx*nb_aatx+atx]); -+ } -+ } -+ } - } - } - -@@ -1105,19 +1185,23 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, - } - - void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, -- int32_t **rxdataF_comp, -- int32_t **ul_ch_mag, -- int32_t **ul_ch_magb, -- uint8_t symbol, -- uint16_t nb_rb) { -+ int32_t **rxdataF_comp, -+ int32_t **ul_ch_mag, -+ int32_t **ul_ch_magb, -+ int32_t ***rho, -+ uint8_t nrOfLayers, -+ uint8_t symbol, -+ uint16_t nb_rb, -+ int length) { - int n_rx = frame_parms->nb_antennas_rx; - #if defined(__x86_64__) || defined(__i386__) -- __m128i *rxdataF_comp128[1+n_rx],*ul_ch_mag128[1+n_rx],*ul_ch_mag128b[1+n_rx]; -+ __m128i *rxdataF_comp128[2],*ul_ch_mag128[2],*ul_ch_mag128b[2]; - #elif defined(__arm__) - int16x8_t *rxdataF_comp128_0,*ul_ch_mag128_0,*ul_ch_mag128_0b; - int16x8_t *rxdataF_comp128_1,*ul_ch_mag128_1,*ul_ch_mag128_1b; - #endif - int32_t i; -+ uint32_t nb_rb_0 = length/12 + ((length%12)?1:0); - - #ifdef __AVX2__ - int off = ((nb_rb&1) == 1)? 4:0; -@@ -1125,23 +1209,34 @@ void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, - int off = 0; - #endif - -- if (frame_parms->nb_antennas_rx>1) { --#if defined(__x86_64__) || defined(__i386__) -- int nb_re = nb_rb*12; -- for (int aa=0;aanb_antennas_rx;aa++) { -- rxdataF_comp128[aa] = (__m128i *)&rxdataF_comp[aa][(symbol*(nb_re + off))]; -- ul_ch_mag128[aa] = (__m128i *)&ul_ch_mag[aa][(symbol*(nb_re + off))]; -- ul_ch_mag128b[aa] = (__m128i *)&ul_ch_magb[aa][(symbol*(nb_re + off))]; -- } -- for (int aa=1;aanb_antennas_rx;aa++) { -- // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) -- for (i=0; i 1) -+ { -+ #if defined(__x86_64__) || defined(__i386__) -+ for (int aatx=0; aatxnb_antennas_rx][(symbol*(nb_re + off))]; -+ ul_ch_mag128[0] = (__m128i *)&ul_ch_mag[aatx*frame_parms->nb_antennas_rx][(symbol*(nb_re + off))]; -+ ul_ch_mag128b[0] = (__m128i *)&ul_ch_magb[aatx*frame_parms->nb_antennas_rx][(symbol*(nb_re + off))]; -+ -+ for (int aa=1;aa < n_rx;aa++) -+ { -+ rxdataF_comp128[1] = (__m128i *)&rxdataF_comp[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))]; -+ ul_ch_mag128[1] = (__m128i *)&ul_ch_mag[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))]; -+ ul_ch_mag128b[1] = (__m128i *)&ul_ch_magb[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))]; -+ -+ // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) -+ for (i=0; iN_RB_DL*12]; - rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12]; - ul_ch_mag128_0 = (int16x8_t *)&ul_ch_mag[0][symbol*frame_parms->N_RB_DL*12]; -@@ -1156,7 +1251,7 @@ void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, - ul_ch_mag128_0b[i] = vhaddq_s16(ul_ch_mag128_0b[i],ul_ch_mag128_1b[i]); - rxdataF_comp128_0[i] = vqaddq_s16(rxdataF_comp128_0[i],(*(int16x8_t *)&jitterc[0])); - } --#endif -+ #endif - } - - #if defined(__x86_64__) || defined(__i386__) -@@ -1165,6 +1260,696 @@ void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, - #endif - } - -+/* Zero Forcing Rx function: nr_det_HhH() -+ * -+ * -+ * */ -+void nr_ulsch_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, -+ int32_t shift) -+{ -+ 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); -+ -+ //det in Q30 format -+ det_fin_128[0] = _mm_abs_epi32(det_re_128); -+ -+ -+#ifdef DEBUG_DLSCH_DEMOD -+ 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]); -+#endif -+ 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_ulsch_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_ulsch_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(); -+} -+__m128i nr_ulsch_comp_muli_sum(__m128i input_x, -+ __m128i input_y, -+ __m128i input_w, -+ __m128i input_z, -+ __m128i det) -+{ -+ int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ; -+ -+ __m128i xy_re_128, xy_im_128, wz_re_128, wz_im_128; -+ __m128i output, 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) -+ -+ // complex multiplication (w_re + jw_im)*(z_re + jz_im) = (w_re*z_re - w_im*z_im) + j(w_im*z_re + w_re*z_im) -+ // the real part -+ wz_re_128 = _mm_sign_epi16(input_w,*(__m128i*)&nr_conjug2[0]); -+ wz_re_128 = _mm_madd_epi16(wz_re_128,input_z); //Re: (w_re*z_re - w_im*z_im) -+ -+ // the imag part -+ wz_im_128 = _mm_shufflelo_epi16(input_w,_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 -+ wz_im_128 = _mm_shufflehi_epi16(wz_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 -+ wz_im_128 = _mm_madd_epi16(wz_im_128,input_z);//Im: (w_im*z_re + w_re*z_im) -+ -+ -+ xy_re_128 = _mm_sub_epi32(xy_re_128, wz_re_128); -+ xy_im_128 = _mm_sub_epi32(xy_im_128, wz_im_128); -+ //print_ints("rx_re:",(int32_t*)&xy_re_128[0]); -+ //print_ints("rx_Img:",(int32_t*)&xy_im_128[0]); -+ //divide by matrix det and convert back to Q15 before packing -+ int sum_det =0; -+ for (int k=0; k<4;k++) { -+ sum_det += ((((int *)&det[0])[k])>>2); -+ //printf("det_%d = %d log2 =%d \n",k,(((int *)&det[0])[k]),log2_approx(((int *)&det[0])[k])); -+ } -+ -+ xy_re_128 = _mm_slli_epi32(xy_re_128,5); -+ xy_re_128 = _mm_srai_epi32(xy_re_128,log2_approx(sum_det)); -+ xy_re_128 = _mm_slli_epi32(xy_re_128,5); -+ -+ xy_im_128 = _mm_slli_epi32(xy_im_128,5); -+ xy_im_128 = _mm_srai_epi32(xy_im_128,log2_approx(sum_det)); -+ xy_im_128 = _mm_slli_epi32(xy_im_128,5); -+ -+ 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 = _mm_packs_epi32(tmp_z0,tmp_z1); -+ -+ _mm_empty(); -+ _m_empty(); -+ return(output); -+} -+/* Zero Forcing Rx function: nr_construct_HhH_elements() -+ * -+ * -+ * */ -+void nr_ulsch_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]); -+ -+#ifdef DEBUG_DLSCH_DEMOD -+ if ((rb<=30)) -+ { -+ 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]); -+ } -+#endif -+ 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_ulsch_zero_forcing_rx_2layers() -+ * -+ * -+ * */ -+uint8_t nr_ulsch_zero_forcing_rx_2layers(int **rxdataF_comp, -+ int **ul_ch_mag, -+ int **ul_ch_magb, -+ int **ul_ch_estimates_ext, -+ unsigned short nb_rb, -+ unsigned char n_rx, -+ unsigned char mod_order, -+ int shift, -+ unsigned char symbol, -+ int length) -+{ -+ int *ch00, *ch01, *ch10, *ch11; -+ int *ch20, *ch30, *ch21, *ch31; -+ uint32_t nb_rb_0 = length/12 + ((length%12)?1:0); -+ -+ #ifdef __AVX2__ -+ int off = ((nb_rb&1) == 1)? 4:0; -+ #else -+ int off = 0; -+ #endif -+ -+ /* 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 *)&ul_ch_estimates_ext[0][symbol*(off+nb_rb*12)]; -+ ch01 = (int *)&ul_ch_estimates_ext[2][symbol*(off+nb_rb*12)]; -+ ch10 = (int *)&ul_ch_estimates_ext[1][symbol*(off+nb_rb*12)]; -+ ch11 = (int *)&ul_ch_estimates_ext[3][symbol*(off+nb_rb*12)]; -+ ch20 = NULL; -+ ch21 = NULL; -+ ch30 = NULL; -+ ch31 = NULL; -+ break; -+ -+ case 4:// -+ ch00 = (int *)&ul_ch_estimates_ext[0][symbol*(off+nb_rb*12)]; -+ ch01 = (int *)&ul_ch_estimates_ext[4][symbol*(off+nb_rb*12)]; -+ ch10 = (int *)&ul_ch_estimates_ext[1][symbol*(off+nb_rb*12)]; -+ ch11 = (int *)&ul_ch_estimates_ext[5][symbol*(off+nb_rb*12)]; -+ ch20 = (int *)&ul_ch_estimates_ext[2][symbol*(off+nb_rb*12)]; -+ ch21 = (int *)&ul_ch_estimates_ext[6][symbol*(off+nb_rb*12)]; -+ ch30 = (int *)&ul_ch_estimates_ext[3][symbol*(off+nb_rb*12)]; -+ ch31 = (int *)&ul_ch_estimates_ext[7][symbol*(off+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_ulsch_conjch0_mult_ch1(ch00, -+ ch00, -+ conjch00_ch00, -+ nb_rb_0, -+ shift); -+ // (1/2^log2_maxh)*conj_H_10xH_10: (1/(64*2))conjH_10*H_10*2^15 -+ nr_ulsch_conjch0_mult_ch1(ch10, -+ ch10, -+ conjch10_ch10, -+ nb_rb_0, -+ shift); -+ // conj_H_00xH_01 -+ nr_ulsch_conjch0_mult_ch1(ch00, -+ ch01, -+ conjch00_ch01, -+ nb_rb_0, -+ shift); // this shift is equal to the channel level log2_maxh -+ // conj_H_10xH_11 -+ nr_ulsch_conjch0_mult_ch1(ch10, -+ ch11, -+ conjch10_ch11, -+ nb_rb_0, -+ shift); -+ // conj_H_01xH_01 -+ nr_ulsch_conjch0_mult_ch1(ch01, -+ ch01, -+ conjch01_ch01, -+ nb_rb_0, -+ shift); -+ // conj_H_11xH_11 -+ nr_ulsch_conjch0_mult_ch1(ch11, -+ ch11, -+ conjch11_ch11, -+ nb_rb_0, -+ shift); -+ // conj_H_01xH_00 -+ nr_ulsch_conjch0_mult_ch1(ch01, -+ ch00, -+ conjch01_ch00, -+ nb_rb_0, -+ shift); -+ // conj_H_11xH_10 -+ nr_ulsch_conjch0_mult_ch1(ch11, -+ ch10, -+ conjch11_ch10, -+ nb_rb_0, -+ shift); -+ } -+ if (n_rx==4){ -+ // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2*16))conjH_20*H_20*2^15 -+ nr_ulsch_conjch0_mult_ch1(ch20, -+ ch20, -+ conjch20_ch20, -+ nb_rb_0, -+ shift); -+ -+ // (1/2^log2_maxh)*conj_H_30xH_30: (1/(64*2*4))conjH_30*H_30*2^15 -+ nr_ulsch_conjch0_mult_ch1(ch30, -+ ch30, -+ conjch30_ch30, -+ nb_rb_0, -+ shift); -+ -+ // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15 -+ nr_ulsch_conjch0_mult_ch1(ch20, -+ ch21, -+ conjch20_ch21, -+ nb_rb_0, -+ shift); -+ -+ nr_ulsch_conjch0_mult_ch1(ch30, -+ ch31, -+ conjch30_ch31, -+ nb_rb_0, -+ shift); -+ -+ nr_ulsch_conjch0_mult_ch1(ch21, -+ ch21, -+ conjch21_ch21, -+ nb_rb_0, -+ shift); -+ -+ nr_ulsch_conjch0_mult_ch1(ch31, -+ ch31, -+ conjch31_ch31, -+ nb_rb_0, -+ shift); -+ -+ // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15 -+ nr_ulsch_conjch0_mult_ch1(ch21, -+ ch20, -+ conjch21_ch20, -+ nb_rb_0, -+ shift); -+ -+ nr_ulsch_conjch0_mult_ch1(ch31, -+ ch30, -+ conjch31_ch30, -+ nb_rb_0, -+ shift); -+ -+ nr_ulsch_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_0, -+ symbol); -+ } -+ if (n_rx==2){ -+ nr_ulsch_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_0, -+ symbol); -+ } -+ //det_HhH = ad -bc -+ nr_ulsch_det_HhH(af_mf_00,//a -+ af_mf_01,//b -+ af_mf_10,//c -+ af_mf_11,//d -+ determ_fin, -+ nb_rb_0, -+ symbol, -+ shift); -+ /* 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,*ul_ch_mag128_0=NULL,*ul_ch_mag128b_0=NULL,*determ_fin_128;//*dl_ch_mag128_1,*dl_ch_mag128b_1,*dl_ch_mag128r_1 -+ __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; -+ __m128i *after_mf_a_128,*after_mf_b_128, *after_mf_c_128, *after_mf_d_128; -+ __m128i QAM_amp128={0},QAM_amp128b={0}; -+ -+ determ_fin_128 = (__m128i *)&determ_fin[0]; -+ -+ rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][symbol*(off+nb_rb*12)];//aatx=0 @ aarx =0 -+ rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[n_rx][symbol*(off+nb_rb*12)];//aatx=1 @ aarx =0 -+ -+ 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; -+ -+ if (mod_order>2) { -+ 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); //4/sqrt{42} -+ QAM_amp128b = _mm_set1_epi16(QAM64_n2); //2/sqrt{42} -+ } -+ ul_ch_mag128_0 = (__m128i *)&ul_ch_mag[0][symbol*(off+nb_rb*12)]; -+ ul_ch_mag128b_0 = (__m128i *)&ul_ch_magb[0][symbol*(off+nb_rb*12)]; -+ } -+ -+ for (int rb=0; rb<3*nb_rb_0; rb++) { -+ if (mod_order>2) { -+ int sum_det =0; -+ for (int k=0; k<4;k++) { -+ sum_det += ((((int *)&determ_fin_128[0])[k])>>2); -+ //printf("det_%d = %d\n",k,sum_det); -+ } -+ -+ mmtmpD2 = _mm_slli_epi32(determ_fin_128[0],5); -+ mmtmpD2 = _mm_srai_epi32(mmtmpD2,log2_approx(sum_det)); -+ mmtmpD2 = _mm_slli_epi32(mmtmpD2,5); -+ -+ mmtmpD3 = _mm_unpacklo_epi32(mmtmpD2,mmtmpD2); -+ -+ mmtmpD2 = _mm_unpackhi_epi32(mmtmpD2,mmtmpD2); -+ -+ mmtmpD2 = _mm_packs_epi32(mmtmpD3,mmtmpD2); -+ -+ ul_ch_mag128_0[0] = mmtmpD2; -+ ul_ch_mag128b_0[0] = mmtmpD2; -+ -+ ul_ch_mag128_0[0] = _mm_mulhi_epi16(ul_ch_mag128_0[0],QAM_amp128); -+ ul_ch_mag128_0[0] = _mm_slli_epi16(ul_ch_mag128_0[0],1); -+ -+ ul_ch_mag128b_0[0] = _mm_mulhi_epi16(ul_ch_mag128b_0[0],QAM_amp128b); -+ ul_ch_mag128b_0[0] = _mm_slli_epi16(ul_ch_mag128b_0[0],1); -+ -+ //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]); -+ //print_shorts("magr layer 1:",(int16_t*)&dl_ch_mag128r_0[0]); -+ //print_shorts("magr layer 2:",(int16_t*)&dl_ch_mag128r_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 -+ //printf("layer_1 \n"); -+ mmtmpD0 = nr_ulsch_comp_muli_sum(rxdataF_comp128_0[0], -+ after_mf_d_128[0], -+ rxdataF_comp128_1[0], -+ after_mf_b_128[0], -+ determ_fin_128[0]); -+ -+ //printf("layer_2 \n"); -+ mmtmpD1 = nr_ulsch_comp_muli_sum(rxdataF_comp128_1[0], -+ after_mf_a_128[0], -+ rxdataF_comp128_0[0], -+ after_mf_c_128[0], -+ determ_fin_128[0]); -+ -+ rxdataF_comp128_0[0] = mmtmpD0; -+ rxdataF_comp128_1[0] = mmtmpD1; -+#ifdef DEBUG_DLSCH_DEMOD -+ printf("\n Rx signal after ZF l%d rb%d\n",symbol,rb); -+ print_shorts(" Rx layer 1:",(int16_t*)&rxdataF_comp128_0[0]); -+ print_shorts(" Rx layer 2:",(int16_t*)&rxdataF_comp128_1[0]); -+#endif -+ determ_fin_128 += 1; -+ ul_ch_mag128_0 += 1; -+ ul_ch_mag128b_0 += 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); -+} -+ -+//============================================================================================== -+ -+/* Main Function */ - int nr_rx_pusch(PHY_VARS_gNB *gNB, - uint8_t ulsch_id, - uint32_t frame, -@@ -1184,21 +1969,29 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, - gNB->pusch_vars[ulsch_id]->cl_done = 0; - - bwp_start_subcarrier = ((rel15_ul->rb_start + rel15_ul->bwp_start)*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size; -- LOG_D(PHY,"pusch %d.%d : bwp_start_subcarrier %d, rb_start %d, first_carrier_offset %d\n", frame,slot,bwp_start_subcarrier, rel15_ul->rb_start, frame_parms->first_carrier_offset); -- LOG_D(PHY,"pusch %d.%d : ul_dmrs_symb_pos %x\n",frame,slot,rel15_ul->ul_dmrs_symb_pos); -- -+ LOG_I(PHY,"pusch %d.%d : bwp_start_subcarrier %d, rb_start %d, first_carrier_offset %d\n", frame,slot,bwp_start_subcarrier, rel15_ul->rb_start, frame_parms->first_carrier_offset); -+ LOG_I(PHY,"pusch %d.%d : ul_dmrs_symb_pos %x\n",frame,slot,rel15_ul->ul_dmrs_symb_pos); -+ LOG_I(PHY,"ulsch RX %x : start_rb %d nb_rb %d mcs %d Nl %d Tpmi %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_ports %d\n", -+ rel15_ul->rnti,rel15_ul->rb_start,rel15_ul->rb_size,rel15_ul->mcs_index, -+ rel15_ul->nrOfLayers,0,rel15_ul->bwp_start,0,rel15_ul->start_symbol_index,rel15_ul->nr_of_symbols, -+ rel15_ul->num_dmrs_cdm_grps_no_data,rel15_ul->ul_dmrs_symb_pos,rel15_ul->dmrs_ports); - //---------------------------------------------------------- - //--------------------- Channel estimation --------------------- - //---------------------------------------------------------- - start_meas(&gNB->ulsch_channel_estimation_stats); -- for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) { -+ for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) -+ { - uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01; - LOG_D(PHY, "symbol %d, dmrs_symbol_flag :%d\n", symbol, dmrs_symbol_flag); -- if (dmrs_symbol_flag == 1) { -+ -+ if (dmrs_symbol_flag == 1) -+ { - if (gNB->pusch_vars[ulsch_id]->dmrs_symbol == INVALID_VALUE) - gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol; - - for (int nl=0; nlnrOfLayers; nl++) -+ { -+ - nr_pusch_channel_estimation(gNB, - slot, - get_dmrs_port(nl,rel15_ul->dmrs_ports), -@@ -1206,6 +1999,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, - ulsch_id, - bwp_start_subcarrier, - rel15_ul); -+ } - - nr_gnb_measurements(gNB, ulsch_id, harq_pid, symbol,rel15_ul->nrOfLayers); - -@@ -1214,9 +2008,12 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, - gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] = 0; - gNB->pusch_vars[ulsch_id]->ulsch_noise_power[aarx] = 0; - } -- gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] += signal_energy_nodc( -- &gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aarx][symbol * frame_parms->ofdm_symbol_size], -+ for (aatx = 0; aatx < rel15_ul->nrOfLayers; aatx++) -+ { -+ gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] += signal_energy_nodc( -+ &gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aatx*gNB->frame_parms.nb_antennas_rx+aarx][symbol * frame_parms->ofdm_symbol_size], - rel15_ul->rb_size * 12); -+ } - for (int rb = 0; rb < rel15_ul->rb_size; rb++) { - gNB->pusch_vars[ulsch_id]->ulsch_noise_power[aarx] += - gNB->measurements.n0_subband_power[aarx][rel15_ul->bwp_start + rel15_ul->rb_start + rb] / -@@ -1234,23 +2031,29 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, - #endif - uint32_t rxdataF_ext_offset = 0; - -- for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) { -+ for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) -+ { - uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01; -- if (dmrs_symbol_flag == 1) { -+ if (dmrs_symbol_flag == 1) -+ { - if ((rel15_ul->ul_dmrs_symb_pos >> ((symbol + 1) % frame_parms->symbols_per_slot)) & 0x01) - AssertFatal(1==0,"Double DMRS configuration is not yet supported\n"); - - gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol; - -- if (rel15_ul->dmrs_config_type == 0) { -+ if (rel15_ul->dmrs_config_type == 0) -+ { - // if no data in dmrs cdm group is 1 only even REs have no data - // if no data in dmrs cdm group is 2 both odd and even REs have no data - nb_re_pusch = rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*6)); - } -- else { -+ else -+ { - nb_re_pusch = rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*4)); - } -- } else { -+ } -+ else -+ { - nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB; - } - -@@ -1260,16 +2063,16 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, - //---------------------------------------------------------- - //--------------------- RBs extraction --------------------- - //---------------------------------------------------------- -- if (nb_re_pusch > 0) { -- -+ if (nb_re_pusch > 0) -+ { - start_meas(&gNB->ulsch_rbs_extraction_stats); -- nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF, -- gNB->pusch_vars[ulsch_id], -- slot, -- symbol, -- dmrs_symbol_flag, -- rel15_ul, -- frame_parms); -+ nr_ulsch_extract_rbs(gNB->common_vars.rxdataF, -+ gNB->pusch_vars[ulsch_id], -+ slot, -+ symbol, -+ dmrs_symbol_flag, -+ rel15_ul, -+ frame_parms); - stop_meas(&gNB->ulsch_rbs_extraction_stats); - - //---------------------------------------------------------- -@@ -1280,8 +2083,9 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, - gNB->ulsch[ulsch_id], - symbol, - dmrs_symbol_flag, -- rel15_ul->rb_size, -- rel15_ul->dmrs_config_type); -+ nb_re_pusch, -+ rel15_ul->nrOfLayers, -+ rel15_ul->rb_size); - - if (gNB->pusch_vars[ulsch_id]->cl_done==0) { - nr_ulsch_channel_level(gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext, -@@ -1312,9 +2116,14 @@ 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, -+ #ifdef SUPPORT_PMI_MATRIC - (rel15_ul->nrOfLayers>1) ? gNB->pusch_vars[ulsch_id]->rho : NULL, -+ #else -+ NULL, -+ #endif - frame_parms, - symbol, -+ nb_re_pusch, - dmrs_symbol_flag, - rel15_ul->qam_mod_order, - rel15_ul->nrOfLayers, -@@ -1327,19 +2136,37 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, - gNB->pusch_vars[ulsch_id]->rxdataF_comp, - gNB->pusch_vars[ulsch_id]->ul_ch_mag0, - gNB->pusch_vars[ulsch_id]->ul_ch_magb0, -+ #ifdef SUPPORT_PMI_MATRIC -+ (rel15_ul->nrOfLayers>1) ? gNB->pusch_vars[ulsch_id]->rho : NULL, -+ #else -+ NULL, -+ #endif -+ rel15_ul->nrOfLayers, - symbol, -- rel15_ul->rb_size); -+ rel15_ul->rb_size, -+ nb_re_pusch); -+ -+ if (rel15_ul->nrOfLayers == 2)//Apply zero forcing for 2 Tx layers -+ nr_ulsch_zero_forcing_rx_2layers(gNB->pusch_vars[ulsch_id]->rxdataF_comp, -+ gNB->pusch_vars[ulsch_id]->ul_ch_mag0, -+ gNB->pusch_vars[ulsch_id]->ul_ch_magb0, -+ gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext, -+ rel15_ul->rb_size, -+ frame_parms->nb_antennas_rx, -+ rel15_ul->qam_mod_order, -+ gNB->pusch_vars[ulsch_id]->log2_maxh, -+ symbol, -+ nb_re_pusch); - stop_meas(&gNB->ulsch_mrc_stats); - -- // transform precoding = 0 means enabled -- if (rel15_ul->transform_precoding == 0) { -- -- #ifdef __AVX2__ -+ if (rel15_ul->transformPrecoder == transformPrecoder_enabled) -+ { -+ #ifdef __AVX2__ - // For odd number of resource blocks need byte alignment to multiple of 8 - int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7); -- #else -+ #else - int nb_re_pusch2 = nb_re_pusch; -- #endif -+ #endif - - // perform IDFT operation on the compensated rxdata if transform precoding is enabled - nr_idft(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][symbol * nb_re_pusch2], nb_re_pusch); -@@ -1351,7 +2178,8 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, - //---------------------------------------------------------- - /* In case PTRS is enabled then LLR will be calculated after PTRS symbols are processed * - * otherwise LLR are calculated for each symbol based upon DMRS channel estimates only. */ -- if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { -+ if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) -+ { - start_meas(&gNB->ulsch_ptrs_processing_stats); - nr_pusch_ptrs_processing(gNB, - frame_parms, -@@ -1370,14 +2198,17 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, - /*-------------------- LLRs computation -------------------------------------------------------------*/ - /*-----------------------------------------------------------------------------------------------------*/ - start_meas(&gNB->ulsch_llr_stats); -- nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][symbol * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)], -- gNB->pusch_vars[ulsch_id]->ul_ch_mag0, -- gNB->pusch_vars[ulsch_id]->ul_ch_magb0, -- &gNB->pusch_vars[ulsch_id]->llr[rxdataF_ext_offset * rel15_ul->qam_mod_order], -- rel15_ul->rb_size, -- gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol], -- symbol, -- rel15_ul->qam_mod_order); -+ for (aatx=0; aatx < rel15_ul->nrOfLayers; aatx++) -+ { -+ nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aatx*frame_parms->nb_antennas_rx][symbol * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)], -+ gNB->pusch_vars[ulsch_id]->ul_ch_mag0[aatx*frame_parms->nb_antennas_rx], -+ gNB->pusch_vars[ulsch_id]->ul_ch_magb0[aatx*frame_parms->nb_antennas_rx], -+ &gNB->pusch_vars[ulsch_id]->llr_layers[aatx][rxdataF_ext_offset * rel15_ul->qam_mod_order], -+ rel15_ul->rb_size, -+ gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol], -+ symbol, -+ rel15_ul->qam_mod_order); -+ } - stop_meas(&gNB->ulsch_llr_stats); - rxdataF_ext_offset += gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol]; - } -diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c -index bf96a76106..ad41ebf3d6 100644 ---- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c -+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c -@@ -64,7 +64,7 @@ void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp, - //---------------------------------------------------------------------------------------------- - - void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, -- int32_t **ul_ch_mag, -+ int32_t *ul_ch_mag, - int16_t *ulsch_llr, - uint32_t nb_rb, - uint32_t nb_re, -@@ -110,12 +110,12 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, - - #if defined(__x86_64__) || defined(__i386__) - #ifdef __AVX2__ -- ch_mag = (__m256i*)&ul_ch_mag[0][(symbol*(off+(nb_rb*12)))]; -+ ch_mag = (__m256i*)&ul_ch_mag[(symbol*(off+(nb_rb*12)))]; - #else -- ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*(off+(nb_rb*12)))]; -+ ch_mag = (__m128i*)&ul_ch_mag[(symbol*(off+(nb_rb*12)))]; - #endif - #elif defined(__arm__) -- ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)]; -+ ch_mag = (int16x8_t*)&ul_ch_mag[(symbol*nb_rb*12)]; - #endif - - #ifdef __AVX2__ -@@ -231,8 +231,8 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, - //---------------------------------------------------------------------------------------------- - - void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, -- int32_t **ul_ch_mag, -- int32_t **ul_ch_magb, -+ int32_t *ul_ch_mag, -+ int32_t *ul_ch_magb, - int16_t *ulsch_llr, - uint32_t nb_rb, - uint32_t nb_re, -@@ -265,15 +265,15 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, - - #if defined(__x86_64__) || defined(__i386__) - #ifdef __AVX2__ -- ch_mag = (__m256i*)&ul_ch_mag[0][(symbol*(off+(nb_rb*12)))]; -- ch_magb = (__m256i*)&ul_ch_magb[0][(symbol*(off+(nb_rb*12)))]; -+ ch_mag = (__m256i*)&ul_ch_mag[(symbol*(off+(nb_rb*12)))]; -+ ch_magb = (__m256i*)&ul_ch_magb[(symbol*(off+(nb_rb*12)))]; - #else -- ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*nb_rb*12)]; -- ch_magb = (__m128i*)&ul_ch_magb[0][(symbol*nb_rb*12)]; -+ ch_mag = (__m128i*)&ul_ch_mag[(symbol*nb_rb*12)]; -+ ch_magb = (__m128i*)&ul_ch_magb[(symbol*nb_rb*12)]; - #endif - #elif defined(__arm__) -- ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)]; -- ch_magb = (int16x8_t*)&ul_ch_magb[0][(symbol*nb_rb*12)]; -+ ch_mag = (int16x8_t*)&ul_ch_mag[(symbol*nb_rb*12)]; -+ ch_magb = (int16x8_t*)&ul_ch_magb[(symbol*nb_rb*12)]; - #endif - - #ifdef __AVX2__ -@@ -471,8 +471,8 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, - - - void nr_ulsch_compute_llr(int32_t *rxdataF_comp, -- int32_t **ul_ch_mag, -- int32_t **ul_ch_magb, -+ int32_t *ul_ch_mag, -+ int32_t *ul_ch_magb, - int16_t *ulsch_llr, - uint32_t nb_rb, - uint32_t nb_re, -diff --git a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c -index 65ae288252..2cb7609d62 100644 ---- a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c -+++ b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c -@@ -148,7 +148,7 @@ short filt8_dcr0_h[8]= { - 0,4096,8192,12288,16384,0,0,0}; - - short filt8_l1[8] = { --24576,16384,0,0,0,0,0,0}; -+24576,16384,8192,0,0,0,0,0}; - - short filt8_ml1[8] = { - -8192,0,8192,16384,8192,0,0,0}; -@@ -163,10 +163,10 @@ short filt8_mm1[8]= { - 0,0,0,0,8192,16384,8192,0}; - - short filt8_dcl1[8]= { --0,0,0,16384,12288,8192,4096,0}; -+0,0,16384,12288,8192,4096,0,0}; - - short filt8_dcr1[8]= { --0,0,0,0,4096,8192,12288,16384}; -+0,0,0,4096,8192,12288,16384,0}; - - short filt8_dcl1_h[8]= { - 0,16384,12288,8192,4096,0,0,0}; -diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c -index 945dc51673..a293eec6d8 100644 ---- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c -+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c -@@ -258,6 +258,15 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, - Ilbrm = 0; - Tbslbrm = 950984; //max tbs - Coderate = 0.0; -+ -+ #if 0 -+ harq_process->a[0] = 0x31; -+ for (int i = 1; i < harq_process->pusch_pdu.pusch_data.tb_size; i++) -+ { -+ harq_process->a[i] = (i&0xff); -+ } -+ #endif -+ - trace_NRpdu(DIRECTION_UPLINK, harq_process->a, harq_process->pusch_pdu.pusch_data.tb_size, 0, WS_C_RNTI, 0, 0, 0,0, 0); - /////////// - ///////////////////////////////////////////////////////////////////////////////////////// -diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c -index 99dc2b658e..5d76e654ba 100644 ---- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c -+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c -@@ -98,13 +98,12 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, - uint8_t thread_id, - int gNB_id) { - -- LOG_D(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot); -+ LOG_I(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot); - - uint32_t available_bits; - uint8_t cwd_index, l; - uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5]; -- int16_t **tx_layers; -- int32_t **txdataF; -+ - int8_t Wf[2], Wt[2], l_prime[2], delta; - uint8_t nb_dmrs_re_per_rb; - int ap, i; -@@ -112,6 +111,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, - - NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms; - NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id]; -+ int16_t **tx_layers = (int16_t **)pusch_ue->txdataF_layers; -+ int16_t **tx_precoding = (int16_t **)pusch_ue->txdataF_precoding; -+ int32_t **txdataF = UE->common_vars.txdataF; - - uint8_t num_of_codewords = 1; // tmp assumption - int Nid_cell = 0; -@@ -148,9 +150,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, - - nb_dmrs_re_per_rb = ((dmrs_type == pusch_dmrs_type1) ? 6:4)*cdm_grps_no_data; - -- LOG_D(PHY,"ulsch %x : start_rb %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_re_per_rb %d\n", -- rnti,start_rb,pusch_pdu->bwp_start,start_sc,start_symbol,number_of_symbols,cdm_grps_no_data,number_dmrs_symbols,nb_dmrs_re_per_rb); -- -+ LOG_I(PHY,"ulsch TX %x : start_rb %d nb_rb %d mod_order %d Nl %d Tpmi %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_re_per_rb %d\n", -+ rnti,start_rb,nb_rb,mod_order,Nl,pusch_pdu->Tpmi,pusch_pdu->bwp_start,start_sc,start_symbol,number_of_symbols,cdm_grps_no_data,number_dmrs_symbols,nb_dmrs_re_per_rb); -+ - // TbD num_of_mod_symbols is set but never used - N_RE_prime = NR_NB_SC_PER_RB*number_of_symbols - nb_dmrs_re_per_rb*number_dmrs_symbols - N_PRB_oh; - harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb*num_of_codewords; -@@ -236,8 +238,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, - /////////////////////////ULSCH layer mapping///////////////////////// - /////////// - -- tx_layers = (int16_t **)pusch_ue->txdataF_layers; -- - nr_ue_layer_mapping(UE->ulsch[thread_id][gNB_id], - Nl, - available_bits/mod_order, -@@ -257,7 +257,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, - int16_t *dmrs_seq = NULL; - - // if transform precoding is enbaled (value 0) -- if (pusch_pdu->transform_precoding == 0) { -+ if (pusch_pdu->transformPrecoder == transformPrecoder_enabled) { - - uint32_t nb_re_pusch=nb_rb * NR_NB_SC_PER_RB; - uint32_t y_offset = 0; -@@ -315,10 +315,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, - LOG_M("UE_DMRS_SEQ.m","UE_DMRS_SEQ", dmrs_seq,nb_re_pusch,1,1); - #endif - -- } -- else -- memcpy(ulsch_ue->y, tx_layers[0], (available_bits/mod_order)*sizeof(int32_t)); -- -+ } - - /////////// - //////////////////////////////////////////////////////////////////////// -@@ -328,145 +325,233 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, - /////////////////////////ULSCH RE mapping///////////////////////// - /////////// - -- txdataF = UE->common_vars.txdataF; -- -- for (ap=0; ap< Nl; ap++) { -- -- uint8_t k_prime = 0; -- uint16_t m = 0; -- -- -- #ifdef DEBUG_PUSCH_MAPPING -+ for (ap=0; ap< Nl; ap++) -+ { -+ uint8_t k_prime = 0; -+ uint16_t m = 0; -+ -+ #ifdef DEBUG_PUSCH_MAPPING - printf("NR_ULSCH_UE: Value of CELL ID %d /t, u %d \n", frame_parms->Nid_cell, u); -- #endif -- -- -- -- // DMRS params for this ap -- get_Wt(Wt, ap, dmrs_type); -- get_Wf(Wf, ap, dmrs_type); -- delta = get_delta(ap, dmrs_type); -- -- for (l=start_symbol; l> l) & 0x01) { -- is_dmrs_sym = 1; -- -- // transform precoding disabled (value 1) -- if (pusch_pdu->transform_precoding == 1){ -- -- if (dmrs_type == pusch_dmrs_type1) -- dmrs_idx = (pusch_pdu->bwp_start + start_rb)*6; -- else -- dmrs_idx = (pusch_pdu->bwp_start + start_rb)*4; -- -- // TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part -- // Perform this on gold sequence, not required when SC FDMA operation is done, -- LOG_D(PHY,"DMRS in symbol %d\n",l); -- nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated -- -- } else { -- dmrs_idx = 0; -- } -- -- -- } else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { -- -- AssertFatal(pusch_pdu->transform_precoding == 1, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); -+ #endif - -- if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) { -- is_ptrs_sym = 1; -- nr_modulation(pusch_dmrs[l][0], nb_rb, DMRS_MOD_ORDER, mod_ptrs); -+ // DMRS params for this ap -+ get_Wt(Wt, ap, dmrs_type); -+ get_Wf(Wf, ap, dmrs_type); -+ delta = get_delta(ap, dmrs_type); -+ -+ for (l=start_symbol; l> l) & 0x01) -+ { -+ is_dmrs_sym = 1; -+ if (pusch_pdu->transformPrecoder == transformPrecoder_disabled) -+ { -+ if (dmrs_type == pusch_dmrs_type1) -+ dmrs_idx = (pusch_pdu->bwp_start + start_rb)*6; -+ else -+ dmrs_idx = (pusch_pdu->bwp_start + start_rb)*4; -+ -+ // TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part -+ // Perform this on gold sequence, not required when SC FDMA operation is done, -+ LOG_D(PHY,"DMRS in symbol %d\n",l); -+ nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated -+ } -+ else -+ { -+ dmrs_idx = 0; -+ } -+ } -+ else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) -+ { -+ AssertFatal(pusch_pdu->transformPrecoder == transformPrecoder_disabled, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); -+ -+ if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) -+ { -+ is_ptrs_sym = 1; -+ nr_modulation(pusch_dmrs[l][0], nb_rb, DMRS_MOD_ORDER, mod_ptrs); -+ } - } -- } - -- for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) { -+ for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) -+ { -+ uint8_t is_dmrs = 0; -+ uint8_t is_ptrs = 0; - -- uint8_t is_dmrs = 0; -- uint8_t is_ptrs = 0; -+ sample_offsetF = l*frame_parms->ofdm_symbol_size + k; - -- sample_offsetF = l*frame_parms->ofdm_symbol_size + k; -- -- if (is_dmrs_sym) { -- if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%frame_parms->ofdm_symbol_size)) -- is_dmrs = 1; -- } else if (is_ptrs_sym) { -+ if (is_dmrs_sym) -+ { -+ if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%frame_parms->ofdm_symbol_size)) -+ is_dmrs = 1; -+ } -+ else if (is_ptrs_sym) -+ { - is_ptrs = is_ptrs_subcarrier(k, -- rnti, -- ap, -- dmrs_type, -- K_ptrs, -- nb_rb, -- pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset, -- start_sc, -- frame_parms->ofdm_symbol_size); -- } -- -- if (is_dmrs == 1) { -- // if transform precoding is enabled -- if (pusch_pdu->transform_precoding == 0) { -- -- ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15; -- ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15; -+ rnti, -+ ap, -+ dmrs_type, -+ K_ptrs, -+ nb_rb, -+ pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset, -+ start_sc, -+ frame_parms->ofdm_symbol_size); -+ } -+ -+ if (is_dmrs == 1) -+ { -+ if (pusch_pdu->transformPrecoder == transformPrecoder_enabled) -+ { -+ ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15; -+ ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15; -+ } -+ else -+ { -+ ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15; -+ ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; -+ } -+ -+ #ifdef DEBUG_PUSCH_MAPPING -+ printf("DMRS: Layer: %d\t, dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n", -+ ap, dmrs_idx, l, k, k_prime, n, ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1], -+ ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1]); -+ #endif -+ -+ dmrs_idx++; -+ k_prime++; -+ k_prime&=1; -+ n+=(k_prime)?0:1; -+ } -+ else if (is_ptrs == 1) -+ { -+ ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15; -+ ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15; -+ -+ ptrs_idx++; -+ } -+ else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) -+ { -+ if (pusch_pdu->transformPrecoder == transformPrecoder_disabled) -+ { -+ ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = ((int16_t *)tx_layers[ap])[m<<1]; -+ ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *)tx_layers[ap])[(m<<1) + 1]; -+ } -+ else -+ { -+ ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1]; -+ ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1]; -+ } -+ -+ #ifdef DEBUG_PUSCH_MAPPING -+ printf("DATA: layer %d\t m %d\t l %d \t k %d \t txdataF: %d %d\n", -+ ap, m, l, k, ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1], -+ ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1]); -+ #endif -+ -+ m++; -+ } -+ else -+ { -+ ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = 0; -+ ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = 0; -+ } -+ -+ if (++k >= frame_parms->ofdm_symbol_size) -+ { -+ k -= frame_parms->ofdm_symbol_size; -+ } -+ } //for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) -+ }//for (l=start_symbol; lnb_antennas_tx; ap++) -+ { -+ for (int l=start_symbol; lTpmi; - -- } else { -- -- ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15; -- ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; -- -+ if (pmi == 0) {//unitary Precoding -+ if(ap< pusch_pdu->nrOfLayers) -+ memcpy((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + k], -+ (void*)&tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)], -+ NR_NB_SC_PER_RB*sizeof(int32_t)); -+ else -+ memset((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + 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 -+ { -+ //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 (pusch_pdu->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 (pusch_pdu->nrOfLayers == 1)//1 layer -+ W_prec = nr_W_1l_4p[pmi][ap]; -+ else if (pusch_pdu->nrOfLayers == 2)//2 layers -+ W_prec = nr_W_2l_4p[pmi][ap]; -+ else if (pusch_pdu->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; - } - -- #ifdef DEBUG_PUSCH_MAPPING -- printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n", -- dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1], -- ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1]); -- #endif -- -- -- dmrs_idx++; -- k_prime++; -- k_prime&=1; -- n+=(k_prime)?0:1; -- -- } else if (is_ptrs == 1) { -- -- ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15; -- ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15; -- -- ptrs_idx++; -- -- } else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) { -- -- ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1]; -- ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1]; -- -- #ifdef DEBUG_PUSCH_MAPPING -- printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", -- m, l, k, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1], -- ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1]); -- #endif -- -- m++; -- -- } else { -- -- ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = 0; -- ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = 0; -- -- } -+ for (int i=0; iofdm_symbol_size + k; -+ int32_t precodatatx_F = nr_layer_precoder(tx_precoding, W_prec, pusch_pdu->nrOfLayers, re_offset); -+ ((int16_t*)txdataF[ap])[(re_offset<<1)] = ((int16_t *) &precodatatx_F)[0]; -+ ((int16_t*)txdataF[ap])[(re_offset<<1) + 1] = ((int16_t *) &precodatatx_F)[1]; -+ -+ if (++k >= frame_parms->ofdm_symbol_size) -+ { -+ k -= frame_parms->ofdm_symbol_size; -+ } -+ } -+ } -+ } //RB loop -+ } // symbol loop -+ }// port loop - -- if (++k >= frame_parms->ofdm_symbol_size) -- k -= frame_parms->ofdm_symbol_size; -- } -- } -- } -- } -+ } //for (cwd_index = 0;cwd_index < num_of_codewords; cwd_index++) - - NR_UL_UE_HARQ_t *harq_process_ulsch=NULL; - harq_process_ulsch = UE->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid]; -diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h -index 11b5112a6c..600ba07cb3 100644 ---- a/openair1/PHY/defs_gNB.h -+++ b/openair1/PHY/defs_gNB.h -@@ -479,7 +479,7 @@ typedef struct { - /// \brief Cross-correlation of two UE signals. - /// - first index: rx antenna [0..nb_antennas_rx[ - /// - second index: symbol [0..] -- int32_t **rho; -+ int32_t ***rho; - /// \f$\log_2(\max|H_i|^2)\f$ - int16_t log2_maxh; - /// \brief Magnitude of Uplink Channel first layer (16QAM level/First 64QAM level). -@@ -509,6 +509,10 @@ typedef struct { - /// \brief llr values. - /// - first index: ? [0..1179743] (hard coded) - int16_t *llr; -+ /// \brief llr values per layer. -+ /// - first index: ? [0..3] (hard coded) -+ /// - first index: ? [0..1179743] (hard coded) -+ int16_t **llr_layers; - /// DMRS symbol index, to be updated every DMRS symbol within a slot. - uint8_t dmrs_symbol; - // PTRS symbol index, to be updated every PTRS symbol within a slot. -diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h -index 69978f5548..02988b590a 100644 ---- a/openair1/PHY/defs_nr_UE.h -+++ b/openair1/PHY/defs_nr_UE.h -@@ -229,6 +229,9 @@ typedef struct { - typedef struct { - /// TX buffers for multiple layers - int32_t *txdataF_layers[NR_MAX_NB_LAYERS]; -+ -+ /// TX buffers for UE-spec transmission -+ int32_t *txdataF_precoding[NR_MAX_NB_LAYERS]; - } NR_UE_PUSCH; - - typedef struct { -diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h -index c385d323e3..fbe094f41c 100644 ---- a/openair1/PHY/defs_nr_common.h -+++ b/openair1/PHY/defs_nr_common.h -@@ -93,7 +93,7 @@ - #define NR_MAX_CSET_DURATION 3 - - #define NR_MAX_NB_RBG 18 --#define NR_MAX_NB_LAYERS 2 // 8 // SU-MIMO (3GPP TS 38.211 V15.4.0 section 7.3.1.3) -+#define NR_MAX_NB_LAYERS 4 // 8 // SU-MIMO (3GPP TS 38.211 V15.4.0 section 7.3.1.3) - #define NR_MAX_NB_CODEWORDS 2 - #define NR_MAX_NB_HARQ_PROCESSES 16 - #define NR_MAX_PDSCH_ENCODED_LENGTH (NR_MAX_NB_RB*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8*NR_MAX_NB_LAYERS) // 8 is the maximum modulation order (it was 950984 before !!) -@@ -104,11 +104,11 @@ - #define MAX_NUM_NR_DLSCH_SEGMENTS (NR_MAX_NB_LAYERS*34) - #define MAX_NR_DLSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056) - --#define MAX_NUM_NR_ULSCH_SEGMENTS 34 -+#define MAX_NUM_NR_ULSCH_SEGMENTS (NR_MAX_NB_LAYERS*34) - #define MAX_NR_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_ULSCH_SEGMENTS*1056) - --#define MAX_NUM_NR_CHANNEL_BITS (14*273*12*8) // 14 symbols, 273 RB --#define MAX_NUM_NR_RE (14*273*12) -+#define MAX_NUM_NR_CHANNEL_BITS (4*14*273*12*8) // 14 symbols, 273 RB -+#define MAX_NUM_NR_RE (4*14*273*12) - #define NR_RX_NB_TH 1 - #define NR_NB_TH_SLOT 2 - -diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c -index d8fa11d157..640a0740ef 100644 ---- a/openair1/SCHED_NR/nr_ru_procedures.c -+++ b/openair1/SCHED_NR/nr_ru_procedures.c -@@ -526,7 +526,8 @@ void nr_fep0(RU_t *ru, int first_half) { - end_symbol = NR_SYMBOLS_PER_SLOT; - } - -- LOG_D(PHY,"In fep0 for slot = %d, first_half = %d, start_symbol = %d, end_symbol = %d\n", proc->tti_rx, first_half, start_symbol, end_symbol); -+ LOG_D(PHY,"In fep0 for slot = %d, first_half = %d, start_symbol = %d, end_symbol = %d, nb_antennas_rx = %d,N_TA_offset = %d\n", -+ proc->tti_rx, first_half, start_symbol, end_symbol,fp->nb_antennas_rx,ru->N_TA_offset); - // printf("fep0: slot %d\n",slot); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+proc->tti_rx, 1); -diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c -index 1685e206ae..63c708e565 100644 ---- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c -+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c -@@ -253,13 +253,13 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { - // if all segments are done - if (rdata->nbSegments == ulsch_harq->processedSegments) { - if (decodeSuccess) { -- LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for SFN/SF %d.%d (pid %d, ndi %d, status %d, round %d, TBS %d, Max interation (all seg) %d)\n", -+ LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for SFN/SF %d.%d (pid %d, ndi %d, status %d, round %d, TBS %d, Max interation (all seg) %d)\n", - gNB->Mod_id,ulsch_harq->frame,ulsch_harq->slot,rdata->harq_pid,pusch_pdu->pusch_data.new_data_indicator,ulsch_harq->status,ulsch_harq->round,ulsch_harq->TBS,rdata->decodeIterations); - ulsch_harq->status = SCH_IDLE; - ulsch_harq->round = 0; - ulsch->harq_mask &= ~(1 << rdata->harq_pid); - -- LOG_D(PHY, "ULSCH received ok \n"); -+ LOG_I(PHY, "ULSCH received ok \n"); - nr_fill_indication(gNB,ulsch_harq->frame, ulsch_harq->slot, rdata->ulsch_id, rdata->harq_pid, 0,0); - //dumpsig=1; - } else { -@@ -281,7 +281,7 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { - } - ulsch_harq->handled = 1; - -- LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id); -+ LOG_I(PHY, "ULSCH %d in error\n",rdata->ulsch_id); - nr_fill_indication(gNB,ulsch_harq->frame, ulsch_harq->slot, rdata->ulsch_id, rdata->harq_pid, 1,0); - } - /* -@@ -365,6 +365,14 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH - number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs - pusch_pdu->qam_mod_order, - pusch_pdu->nrOfLayers); -+ -+ -+ nr_ulsch_layer_demapping(gNB->pusch_vars[ULSCH_id]->llr, -+ pusch_pdu->nrOfLayers, -+ pusch_pdu->qam_mod_order, -+ G, -+ gNB->pusch_vars[ULSCH_id]->llr_layers); -+ - //---------------------------------------------------------- - //------------------- ULSCH unscrambling ------------------- - //---------------------------------------------------------- -@@ -731,7 +739,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { - (ulsch_harq->slot == slot_rx) && - (ulsch_harq->handled == 0)){ - -- LOG_D(PHY, "PUSCH detection started in frame %d slot %d\n", -+ LOG_I(PHY, "PUSCH detection started in frame %d slot %d\n", - frame_rx,slot_rx); - int num_dmrs=0; - for (int s=0;srx_pusch_stats); - no_sig = nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, harq_pid); - if (no_sig) { -- LOG_D(PHY, "PUSCH not detected in frame %d, slot %d\n", frame_rx, slot_rx); -+ LOG_I(PHY, "PUSCH not detected in frame %d, slot %d\n", frame_rx, slot_rx); - nr_fill_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid, 1,1); - return 1; - } -@@ -783,7 +791,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { - dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot) + gNB->pusch_thres) { - NR_gNB_SCH_STATS_t *stats=get_ulsch_stats(gNB,ulsch); - -- LOG_D(PHY, "PUSCH not detected in %d.%d (%d,%d,%d)\n",frame_rx,slot_rx, -+ LOG_I(PHY, "PUSCH not detected in %d.%d (%d,%d,%d)\n",frame_rx,slot_rx, - dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot), - dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot),gNB->pusch_thres); - gNB->pusch_vars[ULSCH_id]->ulsch_power_tot = gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot; -diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c -index f6e4d90bee..8e1df435c3 100644 ---- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c -+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c -@@ -157,7 +157,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ - for (i = 0; i < ul_config->number_pdus; ++i){ - - AssertFatal(ul_config->ul_config_list[i].pdu_type <= FAPI_NR_UL_CONFIG_TYPES,"pdu_type %d out of bounds\n",ul_config->ul_config_list[i].pdu_type); -- LOG_D(PHY, "In %s: processing %s PDU of %d total UL PDUs (ul_config %p) \n", __FUNCTION__, ul_pdu_type[ul_config->ul_config_list[i].pdu_type - 1], ul_config->number_pdus, ul_config); -+ LOG_I(PHY, "In %s i %d: processing %s PDU of %d total UL PDUs (ul_config %p) \n", __FUNCTION__, i, ul_pdu_type[ul_config->ul_config_list[i].pdu_type - 1], ul_config->number_pdus, ul_config); - - uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type, current_harq_pid, gNB_id = 0; - /* PRACH */ -@@ -180,6 +180,8 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ - if (harq_process_ul_ue){ - - nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &harq_process_ul_ue->pusch_pdu; -+ -+ LOG_I(PHY, "In %s i %d: copy pusch_config_pdu nrOfLayers:%d, num_dmrs_cdm_grps_no_data:%d \n", __FUNCTION__, i, pusch_config_pdu->nrOfLayers,pusch_config_pdu->num_dmrs_cdm_grps_no_data); - - memcpy(pusch_pdu, pusch_config_pdu, sizeof(nfapi_nr_ue_pusch_pdu_t)); - -diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c -index 940931694c..0a0a9cc2f9 100644 ---- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c -+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c -@@ -270,9 +270,12 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, - AssertFatal(ue->CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN); -- -- memset(ue->common_vars.txdataF[0], 0, sizeof(int)*14*ue->frame_parms.ofdm_symbol_size); -- -+ -+ for(int i=0; i< ue->frame_parms.nb_antennas_tx; ++i) -+ { -+ memset(ue->common_vars.txdataF[i], 0, sizeof(int)*14*ue->frame_parms.ofdm_symbol_size); -+ } -+ - LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx); - - -diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c -index 1eb6027936..d5a1054654 100644 ---- a/openair1/SIMULATION/NR_PHY/dlsim.c -+++ b/openair1/SIMULATION/NR_PHY/dlsim.c -@@ -768,7 +768,7 @@ int main(int argc, char **argv) - - prepare_scd(scd); - -- fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, 0, 0, 0); -+ fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, n_rx, 0, 0, 0); - - /* RRC parameter validation for secondaryCellGroup */ - fix_scd(scd); -diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c -index 94aea36a67..fb8b4295ae 100644 ---- a/openair1/SIMULATION/NR_PHY/ulschsim.c -+++ b/openair1/SIMULATION/NR_PHY/ulschsim.c -@@ -137,6 +137,7 @@ int main(int argc, char **argv) - uint16_t nb_symb_sch = 12; - uint16_t nb_rb = 50; - uint8_t Imcs = 9; -+ uint8_t Nl = 1; - - double DS_TDL = .03; - -@@ -150,7 +151,7 @@ int main(int argc, char **argv) - randominit(0); - - //while ((c = getopt(argc, argv, "df:hpg:i:j:n:l:m:r:s:S:y:z:M:N:F:R:P:")) != -1) { -- while ((c = getopt(argc, argv, "hg:n:s:S:py:z:M:N:R:F:m:l:r:")) != -1) { -+ while ((c = getopt(argc, argv, "hg:n:s:S:py:z:M:N:R:F:m:l:r:W:")) != -1) { - switch (c) { - /*case 'f': - write_output_file = 1; -@@ -251,7 +252,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)) { - printf("Unsupported number of TX antennas %d. Exiting.\n", n_tx); - exit(-1); - } -@@ -261,7 +262,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)) { - printf("Unsupported number of RX antennas %d. Exiting.\n", n_rx); - exit(-1); - } -@@ -299,6 +300,10 @@ int main(int argc, char **argv) - printf("Illegal PBCH phase (0-3) got %d\n", pbch_phase); - break;*/ - -+ case 'W': -+ Nl = atoi(optarg); -+ break; -+ - case 'm': - Imcs = atoi(optarg); - #ifdef DEBUG_NR_ULSCHSIM -@@ -335,13 +340,14 @@ int main(int argc, char **argv) - printf("-z Number of RX antennas used in UE\n"); - //printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); - //printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); -+ printf("-W number of layer\n"); - printf("-M Multiple SSB positions in burst\n"); - printf("-N Nid_cell\n"); - printf("-R N_RB_UL\n"); - printf("-F Input filename (.txt format) for RX conformance testing\n"); -- printf("-m\n"); -- printf("-l\n"); -- printf("-r\n"); -+ printf("-m MCS\n"); -+ printf("-l number of symbol\n"); -+ printf("-r number of RB\n"); - //printf("-O oversampling factor (1,2,4,8,16)\n"); - //printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); - //printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); -@@ -359,8 +365,8 @@ int main(int argc, char **argv) - snr1 = snr0 + 10; - - gNB2UE = new_channel_desc_scm(n_tx, -- n_rx, -- channel_model, -+ n_rx, -+ channel_model, - 61.44e6, //N_RB2sampling_rate(N_RB_DL), - 40e6, //N_RB2channel_bandwidth(N_RB_DL), - DS_TDL, -@@ -426,8 +432,7 @@ int main(int argc, char **argv) - uint8_t length_dmrs = 1; - uint8_t N_PRB_oh; - uint16_t N_RE_prime,code_rate; -- unsigned char mod_order; -- uint8_t Nl = 1; -+ unsigned char mod_order; - uint8_t rvidx = 0; - uint8_t UE_id = 0; - -@@ -437,9 +442,14 @@ int main(int argc, char **argv) - - NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[0][0][0]; - -+ if ((Nl==4)||(Nl==3)) -+ { -+ nb_re_dmrs = nb_re_dmrs*2; -+ } -+ - mod_order = nr_get_Qm_ul(Imcs, 0); - code_rate = nr_get_code_rate_ul(Imcs, 0); -- available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1); -+ available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, Nl); - TBS = nr_compute_tbs(mod_order,code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, 0, Nl); - - printf("\nAvailable bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order); -diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c -index 69316d6b88..b6cfae3fe1 100644 ---- a/openair1/SIMULATION/NR_PHY/ulsim.c -+++ b/openair1/SIMULATION/NR_PHY/ulsim.c -@@ -282,7 +282,7 @@ int main(int argc, char **argv) - int gNB_id = 0; - int ap; - int tx_offset; -- int32_t txlev=0; -+ int32_t txlev_sum = 0, atxlev[4]; - int start_rb = 0; - int UE_id =0; // [hna] only works for UE_id = 0 because NUMBER_OF_NR_UE_MAX is set to 1 (phy_init_nr_gNB causes segmentation fault) - float target_error_rate = 0.01; -@@ -307,7 +307,7 @@ int main(int argc, char **argv) - uint16_t ptrsSymbPerSlot = 0; - uint16_t ptrsRePerSymb = 0; - -- uint8_t transform_precoding = 1; // 0 - ENABLE, 1 - DISABLE -+ uint8_t transformPrecoder = transformPrecoder_disabled; // 0 - ENABLE, 1 - DISABLE - uint8_t num_dmrs_cdm_grps_no_data = 1; - uint8_t mcs_table = 0; - -@@ -329,7 +329,7 @@ int main(int argc, char **argv) - /* initialize the sin-cos table */ - InitSinLUT(); - -- while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:ikl:m:n:p:r:s:u:w:y:z:F:G:H:M:N:PR:S:T:U:L:Z")) != -1) { -+ while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:kl:m:n:p:r:s:u:w:y:z:F:G:H:M:N:PR:S:T:U:L:Z:W:")) != -1) { - printf("handling optarg %c\n",c); - switch (c) { - -@@ -363,8 +363,8 @@ int main(int argc, char **argv) - scg_fd = fopen(optarg, "r"); - - if (scg_fd == NULL) { -- printf("Error opening %s\n", optarg); -- exit(-1); -+ printf("Error opening %s\n", optarg); -+ exit(-1); - } - - break; -@@ -437,6 +437,10 @@ int main(int argc, char **argv) - case 'm': - Imcs = atoi(optarg); - break; -+ -+ case 'W': -+ precod_nbr_layers = atoi(optarg); -+ break; - - case 'n': - n_trials = atoi(optarg); -@@ -485,9 +489,9 @@ int main(int argc, char **argv) - case 'y': - n_tx = atoi(optarg); - -- if ((n_tx == 0) || (n_tx > 2)) { -- printf("Unsupported number of tx antennas %d\n", n_tx); -- exit(-1); -+ if ((n_tx == 0) || (n_tx > 4)) { -+ printf("Unsupported number of tx antennas %d\n", n_tx); -+ exit(-1); - } - - break; -@@ -496,8 +500,8 @@ int main(int argc, char **argv) - n_rx = atoi(optarg); - - if ((n_rx == 0) || (n_rx > 8)) { -- printf("Unsupported number of rx antennas %d\n", n_rx); -- exit(-1); -+ printf("Unsupported number of rx antennas %d\n", n_rx); -+ exit(-1); - } - - break; -@@ -506,8 +510,8 @@ int main(int argc, char **argv) - input_fd = fopen(optarg, "r"); - - if (input_fd == NULL) { -- printf("Problem with filename %s\n", optarg); -- exit(-1); -+ printf("Problem with filename %s\n", optarg); -+ exit(-1); - } - - break; -@@ -568,11 +572,11 @@ int main(int argc, char **argv) - - case 'Z': - -- transform_precoding = 0; // enabled -+ transformPrecoder = transformPrecoder_enabled; - num_dmrs_cdm_grps_no_data = 2; - mcs_table = 3; - -- printf("NOTE: TRANSFORM PRECODING (SC-FDMA) is ENABLED in UPLINK (0 - ENABLE, 1 - DISABLE) : %d \n", transform_precoding); -+ printf("NOTE: TRANSFORM PRECODING (SC-FDMA) is ENABLED in UPLINK (0 - ENABLE, 1 - DISABLE) : %d \n", transformPrecoder); - - break; - -@@ -611,6 +615,7 @@ int main(int argc, char **argv) - printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:3}, e.g. -U 2 0 2 \n"); - printf("-Q If -F used, read parameters from file\n"); - printf("-Z If -Z is used, SC-FDMA or transform precoding is enabled in Uplink \n"); -+ printf("-W Num of layer for PUSCH\n"); - exit(-1); - break; - -@@ -713,7 +718,7 @@ int main(int argc, char **argv) - - prepare_scd(scd); - -- fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, 0, 0, 0); -+ fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, n_rx, 0, 0, 0); - - // xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup); - -@@ -724,9 +729,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, n_tx, n_rx, 0, scc, &rrc.carrier.mib,0, 0, NULL); -+ rrc_mac_config_req_gNB(0,0, n_tx, n_rx, n_tx, scc, &rrc.carrier.mib,0, 0, NULL); - // UE dedicated configuration -- rrc_mac_config_req_gNB(0,0, n_tx, n_rx, 0, scc, &rrc.carrier.mib,1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); -+ rrc_mac_config_req_gNB(0,0, n_tx, n_rx, n_tx, scc, &rrc.carrier.mib,1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); - frame_parms->nb_antennas_tx = n_tx; - frame_parms->nb_antennas_rx = n_rx; - nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; -@@ -870,14 +875,18 @@ int main(int argc, char **argv) - uint16_t number_dmrs_symbols = get_dmrs_symbols_in_slot(l_prime_mask, nb_symb_sch); - printf("num dmrs sym %d\n",number_dmrs_symbols); - uint8_t nb_re_dmrs = (dmrs_config_type == pusch_dmrs_type1) ? 6 : 4; -- -- // if transform precoding is enabled -- if (transform_precoding == 0) { -+ -+ if ((frame_parms->nb_antennas_tx==4)&&(precod_nbr_layers==4)) -+ { -+ num_dmrs_cdm_grps_no_data = 2; -+ } -+ -+ if (transformPrecoder == transformPrecoder_enabled) { - - AssertFatal(enable_ptrs == 0, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); - - int8_t index = get_index_for_dmrs_lowpapr_seq((NR_NB_SC_PER_RB/2) * nb_rb); -- AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); -+ AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); - - dmrs_config_type = pusch_dmrs_type1; - -@@ -886,7 +895,7 @@ int main(int argc, char **argv) - - nb_re_dmrs = nb_re_dmrs * num_dmrs_cdm_grps_no_data; - -- unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, 1); -+ unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, precod_nbr_layers); - unsigned int TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, 0, precod_nbr_layers); - - -@@ -1082,14 +1091,14 @@ int main(int argc, char **argv) - pusch_pdu->mcs_table = mcs_table; - pusch_pdu->target_code_rate = code_rate; - pusch_pdu->qam_mod_order = mod_order; -- pusch_pdu->transform_precoding = transform_precoding; -+ pusch_pdu->transformPrecoder = transformPrecoder; - pusch_pdu->data_scrambling_id = *scc->physCellId; -- pusch_pdu->nrOfLayers = 1; -+ pusch_pdu->nrOfLayers = precod_nbr_layers; - pusch_pdu->ul_dmrs_symb_pos = l_prime_mask; - pusch_pdu->dmrs_config_type = dmrs_config_type; - pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; - pusch_pdu->scid = 0; -- pusch_pdu->dmrs_ports = 1; -+ pusch_pdu->dmrs_ports = ((1<num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data; - pusch_pdu->resource_alloc = 1; - pusch_pdu->rb_start = start_rb; -@@ -1109,7 +1118,7 @@ int main(int argc, char **argv) - pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0; - - // if transform precoding is enabled -- if (transform_precoding == 0) { -+ if (transformPrecoder == transformPrecoder_enabled) { - - pusch_pdu->dfts_ofdm.low_papr_group_number = *scc->physCellId % 30; // U as defined in 38.211 section 6.4.1.1.1.2 - pusch_pdu->dfts_ofdm.low_papr_sequence_number = 0; // V as defined in 38.211 section 6.4.1.1.1.2 -@@ -1167,10 +1176,10 @@ int main(int argc, char **argv) - ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t)); - ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0; - -- ul_config.ul_config_list[0].pusch_config_pdu.transform_precoding = transform_precoding; -+ ul_config.ul_config_list[0].pusch_config_pdu.transformPrecoder = transformPrecoder; - - // if transform precoding is enabled -- if (transform_precoding == 0) { -+ if (transformPrecoder == transformPrecoder_enabled) { - - ul_config.ul_config_list[0].pusch_config_pdu.dfts_ofdm.low_papr_group_number = *scc->physCellId % 30;// U as defined in 38.211 section 6.4.1.1.1.2 - ul_config.ul_config_list[0].pusch_config_pdu.dfts_ofdm.low_papr_sequence_number = 0;// V as defined in 38.211 section 6.4.1.1.1.2 -@@ -1198,28 +1207,54 @@ int main(int argc, char **argv) - LOG_D(PHY, "Sending Uplink data \n"); - nr_ue_pusch_common_procedures(UE, - slot, -- &UE->frame_parms,1); -- -- if (n_trials==1) { -- LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_parms->samples_per_subframe*10,1,1); -+ &UE->frame_parms, -+ frame_parms->nb_antennas_tx); -+ -+ -+ if (n_trials==1) -+ { -+ LOG_M("txsig0.m","txs0", &UE->common_vars.txdata[0][slot_offset],slot_length,1,1); - LOG_M("txsig0F.m","txs0F", UE->common_vars.txdataF[0],frame_parms->ofdm_symbol_size*14,1,1); -+ if (precod_nbr_layers > 1) -+ { -+ LOG_M("txsig1.m","txs1", &UE->common_vars.txdata[1][slot_offset],slot_length,1,1); -+ LOG_M("txsig1F.m","txs1F", UE->common_vars.txdataF[1],frame_parms->ofdm_symbol_size*14,1,1); -+ if (precod_nbr_layers==4) -+ { -+ LOG_M("txsig2.m","txs2", &UE->common_vars.txdata[2][slot_offset],slot_length,1,1); -+ LOG_M("txsig3.m","txs3", &UE->common_vars.txdata[3][slot_offset],slot_length,1,1); -+ -+ LOG_M("txsig2F.m","txs2F", UE->common_vars.txdataF[2],frame_parms->ofdm_symbol_size*14,1,1); -+ LOG_M("txsig3F.m","txs3F", UE->common_vars.txdataF[3],frame_parms->ofdm_symbol_size*14,1,1); -+ } -+ } - } - /////////// - //////////////////////////////////////////////////// - tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); -- -- txlev = signal_energy(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], -+ txlev_sum = 0; -+ for (int aa=0; aanb_antennas_tx; aa++) -+ { -+ atxlev[aa] = signal_energy(&UE->common_vars.txdata[aa][tx_offset + 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); -- } -- else n_trials = 1; -- -- if (input_fd == NULL ) { -+ -+ txlev_sum += atxlev[aa]; -+ -+ if (n_trials==1) printf("txlev[%d] = %d (%f dB) txlev_sum %d\n",aa,atxlev[aa],10*log10((double)atxlev[aa]),txlev_sum); -+ } -+ } -+ else -+ { -+ n_trials = 1; -+ } - -- sigma_dB = 10 * log10((double)txlev * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;; -+ if (input_fd == NULL ) -+ { -+ sigma_dB = 10 * log10((double)txlev_sum * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;; - sigma = pow(10,sigma_dB/10); - - -- if(n_trials==1) printf("sigma %f (%f dB), txlev %f (factor %f)\n",sigma,sigma_dB,10*log10((double)txlev),(double)(double) -+ if(n_trials==1) printf("sigma %f (%f dB), txlev_sum %f (factor %f)\n",sigma,sigma_dB,10*log10((double)txlev_sum),(double)(double) - frame_parms->ofdm_symbol_size/(12*nb_rb)); - - for (i=0; imax_Doppler == 0) { -+ if (UE2gNB->max_Doppler == 0) -+ { - multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials==1)?1:0); - } else { - multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, 2*slot_length, 0); - } -- for (i=0; inb_antennas_rx; ap++) { -+ for (i=0; inb_antennas_rx; ap++) -+ { -+ if (channel_model == AWGN) -+ { -+ double H_awgn[4][4] ={{1.0, 0.0, 0.0, 0.0},//rx 0 -+ {0.0, 1.0, 0.0, 0.0}, //rx 1 -+ {0.0, 0.0, 1.0, 0.0}, //rx 2 -+ {0.0, 0.0, 0.0, 1.0}};//rx 3 -+ #if 0 -+ double H_awgn_mimo[4][4] ={{1.0, 0.5, 0.25, 0.125},//rx 0 -+ {0.5, 1.0, 0.5, 0.25}, //rx 1 -+ {0.25, 0.5, 1.0, 0.5}, //rx 2 -+ {0.125, 0.25, 0.5, 1.0}};//rx 3 -+ #endif -+ // sum up signals from different Tx antennas -+ r_re[ap][i] = 0; -+ r_im[ap][i] = 0; -+ -+ for (int aa=0; aaofdm_symbol_size/(12*nb_rb))) - SNR;; -+ sigma = pow(10,sigma_dB/10); -+ - ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point - ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); -+ -+ #if 0 -+ ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((r_re[ap][i])); // convert to fixed point -+ ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((r_im[ap][i])); -+ -+ -+ ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) ] = ((int16_t*) &UE->common_vars.txdata[ap][slot_offset])[(2*i) ]; // convert to fixed point -+ ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1] = ((int16_t*) &UE->common_vars.txdata[ap][slot_offset])[(2*i)+1 ]; -+ #endif -+ - /* Add phase noise if enabled */ - if (pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { - phase_noise(ts, &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)], -@@ -1250,7 +1324,8 @@ int main(int argc, char **argv) - } /*End input_fd */ - - -- if(pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { -+ if(pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) -+ { - set_ptrs_symb_idx(&ptrsSymPos, - pusch_pdu->nr_of_symbols, - pusch_pdu->start_symbol_index, -@@ -1268,24 +1343,37 @@ int main(int argc, char **argv) - gNB->UL_INFO.rx_ind.number_of_pdus = 0; - gNB->UL_INFO.crc_ind.number_crcs = 0; - -- phy_procedures_gNB_common_RX(gNB, frame, slot); -+ phy_procedures_gNB_common_RX(gNB, frame, slot); - -- ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot); -+ ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot); - -- if (n_trials==1 && round==0) { -+ if (n_trials==1 && round==0) -+ { - LOG_M("rxsig0.m","rx0",&gNB->common_vars.rxdata[0][slot_offset],slot_length,1,1); - -- LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0]+start_symbol*frame_parms->ofdm_symbol_size,nb_symb_sch*frame_parms->ofdm_symbol_size,1,1); -- -+ LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0],14*frame_parms->ofdm_symbol_size,1,1); -+ if (precod_nbr_layers > 1) -+ { -+ LOG_M("rxsig1.m","rx1",&gNB->common_vars.rxdata[1][slot_offset],slot_length,1,1); -+ LOG_M("rxsigF1.m","rxsF1",gNB->common_vars.rxdataF[1],14*frame_parms->ofdm_symbol_size,1,1); -+ if (precod_nbr_layers==4) -+ { -+ LOG_M("rxsig2.m","rx2",&gNB->common_vars.rxdata[2][slot_offset],slot_length,1,1); -+ LOG_M("rxsig3.m","rx3",&gNB->common_vars.rxdata[3][slot_offset],slot_length,1,1); -+ -+ LOG_M("rxsigF2.m","rxsF2",gNB->common_vars.rxdataF[2],14*frame_parms->ofdm_symbol_size,1,1); -+ LOG_M("rxsigF3.m","rxsF3",gNB->common_vars.rxdataF[3],14*frame_parms->ofdm_symbol_size,1,1); -+ } -+ } - } - - - if (n_trials == 1 && round==0) { --#ifdef __AVX2__ -+ #ifdef __AVX2__ - int off = ((nb_rb&1) == 1)? 4:0; --#else -+ #else - int off = 0; --#endif -+ #endif - - LOG_M("rxsigF0_ext.m","rxsF0_ext", - &gNB->pusch_vars[0]->rxdataF_ext[0][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); -@@ -1298,11 +1386,77 @@ int main(int argc, char **argv) - (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_M("rxsigF0_comp.m","rxsF0_comp", - &gNB->pusch_vars[0]->rxdataF_comp[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); -- LOG_M("chmagF0.m","chmF0", -- &gNB->pusch_vars[0]->ul_ch_mag[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); -- LOG_M("chmagbF0.m","chmbF0", -- &gNB->pusch_vars[0]->ul_ch_magb[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); -- if (n_rx == 2) { -+ LOG_M("chmagF0.m","chmF0", -+ &gNB->pusch_vars[0]->ul_ch_mag[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); -+ LOG_M("chmagbF0.m","chmbF0", -+ &gNB->pusch_vars[0]->ul_ch_magb[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); -+ LOG_M("rxsigF0_llrlayers0.m","rxsF0_llrlayers0", -+ &gNB->pusch_vars[0]->llr_layers[0][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); -+ -+ if (precod_nbr_layers==2) -+ { -+ LOG_M("rxsigF1_ext.m","rxsF1_ext", -+ &gNB->pusch_vars[0]->rxdataF_ext[1][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); -+ -+ LOG_M("chestF3.m","chF3", -+ &gNB->pusch_vars[0]->ul_ch_estimates[3][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); -+ -+ LOG_M("chestF3_ext.m","chF3_ext", -+ &gNB->pusch_vars[0]->ul_ch_estimates_ext[3][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], -+ (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); -+ -+ LOG_M("rxsigF2_comp.m","rxsF2_comp", -+ &gNB->pusch_vars[0]->rxdataF_comp[2][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); -+ -+ LOG_M("rxsigF0_llrlayers1.m","rxsF0_llrlayers1", -+ &gNB->pusch_vars[0]->llr_layers[1][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); -+ -+ } -+ -+ if (precod_nbr_layers==4) -+ { -+ LOG_M("rxsigF1_ext.m","rxsF1_ext", -+ &gNB->pusch_vars[0]->rxdataF_ext[1][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); -+ LOG_M("rxsigF2_ext.m","rxsF2_ext", -+ &gNB->pusch_vars[0]->rxdataF_ext[2][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); -+ LOG_M("rxsigF3_ext.m","rxsF3_ext", -+ &gNB->pusch_vars[0]->rxdataF_ext[3][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); -+ -+ LOG_M("chestF5.m","chF5", -+ &gNB->pusch_vars[0]->ul_ch_estimates[5][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); -+ LOG_M("chestF10.m","chF10", -+ &gNB->pusch_vars[0]->ul_ch_estimates[10][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); -+ LOG_M("chestF15.m","chF15", -+ &gNB->pusch_vars[0]->ul_ch_estimates[15][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); -+ -+ -+ LOG_M("chestF5_ext.m","chF5_ext", -+ &gNB->pusch_vars[0]->ul_ch_estimates_ext[5][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], -+ (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); -+ LOG_M("chestF10_ext.m","chF10_ext", -+ &gNB->pusch_vars[0]->ul_ch_estimates_ext[10][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], -+ (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); -+ LOG_M("chestF15_ext.m","chF15_ext", -+ &gNB->pusch_vars[0]->ul_ch_estimates_ext[15][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], -+ (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); -+ -+ -+ LOG_M("rxsigF4_comp.m","rxsF4_comp", -+ &gNB->pusch_vars[0]->rxdataF_comp[4][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); -+ LOG_M("rxsigF8_comp.m","rxsF8_comp", -+ &gNB->pusch_vars[0]->rxdataF_comp[8][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); -+ LOG_M("rxsigF12_comp.m","rxsF12_comp", -+ &gNB->pusch_vars[0]->rxdataF_comp[12][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); -+ LOG_M("rxsigF0_llrlayers1.m","rxsF0_llrlayers1", -+ &gNB->pusch_vars[0]->llr_layers[1][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); -+ LOG_M("rxsigF0_llrlayers2.m","rxsF0_llrlayers2", -+ &gNB->pusch_vars[0]->llr_layers[2][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); -+ LOG_M("rxsigF0_llrlayers3.m","rxsF0_llrlayers3", -+ &gNB->pusch_vars[0]->llr_layers[3][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); -+ } -+ -+ #if 0 -+ if (n_rx == 2) { - LOG_MM("rxsigF0_comp.m","rxsF1_comp", - &gNB->pusch_vars[0]->rxdataF_comp[1][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("rxsigF0_ext.m","rxsF1_ext", -@@ -1349,9 +1503,10 @@ int main(int argc, char **argv) - LOG_MM("chmagbF0.m","chmbF3", - &gNB->pusch_vars[0]->ul_ch_magb[3][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - } -+ #endif - - LOG_M("rxsigF0_llr.m","rxsF0_llr", -- &gNB->pusch_vars[0]->llr[0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); -+ &gNB->pusch_vars[0]->llr[0],precod_nbr_layers*(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); - } - //////////////////////////////////////////////////////////// - -diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c -index 3f4be9dd58..7e5be9eeba 100644 ---- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c -+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c -@@ -2708,6 +2708,9 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP, - LOG_D(NR_MAC,"dci_pdu->srs_resource_indicator.nbits %d\n",dci_pdu->srs_resource_indicator.nbits); - // Precoding info and number of layers - long transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, ubwpd, (uint8_t*)&format, rnti_type, 0); -+ -+ pusch_antenna_ports = *pusch_Config->maxRank; -+ - dci_pdu->precoding_information.nbits=0; - if (pusch_Config && - pusch_Config->txConfig != NULL){ -diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c -index c23d4bb073..963723725f 100644 ---- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c -+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c -@@ -190,7 +190,7 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con - else - transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled; - } -- -+ pusch_config_pdu->transformPrecoder = transformPrecoder; - - /* PRECOD_NBR_LAYERS */ - if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_nonCodebook)); -@@ -198,11 +198,12 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con - - if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook)){ - -- uint8_t n_antenna_port = 0; //FIXME!!! -+ uint8_t n_antenna_port = mac->phy_config.config_req.carrier_config.num_tx_ant; - - if (n_antenna_port == 1); // 1 antenna port and the higher layer parameter txConfig = codebook 0 bits - -- if (n_antenna_port == 4){ // 4 antenna port and the higher layer parameter txConfig = codebook -+ if (n_antenna_port == 4) -+ { // 4 antenna port and the higher layer parameter txConfig = codebook - - // Table 7.3.1.1.2-2: transformPrecoder=disabled and maxRank = 2 or 3 or 4 - if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) -@@ -212,54 +213,56 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con - - if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { - pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][0]; -- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][1]; -+ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][1]; - } - - if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_partialAndNonCoherent){ - pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][2]; -- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][3]; -+ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][3]; - } - - if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){ - pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][4]; -- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][5]; -+ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][5]; - } - } - - // Table 7.3.1.1.2-3: transformPrecoder= enabled, or transformPrecoder=disabled and maxRank = 1 - if (((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) - || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled)) -- && (*pusch_Config->maxRank == 1)){ -+ && (*pusch_Config->maxRank == 1)) -+ { - - if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { - pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][6]; -- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][7]; -+ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][7]; - } - - if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_partialAndNonCoherent){ - pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][8]; -- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][9]; -+ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][9]; - } - - if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){ - pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][10]; -- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][11]; -+ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][11]; - } - } - } - -- if (n_antenna_port == 4){ // 2 antenna port and the higher layer parameter txConfig = codebook -+ if (n_antenna_port == 2) -+ { // 2 antenna port and the higher layer parameter txConfig = codebook - // Table 7.3.1.1.2-4: transformPrecoder=disabled and maxRank = 2 -- if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (*pusch_Config->maxRank == 2)){ -- -+ if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (*pusch_Config->maxRank == 2)) -+ { - if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { - pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][12]; -- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][13]; -+ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][13]; - } - - if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){ - pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][14]; -- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][15]; -+ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][15]; - } - - } -@@ -267,16 +270,17 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con - // Table 7.3.1.1.2-5: transformPrecoder= enabled, or transformPrecoder= disabled and maxRank = 1 - if (((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) - || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled)) -- && (*pusch_Config->maxRank == 1)){ -+ && (*pusch_Config->maxRank == 1)) -+ { - - if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { - pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][16]; -- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][17]; -+ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][17]; - } - - if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){ - pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][18]; -- pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][19]; -+ pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][19]; - } - - } -@@ -285,9 +289,9 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con - - /*-------------------- Changed to enable Transform precoding in RF SIM------------------------------------------------*/ - -- /*if (pusch_config_pdu->transform_precoding == transform_precoder_enabled) { -+ /*if (pusch_config_pdu->transformPrecoder == transformPrecoder_enabled) { - -- pusch_config_dedicated->transform_precoder = transform_precoder_enabled; -+ pusch_config_dedicated->transform_precoder = transformPrecoder_enabled; - - if(pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL) { - -@@ -309,7 +313,7 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con - - } - } else -- pusch_config_dedicated->transform_precoder = transform_precoder_disabled;*/ -+ pusch_config_dedicated->transformPrecoder = ttransformPrecoder_disabled;*/ - } - - // todo: this function shall be reviewed completely because of the many comments left by the author -@@ -342,7 +346,7 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf - } - long *max_length = NULL; - long *dmrs_type = NULL; -- LOG_D(NR_MAC,"transformPrecoder %s\n",transformPrecoder==NR_PUSCH_Config__transformPrecoder_disabled?"disabled":"enabled"); -+ LOG_I(NR_MAC,"transformPrecoder %s\n",transformPrecoder==NR_PUSCH_Config__transformPrecoder_disabled?"disabled":"enabled"); - - if (pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA) { - max_length = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup->maxLength; -@@ -353,7 +357,7 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf - dmrs_type = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->dmrs_Type; - } - -- LOG_D(NR_MAC,"MappingType%s max_length %s, dmrs_type %s, antenna_ports %d\n",pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA?"A":"B",max_length?"len2":"len1",dmrs_type?"type2":"type1",dci->antenna_ports.val); -+ LOG_I(NR_MAC,"MappingType%s max_length %s, dmrs_type %s, antenna_ports %d\n",pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA?"A":"B",max_length?"len2":"len1",dmrs_type?"type2":"type1",dci->antenna_ports.val); - if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) && - (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-6 - pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC -@@ -369,35 +373,32 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf - } - - if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && -- (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-8/9/10/11 -+ (dmrs_type == NULL) && (max_length == NULL)) -+ { // tables 7.3.1.1.2-8/9/10/11 -+ -+ if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook)) -+ { -+ rank = pusch_config_pdu->nrOfLayers; -+ } - - if (rank == 1) { -- pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; //TBC -- pusch_config_pdu->dmrs_ports = (dci->antenna_ports.val > 1)?(dci->antenna_ports.val-2):(dci->antenna_ports.val); //TBC -+ pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; -+ pusch_config_pdu->dmrs_ports =1<<((dci->antenna_ports.val > 1)?(dci->antenna_ports.val-2):(dci->antenna_ports.val)); - } - - if (rank == 2){ -- pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 0)?2:1; //TBC -- pusch_config_pdu->dmrs_ports = 0; //FIXME -- //pusch_config_pdu->dmrs_ports[0] = (dci->antenna_ports > 1)?(dci->antenna_ports > 2 ?0:2):0; -- //pusch_config_pdu->dmrs_ports[1] = (dci->antenna_ports > 1)?(dci->antenna_ports > 2 ?2:3):1; -+ pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 0)?2:1; -+ pusch_config_pdu->dmrs_ports = (dci->antenna_ports.val > 1)?((dci->antenna_ports.val> 2)?0x5:0xc):0x3; - } - - if (rank == 3){ -- pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC -- pusch_config_pdu->dmrs_ports = 0; //FIXME -- //pusch_config_pdu->dmrs_ports[0] = 0; -- //pusch_config_pdu->dmrs_ports[1] = 1; -- //pusch_config_pdu->dmrs_ports[2] = 2; -+ pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; -+ pusch_config_pdu->dmrs_ports = ((1<num_dmrs_cdm_grps_no_data = 2; //TBC -- pusch_config_pdu->dmrs_ports = 0; //FIXME -- //pusch_config_pdu->dmrs_ports[0] = 0; -- //pusch_config_pdu->dmrs_ports[1] = 1; -- //pusch_config_pdu->dmrs_ports[2] = 2; -- //pusch_config_pdu->dmrs_ports[3] = 3; -+ pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; -+ pusch_config_pdu->dmrs_ports = ((1<n_front_load_symb = table_7_3_1_1_2_23[dci->antenna_ports.val][5]; //FIXME - } - } -- LOG_D(NR_MAC,"num_dmrs_cdm_grps_no_data %d, dmrs_ports %d\n",pusch_config_pdu->num_dmrs_cdm_grps_no_data,pusch_config_pdu->dmrs_ports); -+ LOG_I(NR_MAC,"num_dmrs_cdm_grps_no_data %d, dmrs_ports %d\n",pusch_config_pdu->num_dmrs_cdm_grps_no_data,pusch_config_pdu->dmrs_ports); - } - - // Configuration of Msg3 PDU according to clauses: -@@ -542,6 +543,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, - pusch_config_pdu->dmrs_config_type = pusch_dmrs_type1; - pusch_config_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; - pusch_config_pdu->nrOfLayers = 1; -+ pusch_config_pdu->Tpmi = 0; - pusch_config_pdu->rnti = rnti; - NR_BWP_UplinkCommon_t *initialUplinkBWP; - if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP; -@@ -634,7 +636,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, - pusch_config_pdu->scid = 0; - - // Transform precoding according to 6.1.3 UE procedure for applying transform precoding on PUSCH in 38.214 -- pusch_config_pdu->transform_precoding = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, NULL, NR_RNTI_TC, 0); // TBR fix rnti and take out -+ pusch_config_pdu->transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, NULL, NR_RNTI_TC, 0); // TBR fix rnti and take out - - // Resource allocation in frequency domain according to 6.1.2.2 in TS 38.214 - pusch_config_pdu->resource_alloc = (mac->cg) ? pusch_Config->resourceAllocation : 1; -@@ -680,7 +682,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, - - /* Transform precoding */ - if (rnti_type != NR_RNTI_CS || (rnti_type == NR_RNTI_CS && dci->ndi == 1)) { -- pusch_config_pdu->transform_precoding = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, dci_format, rnti_type, 0); -+ pusch_config_pdu->transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, dci_format, rnti_type, 0); - } - - /*DCI format-related configuration*/ -@@ -716,7 +718,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, - - /* TRANSFORM PRECODING ------------------------------------------------------------------------------------------*/ - -- if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled) { -+ if (pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) { - - pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; - -@@ -761,7 +763,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, - pusch_config_pdu->mcs_index = dci->mcs; - - /* MCS TABLE */ -- if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) { -+ if (pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) { - pusch_config_pdu->mcs_table = get_pusch_mcs_table(pusch_Config ? pusch_Config->mcs_Table : NULL, 0, *dci_format, rnti_type, target_ss, false); - } else { - pusch_config_pdu->mcs_table = get_pusch_mcs_table(pusch_Config ? pusch_Config->mcs_TableTransformPrecoder : NULL, 1, *dci_format, rnti_type, target_ss, false); -@@ -798,9 +800,14 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, - mappingtype, add_pos, dmrslength, - pusch_config_pdu->start_symbol_index, - mac->scc ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position); -- if ((mac->ULbwp[0] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled)) -- pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1; -- else if (*dci_format == NR_UL_DCI_FORMAT_0_0 || (mac->ULbwp[0] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled)) -+ if (mac->ULbwp[0] && pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) -+ { -+ if (*dci_format != NR_UL_DCI_FORMAT_0_1) -+ { -+ pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1; -+ } -+ } -+ else if (*dci_format == NR_UL_DCI_FORMAT_0_0 || (mac->ULbwp[0] && pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled)) - pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; - - // Num PRB Overhead from PUSCH-ServingCellConfig -@@ -821,7 +828,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, - mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup && - mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB && - mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) { -- if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) { -+ if (pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) { - nfapi_nr_ue_ptrs_ports_t ptrs_ports_list; - pusch_config_pdu->pusch_ptrs.ptrs_ports_list = &ptrs_ports_list; - valid_ptrs_setup = set_ul_ptrs_values(mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup, -@@ -909,6 +916,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in - - fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id); - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) -+ LOG_I(NR_MAC,"1# scheduled_response transmitted, %d, %d\n", rx_frame, rx_slot); - mac->if_module->scheduled_response(&scheduled_response); - } - else { -@@ -1022,6 +1030,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in - - fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, rx_frame, rx_slot, ul_info->thread_id); - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ -+ LOG_I(NR_MAC,"3# scheduled_response transmitted,%d, %d\n", frame_tx, slot_tx); - mac->if_module->scheduled_response(&scheduled_response); - } - pthread_mutex_lock(&ul_config->mutex_ul_config); -diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c -index 1cb3fdb708..d9c98852a3 100644 ---- a/openair2/LAYER2/NR_MAC_gNB/config.c -+++ b/openair2/LAYER2/NR_MAC_gNB/config.c -@@ -388,7 +388,7 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts - 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(NR_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); -+ LOG_I(NR_MAC,"Set RX antenna number to %d, Set TX antenna number to %d (num ssb %d: %x,%x)\n",cfg->carrier_config.num_tx_ant.value,cfg->carrier_config.num_rx_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 ); - cfg->num_tlv++; - cfg->num_tlv++; -diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c -index 6ac7f3f82e..5de36bb2db 100644 ---- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c -+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c -@@ -977,9 +977,9 @@ void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, - pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); - pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); - if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) -- pusch_pdu->transform_precoding = 1; -+ pusch_pdu->transformPrecoder = 1; - else -- pusch_pdu->transform_precoding = 0; -+ pusch_pdu->transformPrecoder = 0; - pusch_pdu->data_scrambling_id = *scc->physCellId; - pusch_pdu->nrOfLayers = 1; - pusch_pdu->ul_dmrs_symb_pos = get_l_prime(nr_of_symbols,mappingtype,pusch_dmrs_pos2,pusch_len1,start_symbol_index, scc->dmrs_TypeA_Position); -diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c -index abc007197d..9cbbe7d9a1 100644 ---- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c -+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c -@@ -1139,13 +1139,14 @@ void nr_schedule_ue_spec(module_id_t module_id, - dci_payload.dmrs_sequence_initialization.val = pdsch_pdu->SCID; - LOG_D(NR_MAC, - "%4d.%2d DCI type 1 payload: freq_alloc %d (%d,%d,%d), " -- "time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d tpc %d ti %d\n", -+ "nrOfLayers %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d tpc %d ti %d\n", - frame, - slot, - dci_payload.frequency_domain_assignment.val, - pdsch_pdu->rbStart, - pdsch_pdu->rbSize, - pdsch_pdu->BWPSize, -+ pdsch_pdu->nrOfLayers, - dci_payload.time_domain_assignment.val, - dci_payload.vrb_to_prb_mapping.val, - dci_payload.mcs, -diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c -index f1005cea70..8f7c856a30 100644 ---- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c -+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c -@@ -405,6 +405,7 @@ void nr_preprocessor_phytest(module_id_t module_id, - - uint32_t target_ul_mcs = 9; - uint32_t target_ul_bw = 50; -+uint32_t target_ul_Nl = 1; - uint64_t ulsch_slot_bitmap = (1 << 8); - bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_t slot) - { -@@ -446,15 +447,21 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ - - const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats; - const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0; -- const uint8_t num_dmrs_cdm_grps_no_data = 1; -+ uint8_t num_dmrs_cdm_grps_no_data = 1; -+ if ((target_ul_Nl==4)||(target_ul_Nl==3)) -+ { -+ num_dmrs_cdm_grps_no_data = 2; -+ } -+ - /* we want to avoid a lengthy deduction of DMRS and other parameters in - * every TTI if we can save it, so check whether dci_format, TDA, or - * num_dmrs_cdm_grps_no_data has changed and only then recompute */ - NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; - if (ps->time_domain_allocation != tda - || ps->dci_format != dci_format -+ || ps->nrOfLayers != target_ul_Nl - || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) -- nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, NULL,dci_format, tda, num_dmrs_cdm_grps_no_data, ps); -+ nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, NULL,dci_format, tda, num_dmrs_cdm_grps_no_data,target_ul_Nl,ps); - - uint16_t rbStart = 0; - uint16_t rbSize; -@@ -525,6 +532,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ - sched_pusch->ul_harq_pid = sched_ctrl->retrans_ul_harq.head; - - /* Calculate TBS from MCS */ -+ ps->nrOfLayers = target_ul_Nl; - sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table); - sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table); - if (ps->pusch_Config->tp_pi2BPSK -@@ -539,7 +547,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ - ps->N_PRB_DMRS * ps->num_dmrs_symb, - 0, // nb_rb_oh - 0, -- 1 /* NrOfLayers */) -+ ps->nrOfLayers /* NrOfLayers */) - >> 3; - - /* mark the corresponding RBs as used */ -diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c -index 1c0cb0353e..4583da876f 100644 ---- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c -+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c -@@ -355,6 +355,7 @@ void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc, - long dci_format, - int tda, - uint8_t num_dmrs_cdm_grps_no_data, -+ uint8_t nrOfLayers, - NR_pusch_semi_static_t *ps) - { - ps->dci_format = dci_format; -@@ -371,11 +372,11 @@ void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc, - - ps->pusch_Config = ubwp?ubwp->bwp_Dedicated->pusch_Config->choice.setup:(ubwpd ? ubwpd->pusch_Config->choice.setup : NULL); - if (ps->pusch_Config == NULL || !ps->pusch_Config->transformPrecoder) -- ps->transform_precoding = !scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder; -+ ps->transformPrecoder = !scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder; - else -- ps->transform_precoding = *ps->pusch_Config->transformPrecoder; -+ ps->transformPrecoder = *ps->pusch_Config->transformPrecoder; - const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; -- if (ps->transform_precoding) -+ if (ps->transformPrecoder) - ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config ? ps->pusch_Config->mcs_Table : NULL, - 0, - ps->dci_format, -@@ -392,6 +393,7 @@ void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc, - num_dmrs_cdm_grps_no_data = 2; // in case of transform precoding - no Data sent in DMRS symbol - } - -+ ps->nrOfLayers = nrOfLayers; - ps->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data; - - /* DMRS calculations */ -@@ -689,8 +691,21 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp, - "Non Codebook configuration non supported\n"); - dci_pdu_rel15->srs_resource_indicator.val = 0; // taking resource 0 for SRS - } -+ AssertFatal((pusch_pdu->Tpmi==0), "unsupport Tpmi\n"); -+ dci_pdu_rel15->precoding_information.val= 0; -+ if (pusch_pdu->nrOfLayers == 2) -+ { -+ dci_pdu_rel15->precoding_information.val = 4; -+ } -+ else if (pusch_pdu->nrOfLayers == 4) -+ { -+ dci_pdu_rel15->precoding_information.val = 11; -+ } -+ -+ // antenna_ports.val = 0 for transform precoder is disabled, dmrs-Type=1, maxLength=1, Rank=1/2/3/4 - // Antenna Ports -- dci_pdu_rel15->antenna_ports.val = 0; // TODO for now it is hardcoded, it should depends on cdm group no data and rank -+ dci_pdu_rel15->antenna_ports.val = 0; -+ - // DMRS sequence initialization - dci_pdu_rel15->dmrs_sequence_initialization.val = pusch_pdu->scid; - break; -@@ -699,11 +714,14 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp, - } - - LOG_D(NR_MAC, -- "%s() ULDCI type 0 payload: freq_alloc %d, time_alloc %d, freq_hop_flag %d, mcs %d tpc %d ndi %d rv %d\n", -+ "%s() ULDCI type 0 payload: dci_format %d, freq_alloc %d, time_alloc %d, freq_hop_flag %d, precoding_information.val %d antenna_ports.val %d mcs %d tpc %d ndi %d rv %d\n", - __func__, -+ dci_format, - dci_pdu_rel15->frequency_domain_assignment.val, - dci_pdu_rel15->time_domain_assignment.val, - dci_pdu_rel15->frequency_hopping_flag.val, -+ dci_pdu_rel15->precoding_information.val, -+ dci_pdu_rel15->antenna_ports.val, - dci_pdu_rel15->mcs, - dci_pdu_rel15->tpc, - dci_pdu_rel15->ndi, -diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c -index 9a6fa32b5f..269d6c5359 100644 ---- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c -+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c -@@ -905,7 +905,7 @@ bool allocate_ul_retransmission(module_id_t module_id, - NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; - int rbStart = 0; // wrt BWP start - const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); -- -+ const uint8_t nrOfLayers = 1; - const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_bwp || ubwpd) ? 1 : 2; - const int tda = sched_ctrl->active_ubwp ? RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0; - LOG_D(NR_MAC,"retInfo->time_domain_allocation = %d, tda = %d\n", retInfo->time_domain_allocation, tda); -@@ -926,8 +926,9 @@ bool allocate_ul_retransmission(module_id_t module_id, - - if (ps->time_domain_allocation != tda - || ps->dci_format != dci_format -+ || ps->nrOfLayers != nrOfLayers - || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) -- nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps); -+ nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, nrOfLayers,ps); - LOG_D(NR_MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size); - } else { - /* the retransmission will use a different time domain allocation, check -@@ -939,7 +940,7 @@ bool allocate_ul_retransmission(module_id_t module_id, - rbSize++; - NR_pusch_semi_static_t temp_ps; - int dci_format = get_dci_format(sched_ctrl); -- nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp,ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, &temp_ps); -+ nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp,ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, nrOfLayers, &temp_ps); - uint32_t new_tbs; - uint16_t new_rbSize; - bool success = nr_find_nb_rb(retInfo->Qm, -@@ -1094,7 +1095,7 @@ void pf_ul(module_id_t module_id, - if (max_num_ue < 0) - return; - -- LOG_D(NR_MAC,"Looking for min_rb %d RBs, starting at %d\n", min_rb, rbStart); -+ LOG_D(NR_MAC,"Looking for min_rb %d RBs, starting at %d num_dmrs_cdm_grps_no_data %d\n", min_rb, rbStart, ps->num_dmrs_cdm_grps_no_data); - while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++; - if (rbStart + min_rb >= bwpSize) { - LOG_W(NR_MAC, "cannot allocate continuous UL data for UE %d/RNTI %04x: no resources (rbStart %d, min_rb %d, bwpSize %d\n", -@@ -1106,13 +1107,15 @@ void pf_ul(module_id_t module_id, - /* we want to avoid a lengthy deduction of DMRS and other parameters in - * every TTI if we can save it, so check whether dci_format, TDA, or - * num_dmrs_cdm_grps_no_data has changed and only then recompute */ -+ const uint8_t nrOfLayers = 1; - const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_ubwp || ubwpd) ? 1 : 2; - int dci_format = get_dci_format(sched_ctrl); - const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0; - if (ps->time_domain_allocation != tda - || ps->dci_format != dci_format -+ || ps->nrOfLayers != nrOfLayers - || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) -- nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps); -+ nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data,nrOfLayers, ps); - NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; - sched_pusch->mcs = 9; - update_ul_ue_R_Qm(sched_pusch, ps); -@@ -1125,7 +1128,7 @@ void pf_ul(module_id_t module_id, - ps->N_PRB_DMRS * ps->num_dmrs_symb, - 0, // nb_rb_oh - 0, -- 1 /* NrOfLayers */) -+ ps->nrOfLayers) - >> 3; - - /* Mark the corresponding RBs as used */ -@@ -1205,13 +1208,15 @@ void pf_ul(module_id_t module_id, - /* we want to avoid a lengthy deduction of DMRS and other parameters in - * every TTI if we can save it, so check whether dci_format, TDA, or - * num_dmrs_cdm_grps_no_data has changed and only then recompute */ -+ const uint8_t nrOfLayers = 1; - const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_ubwp || ubwpd) ? 1 : 2; - int dci_format = get_dci_format(sched_ctrl); - const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0; - if (ps->time_domain_allocation != tda - || ps->dci_format != dci_format -+ || ps->nrOfLayers != nrOfLayers - || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) -- nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps); -+ nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, nrOfLayers,ps); - update_ul_ue_R_Qm(sched_pusch, ps); - - /* Calculate the current scheduling bytes and the necessary RBs */ -@@ -1473,7 +1478,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) - sched_ctrl->last_ul_slot = sched_pusch->slot; - - LOG_D(NR_MAC, -- "ULSCH/PUSCH: %4d.%2d RNTI %04x UL sched %4d.%2d DCI L %d start %2d RBS %3d startSymbol %2d nb_symbol %2d dmrs_pos %x MCS %2d TBS %4d HARQ PID %2d round %d RV %d NDI %d est %6d sched %6d est BSR %6d TPC %d\n", -+ "ULSCH/PUSCH: %4d.%2d RNTI %04x UL sched %4d.%2d DCI L %d start %2d RBS %3d startSymbol %2d nb_symbol %2d dmrs_pos %x MCS %2d nrOfLayers %2d num_dmrs_cdm_grps_no_data %2d TBS %4d HARQ PID %2d round %d RV %d NDI %d est %6d sched %6d est BSR %6d TPC %d\n", - frame, - slot, - rnti, -@@ -1486,6 +1491,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) - ps->nrOfSymbols, - ps->ul_dmrs_symb_pos, - sched_pusch->mcs, -+ ps->nrOfLayers, -+ ps->num_dmrs_cdm_grps_no_data, - sched_pusch->tb_size, - harq_id, - cur_harq->round, -@@ -1532,17 +1539,18 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) - pusch_pdu->qam_mod_order = sched_pusch->Qm; - pusch_pdu->mcs_index = sched_pusch->mcs; - pusch_pdu->mcs_table = ps->mcs_table; -- pusch_pdu->transform_precoding = ps->transform_precoding; -+ pusch_pdu->transformPrecoder = ps->transformPrecoder; - if (ps->pusch_Config && ps->pusch_Config->dataScramblingIdentityPUSCH) - pusch_pdu->data_scrambling_id = *ps->pusch_Config->dataScramblingIdentityPUSCH; - else - pusch_pdu->data_scrambling_id = *scc->physCellId; -- pusch_pdu->nrOfLayers = 1; -+ pusch_pdu->nrOfLayers = ps->nrOfLayers; -+ pusch_pdu->num_dmrs_cdm_grps_no_data = ps->num_dmrs_cdm_grps_no_data; - - /* FAPI: DMRS */ - pusch_pdu->ul_dmrs_symb_pos = ps->ul_dmrs_symb_pos; - pusch_pdu->dmrs_config_type = ps->dmrs_config_type; -- if (pusch_pdu->transform_precoding) { // transform precoding disabled -+ if (pusch_pdu->transformPrecoder) { // transform precoding disabled - long *scramblingid=NULL; - if (ps->NR_DMRS_UplinkConfig && pusch_pdu->scid == 0) - scramblingid = ps->NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0; -@@ -1562,7 +1570,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) - } - pusch_pdu->scid = 0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1] - pusch_pdu->num_dmrs_cdm_grps_no_data = ps->num_dmrs_cdm_grps_no_data; -- pusch_pdu->dmrs_ports = 1; -+ pusch_pdu->dmrs_ports = ((1<nrOfLayers) - 1); - - /* FAPI: Pusch Allocation in frequency domain */ - pusch_pdu->resource_alloc = 1; //type 1 -@@ -1588,7 +1596,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) - LOG_D(NR_MAC,"PUSCH PDU : data_scrambling_identity %x, dmrs_scrambling_id %x\n",pusch_pdu->data_scrambling_id,pusch_pdu->ul_dmrs_scrambling_id); - /* TRANSFORM PRECODING --------------------------------------------------------*/ - -- if (pusch_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled){ -+ if (pusch_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled){ - - // U as specified in section 6.4.1.1.1.2 in 38.211, if sequence hopping and group hopping are disabled - pusch_pdu->dfts_ofdm.low_papr_group_number = pusch_pdu->pusch_identity % 30; -diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h -index 91221276b0..8a560580c9 100644 ---- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h -+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h -@@ -298,6 +298,7 @@ void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc, - long dci_format, - int tda, - uint8_t num_dmrs_cdm_grps_no_data, -+ uint8_t nrOfLayers, - NR_pusch_semi_static_t *ps); - - uint8_t nr_get_tpc(int target, uint8_t cqi, int incr); -diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h -index 27f42f4b1d..66b10dad42 100644 ---- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h -+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h -@@ -318,13 +318,14 @@ typedef struct NR_sched_pucch { - typedef struct NR_pusch_semi_static_t { - int dci_format; - int time_domain_allocation; -+ uint8_t nrOfLayers; - uint8_t num_dmrs_cdm_grps_no_data; - - int startSymbolIndex; - int nrOfSymbols; - - NR_PUSCH_Config_t *pusch_Config; -- uint8_t transform_precoding; -+ uint8_t transformPrecoder; - uint8_t mcs_table; - - long mapping_type; -diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c -index ff6923429e..52d03b5e56 100755 ---- a/openair2/RRC/NR/MESSAGES/asn1_msg.c -+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c -@@ -1867,6 +1867,7 @@ int16_t do_RRCReconfiguration( - // 1, - // 1, - // carrier->pdsch_AntennaPorts, -+ // carrier->pusch_AntennaPorts, - // carrier->initial_csi_index[ue_context_p->local_uid + 1], - // ue_context_pP->local_uid); - -diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h -index 9465b9b4b0..6a94450450 100644 ---- a/openair2/RRC/NR/nr_rrc_proto.h -+++ b/openair2/RRC/NR/nr_rrc_proto.h -@@ -79,6 +79,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco - int scg_id, - int servCellIndex, - int dl_antenna_ports, -+ int ul_antenna_ports, - int do_csirs, - int initial_csi_index, - int uid); -@@ -90,6 +91,7 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon - NR_RRCReconfiguration_IEs_t *reconfig, - NR_CellGroupConfig_t *secondaryCellGroup, - int dl_antenna_ports, -+ int ul_antenna_ports, - int do_csirs, - int initial_csi_index, - int uid); -diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c -index f9fce48f41..22e43cbb6a 100644 ---- a/openair2/RRC/NR/rrc_gNB_nsa.c -+++ b/openair2/RRC/NR/rrc_gNB_nsa.c -@@ -241,6 +241,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ - reconfig_ies, - ue_context_p->ue_context.secondaryCellGroup, - carrier->pdsch_AntennaPorts, -+ carrier->pusch_AntennaPorts, - carrier->do_CSIRS, - carrier->initial_csi_index[ue_context_p->local_uid + 1], - ue_context_p->local_uid); -@@ -250,6 +251,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ - reconfig_ies, - ue_context_p->ue_context.secondaryCellGroup, - carrier->pdsch_AntennaPorts, -+ carrier->pusch_AntennaPorts, - carrier->do_CSIRS, - carrier->initial_csi_index[ue_context_p->local_uid + 1], - ue_context_p->local_uid); -@@ -348,7 +350,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_AntennaPorts, - rrc->carrier.sib1_tda, - rrc->carrier.servingcellconfigcommon, - &rrc->carrier.mib, -diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c -index 980bd39c37..d03f361502 100644 ---- a/openair2/RRC/NR/rrc_gNB_reconfig.c -+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c -@@ -55,6 +55,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco - int scg_id, - int servCellIndex, - int dl_antenna_ports, -+ int ul_antenna_ports, - int do_csirs, - int initial_csi_index, - int uid) { -@@ -745,14 +746,14 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco - pusch_Config->codebookSubset=calloc(1,sizeof(*pusch_Config->codebookSubset)); - *pusch_Config->codebookSubset = NR_PUSCH_Config__codebookSubset_nonCoherent; - pusch_Config->maxRank=calloc(1,sizeof(*pusch_Config->maxRank)); -- *pusch_Config->maxRank= 1; -+ *pusch_Config->maxRank= ul_antenna_ports; - pusch_Config->rbg_Size=NULL; - pusch_Config->uci_OnPUSCH=NULL; - pusch_Config->tp_pi2BPSK=NULL; - - /*------------------------------TRANSFORM PRECODING- -----------------------------------------------------------------------*/ - -- uint8_t transform_precoding = NR_PUSCH_Config__transformPrecoder_disabled; -+ uint8_t transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled; - - // TBD: configure this from .conf file, Dedicated params cannot yet be configured in .conf file. - // Enable this to test transform precoding enabled from dedicated config. -@@ -764,13 +765,13 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco - - if (pusch_Config->transformPrecoder == NULL) { - if (servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder != NULL) -- transform_precoding = NR_PUSCH_Config__transformPrecoder_enabled; -+ transformPrecoder = NR_PUSCH_Config__transformPrecoder_enabled; - } - else -- transform_precoding = *pusch_Config->transformPrecoder; -+ transformPrecoder = *pusch_Config->transformPrecoder; - - -- if (transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled ) { -+ if (transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled ) { - /* Enable DMRS uplink config for transform precoding enabled */ - NR_DMRS_UplinkConfig->transformPrecodingEnabled = calloc(1,sizeof(*NR_DMRS_UplinkConfig->transformPrecodingEnabled)); - NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity = NULL; -@@ -1348,6 +1349,7 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon - NR_RRCReconfiguration_IEs_t *reconfig, - NR_CellGroupConfig_t *secondaryCellGroup, - int dl_antenna_ports, -+ int ul_antenna_ports, - int do_csirs, - int initial_csi_index, - int uid) { -@@ -1363,6 +1365,7 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon - 1, - 1, - dl_antenna_ports, -+ ul_antenna_ports, - do_csirs, - initial_csi_index, - uid); -diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c -index 13945998d7..20faa86591 100644 ---- a/targets/ARCH/rfsimulator/simulator.c -+++ b/targets/ARCH/rfsimulator/simulator.c -@@ -429,7 +429,7 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp - if (!alreadyLocked) - pthread_mutex_lock(&Sockmutex); - -- LOG_D(HW,"sending %d samples at time: %ld\n", nsamps, timestamp); -+ LOG_D(HW,"sending %d samples at time: %ld, nbAnt %d\n", nsamps, timestamp, nbAnt); - - for (int i=0; ibuf[i]; -@@ -623,7 +623,7 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest - } - - rfsimulator_state_t *t = device->priv; -- LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextTimestamp+nsamps); -+ LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld, nbAnt %d\n", nsamps, t->nextTimestamp+nsamps, nbAnt); - // deliver data from received data - // check if a UE is connected - int first_sock; -@@ -728,6 +728,7 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest - - for (int a=0; achannel_model != NULL ) // apply a channel model -+ { - rxAddInput( ptr->circularBuf, (struct complex16 *) samplesVoid[a], - a, - ptr->channel_model, -@@ -735,11 +736,21 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest - t->nextTimestamp, - CirSize - ); -- else { // no channel modeling -+ } -+ else -+ { // no channel modeling -+ -+ #if 0 - double H_awgn_mimo[4][4] ={{1.0, 0.5, 0.25, 0.125},//rx 0 - {0.5, 1.0, 0.5, 0.25}, //rx 1 - {0.25, 0.5, 1.0, 0.5}, //rx 2 - {0.125, 0.25, 0.5, 1.0}};//rx 3 -+ #else -+ double H_awgn_mimo[4][4] ={{1.0, 0.0, 0.0, 0.0},//rx 0 -+ {0.0, 1.0, 0.0, 0.0},//rx 1 -+ {0.0, 0.0, 1.0, 0.0},//rx 2 -+ {0.0, 0.0, 0.0, 1.0}};//rx 3 -+ #endif - - sample_t *out=(sample_t *)samplesVoid[a]; - int nbAnt_tx = ptr->th.nbAnt;//number of Tx antennas diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 8314c83ad9..f41b51161b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -1969,9 +1969,9 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, gNB->pusch_vars[ulsch_id]->cl_done = 0; bwp_start_subcarrier = ((rel15_ul->rb_start + rel15_ul->bwp_start)*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size; - LOG_I(PHY,"pusch %d.%d : bwp_start_subcarrier %d, rb_start %d, first_carrier_offset %d\n", frame,slot,bwp_start_subcarrier, rel15_ul->rb_start, frame_parms->first_carrier_offset); - LOG_I(PHY,"pusch %d.%d : ul_dmrs_symb_pos %x\n",frame,slot,rel15_ul->ul_dmrs_symb_pos); - LOG_I(PHY,"ulsch RX %x : start_rb %d nb_rb %d mcs %d Nl %d Tpmi %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_ports %d\n", + LOG_D(PHY,"pusch %d.%d : bwp_start_subcarrier %d, rb_start %d, first_carrier_offset %d\n", frame,slot,bwp_start_subcarrier, rel15_ul->rb_start, frame_parms->first_carrier_offset); + LOG_D(PHY,"pusch %d.%d : ul_dmrs_symb_pos %x\n",frame,slot,rel15_ul->ul_dmrs_symb_pos); + LOG_D(PHY,"ulsch RX %x : start_rb %d nb_rb %d mcs %d Nl %d Tpmi %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_ports %d\n", rel15_ul->rnti,rel15_ul->rb_start,rel15_ul->rb_size,rel15_ul->mcs_index, rel15_ul->nrOfLayers,0,rel15_ul->bwp_start,0,rel15_ul->start_symbol_index,rel15_ul->nr_of_symbols, rel15_ul->num_dmrs_cdm_grps_no_data,rel15_ul->ul_dmrs_symb_pos,rel15_ul->dmrs_ports); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 5d76e654ba..eda1711f6b 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -98,7 +98,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, uint8_t thread_id, int gNB_id) { - LOG_I(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot); + LOG_D(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot); uint32_t available_bits; uint8_t cwd_index, l; @@ -150,7 +150,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, nb_dmrs_re_per_rb = ((dmrs_type == pusch_dmrs_type1) ? 6:4)*cdm_grps_no_data; - LOG_I(PHY,"ulsch TX %x : start_rb %d nb_rb %d mod_order %d Nl %d Tpmi %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_re_per_rb %d\n", + LOG_D(PHY,"ulsch TX %x : start_rb %d nb_rb %d mod_order %d Nl %d Tpmi %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_re_per_rb %d\n", rnti,start_rb,nb_rb,mod_order,Nl,pusch_pdu->Tpmi,pusch_pdu->bwp_start,start_sc,start_symbol,number_of_symbols,cdm_grps_no_data,number_dmrs_symbols,nb_dmrs_re_per_rb); // TbD num_of_mod_symbols is set but never used diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 63c708e565..d77fb94bc1 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -253,17 +253,17 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { // if all segments are done if (rdata->nbSegments == ulsch_harq->processedSegments) { if (decodeSuccess) { - LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for SFN/SF %d.%d (pid %d, ndi %d, status %d, round %d, TBS %d, Max interation (all seg) %d)\n", + LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for SFN/SF %d.%d (pid %d, ndi %d, status %d, round %d, TBS %d, Max interation (all seg) %d)\n", gNB->Mod_id,ulsch_harq->frame,ulsch_harq->slot,rdata->harq_pid,pusch_pdu->pusch_data.new_data_indicator,ulsch_harq->status,ulsch_harq->round,ulsch_harq->TBS,rdata->decodeIterations); ulsch_harq->status = SCH_IDLE; ulsch_harq->round = 0; ulsch->harq_mask &= ~(1 << rdata->harq_pid); - LOG_I(PHY, "ULSCH received ok \n"); + LOG_D(PHY, "ULSCH received ok \n"); nr_fill_indication(gNB,ulsch_harq->frame, ulsch_harq->slot, rdata->ulsch_id, rdata->harq_pid, 0,0); //dumpsig=1; } else { - LOG_I(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, ndi %d, status %d, round %d, RV %d, prb_start %d, prb_size %d, TBS %d) r %d\n", + LOG_D(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, ndi %d, status %d, round %d, RV %d, prb_start %d, prb_size %d, TBS %d) r %d\n", gNB->Mod_id, ulsch_harq->frame, ulsch_harq->slot, rdata->harq_pid, pusch_pdu->pusch_data.new_data_indicator, ulsch_harq->status, ulsch_harq->round, @@ -281,7 +281,7 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { } ulsch_harq->handled = 1; - LOG_I(PHY, "ULSCH %d in error\n",rdata->ulsch_id); + LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id); nr_fill_indication(gNB,ulsch_harq->frame, ulsch_harq->slot, rdata->ulsch_id, rdata->harq_pid, 1,0); } /* @@ -739,7 +739,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { (ulsch_harq->slot == slot_rx) && (ulsch_harq->handled == 0)){ - LOG_I(PHY, "PUSCH detection started in frame %d slot %d\n", + LOG_D(PHY, "PUSCH detection started in frame %d slot %d\n", frame_rx,slot_rx); int num_dmrs=0; for (int s=0;srx_pusch_stats); no_sig = nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, harq_pid); if (no_sig) { - LOG_I(PHY, "PUSCH not detected in frame %d, slot %d\n", frame_rx, slot_rx); + LOG_D(PHY, "PUSCH not detected in frame %d, slot %d\n", frame_rx, slot_rx); nr_fill_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid, 1,1); return 1; } @@ -791,7 +791,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot) + gNB->pusch_thres) { NR_gNB_SCH_STATS_t *stats=get_ulsch_stats(gNB,ulsch); - LOG_I(PHY, "PUSCH not detected in %d.%d (%d,%d,%d)\n",frame_rx,slot_rx, + LOG_D(PHY, "PUSCH not detected in %d.%d (%d,%d,%d)\n",frame_rx,slot_rx, dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot), dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot),gNB->pusch_thres); gNB->pusch_vars[ULSCH_id]->ulsch_power_tot = gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot; diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index d24b90ab3c..d602e38b4b 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -158,7 +158,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ for (i = 0; i < ul_config->number_pdus; ++i){ AssertFatal(ul_config->ul_config_list[i].pdu_type <= FAPI_NR_UL_CONFIG_TYPES,"pdu_type %d out of bounds\n",ul_config->ul_config_list[i].pdu_type); - LOG_I(PHY, "In %s i %d: processing %s PDU of %d total UL PDUs (ul_config %p) \n", __FUNCTION__, i, ul_pdu_type[ul_config->ul_config_list[i].pdu_type - 1], ul_config->number_pdus, ul_config); + LOG_D(PHY, "In %s i %d: processing %s PDU of %d total UL PDUs (ul_config %p) \n", __FUNCTION__, i, ul_pdu_type[ul_config->ul_config_list[i].pdu_type - 1], ul_config->number_pdus, ul_config); uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type, current_harq_pid, gNB_id = 0; /* PRACH */ @@ -182,7 +182,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &harq_process_ul_ue->pusch_pdu; - LOG_I(PHY, "In %s i %d: copy pusch_config_pdu nrOfLayers:%d, num_dmrs_cdm_grps_no_data:%d \n", __FUNCTION__, i, pusch_config_pdu->nrOfLayers,pusch_config_pdu->num_dmrs_cdm_grps_no_data); + LOG_D(PHY, "In %s i %d: copy pusch_config_pdu nrOfLayers:%d, num_dmrs_cdm_grps_no_data:%d \n", __FUNCTION__, i, pusch_config_pdu->nrOfLayers,pusch_config_pdu->num_dmrs_cdm_grps_no_data); memcpy(pusch_pdu, pusch_config_pdu, sizeof(nfapi_nr_ue_pusch_pdu_t)); From 2f7e7b9823c29d517a49ddc4b44d9b8b5dc01dd4 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 10 Dec 2021 10:54:10 +0100 Subject: [PATCH 05/49] remove some more logs --- cmake_targets/autotests/test_case_list.xml | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 00fcfc4140..6c9508b736 100755 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1331,7 +1331,7 @@ -n100 -m9 -r106 -s10 -W2 -y2 -z2 -n100 -m9 -r106 -s13 -W4 -y4 -z4 - nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15 nr_ulsim.test16 nr_ulsim.test16 + nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15 nr_ulsim.test16 nr_ulsim.test17 PUSCH test OK segmentation fault|assertion|exiting|fatal 3 diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 05c1318814..84989ee6dc 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -346,7 +346,7 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf } long *max_length = NULL; long *dmrs_type = NULL; - LOG_I(NR_MAC,"transformPrecoder %s\n",transformPrecoder==NR_PUSCH_Config__transformPrecoder_disabled?"disabled":"enabled"); + LOG_D(NR_MAC,"transformPrecoder %s\n",transformPrecoder==NR_PUSCH_Config__transformPrecoder_disabled?"disabled":"enabled"); if (pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA) { max_length = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup->maxLength; @@ -357,7 +357,8 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf dmrs_type = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->dmrs_Type; } - LOG_I(NR_MAC,"MappingType%s max_length %s, dmrs_type %s, antenna_ports %d\n",pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA?"A":"B",max_length?"len2":"len1",dmrs_type?"type2":"type1",dci->antenna_ports.val); + LOG_D(NR_MAC,"MappingType%s max_length %s, dmrs_type %s, antenna_ports %d\n", + pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA?"A":"B",max_length?"len2":"len1",dmrs_type?"type2":"type1",dci->antenna_ports.val); if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) && (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-6 pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC @@ -509,7 +510,7 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf //pusch_config_pdu->n_front_load_symb = table_7_3_1_1_2_23[dci->antenna_ports.val][5]; //FIXME } } - LOG_I(NR_MAC,"num_dmrs_cdm_grps_no_data %d, dmrs_ports %d\n",pusch_config_pdu->num_dmrs_cdm_grps_no_data,pusch_config_pdu->dmrs_ports); + LOG_D(NR_MAC,"num_dmrs_cdm_grps_no_data %d, dmrs_ports %d\n",pusch_config_pdu->num_dmrs_cdm_grps_no_data,pusch_config_pdu->dmrs_ports); } // Configuration of Msg3 PDU according to clauses: @@ -916,7 +917,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) - LOG_I(NR_MAC,"1# scheduled_response transmitted, %d, %d\n", rx_frame, rx_slot); + LOG_D(NR_MAC,"1# scheduled_response transmitted, %d, %d\n", rx_frame, rx_slot); mac->if_module->scheduled_response(&scheduled_response); } else { @@ -1030,7 +1031,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, rx_frame, rx_slot, ul_info->thread_id); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ - LOG_I(NR_MAC,"3# scheduled_response transmitted,%d, %d\n", frame_tx, slot_tx); + LOG_D(NR_MAC,"3# scheduled_response transmitted,%d, %d\n", frame_tx, slot_tx); mac->if_module->scheduled_response(&scheduled_response); } pthread_mutex_lock(&ul_config->mutex_ul_config); From 882c4b34a2a43a26f62994dc3673b217d94e8783 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 7 Jan 2022 18:03:35 +0100 Subject: [PATCH 06/49] cleanup --- openair1/PHY/INIT/nr_init.c | 11 +-- openair1/PHY/NR_TRANSPORT/nr_ulsch.c | 21 ++--- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 18 ++--- .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 8 -- openair1/SIMULATION/NR_PHY/ulsim.c | 80 ++----------------- 5 files changed, 24 insertions(+), 114 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 2ac3230215..2beda80d36 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -284,10 +284,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, pusch_vars[ULSCH_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); pusch_vars[ULSCH_id]->rho[i] = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS*sizeof(int32_t*)); - for (int j=0; j< max_ul_mimo_layers; j++) - { - for (int k=0; krho[i][j*max_ul_mimo_layers+k]=(int32_t *)malloc16_clear( sizeof(int32_t) * fp->N_RB_UL*12*7*2 ); } } @@ -303,11 +301,10 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, pusch_vars[ULSCH_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); pusch_vars[ULSCH_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); pusch_vars[ULSCH_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); - pusch_vars[ULSCH_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); + pusch_vars[ULSCH_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); } - for (i=0; i< max_ul_mimo_layers; i++) - { + for (i=0; i< max_ul_mimo_layers; i++) { pusch_vars[ULSCH_id]->llr_layers[i] = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear } pusch_vars[ULSCH_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c index 3ea19a9970..6bfcc1d50c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c @@ -145,25 +145,20 @@ void nr_ulsch_layer_demapping(int16_t *llr_cw, { switch (Nl) { - case 1: memcpy((void*)llr_cw, (void*)llr_layers[0], (length)*sizeof(int16_t)); - break; - + break; case 2: case 3: case 4: - for (int i=0; i<(length/Nl/mod_order); i++) - { - for (int l=0; lnb_antennas_rx; aarx++) - { + for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { rxF = (int16_t *)&rxdataF[aarx][soffset+(symbol * frame_parms->ofdm_symbol_size)]; rxF_ext = (int16_t *)&pusch_vars->rxdataF_ext[aarx][symbol * nb_re_pusch2]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6 - if (is_dmrs_symbol == 0) - { + if (is_dmrs_symbol == 0) { // //rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]); if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size) @@ -466,14 +464,10 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, int off = 0; #endif -for (aatx = 0; aatx < nrOfLayers; aatx++) -{ - for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) - { + for (aatx = 0; aatx < nrOfLayers; aatx++) { + for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) { ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*NR_NB_SC_PER_RB))]; - - for (rb=0;rb < nb_rb_0;rb++) - { + for (rb=0;rb < nb_rb_0;rb++) { ul_ch128[0] = _mm_mulhi_epi16(ul_ch128[0], ch_amp128); ul_ch128[0] = _mm_slli_epi16(ul_ch128[0], 3); @@ -484,8 +478,8 @@ for (aatx = 0; aatx < nrOfLayers; aatx++) ul_ch128[2] = _mm_slli_epi16(ul_ch128[2], 3); ul_ch128+=3; } + } } -} #endif } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index a293eec6d8..036c1deaa6 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -259,14 +259,6 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, Tbslbrm = 950984; //max tbs Coderate = 0.0; - #if 0 - harq_process->a[0] = 0x31; - for (int i = 1; i < harq_process->pusch_pdu.pusch_data.tb_size; i++) - { - harq_process->a[i] = (i&0xff); - } - #endif - trace_NRpdu(DIRECTION_UPLINK, harq_process->a, harq_process->pusch_pdu.pusch_data.tb_size, 0, WS_C_RNTI, 0, 0, 0,0, 0); /////////// ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 957a624800..6caa18ae33 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -488,32 +488,26 @@ int main(int argc, char **argv) case 'y': n_tx = atoi(optarg); - if ((n_tx == 0) || (n_tx > 4)) { - printf("Unsupported number of tx antennas %d\n", n_tx); - exit(-1); + printf("Unsupported number of tx antennas %d\n", n_tx); + exit(-1); } - break; case 'z': n_rx = atoi(optarg); - if ((n_rx == 0) || (n_rx > 8)) { - printf("Unsupported number of rx antennas %d\n", n_rx); - exit(-1); + printf("Unsupported number of rx antennas %d\n", n_rx); + exit(-1); } - break; case 'F': input_fd = fopen(optarg, "r"); - if (input_fd == NULL) { - printf("Problem with filename %s\n", optarg); - exit(-1); + printf("Problem with filename %s\n", optarg); + exit(-1); } - break; case 'G': @@ -571,13 +565,10 @@ int main(int argc, char **argv) break; case 'Z': - transformPrecoder = transformPrecoder_enabled; num_dmrs_cdm_grps_no_data = 2; mcs_table = 3; - printf("NOTE: TRANSFORM PRECODING (SC-FDMA) is ENABLED in UPLINK (0 - ENABLE, 1 - DISABLE) : %d \n", transformPrecoder); - break; default: @@ -1300,15 +1291,6 @@ int main(int argc, char **argv) ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); - #if 0 - ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((r_re[ap][i])); // convert to fixed point - ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((r_im[ap][i])); - - - ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) ] = ((int16_t*) &UE->common_vars.txdata[ap][slot_offset])[(2*i) ]; // convert to fixed point - ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1] = ((int16_t*) &UE->common_vars.txdata[ap][slot_offset])[(2*i)+1 ]; - #endif - /* Add phase noise if enabled */ if (pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { phase_noise(ts, &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)], @@ -1451,56 +1433,6 @@ int main(int argc, char **argv) &gNB->pusch_vars[0]->llr_layers[3][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); } - #if 0 - if (n_rx == 2) { - LOG_MM("rxsigF0_comp.m","rxsF1_comp", - &gNB->pusch_vars[0]->rxdataF_comp[1][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("rxsigF0_ext.m","rxsF1_ext", - &gNB->pusch_vars[0]->rxdataF_ext[1][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("chestF0_ext.m","chF1_ext", - &gNB->pusch_vars[0]->ul_ch_estimates_ext[1][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], - (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("chmagF0.m","chmF1", - &gNB->pusch_vars[0]->ul_ch_mag[1][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("chmagbF0.m","chmbF1", - &gNB->pusch_vars[0]->ul_ch_magb[1][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - } else if (n_rx == 4) { - LOG_MM("rxsigF0_comp.m","rxsF1_comp", - &gNB->pusch_vars[0]->rxdataF_comp[1][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("rxsigF0_comp.m","rxsF2_comp", - &gNB->pusch_vars[0]->rxdataF_comp[2][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("rxsigF0_comp.m","rxsF3_comp", - &gNB->pusch_vars[0]->rxdataF_comp[3][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("rxsigF0_ext.m","rxsF1_ext", - &gNB->pusch_vars[0]->rxdataF_ext[1][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("rxsigF0_ext.m","rxsF2_ext", - &gNB->pusch_vars[0]->rxdataF_ext[2][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("rxsigF0_ext.m","rxsF3_ext", - &gNB->pusch_vars[0]->rxdataF_ext[3][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("chestF0_ext.m","chF1_ext", - &gNB->pusch_vars[0]->ul_ch_estimates_ext[1][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], - (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("chestF0_ext.m","chF2_ext", - &gNB->pusch_vars[0]->ul_ch_estimates_ext[2][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], - (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("chestF0_ext.m","chF3_ext", - &gNB->pusch_vars[0]->ul_ch_estimates_ext[3][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], - (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("chmagF0.m","chmF1", - &gNB->pusch_vars[0]->ul_ch_mag[1][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("chmagF0.m","chmF2", - &gNB->pusch_vars[0]->ul_ch_mag[2][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("chmagF0.m","chmF3", - &gNB->pusch_vars[0]->ul_ch_mag[3][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("chmagbF0.m","chmbF1", - &gNB->pusch_vars[0]->ul_ch_magb[1][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("chmagbF0.m","chmbF2", - &gNB->pusch_vars[0]->ul_ch_magb[2][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_MM("chmagbF0.m","chmbF3", - &gNB->pusch_vars[0]->ul_ch_magb[3][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - } - #endif - LOG_M("rxsigF0_llr.m","rxsF0_llr", &gNB->pusch_vars[0]->llr[0],precod_nbr_layers*(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); } From 65698f6a8f813d2a5bf53978d533f0f24db756a0 Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 17 Jan 2022 15:15:47 +0100 Subject: [PATCH 07/49] some improvements in ul-mimo code --- executables/nr-uesoftmodem.c | 2 - .../nfapi/public_inc/nfapi_nr_interface_scf.h | 1 - nfapi/open-nFAPI/nfapi/src/nfapi_p7.c | 2 - openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 311 ++++++++---------- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 8 +- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 38 ++- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 4 + openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 75 ++--- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 1 - 10 files changed, 219 insertions(+), 225 deletions(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 1d36ff9017..ac89bcfd4e 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -493,8 +493,6 @@ int main( int argc, char **argv ) { set_options(CC_id, UE[CC_id]); NR_UE_MAC_INST_t *mac = get_mac_inst(0); - NR_DL_FRAME_PARMS *fp = &UE[CC_id]->frame_parms; - mac->phy_config.config_req.carrier_config.num_tx_ant = fp->nb_antennas_tx; if (get_softmodem_params()->sa) { // set frame config to initial values from command line and assume that the SSB is centered on the grid uint16_t nr_band = get_band(downlink_frequency[CC_id][0],uplink_frequency_offset[CC_id][0]); diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index 4e8d3b9401..e3b7a55f7b 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -1213,7 +1213,6 @@ typedef struct uint8_t transformPrecoder; uint16_t data_scrambling_id; uint8_t nrOfLayers; - uint8_t Tpmi; //DMRS uint16_t ul_dmrs_symb_pos; uint8_t dmrs_config_type; diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c index 9b844d22cf..8d83151ce8 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -950,7 +950,6 @@ static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, ui push8(pusch_pdu->transformPrecoder, ppWritePackedMsg, end) && push16(pusch_pdu->data_scrambling_id, ppWritePackedMsg, end) && push8(pusch_pdu->nrOfLayers, ppWritePackedMsg, end) && - push8(pusch_pdu->Tpmi, ppWritePackedMsg, end) && push16(pusch_pdu->ul_dmrs_symb_pos, ppWritePackedMsg, end) && push8(pusch_pdu->dmrs_config_type, ppWritePackedMsg, end) && push16(pusch_pdu->ul_dmrs_scrambling_id, ppWritePackedMsg, end) && @@ -4449,7 +4448,6 @@ static uint8_t unpack_ul_tti_request_pusch_pdu(void *tlv, uint8_t **ppReadPacked pull8(ppReadPackedMsg, &pusch_pdu->transformPrecoder, end) && pull16(ppReadPackedMsg, &pusch_pdu->data_scrambling_id, end) && pull8(ppReadPackedMsg, &pusch_pdu->nrOfLayers, end) && - pull8(ppReadPackedMsg, &pusch_pdu->Tpmi, end) && pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_symb_pos, end) && pull8(ppReadPackedMsg, &pusch_pdu->dmrs_config_type, end) && pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_scrambling_id, end) && diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 9bbc61d4b6..edd997a30f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -285,7 +285,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, start_meas(&gNB->dlsch_resource_mapping_stats); for (int ap=0; apnrOfLayers; ap++) { - // DMRS params for this ap + // DMRS params for this poir get_Wt(Wt, ap, dmrs_Type); get_Wf(Wf, ap, dmrs_Type); delta = get_delta(ap, dmrs_Type); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index d174d85eac..84ad8aa8af 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -37,6 +37,7 @@ #include "PHY/MODULATION/nr_modulation.h" #include "PHY/MODULATION/modulation_common.h" #include "common/utils/assertions.h" +#include "common/utils/nr/nr_common.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "PHY/NR_TRANSPORT/nr_sch_dmrs.h" @@ -107,7 +108,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, int8_t Wf[2], Wt[2]; int l_prime[2], delta; uint8_t nb_dmrs_re_per_rb; - int ap, i; + int i; int sample_offsetF, N_RE_prime; NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms; @@ -207,99 +208,99 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////// //////////////////////////////////////////////////////////////////////// - /////////////////////////DMRS Modulation///////////////////////// - /////////// - uint32_t ***pusch_dmrs = UE->nr_gold_pusch_dmrs[slot]; - uint16_t n_dmrs = (pusch_pdu->bwp_start + start_rb + nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4); - int16_t mod_dmrs[n_dmrs<<1] __attribute((aligned(16))); - /////////// - //////////////////////////////////////////////////////////////////////// + /////////////////////////DMRS Modulation///////////////////////// + /////////// + uint32_t ***pusch_dmrs = UE->nr_gold_pusch_dmrs[slot]; + uint16_t n_dmrs = (pusch_pdu->bwp_start + start_rb + nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4); + int16_t mod_dmrs[n_dmrs<<1] __attribute((aligned(16))); + /////////// + //////////////////////////////////////////////////////////////////////// - /////////////////////////PTRS parameters' initialization///////////////////////// - /////////// + /////////////////////////PTRS parameters' initialization///////////////////////// + /////////// - int16_t mod_ptrs[nb_rb] __attribute((aligned(16))); // assume maximum number of PTRS per pusch allocation - uint8_t L_ptrs, K_ptrs = 0; - uint16_t beta_ptrs = 1; // temp value until power control is implemented + int16_t mod_ptrs[nb_rb] __attribute((aligned(16))); // assume maximum number of PTRS per pusch allocation + uint8_t L_ptrs, K_ptrs = 0; + uint16_t beta_ptrs = 1; // temp value until power control is implemented - if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { + if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { - K_ptrs = harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_freq_density; - L_ptrs = 1<pusch_pdu.pusch_ptrs.ptrs_time_density; + K_ptrs = harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_freq_density; + L_ptrs = 1<pusch_pdu.pusch_ptrs.ptrs_time_density; - beta_ptrs = 1; // temp value until power control is implemented + beta_ptrs = 1; // temp value until power control is implemented - ulsch_ue->ptrs_symbols = 0; + ulsch_ue->ptrs_symbols = 0; - set_ptrs_symb_idx(&ulsch_ue->ptrs_symbols, - number_of_symbols, - start_symbol, - L_ptrs, - ul_dmrs_symb_pos); - } - - /////////// - //////////////////////////////////////////////////////////////////////////////// - - /////////////////////////ULSCH layer mapping///////////////////////// - /////////// - - nr_ue_layer_mapping(UE->ulsch[thread_id][gNB_id], - Nl, - available_bits/mod_order, - tx_layers); - - /////////// - //////////////////////////////////////////////////////////////////////// - - - //////////////////////// ULSCH transform precoding //////////////////////// - /////////// - - l_prime[0] = 0; // single symbol ap 0 - - uint16_t index; - uint8_t u = 0, v = 0; - int16_t *dmrs_seq = NULL; - - // if transform precoding is enbaled (value 0) - if (pusch_pdu->transformPrecoder == transformPrecoder_enabled) { - - uint32_t nb_re_pusch=nb_rb * NR_NB_SC_PER_RB; - uint32_t y_offset = 0; - uint16_t num_dmrs_res_per_symbol = nb_rb*(NR_NB_SC_PER_RB/2); - - // Calculate index to dmrs seq array based on number of DMRS Subcarriers on this symbol - index = get_index_for_dmrs_lowpapr_seq(num_dmrs_res_per_symbol); - u = pusch_pdu->dfts_ofdm.low_papr_group_number; - v = pusch_pdu->dfts_ofdm.low_papr_sequence_number; - dmrs_seq = dmrs_lowpaprtype1_ul_ref_sig[u][v][index]; - - AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); - AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated"); - - LOG_D(PHY,"Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", u, v, index); - - for (l = start_symbol; l < start_symbol + number_of_symbols; l++) { - - if((ul_dmrs_symb_pos >> l) & 0x01) - /* In the symbol with DMRS no data would be transmitted CDM groups is 2*/ - continue; - - nr_dft(&ulsch_ue->y[y_offset], &((int32_t*)tx_layers[0])[y_offset], nb_re_pusch); - - y_offset = y_offset + nb_re_pusch; - - LOG_D(PHY,"Transform precoding being done on data- symbol: %d, nb_re_pusch: %d, y_offset: %d\n", l, nb_re_pusch, y_offset); - - #ifdef DEBUG_PUSCH_MAPPING - printf("NR_ULSCH_UE: y_offset %d\t nb_re_pusch %d \t Symbol %d \t nb_rb %d \n", - y_offset, nb_re_pusch, l, nb_rb); - #endif + set_ptrs_symb_idx(&ulsch_ue->ptrs_symbols, + number_of_symbols, + start_symbol, + L_ptrs, + ul_dmrs_symb_pos); } - #ifdef DEBUG_DFT_IDFT + /////////// + //////////////////////////////////////////////////////////////////////////////// + + /////////////////////////ULSCH layer mapping///////////////////////// + /////////// + + nr_ue_layer_mapping(UE->ulsch[thread_id][gNB_id], + Nl, + available_bits/mod_order, + tx_layers); + + /////////// + //////////////////////////////////////////////////////////////////////// + + + //////////////////////// ULSCH transform precoding //////////////////////// + /////////// + + l_prime[0] = 0; // single symbol ap 0 + + uint16_t index; + uint8_t u = 0, v = 0; + int16_t *dmrs_seq = NULL; + + // if transform precoding is enbaled (value 0) + if (pusch_pdu->transformPrecoder == transformPrecoder_enabled) { + + uint32_t nb_re_pusch=nb_rb * NR_NB_SC_PER_RB; + uint32_t y_offset = 0; + uint16_t num_dmrs_res_per_symbol = nb_rb*(NR_NB_SC_PER_RB/2); + + // Calculate index to dmrs seq array based on number of DMRS Subcarriers on this symbol + index = get_index_for_dmrs_lowpapr_seq(num_dmrs_res_per_symbol); + u = pusch_pdu->dfts_ofdm.low_papr_group_number; + v = pusch_pdu->dfts_ofdm.low_papr_sequence_number; + dmrs_seq = dmrs_lowpaprtype1_ul_ref_sig[u][v][index]; + + AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); + AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated"); + + LOG_D(PHY,"Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", u, v, index); + + for (l = start_symbol; l < start_symbol + number_of_symbols; l++) { + + if((ul_dmrs_symb_pos >> l) & 0x01) + /* In the symbol with DMRS no data would be transmitted CDM groups is 2*/ + continue; + + nr_dft(&ulsch_ue->y[y_offset], &((int32_t*)tx_layers[0])[y_offset], nb_re_pusch); + + y_offset = y_offset + nb_re_pusch; + + LOG_D(PHY,"Transform precoding being done on data- symbol: %d, nb_re_pusch: %d, y_offset: %d\n", l, nb_re_pusch, y_offset); + + #ifdef DEBUG_PUSCH_MAPPING + printf("NR_ULSCH_UE: y_offset %d\t nb_re_pusch %d \t Symbol %d \t nb_rb %d \n", + y_offset, nb_re_pusch, l, nb_rb); + #endif + } + + #ifdef DEBUG_DFT_IDFT int32_t debug_symbols[MAX_NUM_NR_RE] __attribute__ ((aligned(16))); int offset = 0; printf("NR_ULSCH_UE: available_bits: %d, mod_order: %d", available_bits,mod_order); @@ -320,20 +321,19 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, LOG_M("postDFT_all_symbols.m","UE_postDFT", ulsch_ue->y,number_of_symbols*nb_re_pusch,1,1); LOG_M("DEBUG_IDFT_SYMBOLS.m","UE_Debug_IDFT", debug_symbols,number_of_symbols*nb_re_pusch,1,1); LOG_M("UE_DMRS_SEQ.m","UE_DMRS_SEQ", dmrs_seq,nb_re_pusch,1,1); - #endif + #endif - } + } - /////////// - //////////////////////////////////////////////////////////////////////// + /////////// + //////////////////////////////////////////////////////////////////////// - /////////////////////////ULSCH RE mapping///////////////////////// - /////////// + /////////////////////////ULSCH RE mapping///////////////////////// + /////////// - for (ap=0; ap< Nl; ap++) - { + for (int l=0; l < Nl; l++) { uint8_t k_prime = 0; uint16_t m = 0; @@ -341,24 +341,22 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, printf("NR_ULSCH_UE: Value of CELL ID %d /t, u %d \n", frame_parms->Nid_cell, u); #endif - // DMRS params for this ap - get_Wt(Wt, ap, dmrs_type); - get_Wf(Wf, ap, dmrs_type); - delta = get_delta(ap, dmrs_type); + int dmrs_port = get_dmrs_port(l,pusch_pdu->dmrs_ports); + // DMRS params for this dmrs port + get_Wt(Wt, dmrs_port, dmrs_type); + get_Wf(Wf, dmrs_port, dmrs_type); + delta = get_delta(dmrs_port, dmrs_type); - for (l=start_symbol; l> l) & 0x01) - { + if ((ul_dmrs_symb_pos >> l) & 0x01) { is_dmrs_sym = 1; - if (pusch_pdu->transformPrecoder == transformPrecoder_disabled) - { + if (pusch_pdu->transformPrecoder == transformPrecoder_disabled) { if (dmrs_type == pusch_dmrs_type1) dmrs_idx = (pusch_pdu->bwp_start + start_rb)*6; else @@ -369,39 +367,33 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, LOG_D(PHY,"DMRS in symbol %d\n",l); nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated } - else - { + else { dmrs_idx = 0; } } - else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) - { + else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { AssertFatal(pusch_pdu->transformPrecoder == transformPrecoder_disabled, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); - if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) - { + if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) { is_ptrs_sym = 1; nr_modulation(pusch_dmrs[l][0], nb_rb, DMRS_MOD_ORDER, mod_ptrs); } } - for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) - { + for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) { uint8_t is_dmrs = 0; uint8_t is_ptrs = 0; sample_offsetF = l*frame_parms->ofdm_symbol_size + k; - if (is_dmrs_sym) - { + if (is_dmrs_sym) { if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%frame_parms->ofdm_symbol_size)) is_dmrs = 1; } - else if (is_ptrs_sym) - { + else if (is_ptrs_sym) { is_ptrs = is_ptrs_subcarrier(k, rnti, - ap, + dmrs_port, dmrs_type, K_ptrs, nb_rb, @@ -410,23 +402,20 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, frame_parms->ofdm_symbol_size); } - if (is_dmrs == 1) - { - if (pusch_pdu->transformPrecoder == transformPrecoder_enabled) - { - ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15; - ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15; + if (is_dmrs == 1) { + if (pusch_pdu->transformPrecoder == transformPrecoder_enabled) { + ((int16_t*)tx_precoding[l])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15; + ((int16_t*)tx_precoding[l])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15; } - else - { - ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15; - ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; + else { + ((int16_t*)tx_precoding[l])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15; + ((int16_t*)tx_precoding[l])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; } #ifdef DEBUG_PUSCH_MAPPING printf("DMRS: Layer: %d\t, dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n", - ap, dmrs_idx, l, k, k_prime, n, ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1], - ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1]); + l, dmrs_idx, l, k, k_prime, n, ((int16_t*)tx_precoding[l])[(sample_offsetF)<<1], + ((int16_t*)tx_precoding[l])[((sample_offsetF)<<1) + 1]); #endif dmrs_idx++; @@ -434,47 +423,41 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, k_prime&=1; n+=(k_prime)?0:1; } - else if (is_ptrs == 1) - { - ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15; - ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15; + else if (is_ptrs == 1) { + ((int16_t*)tx_precoding[l])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15; + ((int16_t*)tx_precoding[l])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15; ptrs_idx++; } - else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) - { - if (pusch_pdu->transformPrecoder == transformPrecoder_disabled) - { - ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = ((int16_t *)tx_layers[ap])[m<<1]; - ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *)tx_layers[ap])[(m<<1) + 1]; + else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) { + if (pusch_pdu->transformPrecoder == transformPrecoder_disabled) { + ((int16_t*)tx_precoding[l])[(sample_offsetF)<<1] = ((int16_t *)tx_layers[l])[m<<1]; + ((int16_t*)tx_precoding[l])[((sample_offsetF)<<1) + 1] = ((int16_t *)tx_layers[l])[(m<<1) + 1]; } - else - { - ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1]; - ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1]; + else { + ((int16_t*)tx_precoding[l])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1]; + ((int16_t*)tx_precoding[l])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1]; } #ifdef DEBUG_PUSCH_MAPPING printf("DATA: layer %d\t m %d\t l %d \t k %d \t txdataF: %d %d\n", - ap, m, l, k, ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1], - ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1]); + l, m, l, k, ((int16_t*)tx_precoding[l])[(sample_offsetF)<<1], + ((int16_t*)tx_precoding[l])[((sample_offsetF)<<1) + 1]); #endif m++; } - else - { - ((int16_t*)tx_precoding[ap])[(sample_offsetF)<<1] = 0; - ((int16_t*)tx_precoding[ap])[((sample_offsetF)<<1) + 1] = 0; + else { + ((int16_t*)tx_precoding[l])[(sample_offsetF)<<1] = 0; + ((int16_t*)tx_precoding[l])[((sample_offsetF)<<1) + 1] = 0; } - if (++k >= frame_parms->ofdm_symbol_size) - { + if (++k >= frame_parms->ofdm_symbol_size) { k -= frame_parms->ofdm_symbol_size; } } //for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) }//for (l=start_symbol; lnb_antennas_tx; ap++) - { - for (int l=start_symbol; lnb_antennas_tx; ap++) { + for (int l=start_symbol; lTpmi; @@ -510,12 +490,10 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, k -= frame_parms->ofdm_symbol_size; } } - else - { + else { //get the precoding matrix weights: char *W_prec; - switch (frame_parms->nb_antennas_tx) - { + switch (frame_parms->nb_antennas_tx) { case 1://1 antenna port W_prec = nr_W_1l_2p[pmi][ap]; break; @@ -541,15 +519,13 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, break; } - for (int i=0; iofdm_symbol_size + k; int32_t precodatatx_F = nr_layer_precoder(tx_precoding, W_prec, pusch_pdu->nrOfLayers, re_offset); ((int16_t*)txdataF[ap])[(re_offset<<1)] = ((int16_t *) &precodatatx_F)[0]; ((int16_t*)txdataF[ap])[(re_offset<<1) + 1] = ((int16_t *) &precodatatx_F)[1]; - if (++k >= frame_parms->ofdm_symbol_size) - { + if (++k >= frame_parms->ofdm_symbol_size) { k -= frame_parms->ofdm_symbol_size; } } @@ -557,7 +533,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, } //RB loop } // symbol loop }// port loop - } //for (cwd_index = 0;cwd_index < num_of_codewords; cwd_index++) NR_UL_UE_HARQ_t *harq_process_ulsch=NULL; @@ -573,7 +548,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, uint8_t slot, NR_DL_FRAME_PARMS *frame_parms, - uint8_t Nl) { + uint8_t n_antenna_ports) { int tx_offset, ap; int32_t **txdata; @@ -595,7 +570,7 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, txdataF = UE->common_vars.txdataF; int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; - for(ap = 0; ap < Nl; ap++) { + for(ap = 0; ap < n_antenna_ports; ap++) { for (int s=0;s (%d.%d)\n", @@ -613,7 +588,7 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, } } - for (ap = 0; ap < Nl; ap++) { + for (ap = 0; ap < n_antenna_ports; ap++) { if (frame_parms->Ncp == 1) { // extended cyclic prefix PHY_ofdm_mod(txdataF[ap], &txdata[ap][tx_offset], diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 206a55347c..d185517fcc 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -369,10 +369,10 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH nr_ulsch_layer_demapping(gNB->pusch_vars[ULSCH_id]->llr, - pusch_pdu->nrOfLayers, - pusch_pdu->qam_mod_order, - G, - gNB->pusch_vars[ULSCH_id]->llr_layers); + pusch_pdu->nrOfLayers, + pusch_pdu->qam_mod_order, + G, + gNB->pusch_vars[ULSCH_id]->llr_layers); //---------------------------------------------------------- //------------------- ULSCH unscrambling ------------------- diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 7e5be9eeba..b7f928f709 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -33,6 +33,7 @@ #include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "common/utils/nr/nr_common.h" #include +#include #define reserved 0xffff @@ -2531,6 +2532,30 @@ uint8_t get_transformPrecoding(const NR_BWP_UplinkCommon_t *initialUplinkBWP, return -1; } +uint8_t get_pusch_nb_antenna_ports(NR_PUSCH_Config_t *pusch_Config, + NR_SRS_Config_t *srs_config, + dci_field_t srs_resource_indicator) { + + uint8_t n_antenna_port = 1; + if (get_softmodem_params()->phy_test == 1) { + // temporary hack to allow UL-MIMO in phy-test mode without SRS + n_antenna_port = *pusch_Config->maxRank; + } + else { + if(srs_config != NULL && srs_resource_indicator.nbits > 0) { + for(int rs = 0; rs < srs_config->srs_ResourceSetToAddModList->list.count; rs++) { + NR_SRS_ResourceSet_t *srs_resource_set = srs_config->srs_ResourceSetToAddModList->list.array[rs]; + if(srs_resource_set->usage == NR_SRS_ResourceSet__usage_codebook) { + NR_SRS_Resource_t *srs_resource = srs_config->srs_ResourceToAddModList->list.array[srs_resource_indicator.val]; + AssertFatal(srs_resource != NULL,"SRS resource indicated by DCI does not exist\n"); + n_antenna_port = 1<nrofSRS_Ports; + } + } + } + } + return n_antenna_port; +} + uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP, const NR_BWP_UplinkCommon_t *initialUplinkBWP, const NR_CellGroupConfig_t *cg, @@ -2544,17 +2569,16 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP, uint16_t numRBG = 0; long rbg_size_config; int num_entries = 0; - int pusch_antenna_ports = 1; // TODO hardcoded number of antenna ports for pusch const NR_BWP_DownlinkDedicated_t *bwpd = NULL; const NR_BWP_UplinkDedicated_t *ubwpd = NULL; const NR_BWP_DownlinkCommon_t *bwpc = NULL; const NR_BWP_UplinkCommon_t *ubwpc = NULL; - const NR_PDSCH_Config_t *pdsch_Config = NULL; - const NR_PUSCH_Config_t *pusch_Config = NULL; - const NR_PUCCH_Config_t *pucch_Config = NULL; - const NR_PDCCH_Config_t *pdcch_Config = NULL; - const NR_SRS_Config_t *srs_config = NULL; + NR_PDSCH_Config_t *pdsch_Config = NULL; + NR_PUSCH_Config_t *pusch_Config = NULL; + NR_PUCCH_Config_t *pucch_Config = NULL; + NR_PDCCH_Config_t *pdcch_Config = NULL; + NR_SRS_Config_t *srs_config = NULL; if(bwp_id > 0) { AssertFatal(cg!=NULL,"Cellgroup is null and bwp_id!=0"); bwpd=cg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Dedicated; @@ -2709,7 +2733,7 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP, // Precoding info and number of layers long transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, ubwpd, (uint8_t*)&format, rnti_type, 0); - pusch_antenna_ports = *pusch_Config->maxRank; + uint8_t pusch_antenna_ports = get_pusch_nb_antenna_ports(pusch_Config, srs_config, dci_pdu->srs_resource_indicator); dci_pdu->precoding_information.nbits=0; if (pusch_Config && diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 8182e1c930..23c022bf0c 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -144,6 +144,10 @@ void get_info_from_tda_tables(int default_abc, void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config); void fill_searchSpaceZero(NR_SearchSpace_t *ss0, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config); +uint8_t get_pusch_nb_antenna_ports(NR_PUSCH_Config_t *pusch_Config, + NR_SRS_Config_t *srs_config, + dci_field_t srs_resource_indicator); + uint16_t compute_pucch_prb_size(uint8_t format, uint8_t nr_prbs, uint16_t O_tot, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index adb2c966b0..83981c8a6f 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -44,6 +44,7 @@ /* MAC */ #include "NR_MAC_COMMON/nr_mac.h" +#include "NR_MAC_COMMON/nr_mac_common.h" #include "NR_MAC_UE/mac_proto.h" #include "NR_MAC_UE/mac_extern.h" @@ -181,13 +182,16 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con NR_ServingCellConfigCommon_t *scc = mac->scc; NR_BWP_UplinkDedicated_t *ubwpd=NULL; + NR_SRS_Config_t *srs_config = NULL; if (mac->cg && mac->cg->spCellConfig && mac->cg->spCellConfig->spCellConfigDedicated && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { ubwpd = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP; + srs_config = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config->choice.setup; + } NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[0] ? mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup : @@ -212,7 +216,10 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook)){ - uint8_t n_antenna_port = mac->phy_config.config_req.carrier_config.num_tx_ant; + // The UE shall transmit PUSCH using the same antenna port(s) as the SRS port(s) in the SRS resource indicated by the DCI format 0_1 + // 38.214 Section 6.1.1 + + uint8_t n_antenna_port = get_pusch_nb_antenna_ports(pusch_Config, srs_config, dci->srs_resource_indicator); if (n_antenna_port == 1); // 1 antenna port and the higher layer parameter txConfig = codebook 0 bits @@ -331,10 +338,9 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con } // todo: this function shall be reviewed completely because of the many comments left by the author -void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci) { +void ul_ports_config(NR_UE_MAC_INST_t *mac, int *n_front_load_symb, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci) { - /* ANTENNA_PORTS */ - uint8_t rank = 1; // We need to initialize rank FIXME!!! + uint8_t rank = pusch_config_pdu->nrOfLayers; NR_ServingCellConfigCommon_t *scc = mac->scc; NR_BWP_UplinkDedicated_t *ubwpd=NULL; @@ -373,29 +379,24 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf LOG_D(NR_MAC,"MappingType%s max_length %s, dmrs_type %s, antenna_ports %d\n", pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA?"A":"B",max_length?"len2":"len1",dmrs_type?"type2":"type1",dci->antenna_ports.val); + if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) && - (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-6 - pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC - pusch_config_pdu->dmrs_ports = dci->antenna_ports.val; //TBC + (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-6 + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; + pusch_config_pdu->dmrs_ports = 1<antenna_ports.val; } if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) && - (dmrs_type == NULL) && (max_length != NULL)) { // tables 7.3.1.1.2-7 + (dmrs_type == NULL) && (max_length != NULL)) { // tables 7.3.1.1.2-7 pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC - pusch_config_pdu->dmrs_ports = (dci->antenna_ports.val > 3)?(dci->antenna_ports.val-4):(dci->antenna_ports.val); //TBC - //pusch_config_pdu->n_front_load_symb = (dci->antenna_ports > 3)?2:1; //FIXME + pusch_config_pdu->dmrs_ports = 1<<((dci->antenna_ports.val > 3)?(dci->antenna_ports.val-4):(dci->antenna_ports.val)); + *n_front_load_symb = (dci->antenna_ports.val > 3)?2:1; } if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && - (dmrs_type == NULL) && (max_length == NULL)) - { // tables 7.3.1.1.2-8/9/10/11 + (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-8/9/10/11 - if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook)) - { - rank = pusch_config_pdu->nrOfLayers; - } - if (rank == 1) { pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; pusch_config_pdu->dmrs_ports =1<<((dci->antenna_ports.val > 1)?(dci->antenna_ports.val-2):(dci->antenna_ports.val)); @@ -408,12 +409,12 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf if (rank == 3){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; - pusch_config_pdu->dmrs_ports = ((1<dmrs_ports = 0x7; // ports 0-2 } if (rank == 4){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; - pusch_config_pdu->dmrs_ports = ((1<dmrs_ports = 0xf; // ports 0-3 } } @@ -422,8 +423,8 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf if (rank == 1){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; //TBC - pusch_config_pdu->dmrs_ports = (dci->antenna_ports.val > 1)?(dci->antenna_ports.val > 5 ?(dci->antenna_ports.val-6):(dci->antenna_ports.val-2)):dci->antenna_ports.val; //TBC - //pusch_config_pdu->n_front_load_symb = (dci->antenna_ports.val > 6)?2:1; //FIXME + pusch_config_pdu->dmrs_ports = 1<<((dci->antenna_ports.val > 1)?(dci->antenna_ports.val > 5 ?(dci->antenna_ports.val-6):(dci->antenna_ports.val-2)):dci->antenna_ports.val); + *n_front_load_symb = (dci->antenna_ports.val > 6)?2:1; } if (rank == 2){ @@ -431,7 +432,7 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf pusch_config_pdu->dmrs_ports = 0; //FIXME //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_13[dci->antenna_ports.val][1]; //pusch_config_pdu->dmrs_ports[1] = table_7_3_1_1_2_13[dci->antenna_ports.val][2]; - //pusch_config_pdu->n_front_load_symb = (dci->antenna_ports.val > 3)?2:1; // FIXME + //n_front_load_symb = (dci->antenna_ports.val > 3)?2:1; // FIXME } if (rank == 3){ @@ -440,7 +441,7 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_14[dci->antenna_ports.val][1]; //pusch_config_pdu->dmrs_ports[1] = table_7_3_1_1_2_14[dci->antenna_ports.val][2]; //pusch_config_pdu->dmrs_ports[2] = table_7_3_1_1_2_14[dci->antenna_ports.val][3]; - //pusch_config_pdu->n_front_load_symb = (dci->antenna_ports.val > 1)?2:1; //FIXME + //n_front_load_symb = (dci->antenna_ports.val > 1)?2:1; //FIXME } if (rank == 4){ @@ -450,7 +451,7 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf //pusch_config_pdu->dmrs_ports[1] = table_7_3_1_1_2_15[dci->antenna_ports.val][2]; //pusch_config_pdu->dmrs_ports[2] = table_7_3_1_1_2_15[dci->antenna_ports.val][3]; //pusch_config_pdu->dmrs_ports[3] = table_7_3_1_1_2_15[dci->antenna_ports.val][4]; - //pusch_config_pdu->n_front_load_symb = (dci->antenna_ports.val > 1)?2:1; //FIXME + //n_front_load_symb = (dci->antenna_ports.val > 1)?2:1; //FIXME } } @@ -494,7 +495,7 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf if (rank == 1){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_20[dci->antenna_ports.val][0]; //TBC pusch_config_pdu->dmrs_ports = table_7_3_1_1_2_20[dci->antenna_ports.val][1]; //TBC - //pusch_config_pdu->n_front_load_symb = table_7_3_1_1_2_20[dci->antenna_ports.val][2]; //FIXME + //n_front_load_symb = table_7_3_1_1_2_20[dci->antenna_ports.val][2]; //FIXME } if (rank == 2){ @@ -502,7 +503,7 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf pusch_config_pdu->dmrs_ports = 0; //FIXME //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_21[dci->antenna_ports.val][1]; //pusch_config_pdu->dmrs_ports[1] = table_7_3_1_1_2_21[dci->antenna_ports.val][2]; - //pusch_config_pdu->n_front_load_symb = table_7_3_1_1_2_21[dci->antenna_ports.val][3]; //FIXME + //n_front_load_symb = table_7_3_1_1_2_21[dci->antenna_ports.val][3]; //FIXME } if (rank == 3){ @@ -511,7 +512,7 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_22[dci->antenna_ports.val][1]; //pusch_config_pdu->dmrs_ports[1] = table_7_3_1_1_2_22[dci->antenna_ports.val][2]; //pusch_config_pdu->dmrs_ports[2] = table_7_3_1_1_2_22[dci->antenna_ports.val][3]; - //pusch_config_pdu->n_front_load_symb = table_7_3_1_1_2_22[dci->antenna_ports.val][4]; //FIXME + //n_front_load_symb = table_7_3_1_1_2_22[dci->antenna_ports.val][4]; //FIXME } if (rank == 4){ @@ -521,7 +522,7 @@ void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf //pusch_config_pdu->dmrs_ports[1] = table_7_3_1_1_2_23[dci->antenna_ports.val][2]; //pusch_config_pdu->dmrs_ports[2] = table_7_3_1_1_2_23[dci->antenna_ports.val][3]; //pusch_config_pdu->dmrs_ports[3] = table_7_3_1_1_2_23[dci->antenna_ports.val][4]; - //pusch_config_pdu->n_front_load_symb = table_7_3_1_1_2_23[dci->antenna_ports.val][5]; //FIXME + //n_front_load_symb = table_7_3_1_1_2_23[dci->antenna_ports.val][5]; //FIXME } } LOG_D(NR_MAC,"num_dmrs_cdm_grps_no_data %d, dmrs_ports %d\n",pusch_config_pdu->num_dmrs_cdm_grps_no_data,pusch_config_pdu->dmrs_ports); @@ -565,7 +566,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, else initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP; pusch_dmrs_AdditionalPosition_t add_pos = pusch_dmrs_pos2; - pusch_maxLength_t dmrslength = pusch_len1; + int dmrslength = 1; if (rar_grant) { @@ -712,7 +713,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; ul_layers_config(mac, pusch_config_pdu, dci); - ul_ports_config(mac, pusch_config_pdu, dci); + ul_ports_config(mac, &dmrslength, pusch_config_pdu, dci); } else { @@ -805,22 +806,18 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->absolute_delta_PUSCH = 4; } - if (NR_DMRS_ulconfig != NULL) { + if (NR_DMRS_ulconfig != NULL) add_pos = (NR_DMRS_ulconfig->dmrs_AdditionalPosition == NULL) ? 2 : *NR_DMRS_ulconfig->dmrs_AdditionalPosition; - dmrslength = NR_DMRS_ulconfig->maxLength == NULL ? pusch_len1 : pusch_len2; - } /* DMRS */ l_prime_mask = get_l_prime(pusch_config_pdu->nr_of_symbols, mappingtype, add_pos, dmrslength, pusch_config_pdu->start_symbol_index, mac->scc ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position); - if (mac->ULbwp[0] && pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) - { - if (*dci_format != NR_UL_DCI_FORMAT_0_1) - { + if (mac->ULbwp[0] && pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) { + if (*dci_format != NR_UL_DCI_FORMAT_0_1) { pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1; - } + } } else if (*dci_format == NR_UL_DCI_FORMAT_0_0 || (mac->ULbwp[0] && pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled)) pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index eb727494d8..08208300fd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -691,7 +691,6 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp, "Non Codebook configuration non supported\n"); dci_pdu_rel15->srs_resource_indicator.val = 0; // taking resource 0 for SRS } - AssertFatal((pusch_pdu->Tpmi==0), "unsupport Tpmi\n"); dci_pdu_rel15->precoding_information.val= 0; if (pusch_pdu->nrOfLayers == 2) { From c1d157dc429153fb2284b6fb13839cce81273dca Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 17 Jan 2022 19:28:17 +0100 Subject: [PATCH 08/49] fixing compilation issues --- cmake_targets/CMakeLists.txt | 3 +++ executables/nr-ue.c | 2 ++ openair1/SIMULATION/NR_PHY/dlschsim.c | 3 +++ openair1/SIMULATION/NR_PHY/nr_dummy_functions.c | 2 ++ openair1/SIMULATION/NR_PHY/pucchsim.c | 3 ++- openair1/SIMULATION/NR_PHY/ulschsim.c | 2 ++ 6 files changed, 14 insertions(+), 1 deletion(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index bf3bb2b017..0ff76d145f 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -3171,6 +3171,7 @@ add_executable(nr_dlschsim ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c + ${OPENAIR_DIR}/executables/softmodem-common.c ${UTIL_SRC} ${T_SOURCE} ${SHLIB_LOADER_SOURCES} @@ -3203,6 +3204,7 @@ add_executable(nr_pucchsim ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c + ${OPENAIR_DIR}/executables/softmodem-common.c ${UTIL_SRC} ${T_SOURCE} ${SHLIB_LOADER_SOURCES} @@ -3259,6 +3261,7 @@ add_executable(nr_ulschsim ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c + ${OPENAIR_DIR}/executables/softmodem-common.c ${PHY_INTERFACE_DIR}/queue_t.c ${UTIL_SRC} ${T_SOURCE} diff --git a/executables/nr-ue.c b/executables/nr-ue.c index d2553a03bf..747eb4bb45 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -19,6 +19,8 @@ * contact@openairinterface.org */ +#define _GNU_SOURCE +#include #include #include "executables/nr-uesoftmodem.h" #include "PHY/phy_extern_nr_ue.h" diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index ff07422c6b..5d34b75047 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -47,13 +47,16 @@ #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" #include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c" + //#define DEBUG_NR_DLSCHSIM +THREAD_STRUCT thread_struct; PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; UE_nr_rxtx_proc_t proc; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; +uint64_t downlink_frequency[MAX_NUM_CCs][4]; double cpuf; //uint8_t nfapi_mode = 0; diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c index 7a47410129..69ae17c3ac 100644 --- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c @@ -20,6 +20,8 @@ nfapi_mode_t nfapi_mod; nfapi_mode_t nfapi_getmode(void) { return nfapi_mod; } +void nfapi_setmode(nfapi_mode_t nfapi_mode) {} + int dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info) { return(0); } int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); } void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind, diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index 213924e5fd..9f268bb879 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -46,12 +46,13 @@ #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" #include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c" - +THREAD_STRUCT thread_struct; PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; openair0_config_t openair0_cfg[MAX_CARDS]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; +uint64_t downlink_frequency[MAX_NUM_CCs][4]; double cpuf; //uint8_t nfapi_mode = 0; diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index fb8b4295ae..e51d790d24 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -49,10 +49,12 @@ //#define DEBUG_NR_ULSCHSIM +THREAD_STRUCT thread_struct; PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; +uint64_t downlink_frequency[MAX_NUM_CCs][4]; void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {} From f05c1957512f299f454c3be6603a0f5378b95dfb Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 18 Jan 2022 09:15:05 +0100 Subject: [PATCH 09/49] bugfix for nl index --- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 44 +++++++++++----------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 84ad8aa8af..7fb1a15fac 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -103,7 +103,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, LOG_D(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot); uint32_t available_bits; - uint8_t cwd_index, l; + uint8_t cwd_index; uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5]; int8_t Wf[2], Wt[2]; int l_prime[2], delta; @@ -282,7 +282,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, LOG_D(PHY,"Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", u, v, index); - for (l = start_symbol; l < start_symbol + number_of_symbols; l++) { + for (int l = start_symbol; l < start_symbol + number_of_symbols; l++) { if((ul_dmrs_symb_pos >> l) & 0x01) /* In the symbol with DMRS no data would be transmitted CDM groups is 2*/ @@ -333,7 +333,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////////////////////ULSCH RE mapping///////////////////////// /////////// - for (int l=0; l < Nl; l++) { + for (int nl=0; nl < Nl; nl++) { uint8_t k_prime = 0; uint16_t m = 0; @@ -341,13 +341,13 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, printf("NR_ULSCH_UE: Value of CELL ID %d /t, u %d \n", frame_parms->Nid_cell, u); #endif - int dmrs_port = get_dmrs_port(l,pusch_pdu->dmrs_ports); + int dmrs_port = get_dmrs_port(nl,pusch_pdu->dmrs_ports); // DMRS params for this dmrs port get_Wt(Wt, dmrs_port, dmrs_type); get_Wf(Wf, dmrs_port, dmrs_type); delta = get_delta(dmrs_port, dmrs_type); - for (l=start_symbol; ltransformPrecoder == transformPrecoder_enabled) { - ((int16_t*)tx_precoding[l])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15; - ((int16_t*)tx_precoding[l])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15; + ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15; + ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15; } else { - ((int16_t*)tx_precoding[l])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15; - ((int16_t*)tx_precoding[l])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; + ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15; + ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; } #ifdef DEBUG_PUSCH_MAPPING printf("DMRS: Layer: %d\t, dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n", - l, dmrs_idx, l, k, k_prime, n, ((int16_t*)tx_precoding[l])[(sample_offsetF)<<1], - ((int16_t*)tx_precoding[l])[((sample_offsetF)<<1) + 1]); + l, dmrs_idx, l, k, k_prime, n, ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1], + ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1]); #endif dmrs_idx++; @@ -424,32 +424,32 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, n+=(k_prime)?0:1; } else if (is_ptrs == 1) { - ((int16_t*)tx_precoding[l])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15; - ((int16_t*)tx_precoding[l])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15; + ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15; + ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15; ptrs_idx++; } else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) { if (pusch_pdu->transformPrecoder == transformPrecoder_disabled) { - ((int16_t*)tx_precoding[l])[(sample_offsetF)<<1] = ((int16_t *)tx_layers[l])[m<<1]; - ((int16_t*)tx_precoding[l])[((sample_offsetF)<<1) + 1] = ((int16_t *)tx_layers[l])[(m<<1) + 1]; + ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = ((int16_t *)tx_layers[nl])[m<<1]; + ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = ((int16_t *)tx_layers[nl])[(m<<1) + 1]; } else { - ((int16_t*)tx_precoding[l])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1]; - ((int16_t*)tx_precoding[l])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1]; + ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1]; + ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1]; } #ifdef DEBUG_PUSCH_MAPPING printf("DATA: layer %d\t m %d\t l %d \t k %d \t txdataF: %d %d\n", - l, m, l, k, ((int16_t*)tx_precoding[l])[(sample_offsetF)<<1], - ((int16_t*)tx_precoding[l])[((sample_offsetF)<<1) + 1]); + nl, m, l, k, ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1], + ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1]); #endif m++; } else { - ((int16_t*)tx_precoding[l])[(sample_offsetF)<<1] = 0; - ((int16_t*)tx_precoding[l])[((sample_offsetF)<<1) + 1] = 0; + ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = 0; + ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = 0; } if (++k >= frame_parms->ofdm_symbol_size) { @@ -457,7 +457,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, } } //for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) }//for (l=start_symbol; l Date: Tue, 18 Jan 2022 11:53:57 +0100 Subject: [PATCH 10/49] Shutdown nr-softmodem cleanly --- common/utils/ocp_itti/intertask_interface.cpp | 1 + executables/nr-softmodem.c | 1 - openair1/PHY/INIT/nr_init_ru.c | 12 +++++++----- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp index 44fae9f788..111a423dcb 100644 --- a/common/utils/ocp_itti/intertask_interface.cpp +++ b/common/utils/ocp_itti/intertask_interface.cpp @@ -450,6 +450,7 @@ extern "C" { void itti_wait_tasks_end(void) { shutting_down = false; signal(SIGTERM, catch_sigterm); + signal(SIGINT, catch_sigterm); while (! shutting_down) { sleep(24 * 3600); diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 2b8335167a..9dbc94637c 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -876,7 +876,6 @@ int main( int argc, char **argv ) { nr_phy_free_RU(RC.ru[inst]); } - free_lte_top(); pthread_cond_destroy(&sync_cond); pthread_mutex_destroy(&sync_mutex); pthread_cond_destroy(&nfapi_sync_cond); diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index 4024ed1617..73666b48ac 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -193,7 +193,7 @@ void nr_phy_free_RU(RU_t *ru) free_and_zero(ru->common.rxdata_7_5kHz); // free beamforming input buffers (TX) - for (i = 0; i < 15; i++) free_and_zero(ru->common.txdataF[i]); + for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdataF[i]); free_and_zero(ru->common.txdataF); // free IFFT input buffers (TX) @@ -209,10 +209,12 @@ void nr_phy_free_RU(RU_t *ru) free_and_zero(ru->prach_rxsigF[j][i]); } } - for (i = 0; i < ru->num_gNB; i++) { - for (p = 0; p < 15; p++) { - for (j=0; jnb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]); - free_and_zero(ru->beam_weights[i][p]); + if (ru->do_precoding == 1) { + for (i = 0; i < ru->num_gNB; i++) { + for (p = 0; p < ru->nb_log_antennas; p++) { + for (j=0; jnb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]); + free_and_zero(ru->beam_weights[i][p]); + } } } } From a2244ab32ddd25b97bdaadded7ad2bca4874ad1b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 18 Jan 2022 14:21:58 +0100 Subject: [PATCH 11/49] Stop RU threads at end of nr-softmodem --- executables/nr-softmodem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 9dbc94637c..60efba8464 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -873,6 +873,7 @@ int main( int argc, char **argv ) { } for (int inst = 0; inst < NB_RU; inst++) { + kill_NR_RU_proc(inst); nr_phy_free_RU(RC.ru[inst]); } From 18fd38fa082d878bcee2b2aa6afee021583c5cda Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 18 Jan 2022 14:23:54 +0100 Subject: [PATCH 12/49] Don't call trx_end_func() at nr-softmodem, is done in ru_thread() --- executables/nr-softmodem.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 60efba8464..e01c3078c5 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -886,9 +886,6 @@ int main( int argc, char **argv ) { // *** Handle per CC_id openair0 for(ru_id=0; ru_idrfdevice.trx_end_func) - RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); - if (RC.ru[ru_id]->ifdevice.trx_end_func) RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); } From 3377f91b627e3467d5fbec6c6e4c3daad9375650 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 19 Jan 2022 11:48:51 +0100 Subject: [PATCH 13/49] fix free pusch_vars->rho --- openair1/PHY/INIT/nr_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index d3f1b02826..4b3a896893 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -363,6 +363,7 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) for (int i = 0; i < fp->nb_antennas_rx; i++) { free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext[i]); free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2[i]); + free_and_zero(pusch_vars[ULSCH_id]->rho[i]); } for (int i = 0; i < 4*fp->nb_antennas_rx; i++) { free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates[i]); @@ -376,7 +377,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb0[i]); free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag[i]); free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb[i]); - free_and_zero(pusch_vars[ULSCH_id]->rho[i]); } free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext); free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2); From 4bdc6ac59f1838da60846fc42adf030cf2de99d8 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 19 Jan 2022 18:11:43 +0100 Subject: [PATCH 14/49] minor changes --- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 18 ++++-------- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 29 +++++++------------ openair1/SIMULATION/NR_PHY/ulsim.c | 1 - 3 files changed, 15 insertions(+), 33 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 5286fe8780..3f6540a94a 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -298,16 +298,7 @@ void nr_processULSegment(void* arg) { stop_meas(&phy_vars_gNB->ulsch_deinterleaving_stats); - /*LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n", - harq_pid,r, G, - Kr*3, - ulsch_harq->TBS, - Qm, - nb_rb, - n_layers, - pusch_pdu->pusch_data.rv_index, - ulsch_harq->round);*/ - ////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// @@ -387,13 +378,13 @@ void nr_processULSegment(void* arg) { if (check_crc((uint8_t*)llrProcBuf,length_dec,ulsch_harq->F,crc_type)) { #ifdef PRINT_CRC_CHECK - LOG_I(PHY, "Segment %d CRC OK, iterations %d/%d\n",r,no_iteration_ldpc,max_ldpc_iterations); + LOG_I(PHY,"Segment %d CRC OK, iterations %d/%d\n",r,no_iteration_ldpc,max_ldpc_iterations); #endif rdata->decodeIterations = no_iteration_ldpc; if (rdata->decodeIterations > p_decoderParms->numMaxIter) rdata->decodeIterations--; } else { #ifdef PRINT_CRC_CHECK - LOG_I(PHY, "CRC NOK\n"); + LOG_I(PHY,"CRC NOK\n"); #endif rdata->decodeIterations = max_ldpc_iterations + 1; } @@ -480,7 +471,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, A = (harq_process->TBS)<<3; - LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, n_layers %d, Coderate %d\n",harq_pid,A,G, mcs, n_layers, nb_rb, Qm, n_layers, R); + LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, Coderate %d RV %d round %d\n", + harq_pid, A, G, mcs, n_layers, nb_rb, Qm, R, pusch_pdu->pusch_data.rv_index, harq_process->round); if (R<1024) Coderate = (float) R /(float) 1024; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index dad8d70465..26a7c953c9 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -347,14 +347,12 @@ void nr_ulsch_extract_rbs(int32_t **rxdataF, if (is_dmrs_symbol == 0) { // //rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]); - if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size) - { + if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size) { memcpy1((void*)rxF_ext, (void*)&rxF[start_re*2], nb_re_pusch*sizeof(int32_t)); } - else - { + else { int neg_length = frame_parms->ofdm_symbol_size-start_re; int pos_length = nb_re_pusch-neg_length; memcpy1((void*)rxF_ext,(void*)&rxF[start_re*2],neg_length*sizeof(int32_t)); @@ -373,8 +371,7 @@ void nr_ulsch_extract_rbs(int32_t **rxdataF, memcpy1((void*)ul_ch0_ext,(void*)ul_ch0,nb_re_pusch*sizeof(int32_t)); } } - else - { + else { #ifdef SUPPORT_PMI_MATRIC for (aatx = 0; aatx < pusch_pdu->nrOfLayers; aatx++) #else @@ -390,26 +387,22 @@ void nr_ulsch_extract_rbs(int32_t **rxdataF, ul_ch0_ext_index = 0; ul_ch0_index = 0; - for (re = 0; re < nb_re_pusch; re++) - { + for (re = 0; re < nb_re_pusch; re++) { uint16_t k= start_re+re; is_data_re = allowed_xlsch_re_in_dmrs_symbol(k, start_re, frame_parms->ofdm_symbol_size, pusch_pdu->num_dmrs_cdm_grps_no_data, pusch_pdu->dmrs_config_type); - if (++k >= frame_parms->ofdm_symbol_size) - { + if (++k >= frame_parms->ofdm_symbol_size) { k -= frame_parms->ofdm_symbol_size; } #ifdef DEBUG_RB_EXT - printf("re = %d, kprime %d, n %d, is_dmrs_symbol = %d, symbol = %d\n", re, k_prime, n, is_dmrs_symbol, symbol); + printf("re = %d, is_dmrs_symbol = %d, symbol = %d\n", re, is_dmrs_symbol, symbol); #endif /* save only data and respective channel estimates */ - if (is_data_re == 1) - { - if (aatx == aarx) - { + if (is_data_re == 1) { + if (aatx == aarx) { rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]); rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]); rxF_ext_index +=2; @@ -1206,8 +1199,7 @@ void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, if (n_rx > 1) { #if defined(__x86_64__) || defined(__i386__) - for (int aatx=0; aatxnb_antennas_rx][(symbol*(nb_re + off))]; @@ -2002,8 +1994,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] = 0; gNB->pusch_vars[ulsch_id]->ulsch_noise_power[aarx] = 0; } - for (aatx = 0; aatx < rel15_ul->nrOfLayers; aatx++) - { + for (aatx = 0; aatx < rel15_ul->nrOfLayers; aatx++) { gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] += signal_energy_nodc( &gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aatx*gNB->frame_parms.nb_antennas_rx+aarx][symbol * frame_parms->ofdm_symbol_size], rel15_ul->rb_size * 12); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 32cb2d6d48..8bf43ef0b1 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -243,7 +243,6 @@ nrUE_params_t *get_nrUE_params(void) { // needed for some functions uint16_t n_rnti = 0x1234; openair0_config_t openair0_cfg[MAX_CARDS]; -//const uint8_t nr_rv_round_map[4] = {0, 2, 1, 3}; channel_desc_t *UE2gNB[NUMBER_OF_UE_MAX][NUMBER_OF_gNB_MAX]; From 06d488bb23ac6d17e72eda8fa0a6a5f75fdb2644 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 9 Mar 2022 17:35:38 +0100 Subject: [PATCH 15/49] ulsch memory optimization --- openair1/PHY/INIT/nr_init_ue.c | 4 +- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 26 ++++++---- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 6 ++- .../PHY/NR_UE_TRANSPORT/nr_transport_ue.h | 4 +- .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 47 ++++++++++++------- openair1/PHY/defs_gNB.h | 10 ++-- openair1/PHY/defs_nr_common.h | 3 +- openair1/SIMULATION/NR_PHY/ulschsim.c | 4 +- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 2 +- 9 files changed, 61 insertions(+), 45 deletions(-) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 6626d4614c..5a26bfcfac 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -684,7 +684,7 @@ void term_nr_ue_transport(PHY_VARS_NR_UE *ue) for (int j = 0; j < 2; j++) { for (int k = 0; k < RX_NB_TH_MAX; k++) { free_nr_ue_dlsch(&ue->dlsch[k][i][j], N_RB_DL); - free_nr_ue_ulsch(&ue->ulsch[k][i][j], N_RB_DL); + free_nr_ue_ulsch(&ue->ulsch[k][i][j], N_RB_DL, &ue->frame_parms); } } @@ -702,7 +702,7 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue) for (int k=0; kdlsch[k][i][j] = new_nr_ue_dlsch(1,NR_MAX_DLSCH_HARQ_PROCESSES,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL))!=NULL,"Can't get ue dlsch structures\n"); LOG_D(PHY,"dlsch[%d][%d][%d] => %p\n",k,i,j,ue->dlsch[k][i][j]); - AssertFatal((ue->ulsch[k][i][j] = new_nr_ue_ulsch(ue->frame_parms.N_RB_UL, NR_MAX_ULSCH_HARQ_PROCESSES))!=NULL,"Can't get ue ulsch structures\n"); + AssertFatal((ue->ulsch[k][i][j] = new_nr_ue_ulsch(ue->frame_parms.N_RB_UL, NR_MAX_ULSCH_HARQ_PROCESSES,&ue->frame_parms))!=NULL,"Can't get ue ulsch structures\n"); LOG_D(PHY,"ulsch[%d][%d][%d] => %p\n",k,i,j,ue->ulsch[k][i][j]); } } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 304dad96f0..4a824dc678 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -57,8 +57,7 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr, uint16_t N_RB_UL) { - int i,r; - uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated + uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS; //number of segments to be allocated NR_gNB_ULSCH_t *ulsch = *ulschptr; if (N_RB_UL != 273) { @@ -66,19 +65,21 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr, uint16_t N_RB_UL) a_segments = a_segments/273 +1; } - for (i=0; iharq_processes[i]) { if (ulsch->harq_processes[i]->b) { free_and_zero(ulsch->harq_processes[i]->b); ulsch->harq_processes[i]->b = NULL; } - for (r=0; rharq_processes[i]->c[r]); free_and_zero(ulsch->harq_processes[i]->d[r]); - free_and_zero(ulsch->harq_processes[i]->w[r]); nrLDPC_free_mem(ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]); ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL; } + free_and_zero(ulsch->harq_processes[i]->c); + free_and_zero(ulsch->harq_processes[i]->d); + free_and_zero(ulsch->harq_processes[i]->p_nrLDPC_procBuf); free_and_zero(ulsch->harq_processes[i]); ulsch->harq_processes[i] = NULL; } @@ -92,7 +93,7 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL) NR_gNB_ULSCH_t *ulsch; uint8_t i,r; - uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated + uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS; //number of segments to be allocated if (N_RB_UL != 273) { a_segments = a_segments*N_RB_UL; @@ -109,11 +110,13 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL) ulsch->harq_processes[i] = (NR_UL_gNB_HARQ_t *)malloc16_clear(sizeof(NR_UL_gNB_HARQ_t)); ulsch->harq_processes[i]->b = (uint8_t*)malloc16_clear(ulsch_bytes); + ulsch->harq_processes[i]->c = (uint8_t**)malloc16_clear(a_segments); + ulsch->harq_processes[i]->d = (int16_t**)malloc16_clear(a_segments); + ulsch->harq_processes[i]->p_nrLDPC_procBuf = (t_nrLDPC_procBuf **)malloc16_clear(a_segments); for (r=0; rharq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem(); ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16_clear(8448*sizeof(uint8_t)); ulsch->harq_processes[i]->d[r] = (int16_t*)malloc16_clear((68*384)*sizeof(int16_t)); - ulsch->harq_processes[i]->w[r] = (int16_t*)malloc16_clear((3*(6144+64))*sizeof(int16_t)); } } @@ -265,9 +268,12 @@ void nr_processULSegment(void* arg) { //////////////////////////// ulsch_llr =====> ulsch_harq->e ////////////////////////////// + /// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1) + int16_t harq_e[3*8448]; + nr_deinterleaving_ldpc(E, Qm, - ulsch_harq->e[r], + harq_e, ulsch_llr+r_offset); //for (int i =0; i<16; i++) @@ -292,7 +298,7 @@ void nr_processULSegment(void* arg) { p_decoderParms->BG, p_decoderParms->Z, ulsch_harq->d[r], - ulsch_harq->e[r], + harq_e, ulsch_harq->C, rv_index, ulsch_harq->new_rx, @@ -539,7 +545,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, r_offset = 0; - uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated + uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*n_layers; //number of segments to be allocated if (nb_rb != 273) { a_segments = a_segments*nb_rb; 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 9bc3643557..822edcc3d9 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -63,10 +63,12 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlsch, uint16_t N_RB_DL); */ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint16_t N_RB_DL); +void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulschptr, + uint16_t N_RB_UL, + NR_DL_FRAME_PARMS* frame_parms); -void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulsch, uint16_t N_RB_UL); -NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, int number_of_harq_pids); +NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, int number_of_harq_pids, NR_DL_FRAME_PARMS* frame_parms); /** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/QPSK reception. @param stream0_in Input from channel compensated (MR combined) stream 0 diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index caf3a19d85..9d5beb9d20 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -84,9 +84,9 @@ typedef struct { /// Pointer to the payload + CRC uint8_t *b; /// Pointers to transport block segments - uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS]; + uint8_t **c; /// LDPC-code outputs - uint8_t *d[MAX_NUM_NR_ULSCH_SEGMENTS]; + uint8_t **d; /// LDPC-code outputs (TS 36.212 V15.4.0, Sec 5.3.2 p. 17) uint8_t *e; /// Rate matching (Interleaving) outputs (TS 36.212 V15.4.0, Sec 5.4.2.2 p. 30) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 5160a643fb..b1966aaa43 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -43,10 +43,10 @@ //#define DEBUG_ULSCH_CODING -void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulschptr, uint16_t N_RB_UL) +void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulschptr, + uint16_t N_RB_UL, + NR_DL_FRAME_PARMS* frame_parms) { -{ - int i, r; NR_UE_ULSCH_t *ulsch = *ulschptr; if (ulsch) { @@ -54,15 +54,15 @@ void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulschptr, uint16_t N_RB_UL) printf("Freeing ulsch %p\n",ulsch); #endif - uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated + int max_layers = (frame_parms->nb_antennas_txnb_antennas_tx : NR_MAX_NB_LAYERS; + uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*max_layers; //number of segments to be allocated - if (N_RB_UL != 273) { - a_segments = a_segments*N_RB_UL; - a_segments = a_segments/273 +1; - } + if (N_RB_UL != 273) { + a_segments = a_segments*N_RB_UL; + a_segments = a_segments/273 +1; + } - - for (i=0; iharq_processes[i]) { if (ulsch->harq_processes[i]->a) { @@ -81,7 +81,7 @@ void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulschptr, uint16_t N_RB_UL) free16(ulsch->harq_processes[i]->f,14*N_RB_UL*12*8); ulsch->harq_processes[i]->f = NULL; } - for (r=0; rharq_processes[i]->c[r]) { free16(ulsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768); ulsch->harq_processes[i]->c[r] = NULL; @@ -94,6 +94,15 @@ void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulschptr, uint16_t N_RB_UL) } + if (ulsch->harq_processes[i]->c) { + free16(ulsch->harq_processes[i]->c,a_segments); + ulsch->harq_processes[i]->c = NULL; + } + if (ulsch->harq_processes[i]->d) { + free16(ulsch->harq_processes[i]->d,a_segments); + ulsch->harq_processes[i]->d = NULL; + } + free16(ulsch->harq_processes[i],sizeof(NR_UL_UE_HARQ_t)); ulsch->harq_processes[i] = NULL; } @@ -101,13 +110,13 @@ void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulschptr, uint16_t N_RB_UL) free16(ulsch,sizeof(NR_UE_ULSCH_t)); *ulschptr = NULL; } - } -NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, int number_of_harq_pids) -{ - uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated +NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, int number_of_harq_pids, NR_DL_FRAME_PARMS* frame_parms) { + + int max_layers = (frame_parms->nb_antennas_txnb_antennas_tx : NR_MAX_NB_LAYERS; + uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*max_layers; //number of segments to be allocated if (N_RB_UL != 273) { a_segments = a_segments*N_RB_UL; @@ -140,6 +149,8 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, int number_of_harq_pids) DevAssert(ulsch->harq_processes[i]->b); bzero(ulsch->harq_processes[i]->b,ulsch_bytes); + ulsch->harq_processes[i]->c = malloc16(a_segments); + ulsch->harq_processes[i]->d = malloc16(a_segments); for (int r = 0; r < a_segments; r++) { // account for filler in first segment and CRCs for multiple segment case ulsch->harq_processes[i]->c[r] = malloc16(8448); @@ -240,6 +251,8 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, printf("\n"); */ + int max_payload_bytes = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*harq_process->pusch_pdu.nrOfLayers*1056; + if (A > 3824) { // Add 24-bit crc (polynomial A) to payload crc = crc24a(harq_process->a,A)>>8; @@ -251,7 +264,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, harq_process->B = A+24; - AssertFatal((A/8)+4 <= MAX_NR_ULSCH_PAYLOAD_BYTES,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,MAX_NR_ULSCH_PAYLOAD_BYTES); + AssertFatal((A/8)+4 <= max_payload_bytes,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,max_payload_bytes); memcpy(harq_process->b,harq_process->a,(A/8)+4); } @@ -265,7 +278,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, harq_process->B = A+16; - AssertFatal((A/8)+3 <= MAX_NR_ULSCH_PAYLOAD_BYTES,"A %d is too big (A/8+3 = %d > %d)\n",A,(A/8)+3,MAX_NR_ULSCH_PAYLOAD_BYTES); + AssertFatal((A/8)+3 <= max_payload_bytes,"A %d is too big (A/8+3 = %d > %d)\n",A,(A/8)+3,max_payload_bytes); memcpy(harq_process->b,harq_process->a,(A/8)+3); // using 3 bytes to mimic the case of 24 bit crc } diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 297b58e88e..2bd0bd301a 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -273,7 +273,7 @@ typedef struct { /// The payload + CRC (24 bits) in bits (38.212 V15.4.0 section 5.1) uint32_t B; /// Pointers to code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2) - uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS]; + uint8_t **c; /// Number of bits in each code block (38.212 V15.4.0 section 5.2.2) uint32_t K; /// Number of "Filler" bits added in the code block segmentation (38.212 V15.4.0 section 5.2.2) @@ -281,13 +281,11 @@ typedef struct { /// Number of code blocks after code block segmentation (38.212 V15.4.0 section 5.2.2) uint32_t C; /// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2) - int16_t *d[MAX_NUM_NR_ULSCH_SEGMENTS]; + int16_t **d; /// LDPC processing buffer - t_nrLDPC_procBuf* p_nrLDPC_procBuf[MAX_NUM_NR_ULSCH_SEGMENTS]; + t_nrLDPC_procBuf** p_nrLDPC_procBuf; /// LDPC lifting size (38.212 V15.4.0 table 5.3.2-1) uint32_t Z; - /// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1) - int16_t e[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448]; /// Number of bits in each code block after rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1) uint32_t E; /// Number of segments processed so far @@ -342,8 +340,6 @@ typedef struct { int16_t q_RI[MAX_RI_PAYLOAD]; /// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled uint8_t h[MAX_NUM_CHANNEL_BITS]; - /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) - int16_t *w[MAX_NUM_NR_ULSCH_SEGMENTS]; ////////////////////////////////////////////////////////////// } NR_UL_gNB_HARQ_t; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 5574be705f..a912a896af 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -104,8 +104,7 @@ #define MAX_NUM_NR_DLSCH_SEGMENTS (NR_MAX_NB_LAYERS*34) #define MAX_NR_DLSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056) -#define MAX_NUM_NR_ULSCH_SEGMENTS (NR_MAX_NB_LAYERS*34) -#define MAX_NR_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_ULSCH_SEGMENTS*1056) +#define MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER 34 #define MAX_NUM_NR_CHANNEL_BITS (4*14*273*12*8) // 14 symbols, 273 RB #define MAX_NUM_NR_RE (4*14*273*12) diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 11b94a2221..1a6c788c8d 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -417,7 +417,7 @@ int main(int argc, char **argv) for (sf = 0; sf < 2; sf++) { for (i = 0; i < 2; i++) { - UE->ulsch[sf][0][i] = new_nr_ue_ulsch(N_RB_UL, 8); + UE->ulsch[sf][0][i] = new_nr_ue_ulsch(N_RB_UL, 8, frame_parms); if (!UE->ulsch[sf][0][i]) { printf("Can't get ue ulsch structures.\n"); @@ -628,7 +628,7 @@ int main(int argc, char **argv) for (sf = 0; sf < 2; sf++) for (i = 0; i < 2; i++) - free_nr_ue_ulsch(&UE->ulsch[sf][0][i], N_RB_UL); + free_nr_ue_ulsch(&UE->ulsch[sf][0][i], N_RB_UL, frame_parms); term_nr_ue_signal(UE, 1); free(UE); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 3851ee011d..1c9ebf3eba 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -743,7 +743,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, } else if (get_softmodem_params()->nsa) { - uint8_t mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES]; + uint8_t mac_sdus[MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*1056]; uint16_t sdu_lengths[NB_RB_MAX] = {0}; int TBS_bytes = 848; int mac_ce_len = 0; From 07d20ba12196cf3680319d0fc3e12883d6fc2e9f Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 23 Mar 2022 09:58:55 +0100 Subject: [PATCH 16/49] fix for memory issues --- openair1/PHY/INIT/nr_init_ue.c | 17 ----------------- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 6 +++--- .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 4 ++-- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 19 +++++++++++-------- openair1/PHY/defs_nr_UE.h | 8 -------- 5 files changed, 16 insertions(+), 38 deletions(-) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index a68da3257c..6d3e88faf0 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -155,23 +155,6 @@ void phy_term_nr_ue__PDSCH(NR_UE_PDSCH* pdsch, const NR_DL_FRAME_PARMS *const fp free_and_zero(pdsch->dl_ch_ptrs_estimates_ext); } -void phy_init_nr_ue_PUSCH(NR_UE_PUSCH *const pusch, - const NR_DL_FRAME_PARMS *const fp) { - AssertFatal( pusch, "pusch==0" ); - - int max_encoded_length = fp->N_RB_UL*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8*NR_MAX_NB_LAYERS; - - for (int i=0; itxdataF_precoding[i] = (int32_t *)malloc16_clear((max_encoded_length)*sizeof(int32_t *)); - } -} - -void phy_term_nr_ue_PUSCH(NR_UE_PUSCH *pusch) -{ - for (int i = 0; i < NR_MAX_NB_LAYERS; i++) - free_and_zero(pusch->txdataF_precoding[i]); -} - int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) { // create shortcuts diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 7a76d0736c..33b4b8b17d 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -110,9 +110,9 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL) ulsch->harq_processes[i] = (NR_UL_gNB_HARQ_t *)malloc16_clear(sizeof(NR_UL_gNB_HARQ_t)); ulsch->harq_processes[i]->b = (uint8_t*)malloc16_clear(ulsch_bytes); - ulsch->harq_processes[i]->c = (uint8_t**)malloc16_clear(a_segments); - ulsch->harq_processes[i]->d = (int16_t**)malloc16_clear(a_segments); - ulsch->harq_processes[i]->p_nrLDPC_procBuf = (t_nrLDPC_procBuf **)malloc16_clear(a_segments); + ulsch->harq_processes[i]->c = (uint8_t**)malloc16_clear(a_segments*sizeof(uint8_t *)); + ulsch->harq_processes[i]->d = (int16_t**)malloc16_clear(a_segments*sizeof(int16_t *)); + ulsch->harq_processes[i]->p_nrLDPC_procBuf = (t_nrLDPC_procBuf **)malloc16_clear(a_segments*sizeof(t_nrLDPC_procBuf *)); for (r=0; rharq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem(); ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16_clear(8448*sizeof(uint8_t)); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 0ee817ca77..30219875d9 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -149,8 +149,8 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, int number_of_harq_pids, NR_DL_ DevAssert(ulsch->harq_processes[i]->b); bzero(ulsch->harq_processes[i]->b,ulsch_bytes); - ulsch->harq_processes[i]->c = malloc16(a_segments); - ulsch->harq_processes[i]->d = malloc16(a_segments); + ulsch->harq_processes[i]->c = malloc16(a_segments*sizeof(uint8_t *)); + ulsch->harq_processes[i]->d = malloc16(a_segments*sizeof(uint16_t *)); for (int r = 0; r < a_segments; r++) { // account for filler in first segment and CRCs for multiple segment case ulsch->harq_processes[i]->c[r] = malloc16(8448); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index e8f2b51ee7..380487172f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -122,8 +122,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, int sample_offsetF, N_RE_prime; NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms; - NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id]; - int16_t **tx_precoding = (int16_t **)pusch_ue->txdataF_precoding; int32_t **txdataF = UE->common_vars.txdataF; int N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig @@ -333,13 +331,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, #endif } - else - memcpy(y, tx_layers[0], (available_bits/mod_order)*sizeof(int32_t)); - for (int nl = 0; nl < Nl; nl++) - free_and_zero(tx_layers[nl]); - free_and_zero(tx_layers); - /////////// //////////////////////////////////////////////////////////////////////// @@ -348,6 +340,10 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////////////////////ULSCH RE mapping///////////////////////// /////////// + int encoded_length = frame_parms->N_RB_UL*number_of_symbols*NR_NB_SC_PER_RB*mod_order*Nl; + int16_t **tx_precoding = (int16_t **)malloc16_clear(Nl*sizeof(int16_t *)); + for (int nl=0; nlulsch[thread_id][gNB_id]->harq_processes[harq_pid]; harq_process_ulsch->status = SCH_IDLE; + for (int nl = 0; nl < Nl; nl++) { + free_and_zero(tx_layers[nl]); + free_and_zero(tx_precoding[nl]); + } + free_and_zero(tx_layers); + free_and_zero(tx_precoding); + /////////// //////////////////////////////////////////////////////////////////////// diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 7a8d680d70..04080e7215 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -225,11 +225,6 @@ typedef struct { } NR_UE_COMMON_PER_THREAD; -typedef struct { - /// TX buffers for UE-spec transmission - int32_t *txdataF_precoding[NR_MAX_NB_LAYERS]; - } NR_UE_PUSCH; - typedef struct { bool active[2]; fapi_nr_ul_config_pucch_pdu pucch_pdu[2]; @@ -793,9 +788,6 @@ typedef struct { NR_UE_DLSCH_t *dlsch_p[NUMBER_OF_CONNECTED_gNB_MAX]; NR_UE_DLSCH_t *dlsch_MCH[NUMBER_OF_CONNECTED_gNB_MAX]; - // to be removed again possibly - NR_UE_PUSCH *pusch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX]; - //Paging parameters uint32_t IMSImod1024; uint32_t PF; From d36549f80a988a880e65a071e4ebe2be6f393bfc Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 23 Mar 2022 19:15:02 +0100 Subject: [PATCH 17/49] fix memory issues --- cmake_targets/autotests/test_case_list.xml | 2 +- openair1/PHY/INIT/nr_init.c | 9 ++++++++- openair1/PHY/NR_TRANSPORT/nr_scrambling.c | 1 + openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 7 +++---- openair1/SIMULATION/NR_PHY/ulsim.c | 4 ++-- 6 files changed, 16 insertions(+), 9 deletions(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 36dbe9de07..5687810e69 100755 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1324,7 +1324,7 @@ -n100 -s5 -T 2 1 2 -U 2 0 2 -n100 -s5 -T 2 2 2 -U 2 1 2 -n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3 - -n100 -s5 -Z + -n100 -Z -s5 -n100 -s5 -Z -r75 -n50 -s5 -Z -r216 -R217 -n50 -s5 -Z -r270 -R273 diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 131e74469e..8e698b09cd 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -285,7 +285,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, for (i=0; irxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); pusch_vars[ULSCH_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); - pusch_vars[ULSCH_id]->rho[i] = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS*sizeof(int32_t*)); + pusch_vars[ULSCH_id]->rho[i] = (int32_t **)malloc16_clear(NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS*sizeof(int32_t*)); for (int j=0; j< max_ul_mimo_layers; j++) { for (int k=0; kpusch_vars; for (int ULSCH_id=0; ULSCH_idnumber_of_nr_ulsch_max; ULSCH_id++) { + for (int i=0; i< max_ul_mimo_layers; i++) + free_and_zero(pusch_vars[ULSCH_id]->llr_layers[i]); for (int i = 0; i < Prx; i++) { free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext[i]); free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2[i]); + for (int j=0; j< max_ul_mimo_layers; j++) { + for (int k=0; krho[i][j*max_ul_mimo_layers+k]); + } free_and_zero(pusch_vars[ULSCH_id]->rho[i]); } for (int i = 0; i < n_buf; i++) { @@ -434,6 +440,7 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag[i]); free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb[i]); } + free_and_zero(pusch_vars[ULSCH_id]->llr_layers); free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext); free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2); free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates); diff --git a/openair1/PHY/NR_TRANSPORT/nr_scrambling.c b/openair1/PHY/NR_TRANSPORT/nr_scrambling.c index 4bbecfd994..8a49a7ffe0 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_scrambling.c +++ b/openair1/PHY/NR_TRANSPORT/nr_scrambling.c @@ -52,6 +52,7 @@ void nr_codeword_scrambling(uint8_t *in, ((uint16_t*)&in32)[0] = _mm_movemask_epi8(_mm_slli_epi16(in128[0],7)); ((uint16_t*)&in32)[1] = _mm_movemask_epi8(_mm_slli_epi16(in128[1],7)); out[i]=(in32^s); + LOG_D(PHY,"in[%d] %x => %x\n",i,in32,out[i]); s=lte_gold_generic(&x1, &x2, 0); } //#elsif defined(__arm__) || defined(__aarch64) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 30219875d9..1acb722ecd 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -318,7 +318,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, printf("start ldpc encoder segment %d/%d\n",r,harq_process->C); printf("input %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]); for (int cnt =0 ; cnt < 22*(*pz)/8; cnt ++){ - printf("%d ", harq_process->c[r][cnt]); + printf("%d ", harq_process->c[r][cnt]); } printf("\n"); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 380487172f..740299477b 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -114,7 +114,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, LOG_D(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot); - uint32_t available_bits; int8_t Wf[2], Wt[2]; int l_prime[2], delta; uint8_t nb_dmrs_re_per_rb; @@ -183,7 +182,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////////////////////ULSCH scrambling///////////////////////// /////////// - available_bits = G; + uint32_t available_bits = G; uint32_t scrambled_output[(available_bits>>5)+1]; memset(scrambled_output, 0, ((available_bits>>5)+1)*sizeof(uint32_t)); @@ -200,7 +199,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////////////////////ULSCH modulation///////////////////////// /////////// - int max_num_re = number_of_symbols*nb_rb*NR_NB_SC_PER_RB; + int max_num_re = Nl*number_of_symbols*nb_rb*NR_NB_SC_PER_RB; int32_t d_mod[max_num_re] __attribute__ ((aligned(16))); nr_modulation(scrambled_output, // assume one codeword for the moment @@ -340,7 +339,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////////////////////ULSCH RE mapping///////////////////////// /////////// - int encoded_length = frame_parms->N_RB_UL*number_of_symbols*NR_NB_SC_PER_RB*mod_order*Nl; + int encoded_length = frame_parms->N_RB_UL*14*NR_NB_SC_PER_RB*mod_order*Nl; int16_t **tx_precoding = (int16_t **)malloc16_clear(Nl*sizeof(int16_t *)); for (int nl=0; nlul_dmrs_symb_pos); ptrsSymbPerSlot = get_ptrs_symbols_in_slot(ptrsSymPos, pusch_pdu->start_symbol_index, pusch_pdu->nr_of_symbols); ptrsRePerSymb = ((pusch_pdu->rb_size + ptrs_freq_density - 1)/ptrs_freq_density); - printf("[ULSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb ); + LOG_D(PHY,"[ULSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb ); } //////////////////////////////////////////////////////////// From 15777bbf0e8910b36e9ee7b83579ca9dea6311fb Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 20 Apr 2022 17:05:03 +0200 Subject: [PATCH 18/49] fix for ulsim antenna ports --- openair1/SIMULATION/NR_PHY/ulsim.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 1a027a33d5..ade4e2aad4 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -730,7 +730,7 @@ int main(int argc, char **argv) // TODO do a UECAP for phy-sim const gNB_RrcConfigurationReq conf = { - .pdsch_AntennaPorts = { .N1 = n_tx, .N2 = 1, .XP = 1 }, + .pdsch_AntennaPorts = { .N1 = 1, .N2 = 1, .XP = 1 }, .pusch_AntennaPorts = n_rx, .minRXTXTIME = 0, .do_CSIRS = 0, @@ -751,10 +751,10 @@ int main(int argc, char **argv) rrc_mac_config_req_gNB(0,0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib, rrc.carrier.siblock1, 0, 0, NULL); // UE dedicated configuration rrc_mac_config_req_gNB(0,0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib, rrc.carrier.siblock1, 1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); - frame_parms->nb_antennas_tx = n_tx; + frame_parms->nb_antennas_tx = 1; frame_parms->nb_antennas_rx = n_rx; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; - cfg->carrier_config.num_tx_ant.value = n_tx; + cfg->carrier_config.num_tx_ant.value = 1; cfg->carrier_config.num_rx_ant.value = n_rx; // nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,0,0x01); phy_init_nr_gNB(gNB,0,1); @@ -771,6 +771,8 @@ int main(int argc, char **argv) PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE*)); PHY_vars_UE_g[0][0] = UE; memcpy(&UE->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS)); + UE->frame_parms.nb_antennas_tx = n_tx; + frame_parms->nb_antennas_rx = 1; if (init_nr_ue_signal(UE, 1) != 0) { printf("Error at UE NR initialisation\n"); From f49df054566bc7dc1df20a98a3d191f5001e3dd4 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 20 Apr 2022 18:55:38 +0200 Subject: [PATCH 19/49] fix for ulschsim antenna ports --- openair1/SIMULATION/NR_PHY/ulschsim.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 3f8062a0ce..d76d438446 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -391,8 +391,6 @@ int main(int argc, char **argv) initTpool(tp_param, gNB->threadPool, true); initNotifiedFIFO(gNB->respDecode); frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) - frame_parms->nb_antennas_tx = n_tx; - frame_parms->nb_antennas_rx = n_rx; frame_parms->N_RB_DL = N_RB_DL; frame_parms->N_RB_UL = N_RB_UL; frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL; @@ -400,6 +398,9 @@ int main(int argc, char **argv) memcpy(&gNB->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS)); + gNB->frame_parms.nb_antennas_tx = 1; + gNB->frame_parms.nb_antennas_rx = n_rx; + nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions); phy_init_nr_gNB(gNB, 0, 1); //lowmem @@ -408,6 +409,9 @@ int main(int argc, char **argv) UE = malloc(sizeof(PHY_VARS_NR_UE)); memcpy(&UE->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS)); + UE->frame_parms.nb_antennas_tx = n_tx; + UE->frame_parms.nb_antennas_rx = 1; + //phy_init_nr_top(frame_parms); if (init_nr_ue_signal(UE, 1) != 0) { printf("Error at UE NR initialisation.\n"); From f57f4ce3fedaef00e374db58d0e2e9b41870b2c0 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 22 Apr 2022 09:56:54 +0200 Subject: [PATCH 20/49] bugfix in channel compensation --- openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index b415374dc7..db05e03d4c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -721,7 +721,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, ul_ch_mag128[1] = _mm_mulhi_epi16(ul_ch_mag128[1],QAM_amp128); ul_ch_mag128[1] = _mm_slli_epi16(ul_ch_mag128[1],1); - ul_ch_mag128b[1] = _mm_mulhi_epi16(ul_ch_mag128b[1],QAM_amp128); + ul_ch_mag128b[1] = _mm_mulhi_epi16(ul_ch_mag128b[1],QAM_amp128b); ul_ch_mag128b[1] = _mm_slli_epi16(ul_ch_mag128b[1],1); mmtmpD0 = _mm_madd_epi16(ul_ch128[2],ul_ch128[2]); From 697d72cd01f0742f9d1cb88bc707fbf17ee8f10d Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 22 Apr 2022 18:51:53 +0200 Subject: [PATCH 21/49] adding missing parameter in ulsim --- openair1/SIMULATION/NR_PHY/ulsim.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index ade4e2aad4..64ccffabdd 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -1171,6 +1171,7 @@ int main(int argc, char **argv) ul_config.ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table; ul_config.ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data; ul_config.ul_config_list[0].pusch_config_pdu.nrOfLayers = precod_nbr_layers; + ul_config.ul_config_list[0].pusch_config_pdu.dmrs_ports = ((1< Date: Tue, 26 Apr 2022 10:59:25 +0200 Subject: [PATCH 22/49] fixing bugs and cleaning up ulsim --- openair1/SIMULATION/NR_PHY/ulsim.c | 219 ++++++++++++----------------- 1 file changed, 93 insertions(+), 126 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 64ccffabdd..8b30958131 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -744,13 +744,14 @@ int main(int argc, char **argv) /* RRC parameter validation for secondaryCellGroup */ fix_scd(scd); - AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface"); + AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface"); - gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; + gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; // common configuration rrc_mac_config_req_gNB(0,0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib, rrc.carrier.siblock1, 0, 0, NULL); // UE dedicated configuration - rrc_mac_config_req_gNB(0,0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib, rrc.carrier.siblock1, 1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); + rrc_mac_config_req_gNB(0,0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib, rrc.carrier.siblock1, 1, + secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); frame_parms->nb_antennas_tx = 1; frame_parms->nb_antennas_rx = n_rx; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; @@ -772,7 +773,7 @@ int main(int argc, char **argv) PHY_vars_UE_g[0][0] = UE; memcpy(&UE->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS)); UE->frame_parms.nb_antennas_tx = n_tx; - frame_parms->nb_antennas_rx = 1; + UE->frame_parms.nb_antennas_rx = 1; if (init_nr_ue_signal(UE, 1) != 0) { printf("Error at UE NR initialisation\n"); @@ -825,7 +826,7 @@ int main(int argc, char **argv) unsigned char *estimated_output_bit; unsigned char *test_input_bit; - uint32_t errors_decoding = 0; + uint32_t errors_decoding = 0; test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); @@ -858,21 +859,14 @@ int main(int argc, char **argv) /* validate parameters othwerwise default values are used */ /* -U flag can be used to set DMRS parameters*/ - if(modify_dmrs) - { + if(modify_dmrs) { if(dmrs_arg[0] == 0) - { mapping_type = typeA; - } else if (dmrs_arg[0] == 1) - { mapping_type = typeB; - } /* Additional DMRS positions */ if(dmrs_arg[1] >= 0 && dmrs_arg[1] <=3 ) - { add_pos = dmrs_arg[1]; - } } printf("NOTE: DMRS config is modified with Mapping Type %d , Additional Position %d \n", mapping_type, add_pos ); @@ -882,24 +876,22 @@ int main(int argc, char **argv) printf("num dmrs sym %d\n",number_dmrs_symbols); uint8_t nb_re_dmrs = (dmrs_config_type == pusch_dmrs_type1) ? 6 : 4; - if ((frame_parms->nb_antennas_tx==4)&&(precod_nbr_layers==4)) - { + if ((UE->frame_parms.nb_antennas_tx==4)&&(precod_nbr_layers==4)) num_dmrs_cdm_grps_no_data = 2; - } if (transformPrecoder == transformPrecoder_enabled) { AssertFatal(enable_ptrs == 0, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); int8_t index = get_index_for_dmrs_lowpapr_seq((NR_NB_SC_PER_RB/2) * nb_rb); - AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); + AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); dmrs_config_type = pusch_dmrs_type1; printf("[ULSIM]: TRANSFORM PRECODING ENABLED. Num RBs: %d, index for DMRS_SEQ: %d\n", nb_rb, index); } - nb_re_dmrs = nb_re_dmrs * num_dmrs_cdm_grps_no_data; + nb_re_dmrs = nb_re_dmrs * num_dmrs_cdm_grps_no_data; unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, precod_nbr_layers); unsigned int TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, 0, precod_nbr_layers); @@ -926,17 +918,12 @@ int main(int argc, char **argv) double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size); /* -T option enable PTRS */ - if(enable_ptrs) - { + if(enable_ptrs) { /* validate parameters othwerwise default values are used */ if(ptrs_arg[0] == 0 || ptrs_arg[0] == 1 || ptrs_arg[0] == 2 ) - { ptrs_time_density = ptrs_arg[0]; - } if(ptrs_arg[1] == 2 || ptrs_arg[1] == 4 ) - { ptrs_freq_density = ptrs_arg[1]; - } pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS; printf("NOTE: PTRS Enabled with L %d, K %d \n", ptrs_time_density, ptrs_freq_density ); } @@ -1052,7 +1039,7 @@ int main(int argc, char **argv) uint8_t round = 0; crc_status = 1; - errors_decoding = 0; + errors_decoding = 0; memset((void*)roundStats,0,50*sizeof(roundStats[0])); while (roundframe_parms, - frame_parms->nb_antennas_tx); + UE->frame_parms.nb_antennas_tx); - if (n_trials==1) - { + if (n_trials==1) { LOG_M("txsig0.m","txs0", &UE->common_vars.txdata[0][slot_offset],slot_length,1,1); LOG_M("txsig0F.m","txs0F", UE->common_vars.txdataF[0],frame_parms->ofdm_symbol_size*14,1,1); - if (precod_nbr_layers > 1) - { + if (precod_nbr_layers > 1) { LOG_M("txsig1.m","txs1", &UE->common_vars.txdata[1][slot_offset],slot_length,1,1); LOG_M("txsig1F.m","txs1F", UE->common_vars.txdataF[1],frame_parms->ofdm_symbol_size*14,1,1); - if (precod_nbr_layers==4) - { + if (precod_nbr_layers==4) { LOG_M("txsig2.m","txs2", &UE->common_vars.txdata[2][slot_offset],slot_length,1,1); LOG_M("txsig3.m","txs3", &UE->common_vars.txdata[3][slot_offset],slot_length,1,1); - LOG_M("txsig2F.m","txs2F", UE->common_vars.txdataF[2],frame_parms->ofdm_symbol_size*14,1,1); LOG_M("txsig3F.m","txs3F", UE->common_vars.txdataF[3],frame_parms->ofdm_symbol_size*14,1,1); } @@ -1241,32 +1224,28 @@ int main(int argc, char **argv) //////////////////////////////////////////////////// tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); txlev_sum = 0; - for (int aa=0; aanb_antennas_tx; aa++) - { + for (int aa=0; aanb_antennas_rx; aa++) { atxlev[aa] = signal_energy(&UE->common_vars.txdata[aa][tx_offset + 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); - txlev_sum += atxlev[aa]; + txlev_sum += atxlev[aa]; if (n_trials==1) printf("txlev[%d] = %d (%f dB) txlev_sum %d\n",aa,atxlev[aa],10*log10((double)atxlev[aa]),txlev_sum); } } else - { n_trials = 1; - } - if (input_fd == NULL ) - { + if (input_fd == NULL) { sigma_dB = 10 * log10((double)txlev_sum * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;; sigma = pow(10,sigma_dB/10); if(n_trials==1) printf("sigma %f (%f dB), txlev_sum %f (factor %f)\n",sigma,sigma_dB,10*log10((double)txlev_sum),(double)(double) - frame_parms->ofdm_symbol_size/(12*nb_rb)); + frame_parms->ofdm_symbol_size/(12*nb_rb)); for (i=0; inb_antennas_tx; aa++) { + for (int aa=0; aaframe_parms.nb_antennas_tx; aa++) { s_re[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)]); s_im[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)+1]); } @@ -1274,17 +1253,13 @@ int main(int argc, char **argv) if (UE2gNB->max_Doppler == 0) - { multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials==1)?1:0); - } else { + else multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, 2*slot_length, 0); - } - for (i=0; inb_antennas_rx; ap++) - { - if (channel_model == AWGN) - { + + for (i=0; inb_antennas_rx; ap++) { + if (channel_model == AWGN) { double H_awgn[4][4] ={{1.0, 0.0, 0.0, 0.0},//rx 0 {0.0, 1.0, 0.0, 0.0}, //rx 1 {0.0, 0.0, 1.0, 0.0}, //rx 2 @@ -1299,8 +1274,7 @@ int main(int argc, char **argv) r_re[ap][i] = 0; r_im[ap][i] = 0; - for (int aa=0; aapdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) - { + if(pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { set_ptrs_symb_idx(&ptrsSymPos, pusch_pdu->nr_of_symbols, pusch_pdu->start_symbol_index, @@ -1346,47 +1319,42 @@ int main(int argc, char **argv) ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot); - if (n_trials==1 && round==0) - { - LOG_M("rxsig0.m","rx0",&gNB->common_vars.rxdata[0][slot_offset],slot_length,1,1); - - LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0],14*frame_parms->ofdm_symbol_size,1,1); - if (precod_nbr_layers > 1) - { - LOG_M("rxsig1.m","rx1",&gNB->common_vars.rxdata[1][slot_offset],slot_length,1,1); - LOG_M("rxsigF1.m","rxsF1",gNB->common_vars.rxdataF[1],14*frame_parms->ofdm_symbol_size,1,1); - if (precod_nbr_layers==4) - { - LOG_M("rxsig2.m","rx2",&gNB->common_vars.rxdata[2][slot_offset],slot_length,1,1); - LOG_M("rxsig3.m","rx3",&gNB->common_vars.rxdata[3][slot_offset],slot_length,1,1); - - LOG_M("rxsigF2.m","rxsF2",gNB->common_vars.rxdataF[2],14*frame_parms->ofdm_symbol_size,1,1); - LOG_M("rxsigF3.m","rxsF3",gNB->common_vars.rxdataF[3],14*frame_parms->ofdm_symbol_size,1,1); - } + if (n_trials==1 && round==0) { + LOG_M("rxsig0.m","rx0",&gNB->common_vars.rxdata[0][slot_offset],slot_length,1,1); + LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0],14*frame_parms->ofdm_symbol_size,1,1); + if (precod_nbr_layers > 1) { + LOG_M("rxsig1.m","rx1",&gNB->common_vars.rxdata[1][slot_offset],slot_length,1,1); + LOG_M("rxsigF1.m","rxsF1",gNB->common_vars.rxdataF[1],14*frame_parms->ofdm_symbol_size,1,1); + if (precod_nbr_layers==4) { + LOG_M("rxsig2.m","rx2",&gNB->common_vars.rxdata[2][slot_offset],slot_length,1,1); + LOG_M("rxsig3.m","rx3",&gNB->common_vars.rxdata[3][slot_offset],slot_length,1,1); + LOG_M("rxsigF2.m","rxsF2",gNB->common_vars.rxdataF[2],14*frame_parms->ofdm_symbol_size,1,1); + LOG_M("rxsigF3.m","rxsF3",gNB->common_vars.rxdataF[3],14*frame_parms->ofdm_symbol_size,1,1); + } } - } + } - if (n_trials == 1 && round==0) { + if (n_trials == 1 && round==0) { #ifdef __AVX2__ - __attribute__((unused)) - int off = ((nb_rb&1) == 1)? 4:0; + __attribute__((unused)) + int off = ((nb_rb&1) == 1)? 4:0; #else - __attribute__((unused)) - int off = 0; + __attribute__((unused)) + int off = 0; #endif - LOG_M("rxsigF0_ext.m","rxsF0_ext", - &gNB->pusch_vars[0]->rxdataF_ext[0][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_M("chestF0.m","chF0", - &gNB->pusch_vars[0]->ul_ch_estimates[0][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); - LOG_M("chestT0.m","chT0", - &gNB->pusch_vars[0]->ul_ch_estimates_time[0][0],frame_parms->ofdm_symbol_size,1,1); - LOG_M("chestF0_ext.m","chF0_ext", - &gNB->pusch_vars[0]->ul_ch_estimates_ext[0][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], - (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); - LOG_M("rxsigF0_comp.m","rxsF0_comp", - &gNB->pusch_vars[0]->rxdataF_comp[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + LOG_M("rxsigF0_ext.m","rxsF0_ext", + &gNB->pusch_vars[0]->rxdataF_ext[0][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + LOG_M("chestF0.m","chF0", + &gNB->pusch_vars[0]->ul_ch_estimates[0][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); + LOG_M("chestT0.m","chT0", + &gNB->pusch_vars[0]->ul_ch_estimates_time[0][0],frame_parms->ofdm_symbol_size,1,1); + LOG_M("chestF0_ext.m","chF0_ext", + &gNB->pusch_vars[0]->ul_ch_estimates_ext[0][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))], + (nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); + LOG_M("rxsigF0_comp.m","rxsF0_comp", + &gNB->pusch_vars[0]->rxdataF_comp[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); LOG_M("chmagF0.m","chmF0", &gNB->pusch_vars[0]->ul_ch_mag[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); LOG_M("chmagbF0.m","chmbF0", @@ -1454,48 +1422,47 @@ int main(int argc, char **argv) &gNB->pusch_vars[0]->llr_layers[2][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); LOG_M("rxsigF0_llrlayers3.m","rxsF0_llrlayers3", &gNB->pusch_vars[0]->llr_layers[3][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); - } + } - LOG_M("rxsigF0_llr.m","rxsF0_llr", - &gNB->pusch_vars[0]->llr[0],precod_nbr_layers*(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); - } + LOG_M("rxsigF0_llr.m","rxsF0_llr", + &gNB->pusch_vars[0]->llr[0],precod_nbr_layers*(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); + } //////////////////////////////////////////////////////////// - if ((gNB->ulsch[0]->last_iteration_cnt >= - gNB->ulsch[0]->max_ldpc_iterations+1) || ul_proc_error == 1) { - error_flag = 1; - n_errors[round][snrRun]++; - crc_status = 1; - } else { - crc_status = 0; - } - if(n_trials==1) printf("end of round %d rv_index %d\n",round, rv_index); + if ((gNB->ulsch[0]->last_iteration_cnt >= + gNB->ulsch[0]->max_ldpc_iterations+1) || ul_proc_error == 1) { + error_flag = 1; + n_errors[round][snrRun]++; + crc_status = 1; + } else + crc_status = 0; + if(n_trials==1) printf("end of round %d rv_index %d\n",round, rv_index); - //---------------------------------------------------------- - //----------------- count and print errors ----------------- - //---------------------------------------------------------- + //---------------------------------------------------------- + //----------------- count and print errors ----------------- + //---------------------------------------------------------- - if ((pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) && (SNR==snr0) && (trial==0) && (round==0)) { - ptrs_symbols = 0; - for (int i = pusch_pdu->start_symbol_index; i < pusch_pdu->start_symbol_index + pusch_pdu->nr_of_symbols; i++){ - ptrs_symbols += ((gNB->pusch_vars[UE_id]->ptrs_symbols) >> i) & 1; - } - /* 2*5*(50/2), for RB = 50,K = 2 for 5 OFDM PTRS symbols */ - available_bits -= 2 * ptrs_symbols * ((nb_rb + ptrs_freq_density - 1) /ptrs_freq_density); - printf("[ULSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5d \n",available_bits, (ptrsSymbPerSlot * ptrsRePerSymb * 2) ); - } + if ((pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) && (SNR==snr0) && (trial==0) && (round==0)) { + ptrs_symbols = 0; + for (int i = pusch_pdu->start_symbol_index; i < pusch_pdu->start_symbol_index + pusch_pdu->nr_of_symbols; i++) + ptrs_symbols += ((gNB->pusch_vars[UE_id]->ptrs_symbols) >> i) & 1; - for (i = 0; i < available_bits; i++) { - - if(((ulsch_ue->harq_processes[harq_pid]->f[i] == 0) && (gNB->pusch_vars[UE_id]->llr[i] <= 0)) || - ((ulsch_ue->harq_processes[harq_pid]->f[i] == 1) && (gNB->pusch_vars[UE_id]->llr[i] >= 0))) - { - /*if(errors_scrambling == 0) - printf("\x1B[34m" "[frame %d][trial %d]\t1st bit in error in unscrambling = %d\n" "\x1B[0m", frame, trial, i);*/ - errors_scrambling[round][snrRun]++; - } - } - round++; + /* 2*5*(50/2), for RB = 50,K = 2 for 5 OFDM PTRS symbols */ + available_bits -= 2 * ptrs_symbols * ((nb_rb + ptrs_freq_density - 1) /ptrs_freq_density); + printf("[ULSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5d \n",available_bits, (ptrsSymbPerSlot * ptrsRePerSymb * 2) ); + } + + for (i = 0; i < available_bits; i++) { + + if(((ulsch_ue->harq_processes[harq_pid]->f[i] == 0) && (gNB->pusch_vars[UE_id]->llr[i] <= 0)) || + ((ulsch_ue->harq_processes[harq_pid]->f[i] == 1) && (gNB->pusch_vars[UE_id]->llr[i] >= 0))) { + + /*if(errors_scrambling == 0) + printf("\x1B[34m" "[frame %d][trial %d]\t1st bit in error in unscrambling = %d\n" "\x1B[0m", frame, trial, i);*/ + errors_scrambling[round][snrRun]++; + } + } + round++; } // round From cb456a23cc1f60de459d4184725dd64688ea12f0 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Tue, 26 Apr 2022 20:25:53 +0100 Subject: [PATCH 23/49] Fix in atxlev computation in ulsim (the loop should be over nb_antennas_tx and not nb_antennas_rx) and remove wrong sigma_dB computation --- openair1/SIMULATION/NR_PHY/ulsim.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 8b30958131..3d16eeaa2f 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -1224,7 +1224,7 @@ int main(int argc, char **argv) //////////////////////////////////////////////////// tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); txlev_sum = 0; - for (int aa=0; aanb_antennas_rx; aa++) { + for (int aa=0; aanb_antennas_tx; aa++) { atxlev[aa] = signal_energy(&UE->common_vars.txdata[aa][tx_offset + 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); @@ -1279,9 +1279,6 @@ int main(int argc, char **argv) r_im[ap][i] += s_im[aa][i]*H_awgn[ap][aa]; } } - - sigma_dB = 10 * log10((double)atxlev[ap] * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;; - sigma = pow(10,sigma_dB/10); ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); From 7e172e348bc279a2fc26474a3c8d984b7f82937f Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Wed, 27 Apr 2022 11:51:29 +0100 Subject: [PATCH 24/49] Fix from frame_parms->nb_antennas_tx to UE->frame_parms.nb_antennas_tx in ulsim --- openair1/SIMULATION/NR_PHY/ulsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 3d16eeaa2f..6521324bec 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -1224,7 +1224,7 @@ int main(int argc, char **argv) //////////////////////////////////////////////////// tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); txlev_sum = 0; - for (int aa=0; aanb_antennas_tx; aa++) { + for (int aa=0; aaframe_parms.nb_antennas_tx; aa++) { atxlev[aa] = signal_energy(&UE->common_vars.txdata[aa][tx_offset + 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); From 6af3d0a3641907961b0676262fd99407deeec208 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 28 Apr 2022 11:27:27 +0200 Subject: [PATCH 25/49] change in ulsim test to show degradation in performances for 2rx scenario --- cmake_targets/autotests/test_case_list.xml | 4 ++-- openair1/SIMULATION/NR_PHY/ulsim.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 5687810e69..4f564b9dd8 100755 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1306,7 +1306,7 @@ (Test12: SC-FDMA, 216 PRBs), (Test13: SC-FDMA, 273 PRBs), (Test14: SC-FDMA, 3 DMRS), - (Test15: MCS 16 50 PRBs 2 RX_Antenna) + (Test15: MCS 19 50 PRBs 2 RX_Antenna) (Test16: MCS 9 106 PRBs MIMO 2 layers) (Test17: MCS 9 106 PRBs MIMO 4 layers) @@ -1329,7 +1329,7 @@ -n50 -s5 -Z -r216 -R217 -n50 -s5 -Z -r270 -R273 -n100 -s5 -Z -U 2 0 2 - -n100 -m16 -s10 -z2 + -n100 -m19 -s10 -S15 -z2 -n100 -m9 -r106 -s10 -W2 -y2 -z2 -n100 -m9 -r106 -s13 -W4 -y4 -z4 diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 3d16eeaa2f..6521324bec 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -1224,7 +1224,7 @@ int main(int argc, char **argv) //////////////////////////////////////////////////// tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); txlev_sum = 0; - for (int aa=0; aanb_antennas_tx; aa++) { + for (int aa=0; aaframe_parms.nb_antennas_tx; aa++) { atxlev[aa] = signal_energy(&UE->common_vars.txdata[aa][tx_offset + 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); From 99fde7f7cb09c2300e52da699725dff1830dfb4e Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Thu, 28 Apr 2022 11:50:27 +0100 Subject: [PATCH 26/49] Fix some needed debug logs considering the multi-layer case --- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index db05e03d4c..16c58210e4 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -616,22 +616,21 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, #ifdef DEBUG_CH_COMP int16_t *rxF, *ul_ch; int prnt_idx; + for (int nl=0; nlnb_antennas_rx; aarx++) { + rxF = (int16_t *) &rxdataF_ext[aarx][symbol * (off + (nb_rb * 12))]; + ul_ch = (int16_t *) &ul_ch_estimates_ext[nl * frame_parms->nb_antennas_rx + aarx][symbol * (off + (nb_rb * 12))]; - for (int ant=0; antnb_antennas_rx; ant++) { - rxF = (int16_t *)&rxdataF_ext[ant][symbol*(off+(nb_rb*12))]; - ul_ch = (int16_t *)&ul_ch_estimates_ext[ant][symbol*(off+(nb_rb*12))]; - - printf("--------------------symbol = %d, mod_order = %d, output_shift = %d-----------------------\n", symbol, mod_order, output_shift); - printf("----------------Before compensation------------------\n"); - - for (prnt_idx=0;prnt_idx<12*5*2;prnt_idx+=2){ - - printf("rxF[%d] = (%d,%d)\n", prnt_idx>>1, rxF[prnt_idx],rxF[prnt_idx+1]); - printf("ul_ch[%d] = (%d,%d)\n", prnt_idx>>1, ul_ch[prnt_idx],ul_ch[prnt_idx+1]); + printf("--------symbol = %d, mod_order = %d, output_shift = %d, layer %i, antenna rx = %d -----------\n", + symbol, mod_order, output_shift, nl, aarx); + printf("----------------Before compensation------------------\n"); + for (prnt_idx = 0; prnt_idx < 12 * 5 * 2; prnt_idx += 2) { + printf("rxF[%d] = (%d,%d)\n", prnt_idx >> 1, rxF[prnt_idx], rxF[prnt_idx + 1]); + printf("ul_ch[%d] = (%d,%d)\n", prnt_idx >> 1, ul_ch[prnt_idx], ul_ch[prnt_idx + 1]); + } } } - #endif #ifdef DEBUG_CH_MAG @@ -1137,19 +1136,17 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, #ifdef DEBUG_CH_COMP + for (int nl2=0; nl2nb_antennas_rx; aarx2++) { + rxF = (int16_t *)&rxdataF_comp[nl2*frame_parms->nb_antennas_rx+aarx2][(symbol*(off+(nb_rb*12)))]; - for (int ant=0; antnb_antennas_rx; ant++) { - rxF = (int16_t *)&rxdataF_comp[ant][(symbol*(off+(nb_rb*12)))]; - - printf("----------------After compansation------------------\n"); - - for (prnt_idx=0;prnt_idx<12*5*2;prnt_idx+=2){ - - printf("rxF[%d] = (%d,%d)\n", prnt_idx>>1, rxF[prnt_idx],rxF[prnt_idx+1]); + printf("--------After compansation, layer %i, antenna rx %i----------\n", nl2, aarx2); + for (prnt_idx=0;prnt_idx<12*5*2;prnt_idx+=2){ + printf("rxF[%d] = (%d,%d)\n", prnt_idx>>1, rxF[prnt_idx],rxF[prnt_idx+1]); + } } } - #endif #ifdef DEBUG_CH_MAG From 65f09fecb8e6daf48ecba36a80a7a61612ff734b Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Thu, 28 Apr 2022 14:18:05 +0100 Subject: [PATCH 27/49] First code simplification in UL channel estimation --- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 42 ++++++------------- 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index c3360f692e..f2871eef10 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -321,43 +321,27 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, rxF = (int16_t *)&rxdataF[aarx][(soffset+symbol_offset+nushift+re_offset)]; ul_ch+=8; - for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pusch-3); pilot_cnt += 2) { + for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pusch-3); pilot_cnt++) { ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - #ifdef DEBUG_PUSCH - printf("pilot %u : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]); - printf("data %u : rxF - > (%d,%d) (%d)\n",pilot_cnt,rxF[2],rxF[3],dBc(rxF[2],rxF[3])); - #endif - multadd_real_vector_complex_scalar(fm, - ch, - ul_ch, - 8); - pil += 2; - re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(soffset+symbol_offset+nushift+re_offset)]; - //printf("ul_ch addr %p\n",ul_ch); +#ifdef DEBUG_PUSCH + printf("pilot %4u: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d)\n", + pilot_cnt, pil[0], pil[1], rxF[0], rxF[1], ch[0], ch[1]); + //printf("data %4u: rxF -> (%4d,%4d) (%2d)\n",pilot_cnt, rxF[2], rxF[3], dBc(rxF[2], rxF[3])); +#endif - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - - #ifdef DEBUG_PUSCH - printf("pilot %u : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]); - printf("data %u : rxF - > (%d,%d) (%d)\n",pilot_cnt+1,rxF[2],rxF[3],dBc(rxF[2],rxF[3])); - #endif - multadd_real_vector_complex_scalar(fmm, - ch, - ul_ch, - 8); - - //for (int i= 0; i<16; i++) - //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); + if (pilot_cnt%2 == 0) { + multadd_real_vector_complex_scalar(fmm, ch, ul_ch, 8); + ul_ch+=8; + } else { + multadd_real_vector_complex_scalar(fm, ch, ul_ch, 8); + } pil += 2; re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][soffset+(symbol_offset+nushift+re_offset)]; - ul_ch+=8; + rxF = (int16_t *)&rxdataF[aarx][(soffset+symbol_offset+nushift+re_offset)]; } // Treat first 2 pilots specially (right edge) From 4ecb0401e036a48cca294d449681cee49aeb7782 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Thu, 28 Apr 2022 14:34:43 +0100 Subject: [PATCH 28/49] Second code simplification in UL channel estimation --- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 101 ++---------------- 1 file changed, 7 insertions(+), 94 deletions(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index f2871eef10..acf69fbba2 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -227,101 +227,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, //if ((gNB->frame_parms.N_RB_UL&1)==0) { if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1 && gNB->prb_interpolation == 0){ + LOG_D(PHY,"PUSCH estimation DMRS type 1, Freq-domain interpolation"); - // Treat first 2 pilots specially (left edge) - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_PUSCH - LOG_I(PHY, "In %s ch 0 %d\n", __FUNCTION__, ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); - LOG_I(PHY, "In %s pilot 0 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n", - __FUNCTION__, - rxF[0], - rxF[1], - dBc(rxF[0],rxF[1]), - ch[0], - ch[1], - dBc(ch[0],ch[1]), - pil[0], - pil[1]); - LOG_I(PHY, "In %s data 0 : rxF - > (%d,%d) (%d)\n", __FUNCTION__, rxF[2], rxF[3], dBc(rxF[2],rxF[3])); -#endif - - multadd_real_vector_complex_scalar(fl, - ch, - ul_ch, - 8); - pil += 2; - re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(soffset+symbol_offset+nushift+re_offset)]; - //for (int i= 0; i<8; i++) - //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); - - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - -#ifdef DEBUG_PUSCH - LOG_I(PHY, "In %s pilot 1 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n", - __FUNCTION__, - rxF[0], - rxF[1], - dBc(rxF[0],rxF[1]), - ch[0], - ch[1], - dBc(ch[0],ch[1]), - pil[0], - pil[1]); - LOG_I(PHY, "In %s data 1 : rxF - > (%d,%d) (%d)\n", - __FUNCTION__, - rxF[2], - rxF[3], - dBc(rxF[2],rxF[3])); -#endif - - multadd_real_vector_complex_scalar(fml, - ch, - ul_ch, - 8); - pil += 2; - re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(soffset+symbol_offset+nushift+re_offset)]; - //printf("ul_ch addr %p\n",ul_ch); - - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - -#ifdef DEBUG_PUSCH - LOG_I(PHY, "In %s pilot 2 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n", - __FUNCTION__, - rxF[0], - rxF[1], - dBc(rxF[0],rxF[1]), - ch[0], - ch[1], - dBc(ch[0],ch[1]), - pil[0], - pil[1]); - LOG_I(PHY, "In %s data 2 : rxF - > (%d,%d) (%d)\n", - __FUNCTION__, - rxF[2], - rxF[3], - dBc(rxF[2],rxF[3])); -#endif - - multadd_real_vector_complex_scalar(fmm, - ch, - ul_ch, - 8); - - //for (int i= 0; i<16; i++) - //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); - - pil += 2; - re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(soffset+symbol_offset+nushift+re_offset)]; - ul_ch+=8; - - for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pusch-3); pilot_cnt++) { + for (pilot_cnt = 0; pilot_cnt < (6*nb_rb_pusch-3); pilot_cnt++) { ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); @@ -332,7 +241,11 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, //printf("data %4u: rxF -> (%4d,%4d) (%2d)\n",pilot_cnt, rxF[2], rxF[3], dBc(rxF[2], rxF[3])); #endif - if (pilot_cnt%2 == 0) { + if (pilot_cnt == 0) { + multadd_real_vector_complex_scalar(fl, ch, ul_ch, 8); + } else if (pilot_cnt == 1) { + multadd_real_vector_complex_scalar(fml, ch, ul_ch, 8); + } else if (pilot_cnt%2 == 0) { multadd_real_vector_complex_scalar(fmm, ch, ul_ch, 8); ul_ch+=8; } else { From 735b51a06b59228ef41c26ca8ea7e1d1ce133d2a Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Thu, 28 Apr 2022 15:03:26 +0100 Subject: [PATCH 29/49] Third code simplification in UL channel estimation --- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 81 ++++--------------- 1 file changed, 14 insertions(+), 67 deletions(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index acf69fbba2..2e3d9d8c56 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -230,7 +230,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, LOG_D(PHY,"PUSCH estimation DMRS type 1, Freq-domain interpolation"); - for (pilot_cnt = 0; pilot_cnt < (6*nb_rb_pusch-3); pilot_cnt++) { + for (pilot_cnt = 0; pilot_cnt < 6*nb_rb_pusch; pilot_cnt++) { ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); @@ -245,6 +245,11 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, multadd_real_vector_complex_scalar(fl, ch, ul_ch, 8); } else if (pilot_cnt == 1) { multadd_real_vector_complex_scalar(fml, ch, ul_ch, 8); + } else if (pilot_cnt == (6*nb_rb_pusch-2)) { + multadd_real_vector_complex_scalar(fmr, ch, ul_ch, 8); + ul_ch+=8; + } else if (pilot_cnt == (6*nb_rb_pusch-1)) { + multadd_real_vector_complex_scalar(fr, ch, ul_ch, 8); } else if (pilot_cnt%2 == 0) { multadd_real_vector_complex_scalar(fmm, ch, ul_ch, 8); ul_ch+=8; @@ -256,54 +261,6 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(soffset+symbol_offset+nushift+re_offset)]; } - - // Treat first 2 pilots specially (right edge) - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_PUSCH - printf("pilot %u : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]); - printf("data %u : rxF - > (%d,%d) (%d)\n",pilot_cnt,rxF[2],rxF[3],dBc(rxF[2],rxF[3])); -#endif - multadd_real_vector_complex_scalar(fm, - ch, - ul_ch, - 8); - - //for (int i= 0; i<8; i++) - //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); - - pil += 2; - re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][soffset+(symbol_offset+nushift+re_offset)]; - - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_PUSCH - printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); - printf("pilot %u : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]); - printf("data %u : rxF - > (%d,%d) (%d)\n",pilot_cnt+1,rxF[2],rxF[3],dBc(rxF[2],rxF[3])); -#endif - multadd_real_vector_complex_scalar(fmr, - ch, - ul_ch, - 8); - - pil += 2; - re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][soffset+(symbol_offset+nushift+re_offset)]; - ul_ch+=8; - - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_PUSCH - printf("pilot %u: rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]); - printf("data %u : rxF - > (%d,%d) (%d)\n",pilot_cnt+2,rxF[2],rxF[3],dBc(rxF[2],rxF[3])); -#endif - multadd_real_vector_complex_scalar(fr, - ch, - ul_ch, - 8); - // check if PRB crosses DC and improve estimates around DC if ((bwp_start_subcarrier < gNB->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pusch*12 >= gNB->frame_parms.ofdm_symbol_size)) { @@ -323,10 +280,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, // for proper allignment of SIMD vectors if((gNB->frame_parms.N_RB_UL&1)==0) { - multadd_real_vector_complex_scalar(fdcl, - ch, - ul_ch-4, - 8); + multadd_real_vector_complex_scalar(fdcl, ch, ul_ch-4, 8); pil += 4; re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size; @@ -334,16 +288,11 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(fdcr, - ch, - ul_ch-4, - 8); - } - else { - multadd_real_vector_complex_scalar(fdclh, - ch, - ul_ch, - 8); + multadd_real_vector_complex_scalar(fdcr, ch, ul_ch-4, 8); + + } else { + + multadd_real_vector_complex_scalar(fdclh, ch, ul_ch, 8); pil += 4; re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size; @@ -351,12 +300,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(fdcrh, - ch, - ul_ch, - 8); + multadd_real_vector_complex_scalar(fdcrh, ch, ul_ch, 8); } } + #ifdef DEBUG_PUSCH ul_ch = (int16_t *)&ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset]; for(uint16_t idxP=0; idxP Date: Thu, 28 Apr 2022 16:24:21 +0100 Subject: [PATCH 30/49] Improve debug log --- openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 2e3d9d8c56..b55a9694d8 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -307,10 +307,11 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, #ifdef DEBUG_PUSCH ul_ch = (int16_t *)&ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset]; for(uint16_t idxP=0; idxP Date: Thu, 28 Apr 2022 21:04:41 +0100 Subject: [PATCH 31/49] UL channel estimation with a formulation closer to 3GPP, because this will be useful next --- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 106 ++++++++++++------ openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 2 +- 2 files changed, 72 insertions(+), 36 deletions(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index b55a9694d8..5a196a4030 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -76,6 +76,10 @@ void freq2time(uint16_t ofdm_symbol_size, } } +// Table 6.4.1.1.3-1/2 from TS 38.211 +const uint16_t delta1[8] = {0, 0, 1, 1, 0, 0, 1, 1}; +const uint16_t delta2[12] = {0, 0, 2, 2, 4, 4, 0, 0, 2, 2, 4, 4}; + int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, unsigned char Ns, unsigned short p, @@ -86,7 +90,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, int pilot[3280] __attribute__((aligned(16))); unsigned char aarx; - unsigned short k; + unsigned short k0; unsigned int pilot_cnt,re_cnt; int16_t ch[2],ch_r[2],ch_l[2],*pil,*rxF,*ul_ch; int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh; @@ -112,18 +116,18 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, symbol_offset = gNB->frame_parms.ofdm_symbol_size*symbol; - k = bwp_start_subcarrier; + k0 = bwp_start_subcarrier; int re_offset; uint16_t nb_rb_pusch = pusch_pdu->rb_size; - LOG_D(PHY, "In %s: ch_offset %d, soffset %d, symbol_offset %d OFDM size %d, Ns = %d, k = %d symbol %d\n", + LOG_D(PHY, "In %s: ch_offset %d, soffset %d, symbol_offset %d, OFDM size %d, Ns = %d, k0 = %d, symbol %d\n", __FUNCTION__, ch_offset, soffset, symbol_offset, gNB->frame_parms.ofdm_symbol_size, Ns, - k, + k0, symbol); switch (nushift) { @@ -206,60 +210,92 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, } #endif + // Based on Table 6.4.1.1.3-1/2 from TS 38.211 + int delta = 0; + //int deltas[3] = {0}; + //int n_delta = 0; + if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1) { + delta = delta1[p]; + /*if (pusch_pdu->nrOfLayers <= 2) { + n_delta = 1; + } else { + n_delta = 2; + deltas[1] = 1; + }*/ + } else { + delta = delta2[p]; + /*if (pusch_pdu->nrOfLayers <= 2) { + n_delta = 1; + } else if (pusch_pdu->nrOfLayers <= 4) { + n_delta = 2; + deltas[1] = 2; + } else { + n_delta = 3; + deltas[1] = 2; + deltas[2] = 4; + }*/ + } + for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { - re_offset = k; /* Initializing the Resource element offset for each Rx antenna */ - pil = (int16_t *)&pilot[0]; - rxF = (int16_t *)&rxdataF[aarx][(soffset+symbol_offset+k+nushift)]; + rxF = (int16_t *)&rxdataF[aarx][(soffset + symbol_offset + k0 + nushift)]; ul_ch = (int16_t *)&ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset]; - re_offset = k; + re_offset = k0; memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size)); #ifdef DEBUG_PUSCH LOG_I(PHY, "In %s symbol_offset %d, nushift %d\n", __FUNCTION__, symbol_offset, nushift); LOG_I(PHY, "In %s ch est pilot addr %p, N_RB_UL %d\n", __FUNCTION__, &pilot[0], gNB->frame_parms.N_RB_UL); - LOG_I(PHY, "In %s bwp_start_subcarrier %d, k %d, first_carrier %d, nb_rb_pusch %d\n", __FUNCTION__, bwp_start_subcarrier, k, gNB->frame_parms.first_carrier_offset, nb_rb_pusch); + LOG_I(PHY, "In %s bwp_start_subcarrier %d, k0 %d, first_carrier %d, nb_rb_pusch %d\n", __FUNCTION__, bwp_start_subcarrier, k0, gNB->frame_parms.first_carrier_offset, nb_rb_pusch); LOG_I(PHY, "In %s rxF addr %p p %d\n", __FUNCTION__, rxF, p); LOG_I(PHY, "In %s ul_ch addr %p nushift %d\n", __FUNCTION__, ul_ch, nushift); #endif - //if ((gNB->frame_parms.N_RB_UL&1)==0) { if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1 && gNB->prb_interpolation == 0){ LOG_D(PHY,"PUSCH estimation DMRS type 1, Freq-domain interpolation"); - for (pilot_cnt = 0; pilot_cnt < 6*nb_rb_pusch; pilot_cnt++) { + // For configuration type 1: k = 4*n + 2*k' + delta, + // where k' is 0 or 1, and delta is in Table 6.4.1.1.3-1 from TS 38.211 - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + pilot_cnt = 0; + for (int n = 0; n < 3*nb_rb_pusch; n++) { + for (int k_line = 0; k_line <= 1; k_line++) { + + pilot_cnt++; + + re_offset = (k0 + (n<<2) + (k_line<<1) + delta) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(soffset + symbol_offset + re_offset)]; + + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PUSCH - printf("pilot %4u: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d)\n", - pilot_cnt, pil[0], pil[1], rxF[0], rxF[1], ch[0], ch[1]); - //printf("data %4u: rxF -> (%4d,%4d) (%2d)\n",pilot_cnt, rxF[2], rxF[3], dBc(rxF[2], rxF[3])); + printf("pilot %4u: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d)\n", + pilot_cnt, pil[0], pil[1], rxF[0], rxF[1], ch[0], ch[1]); + //printf("data %4u: rxF -> (%4d,%4d) (%2d)\n",pilot_cnt, rxF[2], rxF[3], dBc(rxF[2], rxF[3])); #endif - if (pilot_cnt == 0) { - multadd_real_vector_complex_scalar(fl, ch, ul_ch, 8); - } else if (pilot_cnt == 1) { - multadd_real_vector_complex_scalar(fml, ch, ul_ch, 8); - } else if (pilot_cnt == (6*nb_rb_pusch-2)) { - multadd_real_vector_complex_scalar(fmr, ch, ul_ch, 8); - ul_ch+=8; - } else if (pilot_cnt == (6*nb_rb_pusch-1)) { - multadd_real_vector_complex_scalar(fr, ch, ul_ch, 8); - } else if (pilot_cnt%2 == 0) { - multadd_real_vector_complex_scalar(fmm, ch, ul_ch, 8); - ul_ch+=8; - } else { - multadd_real_vector_complex_scalar(fm, ch, ul_ch, 8); - } + if (pilot_cnt == 0) { + multadd_real_vector_complex_scalar(fl, ch, ul_ch, 8); + } else if (pilot_cnt == 1) { + multadd_real_vector_complex_scalar(fml, ch, ul_ch, 8); + } else if (pilot_cnt == (6*nb_rb_pusch-2)) { + multadd_real_vector_complex_scalar(fmr, ch, ul_ch, 8); + ul_ch+=8; + } else if (pilot_cnt == (6*nb_rb_pusch-1)) { + multadd_real_vector_complex_scalar(fr, ch, ul_ch, 8); + } else if (pilot_cnt%2 == 0) { + multadd_real_vector_complex_scalar(fmm, ch, ul_ch, 8); + ul_ch+=8; + } else { + multadd_real_vector_complex_scalar(fm, ch, ul_ch, 8); + } - pil += 2; - re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(soffset+symbol_offset+nushift+re_offset)]; + pil += 2; + } } // check if PRB crosses DC and improve estimates around DC @@ -267,7 +303,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ul_ch = (int16_t *)&ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset]; uint16_t idxDC = 2*(gNB->frame_parms.ofdm_symbol_size - bwp_start_subcarrier); uint16_t idxPil = idxDC/2; - re_offset = k; + re_offset = k0; pil = (int16_t *)&pilot[0]; pil += (idxPil-2); ul_ch += (idxDC-4); diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 920b78eac2..4a8aaab4cb 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -39,7 +39,7 @@ #include "nr_refsig.h" #include "PHY/defs_gNB.h" -/*Table 7.4.1.1.2-1/2 from 38.211 */ +// Table 6.4.1.1.3-1/2 from TS 38.211 int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1}}; int wt1[8][2] = {{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1}}; int wf2[12][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1}}; From 724e155a3a7d9e7f7467921cd285e1007cb61039 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Thu, 28 Apr 2022 23:57:19 +0100 Subject: [PATCH 32/49] Move UL delta computation for a function --- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 23 ++++++++----------- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 9 ++++++++ openair1/PHY/NR_REFSIG/nr_refsig.h | 2 ++ 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 5a196a4030..633d453494 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -76,10 +76,6 @@ void freq2time(uint16_t ofdm_symbol_size, } } -// Table 6.4.1.1.3-1/2 from TS 38.211 -const uint16_t delta1[8] = {0, 0, 1, 1, 0, 0, 1, 1}; -const uint16_t delta2[12] = {0, 0, 2, 2, 4, 4, 0, 0, 2, 2, 4, 4}; - int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, unsigned char Ns, unsigned short p, @@ -211,20 +207,17 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, #endif // Based on Table 6.4.1.1.3-1/2 from TS 38.211 - int delta = 0; - //int deltas[3] = {0}; - //int n_delta = 0; + /*int deltas[3] = {0}; + int n_delta = 0; if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1) { - delta = delta1[p]; - /*if (pusch_pdu->nrOfLayers <= 2) { + if (pusch_pdu->nrOfLayers <= 2) { n_delta = 1; } else { n_delta = 2; deltas[1] = 1; - }*/ + } } else { - delta = delta2[p]; - /*if (pusch_pdu->nrOfLayers <= 2) { + if (pusch_pdu->nrOfLayers <= 2) { n_delta = 1; } else if (pusch_pdu->nrOfLayers <= 4) { n_delta = 2; @@ -233,8 +226,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, n_delta = 3; deltas[1] = 2; deltas[2] = 4; - }*/ - } + } + }*/ for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { @@ -260,6 +253,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, // For configuration type 1: k = 4*n + 2*k' + delta, // where k' is 0 or 1, and delta is in Table 6.4.1.1.3-1 from TS 38.211 + int delta = nr_pusch_dmrs_delta(pusch_dmrs_type1, p); + pilot_cnt = 0; for (int n = 0; n < 3*nb_rb_pusch; n++) { for (int k_line = 0; k_line <= 1; k_line++) { diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 4a8aaab4cb..4f089562f6 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -40,8 +40,10 @@ #include "PHY/defs_gNB.h" // Table 6.4.1.1.3-1/2 from TS 38.211 +int delta1[8] = {0, 0, 1, 1, 0, 0, 1, 1}; int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1}}; int wt1[8][2] = {{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1}}; +int delta2[12] = {0, 0, 2, 2, 4, 4, 0, 0, 2, 2, 4, 4}; int wf2[12][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1}}; int wt2[12][2] = {{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1}}; @@ -49,6 +51,13 @@ int wt2[12][2] = {{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1 short nr_rx_mod_table[14] = {0,0,23170,-23170,-23170,23170,23170,-23170,23170,23170,-23170,-23170,-23170,23170}; short nr_rx_nmod_table[14] = {0,0,-23170,23170,23170,-23170,-23170,23170,-23170,-23170,23170,23170,23170,-23170}; +int nr_pusch_dmrs_delta(uint8_t dmrs_config_type, unsigned short p) { + if (dmrs_config_type == pusch_dmrs_type1) { + return delta1[p]; + } else { + return delta2[p]; + } +} int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, unsigned int Ns, diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index df3dad1e59..ad632431eb 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -42,6 +42,8 @@ void nr_init_csi_rs(PHY_VARS_gNB* gNB, uint32_t Nid); void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, uint32_t nid); +int nr_pusch_dmrs_delta(uint8_t dmrs_config_type, unsigned short p); + int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, unsigned int Ns, unsigned int *nr_gold_pusch, From 719d7fb8be19a584454334a5d6ff2013dd3feb28 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Fri, 29 Apr 2022 00:51:55 +0100 Subject: [PATCH 33/49] Improvements in UL channel estimation to consider multiple antennas for dmrs type 1 --- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 633d453494..9bc93938ce 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -246,33 +246,41 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, LOG_I(PHY, "In %s ul_ch addr %p nushift %d\n", __FUNCTION__, ul_ch, nushift); #endif - if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1 && gNB->prb_interpolation == 0){ + if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1 && gNB->prb_interpolation == 0) { LOG_D(PHY,"PUSCH estimation DMRS type 1, Freq-domain interpolation"); // For configuration type 1: k = 4*n + 2*k' + delta, // where k' is 0 or 1, and delta is in Table 6.4.1.1.3-1 from TS 38.211 - int delta = nr_pusch_dmrs_delta(pusch_dmrs_type1, p); - pilot_cnt = 0; + for (int n = 0; n < 3*nb_rb_pusch; n++) { + + // LS estimation + ch[0] = 0; + ch[1] = 0; + for (int p2 = 0; p2nrOfLayers; p2+=2) { + int delta2 = nr_pusch_dmrs_delta(pusch_dmrs_type1, p2); + for (int k_line = 0; k_line <= 1; k_line++) { + re_offset = (k0 + (n << 2) + (k_line << 1) + delta2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *) &rxdataF[aarx][(soffset + symbol_offset + re_offset)]; + ch[0] += (int16_t) (((int32_t) pil[0] * rxF[0] - (int32_t) pil[1] * rxF[1]) >> 15); + ch[1] += (int16_t) (((int32_t) pil[0] * rxF[1] + (int32_t) pil[1] * rxF[0]) >> 15); + pil += 2; + } + } + + // Channel interpolation for (int k_line = 0; k_line <= 1; k_line++) { - pilot_cnt++; - - re_offset = (k0 + (n<<2) + (k_line<<1) + delta) % gNB->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(soffset + symbol_offset + re_offset)]; - - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - #ifdef DEBUG_PUSCH + re_offset = (k0 + (n << 2) + (k_line << 1)) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *) &rxdataF[aarx][(soffset + symbol_offset + re_offset)]; printf("pilot %4u: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d)\n", pilot_cnt, pil[0], pil[1], rxF[0], rxF[1], ch[0], ch[1]); //printf("data %4u: rxF -> (%4d,%4d) (%2d)\n",pilot_cnt, rxF[2], rxF[3], dBc(rxF[2], rxF[3])); #endif - if (pilot_cnt == 0) { multadd_real_vector_complex_scalar(fl, ch, ul_ch, 8); } else if (pilot_cnt == 1) { @@ -288,8 +296,6 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, } else { multadd_real_vector_complex_scalar(fm, ch, ul_ch, 8); } - - pil += 2; } } From c128a5d9e298d17e13dd24e63b9fc5e433b1e9c3 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Fri, 29 Apr 2022 01:11:27 +0100 Subject: [PATCH 34/49] Remove SUPPORT_PMI_MATRIC flag --- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 24 +++---------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 16c58210e4..c22fb011f1 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -359,25 +359,15 @@ void nr_ulsch_extract_rbs(int32_t **rxdataF, memcpy1((void*)&rxF_ext[2*neg_length],(void*)rxF,pos_length*sizeof(int32_t)); } - #ifdef SUPPORT_PMI_MATRIC - for (aatx = 0; aatx < pusch_pdu->nrOfLayers; aatx++) - #else - aatx = aarx; - #endif - { + for (aatx = 0; aatx < pusch_pdu->nrOfLayers; aatx++) { ul_ch0 = &pusch_vars->ul_ch_estimates[aatx*frame_parms->nb_antennas_rx+aarx][pusch_vars->dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_re_pusch2]; - memcpy1((void*)ul_ch0_ext,(void*)ul_ch0,nb_re_pusch*sizeof(int32_t)); } } else { - #ifdef SUPPORT_PMI_MATRIC - for (aatx = 0; aatx < pusch_pdu->nrOfLayers; aatx++) - #else - aatx = aarx; - #endif - { + + for (aatx = 0; aatx < pusch_pdu->nrOfLayers; aatx++) { ul_ch0 = &pusch_vars->ul_ch_estimates[aatx*frame_parms->nb_antennas_rx+aarx][pusch_vars->dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_re_pusch2]; @@ -2098,11 +2088,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, - #ifdef SUPPORT_PMI_MATRIC (rel15_ul->nrOfLayers>1) ? gNB->pusch_vars[ulsch_id]->rho : NULL, - #else - NULL, - #endif frame_parms, symbol, nb_re_pusch, @@ -2118,11 +2104,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, gNB->pusch_vars[ulsch_id]->rxdataF_comp, gNB->pusch_vars[ulsch_id]->ul_ch_mag0, gNB->pusch_vars[ulsch_id]->ul_ch_magb0, - #ifdef SUPPORT_PMI_MATRIC (rel15_ul->nrOfLayers>1) ? gNB->pusch_vars[ulsch_id]->rho : NULL, - #else - NULL, - #endif rel15_ul->nrOfLayers, symbol, rel15_ul->rb_size, From e23679431063b42a091f515cec3da3f381b5277b Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Fri, 29 Apr 2022 01:22:33 +0100 Subject: [PATCH 35/49] Put in ulsim a channel matrix H_awgn_mimo different from identity (it is a matrix equal to matrix used in dlsim) --- openair1/SIMULATION/NR_PHY/ulsim.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 6521324bec..b64b4c22c5 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -1260,23 +1260,19 @@ int main(int argc, char **argv) for (i=0; inb_antennas_rx; ap++) { if (channel_model == AWGN) { - double H_awgn[4][4] ={{1.0, 0.0, 0.0, 0.0},//rx 0 - {0.0, 1.0, 0.0, 0.0}, //rx 1 - {0.0, 0.0, 1.0, 0.0}, //rx 2 - {0.0, 0.0, 0.0, 1.0}};//rx 3 - #if 0 - double H_awgn_mimo[4][4] ={{1.0, 0.5, 0.25, 0.125},//rx 0 - {0.5, 1.0, 0.5, 0.25}, //rx 1 - {0.25, 0.5, 1.0, 0.5}, //rx 2 - {0.125, 0.25, 0.5, 1.0}};//rx 3 - #endif + + double H_awgn_mimo[4][4] ={{1.0, 0.2, 0.1, 0.05}, //rx 0 + {0.2, 1.0, 0.2, 0.1}, //rx 1 + {0.1, 0.2, 1.0, 0.2}, //rx 2 + {0.05, 0.1, 0.2, 1.0}}; //rx 3 + // sum up signals from different Tx antennas r_re[ap][i] = 0; r_im[ap][i] = 0; for (int aa=0; aa Date: Fri, 29 Apr 2022 11:00:40 +0100 Subject: [PATCH 36/49] Fix high MCS test fail for UL (it do not fix the degradation yet) --- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 27 +++---------------- 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 9bc93938ce..e180be6604 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -206,28 +206,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, } #endif - // Based on Table 6.4.1.1.3-1/2 from TS 38.211 - /*int deltas[3] = {0}; - int n_delta = 0; - if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1) { - if (pusch_pdu->nrOfLayers <= 2) { - n_delta = 1; - } else { - n_delta = 2; - deltas[1] = 1; - } - } else { - if (pusch_pdu->nrOfLayers <= 2) { - n_delta = 1; - } else if (pusch_pdu->nrOfLayers <= 4) { - n_delta = 2; - deltas[1] = 2; - } else { - n_delta = 3; - deltas[1] = 2; - deltas[2] = 4; - } - }*/ + uint8_t b_shift = pusch_pdu->nrOfLayers < 4 ? 1 : log2_approx(pusch_pdu->nrOfLayers>>1); for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { @@ -265,8 +244,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, for (int k_line = 0; k_line <= 1; k_line++) { re_offset = (k0 + (n << 2) + (k_line << 1) + delta2) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *) &rxdataF[aarx][(soffset + symbol_offset + re_offset)]; - ch[0] += (int16_t) (((int32_t) pil[0] * rxF[0] - (int32_t) pil[1] * rxF[1]) >> 15); - ch[1] += (int16_t) (((int32_t) pil[0] * rxF[1] + (int32_t) pil[1] * rxF[0]) >> 15); + ch[0] += (int16_t) (((int32_t) pil[0] * rxF[0] - (int32_t) pil[1] * rxF[1]) >> (15+b_shift)); + ch[1] += (int16_t) (((int32_t) pil[0] * rxF[1] + (int32_t) pil[1] * rxF[0]) >> (15+b_shift)); pil += 2; } } From 523f8f2139797682971a94a6a1df44bde0e6b4f0 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Fri, 29 Apr 2022 18:19:49 +0100 Subject: [PATCH 37/49] Put pilot_cnt++ in the right place --- openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index e180be6604..720a1e9b50 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -252,7 +252,6 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, // Channel interpolation for (int k_line = 0; k_line <= 1; k_line++) { - pilot_cnt++; #ifdef DEBUG_PUSCH re_offset = (k0 + (n << 2) + (k_line << 1)) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *) &rxdataF[aarx][(soffset + symbol_offset + re_offset)]; @@ -275,6 +274,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, } else { multadd_real_vector_complex_scalar(fm, ch, ul_ch, 8); } + pilot_cnt++; } } From 1694e1b061867837e950c19ae70c54944cc8326d Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Fri, 29 Apr 2022 19:08:41 +0100 Subject: [PATCH 38/49] Fix b_shift --- openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 720a1e9b50..038f1473f9 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -206,7 +206,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, } #endif - uint8_t b_shift = pusch_pdu->nrOfLayers < 4 ? 1 : log2_approx(pusch_pdu->nrOfLayers>>1); + uint8_t b_shift = pusch_pdu->nrOfLayers == 1; for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { From 4f2854f92cd4c834592b21f9248ad5ae37d9753b Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Mon, 2 May 2022 01:55:03 +0100 Subject: [PATCH 39/49] Fix UL channel estimation for 4 layers --- cmake_targets/autotests/test_case_list.xml | 2 +- .../PHY/NR_ESTIMATION/nr_ul_channel_estimation.c | 16 +++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index f372e7230a..14daa644df 100755 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1331,7 +1331,7 @@ -n100 -s5 -Z -U 2 0 2 -n100 -m19 -s10 -S15 -z2 -n100 -m9 -r106 -s10 -W2 -y2 -z2 - -n100 -m9 -r106 -s13 -W4 -y4 -z4 + -n100 -m9 -r106 -s20 -W4 -y4 -z4 nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15 nr_ulsim.test16 nr_ulsim.test17 PUSCH test OK diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 038f1473f9..20575b45d1 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -233,21 +233,19 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, // where k' is 0 or 1, and delta is in Table 6.4.1.1.3-1 from TS 38.211 pilot_cnt = 0; + int delta = nr_pusch_dmrs_delta(pusch_dmrs_type1, p); for (int n = 0; n < 3*nb_rb_pusch; n++) { // LS estimation ch[0] = 0; ch[1] = 0; - for (int p2 = 0; p2nrOfLayers; p2+=2) { - int delta2 = nr_pusch_dmrs_delta(pusch_dmrs_type1, p2); - for (int k_line = 0; k_line <= 1; k_line++) { - re_offset = (k0 + (n << 2) + (k_line << 1) + delta2) % gNB->frame_parms.ofdm_symbol_size; - rxF = (int16_t *) &rxdataF[aarx][(soffset + symbol_offset + re_offset)]; - ch[0] += (int16_t) (((int32_t) pil[0] * rxF[0] - (int32_t) pil[1] * rxF[1]) >> (15+b_shift)); - ch[1] += (int16_t) (((int32_t) pil[0] * rxF[1] + (int32_t) pil[1] * rxF[0]) >> (15+b_shift)); - pil += 2; - } + for (int k_line = 0; k_line <= 1; k_line++) { + re_offset = (k0 + (n << 2) + (k_line << 1) + delta) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *) &rxdataF[aarx][(soffset + symbol_offset + re_offset)]; + ch[0] += (int16_t) (((int32_t) pil[0] * rxF[0] - (int32_t) pil[1] * rxF[1]) >> (15+b_shift)); + ch[1] += (int16_t) (((int32_t) pil[0] * rxF[1] + (int32_t) pil[1] * rxF[0]) >> (15+b_shift)); + pil += 2; } // Channel interpolation From 6b6528cc944be640b19ef0c83fa0522e9ff48f10 Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 2 May 2022 10:41:42 +0200 Subject: [PATCH 40/49] revert H_awgn_mimo in simulator --- targets/ARCH/rfsimulator/simulator.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 38902984b6..127b2975d5 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -705,17 +705,10 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest } else { // no channel modeling - #if 0 double H_awgn_mimo[4][4] ={{1.0, 0.2, 0.1, 0.05}, //rx 0 {0.2, 1.0, 0.2, 0.1}, //rx 1 {0.1, 0.2, 1.0, 0.2}, //rx 2 {0.05, 0.1, 0.2, 1.0}};//rx 3 - #else - double H_awgn_mimo[4][4] ={{1.0, 0.0, 0.0, 0.0},//rx 0 - {0.0, 1.0, 0.0, 0.0},//rx 1 - {0.0, 0.0, 1.0, 0.0},//rx 2 - {0.0, 0.0, 0.0, 1.0}};//rx 3 - #endif sample_t *out=(sample_t *)samplesVoid[a]; int nbAnt_tx = ptr->th.nbAnt;//number of Tx antennas From 5de85671d82fac4aefc666ed9c0c8232f112e228 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Mon, 2 May 2022 16:58:08 +0100 Subject: [PATCH 41/49] Fix heap buffer overflow --- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index c22fb011f1..b11423b083 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -807,21 +807,17 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, int avg_rho_re[frame_parms->nb_antennas_rx][nrOfLayers*nrOfLayers]; int avg_rho_im[frame_parms->nb_antennas_rx][nrOfLayers*nrOfLayers]; - for (aarx=0; aarxnb_antennas_rx; aarx++) - { - for (aatx=0; aatx < nrOfLayers; aatx++) - { - ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; - - for (int atx=0; atx< nrOfLayers; atx++) - { + for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) { + for (aatx=0; aatx < nrOfLayers; aatx++) { + for (int atx=0; atx< nrOfLayers; atx++) { + avg_rho_re[aarx][aatx*nrOfLayers+atx] = 0; avg_rho_im[aarx][aatx*nrOfLayers+atx] = 0; rho128 = (__m128i *)&rho[aarx][aatx*nrOfLayers+atx][symbol*(off+(nb_rb*12))]; + ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; ul_ch128_2 = (__m128i *)&ul_ch_estimates_ext[atx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; - for (rb=0; rb Date: Mon, 2 May 2022 19:07:07 +0100 Subject: [PATCH 42/49] Fix logs in help of ulsim --- openair1/SIMULATION/NR_PHY/ulsim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index b64b4c22c5..e537277f46 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -605,8 +605,8 @@ int main(int argc, char **argv) printf("-u Set the numerology\n"); printf("-w Start PRB for PUSCH\n"); //printf("-x Transmission mode (1,2,6 for the moment)\n"); - printf("-y Number of TX antennas used in eNB\n"); - printf("-z Number of RX antennas used in UE\n"); + printf("-y Number of TX antennas used at UE\n"); + printf("-z Number of RX antennas used at gNB\n"); printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); //printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); printf("-F Input filename (.txt format) for RX conformance testing\n"); From b6a018089b8be24a793a620a0e4b7ff212edc3ae Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Mon, 2 May 2022 23:53:13 +0100 Subject: [PATCH 43/49] Fix in nr_ulsch_extract_rbs --- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 43 ++++++------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index b11423b083..6975eafee1 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -308,31 +308,26 @@ void nr_ulsch_extract_rbs(int32_t **rxdataF, unsigned char symbol, uint8_t is_dmrs_symbol, nfapi_nr_pusch_pdu_t *pusch_pdu, - NR_DL_FRAME_PARMS *frame_parms) -{ + NR_DL_FRAME_PARMS *frame_parms) { unsigned short start_re, re, nb_re_pusch; unsigned char aarx, aatx; uint32_t rxF_ext_index = 0; uint32_t ul_ch0_ext_index = 0; uint32_t ul_ch0_index = 0; - //uint8_t k_prime; - //uint16_t n; int16_t *rxF,*rxF_ext; int *ul_ch0,*ul_ch0_ext; - //uint8_t delta = 0; int soffset = (slot&3)*frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size; #ifdef DEBUG_RB_EXT - printf("--------------------symbol = %d-----------------------\n", symbol); printf("--------------------ch_ext_index = %d-----------------------\n", symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size); - #endif uint8_t is_data_re; start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start + pusch_pdu->bwp_start) * NR_NB_SC_PER_RB)%frame_parms->ofdm_symbol_size; nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size; + #ifdef __AVX2__ int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7); #else @@ -341,18 +336,13 @@ void nr_ulsch_extract_rbs(int32_t **rxdataF, for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { - rxF = (int16_t *)&rxdataF[aarx][soffset+(symbol * frame_parms->ofdm_symbol_size)]; - rxF_ext = (int16_t *)&pusch_vars->rxdataF_ext[aarx][symbol * nb_re_pusch2]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6 + rxF = (int16_t *)&rxdataF[aarx][soffset+(symbol * frame_parms->ofdm_symbol_size)]; + rxF_ext = (int16_t *)&pusch_vars->rxdataF_ext[aarx][symbol * nb_re_pusch2]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6 if (is_dmrs_symbol == 0) { - // - //rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]); if (start_re + nb_re_pusch <= frame_parms->ofdm_symbol_size) { - memcpy1((void*)rxF_ext, - (void*)&rxF[start_re*2], - nb_re_pusch*sizeof(int32_t)); - } - else { + memcpy1((void*)rxF_ext, (void*)&rxF[start_re*2], nb_re_pusch*sizeof(int32_t)); + } else { int neg_length = frame_parms->ofdm_symbol_size-start_re; int pos_length = nb_re_pusch-neg_length; memcpy1((void*)rxF_ext,(void*)&rxF[start_re*2],neg_length*sizeof(int32_t)); @@ -360,28 +350,23 @@ void nr_ulsch_extract_rbs(int32_t **rxdataF, } for (aatx = 0; aatx < pusch_pdu->nrOfLayers; aatx++) { - ul_ch0 = &pusch_vars->ul_ch_estimates[aatx*frame_parms->nb_antennas_rx+aarx][pusch_vars->dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available + ul_ch0 = &pusch_vars->ul_ch_estimates[aatx*frame_parms->nb_antennas_rx+aarx][pusch_vars->dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_re_pusch2]; memcpy1((void*)ul_ch0_ext,(void*)ul_ch0,nb_re_pusch*sizeof(int32_t)); } - } - else { + + } else { for (aatx = 0; aatx < pusch_pdu->nrOfLayers; aatx++) { - ul_ch0 = &pusch_vars->ul_ch_estimates[aatx*frame_parms->nb_antennas_rx+aarx][pusch_vars->dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available + ul_ch0 = &pusch_vars->ul_ch_estimates[aatx*frame_parms->nb_antennas_rx+aarx][pusch_vars->dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*nb_re_pusch2]; - //n = 0; - //k_prime = 0; rxF_ext_index = 0; ul_ch0_ext_index = 0; - ul_ch0_index = 0; - + ul_ch0_index = 0; for (re = 0; re < nb_re_pusch; re++) { - uint16_t k= start_re+re; - + uint16_t k = start_re + re; is_data_re = allowed_xlsch_re_in_dmrs_symbol(k, start_re, frame_parms->ofdm_symbol_size, pusch_pdu->num_dmrs_cdm_grps_no_data, pusch_pdu->dmrs_config_type); - if (++k >= frame_parms->ofdm_symbol_size) { k -= frame_parms->ofdm_symbol_size; } @@ -390,9 +375,9 @@ void nr_ulsch_extract_rbs(int32_t **rxdataF, printf("re = %d, is_dmrs_symbol = %d, symbol = %d\n", re, is_dmrs_symbol, symbol); #endif - /* save only data and respective channel estimates */ + // save only data and respective channel estimates if (is_data_re == 1) { - if (aatx == aarx) { + if (aatx == 0) { rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]); rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]); rxF_ext_index +=2; From e3fd9f7f8cdf907ef14a758e7cddb1e091160e5d Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Tue, 3 May 2022 00:29:44 +0100 Subject: [PATCH 44/49] To use the channel generated by multipath_channel() for single-layer case in ulsim --- openair1/SIMULATION/NR_PHY/ulsim.c | 38 ++++++++++++++++-------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index e537277f46..fc4f916242 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -1251,34 +1251,36 @@ int main(int argc, char **argv) } } - - if (UE2gNB->max_Doppler == 0) - multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials==1)?1:0); - else - multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, 2*slot_length, 0); - - for (i=0; inb_antennas_rx; ap++) { - if (channel_model == AWGN) { - - double H_awgn_mimo[4][4] ={{1.0, 0.2, 0.1, 0.05}, //rx 0 - {0.2, 1.0, 0.2, 0.1}, //rx 1 - {0.1, 0.2, 1.0, 0.2}, //rx 2 - {0.05, 0.1, 0.2, 1.0}}; //rx 3 - + // The multipath_channel() function calculates a channel matrix with only 1's. So the channel rank is 1, and we + // cannot use multi-layer. To solve this issue, for now we use the H_awgn_mimo matrix for multi-layer. + if (precod_nbr_layers == 1) { + if (UE2gNB->max_Doppler == 0) { + multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials==1)?1:0); + } else { + multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, 2*slot_length, 0); + } + } else { + double H_awgn_mimo[4][4] ={{1.0, 0.2, 0.1, 0.05}, //rx 0 + {0.2, 1.0, 0.2, 0.1}, //rx 1 + {0.1, 0.2, 1.0, 0.2}, //rx 2 + {0.05, 0.1, 0.2, 1.0}}; //rx 3 + for (i=0; inb_antennas_rx; ap++) { // sum up signals from different Tx antennas r_re[ap][i] = 0; r_im[ap][i] = 0; - for (int aa=0; aanb_antennas_rx; ap++) { ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); - /* Add phase noise if enabled */ if (pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { phase_noise(ts, &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)], From 2162ba6d82b365afc617f74c82f30ca6cde45323 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Tue, 3 May 2022 10:03:56 +0100 Subject: [PATCH 45/49] Fix sigma in ulsim --- openair1/SIMULATION/NR_PHY/ulsim.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index fc4f916242..c22ff82be6 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -1237,7 +1237,9 @@ int main(int argc, char **argv) n_trials = 1; if (input_fd == NULL) { - sigma_dB = 10 * log10((double)txlev_sum * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;; + // Justification of division by precod_nbr_layers: + // When the channel is the identity matrix, the results in terms of SNR should be almost equal for 2x2 and 4x4. + sigma_dB = 10 * log10((double)txlev_sum/precod_nbr_layers * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;; sigma = pow(10,sigma_dB/10); From cfa37e721329932bdcb864ab940f3871342b35f6 Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 3 May 2022 12:21:47 +0200 Subject: [PATCH 46/49] cosmetic changes --- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 75 +++++++------------ openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 6 +- openair1/SIMULATION/NR_PHY/ulschsim.c | 2 - openair1/SIMULATION/NR_PHY/ulsim.c | 6 +- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 16 ++-- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 2 - .../NR_MAC_gNB/gNB_scheduler_primitives.c | 4 - 7 files changed, 35 insertions(+), 76 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 6975eafee1..5066316e62 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -478,17 +478,14 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, int off = 0; #endif - for (aatx = 0; aatx < nrOfLayers; aatx++) - { - for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) - { + for (aatx = 0; aatx < nrOfLayers; aatx++) { + for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { //clear average level avg128U = _mm_setzero_si128(); ul_ch128=(__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; - for (rb = 0; rb < nb_rb_0; rb++) - { + for (rb = 0; rb < nb_rb_0; rb++) { avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[0], ul_ch128[0]), x)); avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[1], ul_ch128[1]), x)); avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[2], ul_ch128[2]), x)); @@ -499,10 +496,9 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, ((int32_t*)&avg128U)[1] + ((int32_t*)&avg128U)[2] + ((int32_t*)&avg128U)[3]) / y; - } } - + _mm_empty(); _m_empty(); @@ -637,23 +633,19 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, QAM_amp128b = _mm_setzero_si128(); uint32_t nb_rb_0 = length/12 + ((length%12)?1:0); - for (aatx=0; aatxnb_antennas_rx; aarx++) - { + for (aarx=0; aarxnb_antennas_rx; aarx++) { ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; ul_ch_mag128 = (__m128i *)&ul_ch_mag[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; ul_ch_mag128b = (__m128i *)&ul_ch_magb[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; @@ -661,10 +653,8 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, rxdataF_comp128 = (__m128i *)&rxdataF_comp[aatx*frame_parms->nb_antennas_rx+aarx][symbol*(off+(nb_rb*12))]; - for (rb=0; rb2) - { + for (rb=0; rb2) { // get channel amplitude if not QPSK //print_shorts("ch:",(int16_t*)&ul_ch128[0]); @@ -1164,8 +1154,7 @@ void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, int off = 0; #endif - if (n_rx > 1) - { + if (n_rx > 1) { #if defined(__x86_64__) || defined(__i386__) for (int aatx=0; aatxnb_antennas_rx][(symbol*(nb_re + off))]; ul_ch_mag128b[0] = (__m128i *)&ul_ch_magb[aatx*frame_parms->nb_antennas_rx][(symbol*(nb_re + off))]; - for (int aa=1;aa < n_rx;aa++) - { + for (int aa=1;aa < n_rx;aa++) { rxdataF_comp128[1] = (__m128i *)&rxdataF_comp[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))]; ul_ch_mag128[1] = (__m128i *)&ul_ch_mag[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))]; ul_ch_mag128b[1] = (__m128i *)&ul_ch_magb[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))]; // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) - for (i=0; iulsch_channel_estimation_stats); - for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) - { + for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) { uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01; LOG_D(PHY, "symbol %d, dmrs_symbol_flag :%d\n", symbol, dmrs_symbol_flag); - if (dmrs_symbol_flag == 1) - { + if (dmrs_symbol_flag == 1) { if (gNB->pusch_vars[ulsch_id]->dmrs_symbol == INVALID_VALUE) gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol; - for (int nl=0; nlnrOfLayers; nl++) - { + for (int nl=0; nlnrOfLayers; nl++) { nr_pusch_channel_estimation(gNB, slot, @@ -1984,29 +1968,24 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, #endif uint32_t rxdataF_ext_offset = 0; - for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) - { + for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) { uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01; - if (dmrs_symbol_flag == 1) - { + if (dmrs_symbol_flag == 1) { if ((rel15_ul->ul_dmrs_symb_pos >> ((symbol + 1) % frame_parms->symbols_per_slot)) & 0x01) AssertFatal(1==0,"Double DMRS configuration is not yet supported\n"); gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol; - if (rel15_ul->dmrs_config_type == 0) - { + if (rel15_ul->dmrs_config_type == 0) { // if no data in dmrs cdm group is 1 only even REs have no data // if no data in dmrs cdm group is 2 both odd and even REs have no data nb_re_pusch = rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*6)); } - else - { + else { nb_re_pusch = rel15_ul->rb_size *(12 - (rel15_ul->num_dmrs_cdm_grps_no_data*4)); } } - else - { + else { nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB; } @@ -2016,8 +1995,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, //---------------------------------------------------------- //--------------------- RBs extraction --------------------- //---------------------------------------------------------- - if (nb_re_pusch > 0) - { + if (nb_re_pusch > 0) { start_meas(&gNB->ulsch_rbs_extraction_stats); nr_ulsch_extract_rbs(gNB->common_vars.rxdataF, gNB->pusch_vars[ulsch_id], @@ -2104,8 +2082,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, nb_re_pusch); stop_meas(&gNB->ulsch_mrc_stats); - if (rel15_ul->transformPrecoder == transformPrecoder_enabled) - { + if (rel15_ul->transformPrecoder == transformPrecoder_enabled) { #ifdef __AVX2__ // For odd number of resource blocks need byte alignment to multiple of 8 int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7); @@ -2123,8 +2100,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, //---------------------------------------------------------- /* In case PTRS is enabled then LLR will be calculated after PTRS symbols are processed * * otherwise LLR are calculated for each symbol based upon DMRS channel estimates only. */ - if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) - { + if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { start_meas(&gNB->ulsch_ptrs_processing_stats); nr_pusch_ptrs_processing(gNB, frame_parms, @@ -2143,8 +2119,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, /*-------------------- LLRs computation -------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------------------------*/ start_meas(&gNB->ulsch_llr_stats); - for (aatx=0; aatx < rel15_ul->nrOfLayers; aatx++) - { + for (aatx=0; aatx < rel15_ul->nrOfLayers; aatx++) { nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aatx*frame_parms->nb_antennas_rx][symbol * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)], gNB->pusch_vars[ulsch_id]->ul_ch_mag0[aatx*frame_parms->nb_antennas_rx], gNB->pusch_vars[ulsch_id]->ul_ch_magb0[aatx*frame_parms->nb_antennas_rx], diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 114d1a424b..8243d8b0c9 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -283,12 +283,10 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, AssertFatal(ue->CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN); - + for(int i=0; i< ue->frame_parms.nb_antennas_tx; ++i) - { memset(ue->common_vars.txdataF[i], 0, sizeof(int)*14*ue->frame_parms.ofdm_symbol_size); - } - + LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx); start_meas(&ue->phy_proc_tx); diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index d76d438446..1eaeb6139b 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -444,9 +444,7 @@ int main(int argc, char **argv) NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[0][0]; if ((Nl==4)||(Nl==3)) - { nb_re_dmrs = nb_re_dmrs*2; - } mod_order = nr_get_Qm_ul(Imcs, 0); code_rate = nr_get_code_rate_ul(Imcs, 0); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index c22ff82be6..4d271b4d1d 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -1359,8 +1359,7 @@ int main(int argc, char **argv) LOG_M("rxsigF0_llrlayers0.m","rxsF0_llrlayers0", &gNB->pusch_vars[0]->llr_layers[0][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0); - if (precod_nbr_layers==2) - { + if (precod_nbr_layers==2) { LOG_M("rxsigF1_ext.m","rxsF1_ext", &gNB->pusch_vars[0]->rxdataF_ext[1][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); @@ -1379,8 +1378,7 @@ int main(int argc, char **argv) } - if (precod_nbr_layers==4) - { + if (precod_nbr_layers==4) { LOG_M("rxsigF1_ext.m","rxsF1_ext", &gNB->pusch_vars[0]->rxdataF_ext[1][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1); LOG_M("rxsigF2_ext.m","rxsF2_ext", diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index c70044ddeb..3201b51d30 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -231,8 +231,7 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con if (n_antenna_port == 1); // 1 antenna port and the higher layer parameter txConfig = codebook 0 bits - if (n_antenna_port == 4) - { // 4 antenna port and the higher layer parameter txConfig = codebook + if (n_antenna_port == 4) { // 4 antenna port and the higher layer parameter txConfig = codebook // Table 7.3.1.1.2-2: transformPrecoder=disabled and maxRank = 2 or 3 or 4 if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) @@ -259,8 +258,7 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con // Table 7.3.1.1.2-3: transformPrecoder= enabled, or transformPrecoder=disabled and maxRank = 1 if (((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled)) - && (*pusch_Config->maxRank == 1)) - { + && (*pusch_Config->maxRank == 1)) { if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][6]; @@ -279,11 +277,10 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con } } - if (n_antenna_port == 2) - { // 2 antenna port and the higher layer parameter txConfig = codebook + if (n_antenna_port == 2) { + // 2 antenna port and the higher layer parameter txConfig = codebook // Table 7.3.1.1.2-4: transformPrecoder=disabled and maxRank = 2 - if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (*pusch_Config->maxRank == 2)) - { + if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (*pusch_Config->maxRank == 2)) { if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][12]; pusch_config_pdu->Tpmi = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][13]; @@ -299,8 +296,7 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con // Table 7.3.1.1.2-5: transformPrecoder= enabled, or transformPrecoder= disabled and maxRank = 1 if (((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled)) - && (*pusch_Config->maxRank == 1)) - { + && (*pusch_Config->maxRank == 1)) { if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][16]; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 55bcec0de6..9df3a5e397 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -459,9 +459,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0; uint8_t num_dmrs_cdm_grps_no_data = 1; if ((target_ul_Nl==4)||(target_ul_Nl==3)) - { num_dmrs_cdm_grps_no_data = 2; - } /* we want to avoid a lengthy deduction of DMRS and other parameters in * every TTI if we can save it, so check whether dci_format, TDA, or diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index c40caa7316..d426bc69c7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -1011,13 +1011,9 @@ void config_uldci(const NR_SIB1_t *sib1, } dci_pdu_rel15->precoding_information.val= 0; if (pusch_pdu->nrOfLayers == 2) - { dci_pdu_rel15->precoding_information.val = 4; - } else if (pusch_pdu->nrOfLayers == 4) - { dci_pdu_rel15->precoding_information.val = 11; - } // antenna_ports.val = 0 for transform precoder is disabled, dmrs-Type=1, maxLength=1, Rank=1/2/3/4 // Antenna Ports From 7aa3bfaa54bc9e9c1d8d8d3033918c2d60a9e8d6 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Tue, 3 May 2022 18:25:57 +0100 Subject: [PATCH 47/49] Revert deleted rfdevice.trx_end_func() --- executables/nr-softmodem.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index a9214535d3..7ec316ccd1 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -848,6 +848,9 @@ int main( int argc, char **argv ) { // *** Handle per CC_id openair0 for(ru_id=0; ru_idrfdevice.trx_end_func) + RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); + if (RC.ru[ru_id]->ifdevice.trx_end_func) RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); } From f2974b431b12f78274c175da04e090c07a13c89f Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Tue, 3 May 2022 19:25:14 +0100 Subject: [PATCH 48/49] Revert transformPrecoder to transform_precoding --- .../nfapi/public_inc/fapi_nr_ue_interface.h | 2 +- .../nfapi/public_inc/nfapi_nr_interface_scf.h | 2 +- nfapi/open-nFAPI/nfapi/src/nfapi_p7.c | 4 ++-- .../PHY/NR_ESTIMATION/nr_ul_channel_estimation.c | 2 +- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 10 +++++----- openair1/SIMULATION/NR_PHY/ulsim.c | 16 ++++++++-------- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 16 ++++++++-------- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 4 ++-- .../LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c | 6 +++--- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 6 +++--- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 +- 12 files changed, 36 insertions(+), 36 deletions(-) diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 01f3847bb2..fcc243f5cd 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -305,7 +305,7 @@ typedef struct uint8_t qam_mod_order; uint8_t mcs_index; uint8_t mcs_table; - uint8_t transformPrecoder; + uint8_t transform_precoding; uint16_t data_scrambling_id; uint8_t nrOfLayers; uint8_t Tpmi; diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index cfa8022526..c3a173758c 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -1210,7 +1210,7 @@ typedef struct uint8_t qam_mod_order; uint8_t mcs_index; uint8_t mcs_table; - uint8_t transformPrecoder; + uint8_t transform_precoding; uint16_t data_scrambling_id; uint8_t nrOfLayers; //DMRS diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c index 4d479da1b0..3adde23e7d 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -947,7 +947,7 @@ static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, ui push8(pusch_pdu->qam_mod_order, ppWritePackedMsg, end) && push8(pusch_pdu->mcs_index, ppWritePackedMsg, end) && push8(pusch_pdu->mcs_table, ppWritePackedMsg, end) && - push8(pusch_pdu->transformPrecoder, ppWritePackedMsg, end) && + push8(pusch_pdu->transform_precoding, ppWritePackedMsg, end) && push16(pusch_pdu->data_scrambling_id, ppWritePackedMsg, end) && push8(pusch_pdu->nrOfLayers, ppWritePackedMsg, end) && push16(pusch_pdu->ul_dmrs_symb_pos, ppWritePackedMsg, end) && @@ -4481,7 +4481,7 @@ static uint8_t unpack_ul_tti_request_pusch_pdu(void *tlv, uint8_t **ppReadPacked pull8(ppReadPackedMsg, &pusch_pdu->qam_mod_order, end) && pull8(ppReadPackedMsg, &pusch_pdu->mcs_index, end) && pull8(ppReadPackedMsg, &pusch_pdu->mcs_table, end) && - pull8(ppReadPackedMsg, &pusch_pdu->transformPrecoder, end) && + pull8(ppReadPackedMsg, &pusch_pdu->transform_precoding, end) && pull16(ppReadPackedMsg, &pusch_pdu->data_scrambling_id, end) && pull8(ppReadPackedMsg, &pusch_pdu->nrOfLayers, end) && pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_symb_pos, end) && diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 20575b45d1..9e2b3d2d4e 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -169,7 +169,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, gNB->pusch_gold_init[pusch_pdu->scid] = pusch_pdu->ul_dmrs_scrambling_id; nr_gold_pusch(gNB, pusch_pdu->scid, pusch_pdu->ul_dmrs_scrambling_id); } - if (pusch_pdu->transformPrecoder == transformPrecoder_disabled) { + if (pusch_pdu->transform_precoding == transformPrecoder_disabled) { nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], (1000+p), 0, nb_rb_pusch, (pusch_pdu->bwp_start + pusch_pdu->rb_start)*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type); } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 5066316e62..e81ef00cac 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -2082,7 +2082,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, nb_re_pusch); stop_meas(&gNB->ulsch_mrc_stats); - if (rel15_ul->transformPrecoder == transformPrecoder_enabled) { + if (rel15_ul->transform_precoding == transformPrecoder_enabled) { #ifdef __AVX2__ // For odd number of resource blocks need byte alignment to multiple of 8 int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index e4b6dbcc1d..450805a26c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -282,7 +282,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /// Transform-coded "y"-sequences (for definition see 38-211 V15.3.0 2018-09, subsection 6.3.1.4) int32_t y[max_num_re] __attribute__ ((aligned(16))); - if (pusch_pdu->transformPrecoder == transformPrecoder_enabled) { + if (pusch_pdu->transform_precoding == transformPrecoder_enabled) { uint32_t nb_re_pusch=nb_rb * NR_NB_SC_PER_RB; uint32_t y_offset = 0; @@ -377,7 +377,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, if ((ul_dmrs_symb_pos >> l) & 0x01) { is_dmrs_sym = 1; - if (pusch_pdu->transformPrecoder == transformPrecoder_disabled){ + if (pusch_pdu->transform_precoding == transformPrecoder_disabled){ if (dmrs_type == pusch_dmrs_type1) dmrs_idx = (pusch_pdu->bwp_start + start_rb)*6; @@ -393,7 +393,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, } } else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { - AssertFatal(pusch_pdu->transformPrecoder == transformPrecoder_disabled, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); + AssertFatal(pusch_pdu->transform_precoding == transformPrecoder_disabled, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) { is_ptrs_sym = 1; @@ -424,7 +424,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, if (is_dmrs == 1) { // if transform precoding is enabled - if (pusch_pdu->transformPrecoder == transformPrecoder_enabled) { + if (pusch_pdu->transform_precoding == transformPrecoder_enabled) { ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15; ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15; } else { @@ -448,7 +448,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15; ptrs_idx++; } else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) { - if (pusch_pdu->transformPrecoder == transformPrecoder_disabled) { + if (pusch_pdu->transform_precoding == transformPrecoder_disabled) { ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = ((int16_t *)tx_layers[nl])[m<<1]; ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = ((int16_t *)tx_layers[nl])[(m<<1) + 1]; } diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 4d271b4d1d..fc44e993bb 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -323,7 +323,7 @@ int main(int argc, char **argv) uint16_t ptrsSymbPerSlot = 0; uint16_t ptrsRePerSymb = 0; - uint8_t transformPrecoder = transformPrecoder_disabled; // 0 - ENABLE, 1 - DISABLE + uint8_t transform_precoding = transformPrecoder_disabled; // 0 - ENABLE, 1 - DISABLE uint8_t num_dmrs_cdm_grps_no_data = 1; uint8_t mcs_table = 0; @@ -581,10 +581,10 @@ int main(int argc, char **argv) break; case 'Z': - transformPrecoder = transformPrecoder_enabled; + transform_precoding = transformPrecoder_enabled; num_dmrs_cdm_grps_no_data = 2; mcs_table = 3; - printf("NOTE: TRANSFORM PRECODING (SC-FDMA) is ENABLED in UPLINK (0 - ENABLE, 1 - DISABLE) : %d \n", transformPrecoder); + printf("NOTE: TRANSFORM PRECODING (SC-FDMA) is ENABLED in UPLINK (0 - ENABLE, 1 - DISABLE) : %d \n", transform_precoding); break; default: @@ -879,7 +879,7 @@ int main(int argc, char **argv) if ((UE->frame_parms.nb_antennas_tx==4)&&(precod_nbr_layers==4)) num_dmrs_cdm_grps_no_data = 2; - if (transformPrecoder == transformPrecoder_enabled) { + if (transform_precoding == transformPrecoder_enabled) { AssertFatal(enable_ptrs == 0, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); @@ -1084,7 +1084,7 @@ int main(int argc, char **argv) pusch_pdu->mcs_table = mcs_table; pusch_pdu->target_code_rate = code_rate; pusch_pdu->qam_mod_order = mod_order; - pusch_pdu->transformPrecoder = transformPrecoder; + pusch_pdu->transform_precoding = transform_precoding; pusch_pdu->data_scrambling_id = *scc->physCellId; pusch_pdu->nrOfLayers = precod_nbr_layers; pusch_pdu->ul_dmrs_symb_pos = l_prime_mask; @@ -1111,7 +1111,7 @@ int main(int argc, char **argv) pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0; // if transform precoding is enabled - if (transformPrecoder == transformPrecoder_enabled) { + if (transform_precoding == transformPrecoder_enabled) { pusch_pdu->dfts_ofdm.low_papr_group_number = *scc->physCellId % 30; // U as defined in 38.211 section 6.4.1.1.1.2 pusch_pdu->dfts_ofdm.low_papr_sequence_number = 0; // V as defined in 38.211 section 6.4.1.1.1.2 @@ -1171,10 +1171,10 @@ int main(int argc, char **argv) ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t)); ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0; - ul_config.ul_config_list[0].pusch_config_pdu.transformPrecoder = transformPrecoder; + ul_config.ul_config_list[0].pusch_config_pdu.transform_precoding = transform_precoding; // if transform precoding is enabled - if (transformPrecoder == transformPrecoder_enabled) { + if (transform_precoding == transformPrecoder_enabled) { ul_config.ul_config_list[0].pusch_config_pdu.dfts_ofdm.low_papr_group_number = *scc->physCellId % 30;// U as defined in 38.211 section 6.4.1.1.1.2 ul_config.ul_config_list[0].pusch_config_pdu.dfts_ofdm.low_papr_sequence_number = 0;// V as defined in 38.211 section 6.4.1.1.1.2 diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 3201b51d30..868db25463 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -216,7 +216,7 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con else transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled; } - pusch_config_pdu->transformPrecoder = transformPrecoder; + pusch_config_pdu->transform_precoding = transformPrecoder; /* PRECOD_NBR_LAYERS */ if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_nonCodebook)); @@ -656,7 +656,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->scid = 0; // Transform precoding according to 6.1.3 UE procedure for applying transform precoding on PUSCH in 38.214 - pusch_config_pdu->transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, NULL, NR_RNTI_TC, 0); // TBR fix rnti and take out + pusch_config_pdu->transform_precoding = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, NULL, NR_RNTI_TC, 0); // TBR fix rnti and take out // Resource allocation in frequency domain according to 6.1.2.2 in TS 38.214 pusch_config_pdu->resource_alloc = (mac->cg) ? pusch_Config->resourceAllocation : 1; @@ -702,7 +702,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, /* Transform precoding */ if (rnti_type != NR_RNTI_CS || (rnti_type == NR_RNTI_CS && dci->ndi == 1)) { - pusch_config_pdu->transformPrecoder = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, dci_format, rnti_type, 0); + pusch_config_pdu->transform_precoding = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, dci_format, rnti_type, 0); } /*DCI format-related configuration*/ @@ -743,7 +743,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, /* TRANSFORM PRECODING ------------------------------------------------------------------------------------------*/ - if (pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) { + if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled) { pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; @@ -796,7 +796,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->mcs_index = dci->mcs; /* MCS TABLE */ - if (pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) { + if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) { pusch_config_pdu->mcs_table = get_pusch_mcs_table(pusch_Config ? pusch_Config->mcs_Table : NULL, 0, *dci_format, rnti_type, target_ss, false); } else { pusch_config_pdu->mcs_table = get_pusch_mcs_table(pusch_Config ? pusch_Config->mcs_TableTransformPrecoder : NULL, 1, *dci_format, rnti_type, target_ss, false); @@ -831,12 +831,12 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, mappingtype, add_pos, dmrslength, pusch_config_pdu->start_symbol_index, mac->scc ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position); - if (mac->ULbwp[0] && pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) { + if (mac->ULbwp[0] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) { if (*dci_format != NR_UL_DCI_FORMAT_0_1) { pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1; } } - else if (*dci_format == NR_UL_DCI_FORMAT_0_0 || (mac->ULbwp[0] && pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled)) + else if (*dci_format == NR_UL_DCI_FORMAT_0_0 || (mac->ULbwp[0] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled)) pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; // Num PRB Overhead from PUSCH-ServingCellConfig @@ -857,7 +857,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup && mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB && mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) { - if (pusch_config_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) { + if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) { nfapi_nr_ue_ptrs_ports_t ptrs_ports_list; pusch_config_pdu->pusch_ptrs.ptrs_ports_list = &ptrs_ports_list; valid_ptrs_setup = set_ul_ptrs_values(mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index c9a22b92c2..9a651293b2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1058,9 +1058,9 @@ void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, pusch_pdu->cyclic_prefix = 0; pusch_pdu->mcs_table = 0; if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) - pusch_pdu->transformPrecoder = 1; + pusch_pdu->transform_precoding = 1; else - pusch_pdu->transformPrecoder = 0; + pusch_pdu->transform_precoding = 0; pusch_pdu->data_scrambling_id = *scc->physCellId; pusch_pdu->nrOfLayers = 1; pusch_pdu->ul_dmrs_symb_pos = get_l_prime(nr_of_symbols,mappingtype,pusch_dmrs_pos2,pusch_len1,start_symbol_index, scc->dmrs_TypeA_Position); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index d426bc69c7..728948ba53 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -687,11 +687,11 @@ void nr_set_pusch_semi_static(const NR_SIB1_t *sib1, ps->pusch_Config = ubwp && ubwp->bwp_Dedicated && ubwp->bwp_Dedicated->pusch_Config ? ubwp->bwp_Dedicated->pusch_Config->choice.setup : (ubwpd ? ubwpd->pusch_Config->choice.setup : NULL); if (ps->pusch_Config == NULL || !ps->pusch_Config->transformPrecoder) - ps->transformPrecoder = !scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder; + ps->transform_precoding = !scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder; else - ps->transformPrecoder = *ps->pusch_Config->transformPrecoder; + ps->transform_precoding = *ps->pusch_Config->transformPrecoder; const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - if (ps->transformPrecoder) + if (ps->transform_precoding) ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config ? ps->pusch_Config->mcs_Table : NULL, 0, ps->dci_format, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 4061590f6e..4fba22a0c0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1794,7 +1794,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) pusch_pdu->qam_mod_order = sched_pusch->Qm; pusch_pdu->mcs_index = sched_pusch->mcs; pusch_pdu->mcs_table = ps->mcs_table; - pusch_pdu->transformPrecoder = ps->transformPrecoder; + pusch_pdu->transform_precoding = ps->transform_precoding; if (ps->pusch_Config && ps->pusch_Config->dataScramblingIdentityPUSCH) pusch_pdu->data_scrambling_id = *ps->pusch_Config->dataScramblingIdentityPUSCH; else @@ -1805,7 +1805,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) /* FAPI: DMRS */ pusch_pdu->ul_dmrs_symb_pos = ps->ul_dmrs_symb_pos; pusch_pdu->dmrs_config_type = ps->dmrs_config_type; - if (pusch_pdu->transformPrecoder) { // transform precoding disabled + if (pusch_pdu->transform_precoding) { // transform precoding disabled long *scramblingid=NULL; if (ps->NR_DMRS_UplinkConfig && pusch_pdu->scid == 0) scramblingid = ps->NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0; @@ -1852,7 +1852,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) LOG_D(NR_MAC,"PUSCH PDU : data_scrambling_identity %x, dmrs_scrambling_id %x\n",pusch_pdu->data_scrambling_id,pusch_pdu->ul_dmrs_scrambling_id); /* TRANSFORM PRECODING --------------------------------------------------------*/ - if (pusch_pdu->transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled){ + if (pusch_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled){ // U as specified in section 6.4.1.1.1.2 in 38.211, if sequence hopping and group hopping are disabled pusch_pdu->dfts_ofdm.low_papr_group_number = pusch_pdu->pusch_identity % 30; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 4b55c70d1e..051f5927ec 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -350,7 +350,7 @@ typedef struct NR_pusch_semi_static_t { int nrOfSymbols; NR_PUSCH_Config_t *pusch_Config; - uint8_t transformPrecoder; + uint8_t transform_precoding; uint8_t mcs_table; long mapping_type; From d7795c9dffe91fb81509c11a6f2dcec921b3f735 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Fri, 6 May 2022 16:15:43 +0100 Subject: [PATCH 49/49] Fix build after merge --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index a8ee9f4b98..be3c2beb26 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2878,6 +2878,7 @@ void nr_mac_update_timers(module_id_t module_id, int dci_format = get_dci_format(sched_ctrl); const uint8_t num_dmrs_cdm_grps_no_data = (ubwp || ubwpd) ? 1 : 2; + const uint8_t nrOfLayers = 1; const int utda = ubwp && preferred_ul_tda[ubwp->bwp_Id][slot] >= 0 ? preferred_ul_tda[ubwp->bwp_Id][slot] : (ups->time_domain_allocation >= 0 ? ups->time_domain_allocation : 0); @@ -2888,6 +2889,7 @@ void nr_mac_update_timers(module_id_t module_id, dci_format, utda, num_dmrs_cdm_grps_no_data, + nrOfLayers, ups); } }