From a07a830a0fcabf08e4c831cb1a7f9ac6a7080022 Mon Sep 17 00:00:00 2001 From: Thomas Dreibholz Date: Tue, 3 Mar 2020 10:26:14 +0100 Subject: [PATCH 01/25] Check result of openair0_device_load() and exit when loading the device fails. --- targets/RT/USER/lte-ru.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index f88d98536d..aa359b28a9 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -2342,7 +2342,11 @@ void init_RU_proc(RU_t *ru) { init_frame_parms(ru->frame_parms,1); ru->frame_parms->nb_antennas_rx = ru->nb_rx; phy_init_RU(ru); - openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); + ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); + if (ret < 0) { + LOG_I(PHY,"Exiting, cannot load device\n"); + exit(1); + } if (setup_RU_buffers(ru)!=0) { printf("Exiting, cannot initialize RU Buffers\n"); From 04789ff9f50c2250707280bfa588b2360a082884 Mon Sep 17 00:00:00 2001 From: Thomas Dreibholz Date: Tue, 3 Mar 2020 10:37:38 +0100 Subject: [PATCH 02/25] Made error message more informative. --- targets/RT/USER/lte-ru.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index aa359b28a9..43cb414bd3 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -2344,7 +2344,7 @@ void init_RU_proc(RU_t *ru) { phy_init_RU(ru); ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); if (ret < 0) { - LOG_I(PHY,"Exiting, cannot load device\n"); + LOG_I(PHY,"Exiting, cannot load device. Make sure that your SDR board is connected!\n"); exit(1); } From 34c118c03e75059b0c6fd5207c403eec708e63ec Mon Sep 17 00:00:00 2001 From: Thomas Dreibholz Date: Tue, 3 Mar 2020 10:29:29 +0100 Subject: [PATCH 03/25] Error should create a log entry, not use printf(). --- targets/RT/USER/lte-ru.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 43cb414bd3..fa08d96b5f 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -2349,8 +2349,8 @@ void init_RU_proc(RU_t *ru) { } if (setup_RU_buffers(ru)!=0) { - printf("Exiting, cannot initialize RU Buffers\n"); - exit(-1); + LOG_I(PHY,"Exiting, cannot initialize RU Buffers\n"); + exit(1); } } From a51dc94e8bed5a8cf6839ced6bbddceb5e9374cc Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 3 Mar 2020 19:18:49 +0100 Subject: [PATCH 04/25] Set correct UE ID in Kenb Refresh Req NAS triggered the Kenb Refresh Req always for (hardcoded) UE 0. This fixes this by setting the correct UE ID. An effect of this was that the Kenb would always be set for UE 0, regardless for which UE it was actually intended. This led for integrity check failures for every UE with ID > 0. --- openair3/NAS/UE/EMM/SecurityModeControl.c | 2 +- openair3/NAS/UE/nas_itti_messaging.c | 4 ++-- openair3/NAS/UE/nas_itti_messaging.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c index 7bdd21572e..67bfaf784e 100644 --- a/openair3/NAS/UE/EMM/SecurityModeControl.c +++ b/openair3/NAS/UE/EMM/SecurityModeControl.c @@ -286,7 +286,7 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, user->emm_data->security->selected_algorithms.encryption = seea; user->emm_data->security->selected_algorithms.integrity = seia; #if defined(NAS_BUILT_IN_UE) - nas_itti_kenb_refresh_req(security_data->kenb.value); + nas_itti_kenb_refresh_req(security_data->kenb.value, user->ueid); #endif } diff --git a/openair3/NAS/UE/nas_itti_messaging.c b/openair3/NAS/UE/nas_itti_messaging.c index 55566700d7..885ebbdd81 100644 --- a/openair3/NAS/UE/nas_itti_messaging.c +++ b/openair3/NAS/UE/nas_itti_messaging.c @@ -100,7 +100,7 @@ int nas_itti_protected_msg(const char *buffer, const nas_message_t *msg, const i extern unsigned char NB_eNB_INST; -int nas_itti_kenb_refresh_req(const Byte_t kenb[32]) { +int nas_itti_kenb_refresh_req(const Byte_t kenb[32], int user_id) { MessageDef *message_p; message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_KENB_REFRESH_REQ); memcpy(NAS_KENB_REFRESH_REQ(message_p).kenb, kenb, sizeof(NAS_KENB_REFRESH_REQ(message_p).kenb)); @@ -125,7 +125,7 @@ int nas_itti_kenb_refresh_req(const Byte_t kenb[32]) { kenb[20], kenb[21], kenb[22], kenb[23], kenb[24], kenb[25], kenb[26], kenb[27], kenb[28], kenb[29], kenb[30], kenb[31]); - return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p); + return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + user_id, message_p); } int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat, int user_id) { diff --git a/openair3/NAS/UE/nas_itti_messaging.h b/openair3/NAS/UE/nas_itti_messaging.h index d958317e5a..967bbb3059 100644 --- a/openair3/NAS/UE/nas_itti_messaging.h +++ b/openair3/NAS/UE/nas_itti_messaging.h @@ -48,7 +48,7 @@ int nas_itti_protected_msg( # if defined(NAS_BUILT_IN_UE) -int nas_itti_kenb_refresh_req(const Byte_t kenb[32]); +int nas_itti_kenb_refresh_req(const Byte_t kenb[32], int user_id); int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat, int user_id); From 05577be422c3324c6cdfe40ea9f9807ba9c5ae89 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 4 Mar 2020 09:58:00 +0100 Subject: [PATCH 05/25] Reduce logging verbosity and levels --- openair2/PHY_INTERFACE/phy_stub_UE.c | 8 ++++---- openair3/NAS/COMMON/UTIL/nas_log.h | 9 +++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index 14974c2e15..4b331c1cb0 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -209,8 +209,8 @@ void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL UL_INFO->rach_ind.rach_indication_body.preamble_list[0].instance_length = 0; - LOG_E(PHY,"\n\n\n\nDJP - this needs to be sent to VNF **********************************************\n\n\n\n"); - LOG_E(PHY,"UE Filling NFAPI indication for RACH : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", + //LOG_E(PHY,"\n\n\n\nDJP - this needs to be sent to VNF **********************************************\n\n\n\n"); + LOG_I(PHY,"UE Filling NFAPI indication for RACH : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.timing_advance, UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.preamble, UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti, @@ -685,7 +685,7 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) //, if((dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index >= 0) &&(dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1)){ //if(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL){ - LOG_E(MAC, "dl_config_req_UE_MAC 2 Received data: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d, tx_req_num_elems: %d \n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index, tx_req_num_elems); + LOG_I(MAC, "dl_config_req_UE_MAC 2 Received data: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d, tx_req_num_elems: %d \n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index, tx_req_num_elems); ue_send_sdu(Mod_id, 0, sfn, sf, tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data, @@ -699,7 +699,7 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) //, } } else { - LOG_E(MAC,"[UE %d] Frame %d, subframe %d : DLSCH PDU from NFAPI not for this UE \n",Mod_id, sfn,sf); + LOG_W(MAC,"[UE %d] Frame %d, subframe %d : DLSCH PDU from NFAPI not for this UE \n",Mod_id, sfn,sf); i++; } } diff --git a/openair3/NAS/COMMON/UTIL/nas_log.h b/openair3/NAS/COMMON/UTIL/nas_log.h index b41e34c51b..d1531fa6db 100644 --- a/openair3/NAS/COMMON/UTIL/nas_log.h +++ b/openair3/NAS/COMMON/UTIL/nas_log.h @@ -95,14 +95,15 @@ typedef enum { /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ +#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) #ifdef LOG_E # define LOG_TRACE(s, x, args...) \ do { \ switch (s) { \ - case ERROR: LOG_E(NAS, " %s:%d " x "\n", __FILE__, __LINE__, ##args); break; \ - case WARNING: LOG_W(NAS, " %s:%d " x "\n", __FILE__, __LINE__, ##args); break; \ - case INFO: LOG_I(NAS, " %s:%d " x "\n", __FILE__, __LINE__, ##args); break; \ - default: LOG_D(NAS, " %s:%d " x "\n", __FILE__, __LINE__, ##args); break; \ + case ERROR: LOG_E(NAS, " %s:%d " x "\n", __FILENAME__, __LINE__, ##args); break; \ + case WARNING: LOG_W(NAS, " %s:%d " x "\n", __FILENAME__, __LINE__, ##args); break; \ + case INFO: LOG_I(NAS, " %s:%d " x "\n", __FILENAME__, __LINE__, ##args); break; \ + default: LOG_D(NAS, " %s:%d " x "\n", __FILENAME__, __LINE__, ##args); break; \ } \ } while (0) From e72e1d87f2b45f0f22cf152b255f1c451a994a7c Mon Sep 17 00:00:00 2001 From: adk Date: Mon, 3 Feb 2020 17:02:30 +0100 Subject: [PATCH 06/25] added PUSCH PTRS structs (UE + gNB) and parameters initialization --- openair1/PHY/INIT/nr_init.c | 19 ++++++++++-- openair1/PHY/INIT/nr_init_ue.c | 25 ++++++++++++++-- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 2 +- openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c | 2 +- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 10 +++---- openair1/PHY/NR_UE_TRANSPORT/dci_nr.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 12 ++++---- openair1/PHY/defs_gNB.h | 5 ++-- openair1/PHY/defs_nr_UE.h | 4 ++- openair1/PHY/impl_defs_nr.h | 30 +++++++++++++++++-- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 4 +-- 11 files changed, 87 insertions(+), 28 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index f0ad3cbaae..f10a7426dd 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -85,6 +85,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, nfapi_nr_config_request_t *cfg = &gNB->gNB_config; NR_gNB_COMMON *const common_vars = &gNB->common_vars; NR_gNB_PUSCH **const pusch_vars = gNB->pusch_vars; + dmrs_UplinkConfig_t *dmrs_Uplink_Config = &gNB->pusch_config.dmrs_UplinkConfig; + ptrs_UplinkConfig_t *ptrs_Uplink_Config = &gNB->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig; /*LTE_eNB_SRS *const srs_vars = gNB->srs_vars; LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;*/ @@ -154,9 +156,9 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, } //------------- config PUSCH DMRS parameters(to be updated from RRC)--------------// - gNB->dmrs_UplinkConfig.pusch_dmrs_type = pusch_dmrs_type1; - gNB->dmrs_UplinkConfig.pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0; - gNB->dmrs_UplinkConfig.pusch_maxLength = pusch_len1; + dmrs_Uplink_Config->pusch_dmrs_type = pusch_dmrs_type1; + dmrs_Uplink_Config->pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0; + dmrs_Uplink_Config->pusch_maxLength = pusch_len1; //--------------------------------------------------------------------------------// nr_init_pdsch_dmrs(gNB, cfg->sch_config.physical_cell_id.value); @@ -168,6 +170,17 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, gNB->pusch_config.pusch_TimeDomainResourceAllocation[i]->mappingType = typeB; } + gNB->ptrs_configured = 0; + + //------------- config PUSCH PTRS parameters(to be updated from RRC)--------------// + ptrs_Uplink_Config->timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration + ptrs_Uplink_Config->timeDensity.ptrs_mcs2 = 0; + ptrs_Uplink_Config->timeDensity.ptrs_mcs3 = 0; + ptrs_Uplink_Config->frequencyDensity.n_rb0 = 0; // setting N_RB values to 0 indicate abscence of frequency_density field in the configuration + ptrs_Uplink_Config->frequencyDensity.n_rb1 = 0; + ptrs_Uplink_Config->resourceElementOffset = 0; + //--------------------------------------------------------------------------------// + /// Transport init necessary for NR synchro init_nr_transport(gNB); diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 461f441b2c..7b7954583d 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -659,6 +659,8 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, abstraction_flag = 0; fp->nb_antennas_tx = 1; fp->nb_antennas_rx=1; + dmrs_UplinkConfig_t *dmrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig; + ptrs_UplinkConfig_t *ptrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig; printf("Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,fp->nb_antennas_tx,fp->nb_antennas_rx); //LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_eNB_INST); nr_init_frame_parms_ue(fp,NR_MU_1,NORMAL,fp->N_RB_DL,n_ssb_crb,k_ssb); @@ -711,9 +713,9 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, } //------------- config DMRS parameters--------------// - ue->dmrs_UplinkConfig.pusch_dmrs_type = pusch_dmrs_type1; - ue->dmrs_UplinkConfig.pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0; - ue->dmrs_UplinkConfig.pusch_maxLength = pusch_len1; + dmrs_Uplink_Config->pusch_dmrs_type = pusch_dmrs_type1; + dmrs_Uplink_Config->pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0; + dmrs_Uplink_Config->pusch_maxLength = pusch_len1; //-------------------------------------------------// ue->dmrs_DownlinkConfig.pdsch_dmrs_type = pdsch_dmrs_type1; ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition = pdsch_dmrs_pos0; @@ -743,6 +745,23 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, /////////// //////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////PUSCH PTRS init///////////////////////// + /////////// + + ue->ptrs_configured = 0; // flag to be toggled by RCC + + //------------- config PTRS parameters--------------// + ptrs_Uplink_Config->timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration + ptrs_Uplink_Config->timeDensity.ptrs_mcs2 = 0; + ptrs_Uplink_Config->timeDensity.ptrs_mcs3 = 0; + ptrs_Uplink_Config->frequencyDensity.n_rb0 = 0; // setting N_RB values to 0 indicate abscence of frequency_density field in the configuration + ptrs_Uplink_Config->frequencyDensity.n_rb1 = 0; + ptrs_Uplink_Config->resourceElementOffset = 0; + //-------------------------------------------------// + + /////////// + //////////////////////////////////////////////////////////////////////////////////////////// + for (i=0; i<10; i++) ue->tx_power_dBm[i]=-127; diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index ab6ccd929b..83c6f054cd 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -117,7 +117,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, //------------------generate DMRS------------------// - length_dmrs = gNB->dmrs_UplinkConfig.pusch_maxLength; + length_dmrs = dmrs_UplinkConfig->pusch_maxLength; nr_gold_pusch(gNB, symbol, n_idDMRS, length_dmrs); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c index 9736e97e34..a158d5bf62 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c @@ -338,7 +338,7 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, rel15_ul->ulsch_pdu_rel15.number_rbs = ulsch_pdu->rb_size; rel15_ul->ulsch_pdu_rel15.start_symbol = ulsch_pdu->start_symbol_index; rel15_ul->ulsch_pdu_rel15.number_symbols = ulsch_pdu->nr_of_symbols; - rel15_ul->ulsch_pdu_rel15.length_dmrs = gNB->dmrs_UplinkConfig.pusch_maxLength; + rel15_ul->ulsch_pdu_rel15.length_dmrs = gNB->pusch_config.dmrs_UplinkConfig.pusch_maxLength; rel15_ul->ulsch_pdu_rel15.Qm = ulsch_pdu->qam_mod_order; rel15_ul->ulsch_pdu_rel15.mcs = ulsch_pdu->mcs_index; rel15_ul->ulsch_pdu_rel15.rv = ulsch_pdu->pusch_data.rv_index; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index eb35fd7dc6..1def3d5033 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -1030,12 +1030,12 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, 0, 0, rel15_ul->number_symbols, - &gNB->dmrs_UplinkConfig, + &gNB->pusch_config.dmrs_UplinkConfig, mapping_type, frame_parms->ofdm_symbol_size); if (dmrs_symbol_flag == 1){ - nb_re_pusch = rel15_ul->number_rbs * ((gNB->dmrs_UplinkConfig.pusch_dmrs_type==pusch_dmrs_type1)?6:8); + nb_re_pusch = rel15_ul->number_rbs * ((gNB->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type==pusch_dmrs_type1)?6:8); gNB->pusch_vars[UE_id]->dmrs_symbol = symbol; } else { nb_re_pusch = rel15_ul->number_rbs * NR_NB_SC_PER_RB; @@ -1054,7 +1054,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, symbol, bwp_start_subcarrier, rel15_ul->number_rbs, - &gNB->dmrs_UplinkConfig); + &gNB->pusch_config.dmrs_UplinkConfig); //---------------------------------------------------------- //--------------------- RBs extraction --------------------- @@ -1073,7 +1073,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, gNB->pusch_vars[UE_id]->dmrs_symbol, rel15_ul->number_symbols, mapping_type, - &gNB->dmrs_UplinkConfig); + &gNB->pusch_config.dmrs_UplinkConfig); nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, frame_parms, @@ -1081,7 +1081,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, symbol, dmrs_symbol_flag, rel15_ul->number_rbs, - gNB->dmrs_UplinkConfig.pusch_dmrs_type); + gNB->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type); if (first_symbol_flag==1) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 69077f0276..162ab6958f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -1975,7 +1975,7 @@ uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue, PUSCH_Config_t pusch_config = ue->pusch_config; PUCCH_Config_t pucch_config_dedicated = ue->pucch_config_dedicated_nr[eNB_id]; crossCarrierSchedulingConfig_t crossCarrierSchedulingConfig = ue->crossCarrierSchedulingConfig; - dmrs_UplinkConfig_t dmrs_UplinkConfig = ue->dmrs_UplinkConfig; + dmrs_UplinkConfig_t dmrs_UplinkConfig = ue->pusch_config.dmrs_UplinkConfig; dmrs_DownlinkConfig_t dmrs_DownlinkConfig = ue->dmrs_DownlinkConfig; csi_MeasConfig_t csi_MeasConfig = ue->csi_MeasConfig; PUSCH_ServingCellConfig_t PUSCH_ServingCellConfig= ue->PUSCH_ServingCellConfig; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index b912834f9d..bdcbe3327a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -142,14 +142,14 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, 0, 0, harq_process_ul_ue->number_of_symbols, - &UE->dmrs_UplinkConfig, + &UE->pusch_config.dmrs_UplinkConfig, mapping_type, frame_parms->ofdm_symbol_size); - ulsch_ue->length_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength; + ulsch_ue->length_dmrs = UE->pusch_config.dmrs_UplinkConfig.pusch_maxLength; ulsch_ue->rnti = n_rnti; ulsch_ue->Nid_cell = Nid_cell; - ulsch_ue->nb_re_dmrs = ((UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols; + ulsch_ue->nb_re_dmrs = ((UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols; N_RE_prime = NR_NB_SC_PER_RB*harq_process_ul_ue->number_of_symbols - ulsch_ue->nb_re_dmrs - N_PRB_oh; @@ -277,7 +277,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, pusch_dmrs = UE->nr_gold_pusch_dmrs[slot]; n_dmrs = (harq_process_ul_ue->nb_rb*ulsch_ue->nb_re_dmrs); int16_t mod_dmrs[n_dmrs<<1]; - dmrs_type = UE->dmrs_UplinkConfig.pusch_dmrs_type; + dmrs_type = UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type; /////////// //////////////////////////////////////////////////////////////////////// @@ -313,7 +313,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, 0, 0, harq_process_ul_ue->number_of_symbols, - &UE->dmrs_UplinkConfig, + &UE->pusch_config.dmrs_UplinkConfig, mapping_type, frame_parms->ofdm_symbol_size); @@ -379,7 +379,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, n, delta, harq_process_ul_ue->number_of_symbols, - &UE->dmrs_UplinkConfig, + &UE->pusch_config.dmrs_UplinkConfig, mapping_type, frame_parms->ofdm_symbol_size); diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 3c0f0db8da..91a50d7361 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -669,6 +669,9 @@ typedef struct PHY_VARS_gNB_s { /// PDSCH DMRS sequence uint32_t ****nr_gold_pdsch_dmrs; + + /// flag to indicate if PTRS is configured + uint8_t ptrs_configured; /// PUSCH DMRS uint32_t nr_gold_pusch[2][20][2][NR_MAX_PUSCH_DMRS_INIT_LENGTH_DWORD]; @@ -727,8 +730,6 @@ typedef struct PHY_VARS_gNB_s { // SRS Variables SOUNDINGRS_UL_CONFIG_DEDICATED soundingrs_ul_config_dedicated[NUMBER_OF_UE_MAX]; - dmrs_UplinkConfig_t dmrs_UplinkConfig; - dmrs_DownlinkConfig_t dmrs_DownlinkConfig; uint8_t ncs_cell[20][7]; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index d72979262c..de4f886903 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -1012,6 +1012,9 @@ typedef struct { /// PUSCH DMRS sequence uint32_t ****nr_gold_pusch_dmrs; + /// flag to indicate if PTRS is configured + uint8_t ptrs_configured; + uint32_t X_u[64][839]; uint32_t high_speed_flag; @@ -1143,7 +1146,6 @@ typedef struct { crossCarrierSchedulingConfig_t crossCarrierSchedulingConfig; supplementaryUplink_t supplementaryUplink; - dmrs_UplinkConfig_t dmrs_UplinkConfig; dmrs_DownlinkConfig_t dmrs_DownlinkConfig; csi_MeasConfig_t csi_MeasConfig; PUSCH_ServingCellConfig_t PUSCH_ServingCellConfig; diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h index 6e13973dd9..3519b97278 100644 --- a/openair1/PHY/impl_defs_nr.h +++ b/openair1/PHY/impl_defs_nr.h @@ -510,9 +510,6 @@ typedef struct { uint8_t startSymbolAndLength; } PUSCH_TimeDomainResourceAllocation_t; ////////////////////////////////////////////////////////////////////////////////################################ -typedef struct { // The IE PTRS-UplinkConfig is used to configure uplink Phase-Tracking-Reference-Signals (PTRS) - -} ptrs_UplinkConfig_t; typedef enum{ maxCodeBlockGroupsPerTransportBlock_n2 = 2, maxCodeBlockGroupsPerTransportBlock_n4 = 4, @@ -544,6 +541,12 @@ typedef enum { pusch_dmrs_pos2 = 2, pusch_dmrs_pos3 = 3, } pusch_dmrs_AdditionalPosition_t; +typedef enum { + offset00 = 0, + offset01 = 1, + offset10 = 2, + offset11 = 3, +} ptrs_resource_elementoffset_t; typedef enum { pdsch_len1 = 1, pdsch_len2 = 2 @@ -552,6 +555,22 @@ typedef enum { pusch_len1 = 1, pusch_len2 = 2 } pusch_maxLength_t; +typedef struct { + uint8_t ptrs_mcs1; + uint8_t ptrs_mcs2; + uint8_t ptrs_mcs3; +} ptrs_time_density_t; +typedef struct { + uint16_t n_rb0; + uint16_t n_rb1; +} ptrs_frequency_density_t; +typedef struct { // The IE PTRS-UplinkConfig is used to configure uplink Phase-Tracking-Reference-Signals (PTRS) + uint8_t num_ptrs_ports; + ptrs_resource_elementoffset_t resourceElementOffset; + ptrs_time_density_t timeDensity; + ptrs_frequency_density_t frequencyDensity; + uint32_t ul_ptrs_power; +} ptrs_UplinkConfig_t; typedef struct { // The IE DMRS-DownlinkConfig is used to configure downlink demodulation reference signals for PDSCH pdsch_dmrs_type_t pdsch_dmrs_type; pdsch_dmrs_AdditionalPosition_t pdsch_dmrs_AdditionalPosition; @@ -563,6 +582,7 @@ typedef struct { // The IE DMRS-UplinkConfig is used to configure uplink demodul pusch_dmrs_type_t pusch_dmrs_type; pusch_dmrs_AdditionalPosition_t pusch_dmrs_AdditionalPosition; pusch_maxLength_t pusch_maxLength; + ptrs_UplinkConfig_t ptrs_UplinkConfig; uint16_t scramblingID0; uint16_t scramblingID1; } dmrs_UplinkConfig_t; @@ -647,6 +667,10 @@ typedef struct { * resourceAllocation */ ul_resourceAllocation_t ul_resourceAllocation; +/* + * DMRS-Uplinkconfig + */ + dmrs_UplinkConfig_t dmrs_UplinkConfig; /* * rgb_Size */ diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index fb6d1a6c37..40bbe7322d 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -244,11 +244,11 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id 0, 0, number_symbols, - &gNB->dmrs_UplinkConfig, + &gNB->pusch_config.dmrs_UplinkConfig, mapping_type, frame_parms->ofdm_symbol_size); - nb_re_dmrs = ((gNB->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols; + nb_re_dmrs = ((gNB->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols; G = nr_get_G(nfapi_ulsch_pdu_rel15->number_rbs, number_symbols, From 505d06e945856ad1e13e832957ae366dda7b1e86 Mon Sep 17 00:00:00 2001 From: adk Date: Thu, 13 Feb 2020 18:24:55 +0100 Subject: [PATCH 07/25] PUSCH PTRS generation --- cmake_targets/CMakeLists.txt | 2 + openair1/PHY/NR_REFSIG/ptrs_nr.c | 429 ++++++++++++++++++ openair1/PHY/NR_REFSIG/ptrs_nr.h | 82 ++++ .../PHY/NR_UE_TRANSPORT/nr_transport_ue.h | 2 + openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 74 ++- 5 files changed, 583 insertions(+), 6 deletions(-) create mode 100644 openair1/PHY/NR_REFSIG/ptrs_nr.c create mode 100644 openair1/PHY/NR_REFSIG/ptrs_nr.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index c4d3d7e62e..6a0f6e1538 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1467,6 +1467,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/dmrs_nr.c + ${OPENAIR1_DIR}/PHY/NR_REFSIG/ptrs_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/filt16a_32.c ${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c ${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c @@ -1513,6 +1514,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/dmrs_nr.c + ${OPENAIR1_DIR}/PHY/NR_REFSIG/ptrs_nr.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold_ue.c ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/filt16a_32.c ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.c b/openair1/PHY/NR_REFSIG/ptrs_nr.c new file mode 100644 index 0000000000..9be37d2d95 --- /dev/null +++ b/openair1/PHY/NR_REFSIG/ptrs_nr.c @@ -0,0 +1,429 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/********************************************************************** +* +* FILENAME : ptrs_nr.c +* +* MODULE : phase tracking reference signals +* +* DESCRIPTION : resource element mapping of ptrs sequences +* 3GPP TS 38.211 and 3GPP TS 38.214 +* +************************************************************************/ + +#include +#include +#include "dmrs_nr.h" +#include "PHY/NR_REFSIG/ptrs_nr.h" + +/***********************************************************************/ + + + //#define max(a,b) (((a) > (b)) ? (a) : (b)) + +// TS 38.211 Table 6.4.1.2.2.1-1: The parameter kRE_ref. +// The first 4 colomns are DM-RS Configuration type 1 and the last 4 colomns are DM-RS Configuration type 2. + +int16_t table_6_4_1_2_2_1_1_pusch_ptrs_kRE_ref [6][8] = { +{ 0, 2, 6, 8, 0, 1, 6, 7}, +{ 2, 4, 8, 10, 1, 6, 7, 0}, +{ 1, 3, 7, 9, 2, 3, 8, 9}, +{ 3, 5, 9, 11, 3, 8, 9, 2}, +{-1, -1, -1, -1, 4, 5, 10, 11}, +{-1, -1, -1, -1, 5, 10, 11, 4}, +}; + + +/******************************************************************* +* +* NAME : get_kRE_ref +* +* PARAMETERS : dmrs_antenna_port DMRS antenna port +* pusch_dmrs_type PUSCH DMRS type +* resourceElementOffset the parameter resourceElementOffset +* +* RETURN : the parameter k_RE_ref +* +* DESCRIPTION : 3GPP TS 38.211 Table 6.4.1.2.2.1-1 +* +*********************************************************************/ + +int16_t get_kRE_ref(uint8_t dmrs_antenna_port, uint8_t pusch_dmrs_type, uint8_t resourceElementOffset) { + + uint8_t colomn; + int16_t k_RE_ref; + + colomn = resourceElementOffset; + + if (pusch_dmrs_type == 2) + colomn += 4; + + k_RE_ref = table_6_4_1_2_2_1_1_pusch_ptrs_kRE_ref[dmrs_antenna_port][colomn]; + + AssertFatal(k_RE_ref>=0,"invalid k_RE_ref < 0. Check PTRS Configuration\n"); + + return k_RE_ref; +} + + +/******************************************************************* +* +* NAME : get_K_ptrs +* +* PARAMETERS : ptrs_UplinkConfig PTRS uplink configuration +* N_RB number of RBs scheduled for PUSCH +* +* RETURN : the parameter K_ptrs +* +* DESCRIPTION : 3GPP TS 38.214 6.2.3 Table 6.2.3.1-2 +* +*********************************************************************/ + +uint8_t get_K_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint16_t N_RB){ + + uint16_t nrb0, nrb1; + + nrb0 = ptrs_UplinkConfig->frequencyDensity.n_rb0; + nrb1 = ptrs_UplinkConfig->frequencyDensity.n_rb1; + + if (nrb0 == 0 || nrb0 == 0) + return 2; + + if (N_RB < nrb0){ + LOG_I(PHY,"PUSH PT-RS is not present.\n"); + return 0; + } + else if (N_RB >= nrb0 && N_RB < nrb1) + return 2; + else + return 4; +} + +/******************************************************************* +* +* NAME : set_ptrs_symb_idx +* +* PARAMETERS : ptrs_symbols PTRS OFDM symbol indicies bit mask +* ptrs_UplinkConfig PTRS uplink configuration +* dmrs_UplinkConfig DMRS uplink configuration +* mapping_type PUSCH time domain mapping type +* duration_in_symbols number of scheduled PUSCH ofdm symbols +* start_symbol first ofdm symbol of PUSCH within slot +* L_ptrs the parameter L_ptrs +* ofdm_symbol_size FFT size +* +* RETURN : sets the bit map of PTRS ofdm symbol indicies +* +* DESCRIPTION : 3GPP TS 38.211 6.4.1.2.2.1 +* +*********************************************************************/ + +void set_ptrs_symb_idx(uint16_t *ptrs_symbols, + ptrs_UplinkConfig_t *ptrs_UplinkConfig, + dmrs_UplinkConfig_t *dmrs_UplinkConfig, + uint8_t mapping_type, + uint8_t duration_in_symbols, + uint8_t start_symbol, + uint8_t L_ptrs, + uint16_t ofdm_symbol_size) { + + uint8_t i, last_symbol, is_dmrs_symbol1, is_dmrs_symbol2; + int16_t l_ref; + + *ptrs_symbols = 0; + i = 0; + is_dmrs_symbol1 = 0; + is_dmrs_symbol2 = 0; + l_ref = start_symbol; + last_symbol = start_symbol + duration_in_symbols - 1; + + while ( (l_ref + i*L_ptrs) <= last_symbol) { + + is_dmrs_symbol1 = is_dmrs_symbol(max((l_ref + (i-1)*L_ptrs + 1), l_ref), + 0, + 0, + 0, + 0, + 0, + duration_in_symbols, + dmrs_UplinkConfig, + mapping_type, + ofdm_symbol_size); + + is_dmrs_symbol2 = is_dmrs_symbol(l_ref + i*L_ptrs, + 0, + 0, + 0, + 0, + 0, + duration_in_symbols, + dmrs_UplinkConfig, + mapping_type, + ofdm_symbol_size); + + if ( is_dmrs_symbol1 + is_dmrs_symbol2 > 0 ) { + + if (dmrs_UplinkConfig->pusch_maxLength == 2) + l_ref = l_ref + i*L_ptrs + 1; + else + l_ref = l_ref + i*L_ptrs; + + i = 1; + + continue; + + } + + *ptrs_symbols = *ptrs_symbols | (1<<(l_ref + i*L_ptrs)); + i++; + } +} + +/******************************************************************* +* +* NAME : get_L_ptrs +* +* PARAMETERS : ptrs_UplinkConfig PTRS uplink configuration +* I_mcs MCS index used for PUSCH +* +* RETURN : the parameter L_ptrs +* +* DESCRIPTION : 3GPP TS 38.214 6.2.3 Table 6.2.3.1-1 +* +*********************************************************************/ + +uint8_t get_L_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint8_t I_mcs) { + + uint8_t mcs1, mcs2, mcs3; + + mcs1 = ptrs_UplinkConfig->timeDensity.ptrs_mcs1; + mcs2 = ptrs_UplinkConfig->timeDensity.ptrs_mcs2; + mcs3 = ptrs_UplinkConfig->timeDensity.ptrs_mcs3; + + if (mcs1 == 0 || mcs2 == 0 || mcs3 == 0) + return 1; + + if (I_mcs < mcs1){ + LOG_I(PHY,"PUSH PT-RS is not present.\n"); + return 0; + } + else if (I_mcs >= mcs1 && I_mcs < mcs2) + return 4; + else if (I_mcs >= mcs2 && I_mcs < mcs3) + return 2; + else + return 1; +} + +/******************************************************************* +* +* NAME : is_ptrs_subcarrier +* +* PARAMETERS : k subcarrier index +* K_ptrs the parameter K_ptrs +* n_rnti UE CRNTI +* N_RB number of RBs scheduled for PUSCH +* k_RE_ref the parameter k_RE_ref +* start_sc first subcarrier index +* ofdm_symbol_size FFT size +* +* RETURN : 1 if subcarrier k is PTRS, or 0 otherwise +* +* DESCRIPTION : 3GPP TS 38.211 6.4.1.2 Phase-tracking reference signal for PUSCH +* +*********************************************************************/ + +uint8_t is_ptrs_subcarrier(uint16_t k, uint8_t K_ptrs, uint16_t n_rnti, uint16_t N_RB, int16_t k_RE_ref, uint16_t start_sc, uint16_t ofdm_symbol_size) { + + uint16_t k_RB_ref, i, sc; + + i = 0; + sc = 0; + k_RB_ref = 0; + + if (N_RB % K_ptrs == 0) + k_RB_ref = n_rnti % K_ptrs; + else + k_RB_ref = n_rnti % (N_RB % K_ptrs); + + while (k > sc){ + + sc = (start_sc + k_RE_ref + (i*K_ptrs + k_RB_ref)*NR_NB_SC_PER_RB)%ofdm_symbol_size; + i++; + + } + + if (k == sc) + return 1; + else + return 0; + +} + +/******************************************************************* +* +* NAME : is_ptrs_symbol +* +* PARAMETERS : l ofdm symbol index within slot +* k subcarrier index +* n_rnti UE CRNTI +* N_RB number of RBs scheduled for PUSCH +* duration_in_symbols number of scheduled PUSCH ofdm symbols +* dmrs_antenna_port DMRS antenna port +* K_ptrs the parameter K_ptrs +* ptrs_symbols bit mask of ptrs +* start_sc first subcarrier index +* ofdm_symbol_size FFT size +* pusch_dmrs_type PUSCH DMRS type (1 or 2) +* ptrs_UplinkConfig PTRS uplink configuration +* +* RETURN : 0 if symbol(k,l) is data, or 1 if symbol(k,l) is ptrs +* +* DESCRIPTION : 3GPP TS 38.211 6.4.1.2 Phase-tracking reference signal for PUSCH +* +*********************************************************************/ + +uint8_t is_ptrs_symbol(uint8_t l, + uint16_t k, + uint16_t n_rnti, + uint16_t N_RB, + uint8_t duration_in_symbols, + uint8_t dmrs_antenna_port, + uint8_t K_ptrs, + uint16_t ptrs_symbols, + uint16_t start_sc, + uint16_t ofdm_symbol_size, + pusch_dmrs_type_t pusch_dmrs_type, + ptrs_UplinkConfig_t *ptrs_UplinkConfig) { + + uint8_t is_ptrs_freq, is_ptrs_time; + int16_t k_RE_ref; + + is_ptrs_freq = 0; + is_ptrs_time = 0; + + k_RE_ref = get_kRE_ref(dmrs_antenna_port, pusch_dmrs_type, ptrs_UplinkConfig->resourceElementOffset); + + is_ptrs_freq = is_ptrs_subcarrier(k, K_ptrs, n_rnti, N_RB, k_RE_ref, start_sc, ofdm_symbol_size); + + if (is_ptrs_freq == 0) + return 0; + + if (((ptrs_symbols>>l)&1) == 1) + is_ptrs_time = 1; + + if (is_ptrs_time && is_ptrs_freq) + return 1; + else + return 0; + +} + +/* +int main(int argc, char const *argv[]) +{ + + dmrs_UplinkConfig_t dmrs_Uplink_Config; + ptrs_UplinkConfig_t ptrs_Uplink_Config; + uint8_t resourceElementOffset; + uint8_t dmrs_antenna_port; + uint8_t L_ptrs, K_ptrs; + int16_t k_RE_ref; + uint16_t N_RB, ptrs_symbols, ofdm_symbol_size, k; + uint8_t duration_in_symbols, I_mcs; + uint8_t start_symbol, l; + uint8_t ptrs_symbol_flag; + uint16_t n_rnti; + + dmrs_Uplink_Config.pusch_dmrs_type = pusch_dmrs_type1; + dmrs_Uplink_Config.pusch_dmrs_AdditionalPosition = pusch_dmrs_pos1; + dmrs_Uplink_Config.pusch_maxLength = pusch_len2; + + ptrs_Uplink_Config.timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration + ptrs_Uplink_Config.timeDensity.ptrs_mcs2 = 0; + ptrs_Uplink_Config.timeDensity.ptrs_mcs3 = 0; + ptrs_Uplink_Config.frequencyDensity.n_rb0 = 0; // setting N_RB values to 0 indicate abscence of frequency_density field in the configuration + ptrs_Uplink_Config.frequencyDensity.n_rb1 = 0; + ptrs_Uplink_Config.resourceElementOffset = 0; + + n_rnti = 0x1234; + resourceElementOffset = 0; + ptrs_symbols = 0; + dmrs_antenna_port = 0; + N_RB = 50; + duration_in_symbols = 14; + ofdm_symbol_size = 2048; + I_mcs = 9; + start_symbol = 0; + ptrs_symbol_flag = 0; + + k_RE_ref = get_kRE_ref(dmrs_antenna_port, dmrs_Uplink_Config.pusch_dmrs_type, resourceElementOffset); + + K_ptrs = get_K_ptrs(&ptrs_Uplink_Config, N_RB); + + L_ptrs = get_L_ptrs(&ptrs_Uplink_Config, I_mcs); + + set_ptrs_symb_idx(&ptrs_symbols, + &ptrs_Uplink_Config, + &dmrs_Uplink_Config, + 1, + duration_in_symbols, + start_symbol, + L_ptrs, + ofdm_symbol_size); + + printf("PTRS OFDM symbol indicies: "); + + for (l = start_symbol; l < start_symbol + duration_in_symbols; l++){ + + ptrs_symbol_flag = is_ptrs_symbol(l, + 0, + n_rnti, + N_RB, + duration_in_symbols, + dmrs_antenna_port, + K_ptrs, + ptrs_symbols, + dmrs_Uplink_Config.pusch_dmrs_type, + &ptrs_Uplink_Config); + + if (ptrs_symbol_flag == 1) + printf(" %d ", l); + + } + + printf("\n"); + + printf("PTRS subcarrier indicies: "); + + for (k = 0; k < N_RB*12; k++){ + + if (is_ptrs_subcarrier(k, K_ptrs, n_rnti, N_RB, k_RE_ref) == 1) + printf(" %d ", k); + + } + + printf("\n"); + + return 0; +} +*/ \ No newline at end of file diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.h b/openair1/PHY/NR_REFSIG/ptrs_nr.h new file mode 100644 index 0000000000..f3b42fff30 --- /dev/null +++ b/openair1/PHY/NR_REFSIG/ptrs_nr.h @@ -0,0 +1,82 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/********************************************************************** +* +* FILENAME : dmrs.h +* +* MODULE : demodulation reference signals +* +* DESCRIPTION : generation of dmrs sequences for NR 5G +* 3GPP TS 38.211 +* +************************************************************************/ + +#ifndef PTRS_NR_H +#define PTRS_NR_H + +#include "PHY/defs_nr_UE.h" + +/************** CODE GENERATION ***********************************/ + +/************** DEFINE ********************************************/ + + +/************* STRUCTURES *****************************************/ + + +/************** VARIABLES *****************************************/ + +/************** FUNCTION ******************************************/ + +int16_t get_kRE_ref(uint8_t dmrs_antenna_port, uint8_t pusch_dmrs_type, uint8_t resourceElementOffset); + +uint8_t get_K_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint16_t N_RB); + +void set_ptrs_symb_idx(uint16_t *ptrs_symbols, + ptrs_UplinkConfig_t *ptrs_UplinkConfig, + dmrs_UplinkConfig_t *dmrs_UplinkConfig, + uint8_t mapping_type, + uint8_t duration_in_symbols, + uint8_t start_symbol, + uint8_t L_ptrs, + uint16_t ofdm_symbol_size); + +uint8_t get_L_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint8_t I_mcs); + +uint8_t is_ptrs_subcarrier(uint16_t k, uint8_t K_ptrs, uint16_t n_rnti, uint16_t N_RB, int16_t k_RE_ref, uint16_t start_sc, uint16_t ofdm_symbol_size); + +uint8_t is_ptrs_symbol(uint8_t l, + uint16_t k, + uint16_t n_rnti, + uint16_t N_RB, + uint8_t duration_in_symbols, + uint8_t dmrs_antenna_port, + uint8_t K_ptrs, + uint16_t ptrs_symbols, + uint16_t start_sc, + uint16_t ofdm_symbol_size, + pusch_dmrs_type_t pusch_dmrs_type, + ptrs_UplinkConfig_t *ptrs_UplinkConfig); + + + +#endif /* PTRS_NR_H */ \ No newline at end of file diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index 39b037a600..a10b6231a0 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -240,6 +240,8 @@ typedef struct { int16_t Po_SRS; /// num active cba group uint8_t num_active_cba_groups; + /// bit mask of PT-RS ofdm symbol indicies + uint16_t ptrs_symbols; /// num dci found for cba //uint8_t num_cba_dci[10]; /// allocated CBA RNTI diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index bdcbe3327a..3caaa6c99f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -31,6 +31,7 @@ */ #include #include "PHY/NR_REFSIG/dmrs_nr.h" +#include "PHY/NR_REFSIG/ptrs_nr.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "PHY/MODULATION/nr_modulation.h" @@ -105,19 +106,22 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, int32_t **txdataF; uint16_t start_sc, start_rb; int8_t Wf[2], Wt[2], l_prime[2], delta; - uint16_t n_dmrs, code_rate, number_dmrs_symbols; + uint16_t n_dmrs, code_rate, number_dmrs_symbols, k; uint8_t dmrs_type; uint8_t mapping_type; int ap, start_symbol, Nid_cell, i; int sample_offsetF, N_RE_prime, N_PRB_oh; uint16_t n_rnti; uint8_t data_existing =0; + uint8_t L_ptrs, K_ptrs; // PTRS parameters + uint16_t beta_ptrs; // PTRS parameter related to power control NR_UE_ULSCH_t *ulsch_ue; NR_UL_UE_HARQ_t *harq_process_ul_ue; NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms; NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id]; uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES]; + ptrs_UplinkConfig_t *ptrs_Uplink_Config = &UE->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig; num_of_codewords = 1; // tmp assumption n_rnti = 0x1234; @@ -281,6 +285,36 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////// //////////////////////////////////////////////////////////////////////// + + /////////////////////////PTRS parameters' initialization///////////////////////// + /////////// + + int16_t mod_ptrs[(harq_process_ul_ue->nb_rb/2)*(NR_SYMBOLS_PER_SLOT-1)*2]; // assume maximum number of PTRS per pusch allocation + K_ptrs = 0; // just to avoid a warning + + if (UE->ptrs_configured == 1) { + + K_ptrs = get_K_ptrs(ptrs_Uplink_Config, harq_process_ul_ue->nb_rb); + + L_ptrs = get_L_ptrs(ptrs_Uplink_Config, harq_process_ul_ue->mcs); + + beta_ptrs = 1; // temp value until power control is implemented + + ulsch_ue->ptrs_symbols = 0; + + set_ptrs_symb_idx(&ulsch_ue->ptrs_symbols, + ptrs_Uplink_Config, + &UE->pusch_config.dmrs_UplinkConfig, + 1, + harq_process_ul_ue->number_of_symbols, + start_symbol, + L_ptrs, + frame_parms->ofdm_symbol_size); + } + + /////////// + //////////////////////////////////////////////////////////////////////////////// + /////////////////////////ULSCH layer mapping///////////////////////// /////////// @@ -357,8 +391,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, uint8_t k_prime=0; - uint8_t is_dmrs; - uint16_t m=0, n=0, dmrs_idx=0, k=0; + uint8_t is_dmrs, is_ptrs; + uint16_t m=0, n=0, dmrs_idx=0, ptrs_idx = 0; for (l=start_symbol; lnumber_of_symbols; l++) { @@ -371,6 +405,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, sample_offsetF = l*frame_parms->ofdm_symbol_size + k; is_dmrs = 0; + is_ptrs = 0; is_dmrs = is_dmrs_symbol(l, k, @@ -383,9 +418,26 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, mapping_type, frame_parms->ofdm_symbol_size); + if (UE->ptrs_configured == 1){ + is_ptrs = is_ptrs_symbol(l, + k, + ulsch_ue->rnti, + harq_process_ul_ue->nb_rb, + harq_process_ul_ue->number_of_symbols, + ap, + K_ptrs, + ulsch_ue->ptrs_symbols, + start_sc, + frame_parms->ofdm_symbol_size, + UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type, + ptrs_Uplink_Config); + } + if (is_dmrs == 1) { - 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 + if (k == start_sc){ + 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 + } ((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; @@ -401,9 +453,19 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, k_prime++; k_prime&=1; n+=(k_prime)?0:1; - } - else { + } else if (is_ptrs == 1) { + + if (k == start_sc){ + nr_modulation(pusch_dmrs[l][0], harq_process_ul_ue->nb_rb/2, DMRS_MOD_ORDER, mod_ptrs); + } + + ((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 { ((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]; From 00ff5e8a5cfe7fc8ee634a3af1cdc9daf82529be Mon Sep 17 00:00:00 2001 From: adk Date: Tue, 3 Mar 2020 11:33:07 +0100 Subject: [PATCH 08/25] PUSCH PTRS extraction and fixing nr_ulsim --- openair1/PHY/INIT/nr_init.c | 54 ++++---- openair1/PHY/INIT/nr_init_ue.c | 2 +- .../PHY/NR_TRANSPORT/nr_transport_proto.h | 14 +- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 123 ++++++++++++++---- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 1 + openair1/PHY/defs_gNB.h | 14 ++ openair1/SIMULATION/NR_PHY/ulsim.c | 6 +- 7 files changed, 153 insertions(+), 61 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index f10a7426dd..00fd616aa0 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -170,7 +170,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, gNB->pusch_config.pusch_TimeDomainResourceAllocation[i]->mappingType = typeB; } - gNB->ptrs_configured = 0; + gNB->ptrs_configured = 1; //------------- config PUSCH PTRS parameters(to be updated from RRC)--------------// ptrs_Uplink_Config->timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration @@ -234,32 +234,36 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, for (int UE_id=0; UE_idrxdataF_ext = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - pusch_vars[UE_id]->rxdataF_ext2 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - pusch_vars[UE_id]->ul_ch_estimates = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - pusch_vars[UE_id]->ul_ch_estimates_ext = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - pusch_vars[UE_id]->ul_ch_estimates_time = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - pusch_vars[UE_id]->rxdataF_comp = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - pusch_vars[UE_id]->ul_ch_mag0 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - pusch_vars[UE_id]->ul_ch_magb0 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - pusch_vars[UE_id]->ul_ch_mag = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - pusch_vars[UE_id]->ul_ch_magb = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - pusch_vars[UE_id]->rho = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) ); + pusch_vars[UE_id]->rxdataF_ext = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); + pusch_vars[UE_id]->rxdataF_ext2 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); + pusch_vars[UE_id]->ul_ch_estimates = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); + pusch_vars[UE_id]->ul_ch_estimates_ext = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); + pusch_vars[UE_id]->ul_ch_ptrs_estimates = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); + pusch_vars[UE_id]->ul_ch_ptrs_estimates_ext = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); + pusch_vars[UE_id]->ul_ch_estimates_time = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); + pusch_vars[UE_id]->rxdataF_comp = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); + pusch_vars[UE_id]->ul_ch_mag0 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); + pusch_vars[UE_id]->ul_ch_magb0 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); + pusch_vars[UE_id]->ul_ch_mag = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); + pusch_vars[UE_id]->ul_ch_magb = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); + pusch_vars[UE_id]->rho = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) ); for (i=0; inb_antennas_rx; i++) { // RK 2 times because of output format of FFT! // FIXME We should get rid of this - pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); - pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); - pusch_vars[UE_id]->ul_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); - pusch_vars[UE_id]->ul_ch_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); - pusch_vars[UE_id]->ul_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size ); - pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); - pusch_vars[UE_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 ); - pusch_vars[UE_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 ); - pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 ); - pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 ); - pusch_vars[UE_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) ); + pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); + pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); + pusch_vars[UE_id]->ul_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); + pusch_vars[UE_id]->ul_ch_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); + pusch_vars[UE_id]->ul_ch_ptrs_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*2*fp->symbols_per_slot ); // max intensity in freq is 1 sc every 2 RBs + pusch_vars[UE_id]->ul_ch_ptrs_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*2*fp->symbols_per_slot ); + pusch_vars[UE_id]->ul_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size ); + pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); + pusch_vars[UE_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 ); + pusch_vars[UE_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 ); + pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 ); + pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 ); + pusch_vars[UE_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) ); } pusch_vars[UE_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear @@ -363,6 +367,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(pusch_vars[UE_id]->rxdataF_ext2[i]); free_and_zero(pusch_vars[UE_id]->ul_ch_estimates[i]); free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_ext[i]); + free_and_zero(pusch_vars[UE_id]->ul_ch_ptrs_estimates[i]); + free_and_zero(pusch_vars[UE_id]->ul_ch_ptrs_estimates_ext[i]); free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_time[i]); free_and_zero(pusch_vars[UE_id]->rxdataF_comp[i]); free_and_zero(pusch_vars[UE_id]->ul_ch_mag0[i]); @@ -376,6 +382,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(pusch_vars[UE_id]->rxdataF_ext2); free_and_zero(pusch_vars[UE_id]->ul_ch_estimates); free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_ext); + free_and_zero(pusch_vars[UE_id]->ul_ch_ptrs_estimates); + free_and_zero(pusch_vars[UE_id]->ul_ch_ptrs_estimates_ext); free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_time); free_and_zero(pusch_vars[UE_id]->rxdataF_comp); free_and_zero(pusch_vars[UE_id]->ul_ch_mag0); diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 7b7954583d..773d048942 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -748,7 +748,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, /////////////////////////PUSCH PTRS init///////////////////////// /////////// - ue->ptrs_configured = 0; // flag to be toggled by RCC + ue->ptrs_configured = 1; // flag to be toggled by RCC //------------- config PTRS parameters--------------// ptrs_Uplink_Config->timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 4c8d8650e3..d3985bfd8b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -65,20 +65,18 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, @param is_dmrs_symbol, flag to indicate wether this OFDM symbol contains DMRS symbols or not. */ -void nr_ulsch_extract_rbs_single(int **rxdataF, - int **ul_ch_estimates, - int **rxdataF_ext, - int **ul_ch_estimates_ext, - uint32_t rxdataF_ext_offset, - // unsigned int *rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment +void nr_ulsch_extract_rbs_single(int32_t **rxdataF, + NR_gNB_PUSCH *pusch_vars, unsigned char symbol, unsigned short start_rb, unsigned short nb_rb_pusch, + uint16_t n_rnti, NR_DL_FRAME_PARMS *frame_parms, - uint8_t dmrs_symbol, uint16_t number_symbols, uint8_t mapping_type, - dmrs_UplinkConfig_t *dmrs_UplinkConfig); + uint8_t ptrs_configured, + dmrs_UplinkConfig_t *dmrs_UplinkConfig, + ptrs_UplinkConfig_t *ptrs_Uplink_Config); void nr_ulsch_scale_channel(int32_t **ul_ch_estimates_ext, NR_DL_FRAME_PARMS *frame_parms, diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 1def3d5033..93cb721f36 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -4,6 +4,7 @@ #include "PHY/impl_defs_top.h" #include "PHY/NR_TRANSPORT/nr_sch_dmrs.h" #include "PHY/NR_REFSIG/dmrs_nr.h" +#include "PHY/NR_REFSIG/ptrs_nr.h" #include "PHY/NR_ESTIMATION/nr_ul_estimation.h" #include "PHY/defs_nr_common.h" @@ -221,31 +222,32 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH) } -void nr_ulsch_extract_rbs_single(int **rxdataF, - int **ul_ch_estimates, - int **rxdataF_ext, - int **ul_ch_estimates_ext, - uint32_t rxdataF_ext_offset, - // unsigned int *rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment +void nr_ulsch_extract_rbs_single(int32_t **rxdataF, + NR_gNB_PUSCH *pusch_vars, unsigned char symbol, unsigned short start_rb, unsigned short nb_rb_pusch, + uint16_t n_rnti, NR_DL_FRAME_PARMS *frame_parms, - uint8_t dmrs_symbol, uint16_t number_symbols, uint8_t mapping_type, - dmrs_UplinkConfig_t *dmrs_UplinkConfig) + uint8_t ptrs_configured, + dmrs_UplinkConfig_t *dmrs_UplinkConfig, + ptrs_UplinkConfig_t *ptrs_Uplink_Config) { unsigned short start_re, re, nb_re_pusch; unsigned char aarx; + uint8_t K_ptrs; uint32_t rxF_ext_index = 0; uint32_t ul_ch0_ext_index = 0; uint32_t ul_ch0_index = 0; - uint8_t is_dmrs_symbol_flag, k_prime; - uint16_t n=0; - + uint32_t ul_ch0_ptrs_ext_index = 0; + uint32_t ul_ch0_ptrs_index = 0; + uint8_t is_dmrs_symbol_flag, is_ptrs_symbol_flag,k_prime; + uint16_t n=0, num_ptrs_symbols; int16_t *rxF,*rxF_ext; int *ul_ch0,*ul_ch0_ext; + int *ul_ch0_ptrs,*ul_ch0_ptrs_ext; #ifdef DEBUG_RB_EXT @@ -258,15 +260,23 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, nb_re_pusch = NR_NB_SC_PER_RB * nb_rb_pusch; is_dmrs_symbol_flag = 0; + is_ptrs_symbol_flag = 0; + num_ptrs_symbols = 0; + + K_ptrs = get_K_ptrs(ptrs_Uplink_Config, nb_rb_pusch); for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { rxF = (int16_t *)&rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size]; - rxF_ext = (int16_t *)&rxdataF_ext[aarx][symbol * nb_re_pusch]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6 + rxF_ext = (int16_t *)&pusch_vars->rxdataF_ext[aarx][symbol * nb_re_pusch]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6 - ul_ch0 = &ul_ch_estimates[aarx][dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available + 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 = &ul_ch_estimates_ext[aarx][symbol*nb_re_pusch]; + ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aarx][symbol*nb_re_pusch]; + + ul_ch0_ptrs = &pusch_vars->ul_ch_ptrs_estimates[aarx][pusch_vars->ptrs_symbol_index*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available + + ul_ch0_ptrs_ext = &pusch_vars->ul_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pusch]; n = 0; k_prime = 0; @@ -283,15 +293,36 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, dmrs_UplinkConfig, mapping_type, frame_parms->ofdm_symbol_size); + + if (ptrs_configured == 1){ + is_ptrs_symbol_flag = is_ptrs_symbol(symbol, + (start_re + re)%frame_parms->ofdm_symbol_size, + n_rnti, + nb_rb_pusch, + number_symbols, + aarx, + K_ptrs, + pusch_vars->ptrs_symbols, + start_re, + frame_parms->ofdm_symbol_size, + dmrs_UplinkConfig->pusch_dmrs_type, + ptrs_Uplink_Config); + + if (is_ptrs_symbol_flag == 1) + num_ptrs_symbols++; + + } + #ifdef DEBUG_RB_EXT printf("re = %d, is_dmrs_symbol_flag = %d, symbol = %d\n", re, is_dmrs_symbol_flag, symbol); #endif - if ( is_dmrs_symbol_flag == 0 ) { + if ( is_dmrs_symbol_flag == 0 && is_ptrs_symbol_flag == 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]; + ul_ch0_ptrs_ext[ul_ch0_ptrs_ext_index] = ul_ch0_ptrs[ul_ch0_ptrs_index]; #ifdef DEBUG_RB_EXT printf("rxF_ext[%d] = %d\n", rxF_ext_index, rxF_ext[rxF_ext_index]); @@ -299,6 +330,7 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, #endif ul_ch0_ext_index++; + ul_ch0_ptrs_ext_index++; rxF_ext_index +=2; } else { k_prime++; @@ -306,8 +338,12 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, n+=(k_prime)?0:1; } ul_ch0_index++; + ul_ch0_ptrs_index++; } } + + pusch_vars->ptrs_sc_per_ofdm_symbol = num_ptrs_symbols; + } void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, @@ -1001,17 +1037,21 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, unsigned char harq_pid) { - uint8_t first_symbol_flag, aarx, aatx, dmrs_symbol_flag; // dmrs_symbol_flag, a flag to indicate DMRS REs in current symbol - NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; - nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15; + uint8_t first_symbol_flag, aarx, aatx, dmrs_symbol_flag, ptrs_symbol_flag; // dmrs_symbol_flag, a flag to indicate DMRS REs in current symbol uint32_t nb_re_pusch, bwp_start_subcarrier; uint8_t mapping_type; + uint8_t L_ptrs = 0; // PTRS parameter int avgs; int avg[4]; + NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; + nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15; + ptrs_UplinkConfig_t *ptrs_Uplink_Config = &gNB->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig; dmrs_symbol_flag = 0; + ptrs_symbol_flag = 0; first_symbol_flag = 0; mapping_type = gNB->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType; + gNB->pusch_vars[UE_id]->ptrs_sc_per_ofdm_symbol = 0; if (mapping_type == typeB) { @@ -1019,6 +1059,20 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0; gNB->pusch_vars[UE_id]->dmrs_symbol = 0; first_symbol_flag = 1; + + L_ptrs = get_L_ptrs(ptrs_Uplink_Config, rel15_ul->mcs); + + gNB->pusch_vars[UE_id]->ptrs_symbols = 0; + + set_ptrs_symb_idx(&gNB->pusch_vars[UE_id]->ptrs_symbols, + ptrs_Uplink_Config, + &gNB->pusch_config.dmrs_UplinkConfig, + 1, + rel15_ul->number_symbols, + rel15_ul->start_symbol, + L_ptrs, + frame_parms->ofdm_symbol_size); + } bwp_start_subcarrier = (rel15_ul->start_rb*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size; @@ -1041,6 +1095,25 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, nb_re_pusch = rel15_ul->number_rbs * NR_NB_SC_PER_RB; } + if (gNB->ptrs_configured == 1) + ptrs_symbol_flag = is_ptrs_symbol(symbol, + 0, + gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu.rnti, + rel15_ul->number_rbs, + rel15_ul->number_symbols, + 0, + get_K_ptrs(ptrs_Uplink_Config, rel15_ul->number_rbs), + gNB->pusch_vars[UE_id]->ptrs_symbols, + 0, + frame_parms->ofdm_symbol_size, + gNB->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type, + ptrs_Uplink_Config); + + + if (ptrs_symbol_flag == 1){ + gNB->pusch_vars[UE_id]->ptrs_symbol_index = symbol; + } + //---------------------------------------------------------- //--------------------- Channel estimation --------------------- @@ -1061,19 +1134,17 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, //---------------------------------------------------------- nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF, - gNB->pusch_vars[UE_id]->ul_ch_estimates, - gNB->pusch_vars[UE_id]->rxdataF_ext, - gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, - gNB->pusch_vars[UE_id]->rxdataF_ext_offset, - // rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment + gNB->pusch_vars[UE_id], symbol, rel15_ul->start_rb, rel15_ul->number_rbs, + gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu.rnti, frame_parms, - gNB->pusch_vars[UE_id]->dmrs_symbol, rel15_ul->number_symbols, mapping_type, - &gNB->pusch_config.dmrs_UplinkConfig); + gNB->ptrs_configured, + &gNB->pusch_config.dmrs_UplinkConfig, + ptrs_Uplink_Config); nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, frame_parms, @@ -1131,7 +1202,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, symbol, rel15_ul->Qm); - gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re_pusch; + gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re_pusch - gNB->pusch_vars[UE_id]->ptrs_sc_per_ofdm_symbol; } else { LOG_E(PHY, "PUSCH mapping type A is not supported \n"); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 3caaa6c99f..26800ed584 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -546,6 +546,7 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, frame_parms); } } + /////////// //////////////////////////////////////////////////// return 0; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 91a50d7361..3bca1138c0 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -375,6 +375,14 @@ typedef struct { /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ int32_t **ul_ch_estimates_ext; + /// \brief Hold the PTRS phase estimates in frequency domain. + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_ptrs_estimates; + /// \brief Uplink phase estimates extracted in PRBS. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_ptrs_estimates_ext; /// \brief Holds the compensated signal. /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ @@ -416,6 +424,12 @@ typedef struct { int16_t *llr; // 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. + uint8_t ptrs_symbol_index; + /// bit mask of PT-RS ofdm symbol indicies + uint16_t ptrs_symbols; + // PTRS subcarriers per OFDM symbol + uint16_t ptrs_sc_per_ofdm_symbol; } NR_gNB_PUSCH; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index adfb09ea6e..36603c2ec0 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -428,7 +428,7 @@ int main(int argc, char **argv) uint16_t number_dmrs_symbols = 0; unsigned int available_bits; uint8_t nb_re_dmrs; - uint8_t length_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength; + uint8_t length_dmrs = UE->pusch_config.dmrs_UplinkConfig.pusch_maxLength; unsigned char mod_order; uint16_t code_rate; @@ -440,12 +440,12 @@ int main(int argc, char **argv) 0, 0, nb_symb_sch, - &UE->dmrs_UplinkConfig, + &UE->pusch_config.dmrs_UplinkConfig, UE->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType, frame_parms->ofdm_symbol_size); mod_order = nr_get_Qm_ul(Imcs, 0); - nb_re_dmrs = ((UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1) ? 6 : 4) * number_dmrs_symbols; + nb_re_dmrs = ((UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1) ? 6 : 4) * number_dmrs_symbols; 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); TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, precod_nbr_layers); From 8fbdfa39ec6051b29f65ee8a5beb273bd4a7e84f Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 5 Mar 2020 10:27:35 +0100 Subject: [PATCH 09/25] disable PUSCH PTRS for now As adding PTRS leads to shortening of the coded data, redudandency is removed and the performance decreases on a pure AWGN channel. So PTRS should only be enabled if phase noise is present. --- openair1/PHY/INIT/nr_init.c | 2 +- openair1/PHY/INIT/nr_init_ue.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 00fd616aa0..bf8f857a04 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -170,7 +170,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, gNB->pusch_config.pusch_TimeDomainResourceAllocation[i]->mappingType = typeB; } - gNB->ptrs_configured = 1; + gNB->ptrs_configured = 0; //------------- config PUSCH PTRS parameters(to be updated from RRC)--------------// ptrs_Uplink_Config->timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 773d048942..7b7954583d 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -748,7 +748,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, /////////////////////////PUSCH PTRS init///////////////////////// /////////// - ue->ptrs_configured = 1; // flag to be toggled by RCC + ue->ptrs_configured = 0; // flag to be toggled by RCC //------------- config PTRS parameters--------------// ptrs_Uplink_Config->timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration From 5f851d45b32b91b68412338503dc4aa52fb26b91 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 4 Mar 2020 15:45:16 +0100 Subject: [PATCH 10/25] Fill UE RX Indication Rel9 to prevent error message --- openair2/PHY_INTERFACE/phy_stub_UE.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index 4b331c1cb0..bff50310b4 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -71,6 +71,8 @@ void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND //pdu->rx_indication_rel8.length = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3; pdu->rx_indication_rel8.length = buflen; pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation + pdu->rx_indication_rel9.tl.tag = NFAPI_RX_INDICATION_REL9_TAG; + pdu->rx_indication_rel9.timing_advance_r9 = 0; // ulsch_buffer is necessary to keep its value. //pdu->data = ulsch_buffer; From c321f9b5a351d2c4c8073a3136d3a74cb3418cba Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Mar 2020 10:18:03 +0100 Subject: [PATCH 11/25] Make UE mem alloc for UL_INFO only once in PHY stub mode --- targets/RT/USER/lte-ue.c | 67 +++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 38 deletions(-) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 5a8afc2358..940d65282d 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -992,6 +992,19 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) phy_stub_ticking->num_single_thread[ue_thread_id] = -1; UE = rtd->UE; + UL_INFO = (UL_IND_t *)malloc(sizeof(UL_IND_t)); + UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = calloc(NB_UE_INST, sizeof(nfapi_rx_indication_pdu_t)); + UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0; + UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = calloc(NB_UE_INST, sizeof(nfapi_crc_indication_pdu_t)); + UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0; + UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = calloc(NB_UE_INST, sizeof(nfapi_harq_indication_pdu_t)); + UL_INFO->harq_ind.harq_indication_body.number_of_harqs = 0; + UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = calloc(NB_UE_INST, sizeof(nfapi_sr_indication_pdu_t)); + UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; + UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list = calloc(NB_UE_INST, sizeof(nfapi_cqi_indication_pdu_t)); + UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list = calloc(NB_UE_INST, sizeof(nfapi_cqi_indication_raw_pdu_t)); + UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis = 0; + if(ue_thread_id == 0) { phy_stub_ticking->ticking_var = -1; proc->subframe_rx=proc->sub_frame_start; @@ -1064,20 +1077,6 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) initRefTimes(t3); pickTime(current); updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)");*/ - // Not sure whether we should put the memory allocation here and not sure how much memory - //we should allocate for each subframe cycle. - UL_INFO = (UL_IND_t *)malloc(sizeof(UL_IND_t)); - UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = (nfapi_rx_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_rx_indication_pdu_t)); - UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0; - UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = (nfapi_crc_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_crc_indication_pdu_t)); - UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0; - UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = (nfapi_harq_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_harq_indication_pdu_t)); - UL_INFO->harq_ind.harq_indication_body.number_of_harqs = 0; - UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = (nfapi_sr_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_sr_indication_pdu_t)); - UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; - UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list = (nfapi_cqi_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_pdu_t)); - UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list = (nfapi_cqi_indication_raw_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_raw_pdu_t)); - UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis = 0; if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) { LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); @@ -1267,30 +1266,6 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; } - // Free UL_INFO messages - //if(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list != NULL){ - free(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list); - UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = NULL; - //} - //if(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list != NULL){ - free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list); - UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = NULL; - //} - //if(UL_INFO->harq_ind.harq_indication_body.harq_pdu_list !=NULL){ - free(UL_INFO->harq_ind.harq_indication_body.harq_pdu_list); - UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = NULL; - //} - //if(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list!=NULL){ - free(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list); - UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = NULL; - //} - free(UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list); - UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list = NULL; - free(UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list); - UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list = NULL; - free(UL_INFO); - UL_INFO = NULL; - // De-allocate memory of nfapi requests copies before next subframe round if(dl_config_req!=NULL) { if(dl_config_req->vendor_extension!=NULL) { @@ -1334,6 +1309,22 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) } } + // Free UL_INFO messages + free(UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list); + UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list = NULL; + free(UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list); + UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list = NULL; + free(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list); + UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = NULL; + free(UL_INFO->harq_ind.harq_indication_body.harq_pdu_list); + UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = NULL; + free(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list); + UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = NULL; + free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list); + UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = NULL; + free(UL_INFO); + UL_INFO = NULL; + // thread finished free(arg); return &UE_thread_rxtx_retval; From 15a2767562fc6e3eba71c2776e67c6cd497636f6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Mar 2020 11:39:38 +0100 Subject: [PATCH 12/25] Don't call fill_ulsch_cqi_indication_UE_MAC() This functions fills the ULSCH CQI indication message incorrectly. Also, it should only be triggered when the eNB requests CSI. We disable it here and a subsequent commit enables it again. --- openair2/PHY_INTERFACE/phy_stub_UE.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index bff50310b4..6ba238aa75 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -489,7 +489,7 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index); } } - fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti); + //fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti); } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) { @@ -519,7 +519,7 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, if(ulsch_harq_information!=NULL) fill_ulsch_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti); - fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti); + //fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti); } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) { From 8af8836c4beb8db31a57c8cdfbe0de859acb1c8c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 4 Mar 2020 18:21:46 +0100 Subject: [PATCH 13/25] Call oai_nfapi_cqi_indication() to send cqi_indications --- targets/RT/USER/lte-ue.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 940d65282d..0b2f14d384 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -88,7 +88,7 @@ extern void oai_subframe_ind(uint16_t sfn, uint16_t sf); extern void multicast_link_start(void (*rx_handlerP) (unsigned int, char *), unsigned char _multicast_group, char *multicast_ifname); extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind); -extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind); +extern int oai_nfapi_cqi_indication(nfapi_cqi_indication_t *cqi_ind); extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind); extern int oai_nfapi_sr_indication(nfapi_sr_indication_t *ind); extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind); @@ -1252,6 +1252,11 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0; } + if (UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis > 0) { + oai_nfapi_cqi_indication(&UL_INFO->cqi_ind); + UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis = 0; + } + if(UL_INFO->harq_ind.harq_indication_body.number_of_harqs>0) { //LOG_D(MAC, "ul_config_req_UE_MAC 2.4, SFN/SF of PNF counter:%d.%d, number_of_harqs: %d \n", timer_frame, timer_subframe, UL_INFO->harq_ind.harq_indication_body.number_of_harqs); oai_nfapi_harq_indication(&UL_INFO->harq_ind); From b34a0e2f54e382a8e3f4fee776ffe325af4e782d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Mar 2020 10:18:32 +0100 Subject: [PATCH 14/25] Increase (fixed) PHR for UE phy stub mode (L2 sim) --- openair2/LAYER2/MAC/ue_procedures.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 8518cba14c..1205851915 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -2158,7 +2158,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)) { if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { //Substitute with a static value for the MAC layer abstraction (phy_stub mode) - phr_p->PH = 40; + phr_p->PH = 60; } else { phr_p->PH = get_phr_mapping(module_idP, CC_id, eNB_index); } From 943f907ae1d3dc66b271c540fadf068413d6a429 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Mar 2020 16:02:52 +0100 Subject: [PATCH 15/25] Send correct ULSCH CQI indication message in L2 sim --- openair2/PHY_INTERFACE/phy_stub_UE.c | 29 ++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index 6ba238aa75..9aa3400a33 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -241,27 +241,32 @@ void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint16_t frame,uint8_t subfram nfapi_cqi_indication_pdu_t *pdu = &UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list[UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis]; nfapi_cqi_indication_raw_pdu_t *raw_pdu = &UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list[UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis]; + UL_INFO->cqi_ind.sfn_sf = frame << 4 | subframe; + // because of nfapi_vnf.c:733, set message id to 0, not NFAPI_RX_CQI_INDICATION; + UL_INFO->cqi_ind.header.message_id = 0; + UL_INFO->cqi_ind.cqi_indication_body.tl.tag = NFAPI_CQI_INDICATION_BODY_TAG; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; pdu->rx_ue_information.rnti = rnti; // Since we assume that CRC flag is always 0 (ACK) I guess that data_offset should always be 0. - pdu->cqi_indication_rel9.data_offset = 0; + pdu->cqi_indication_rel8.data_offset = 0; // by default set O to rank 1 value - //pdu->cqi_indication_rel9.length = (ulsch_harq->Or1>>3) + ((ulsch_harq->Or1&7) > 0 ? 1 : 0); + //pdu->cqi_indication_rel8.length = (ulsch_harq->Or1>>3) + ((ulsch_harq->Or1&7) > 0 ? 1 : 0); // Not useful field for our case - pdu->cqi_indication_rel9.tl.tag = NFAPI_CQI_INDICATION_REL9_TAG; - pdu->cqi_indication_rel9.length = 0; - pdu->cqi_indication_rel9.ri[0] = 0; + pdu->cqi_indication_rel8.tl.tag = NFAPI_CQI_INDICATION_REL8_TAG; + pdu->cqi_indication_rel8.length = 1; + pdu->cqi_indication_rel8.ri = 0; - pdu->cqi_indication_rel9.timing_advance = 0; - pdu->cqi_indication_rel9.number_of_cc_reported = 1; - pdu->ul_cqi_information.channel = 1; // PUSCH + pdu->cqi_indication_rel8.timing_advance = 0; + //pdu->cqi_indication_rel8.number_of_cc_reported = 1; + pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; + pdu->ul_cqi_information.channel = 1; // PUSCH - // Not sure how to substitute this. This should be the actual CQI value? So can - // we hardcode it to a specific value? - //memcpy((void*)raw_pdu->pdu,ulsch_harq->o,pdu->cqi_indication_rel9.length); - raw_pdu->pdu[0] = 7; + // eNB_scheduler_primitives.c:4839: the upper four bits seem to be the CQI + const int cqi = 15; + raw_pdu->pdu[0] = cqi << 4; From 6866be7175ca86af7ab229c695ec475730589cca Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Mar 2020 15:28:36 +0100 Subject: [PATCH 16/25] Trigger ULSCH CQI ind only when instructed --- openair2/PHY_INTERFACE/phy_stub_UE.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index 9aa3400a33..9357e354d4 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -494,8 +494,6 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index); } } - //fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti); - } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) { @@ -524,8 +522,6 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, if(ulsch_harq_information!=NULL) fill_ulsch_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti); - //fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti); - } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) { @@ -812,8 +808,18 @@ int hi_dci0_req_UE_MAC(nfapi_hi_dci0_request_t* req, module_id_t Mod_id) if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) { - LOG_D(PHY,"[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - NFAPI_HI_DCI0_DCI_PDU_TYPE not used \n", NFAPI_SFNSF2DEC(req->sfn_sf), i); - + LOG_D(PHY, + "[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - " + "NFAPI_HI_DCI0_DCI_PDU_TYPE\n", + NFAPI_SFNSF2DEC(req->sfn_sf), + i); + const nfapi_hi_dci0_dci_pdu_rel8_t *dci = &req->hi_dci0_request_body.hi_dci0_pdu_list[i].dci_pdu.dci_pdu_rel8; + if (dci->rnti != UE_mac_inst[Mod_id].crnti) + continue; + const int sfn = NFAPI_SFNSF2SFN(req->sfn_sf); + const int sf = NFAPI_SFNSF2SF(req->sfn_sf); + if (dci->cqi_csi_request) + fill_ulsch_cqi_indication_UE_MAC(Mod_id, sfn, sf, UL_INFO, dci->rnti); } else if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type == NFAPI_HI_DCI0_HI_PDU_TYPE) { From 6ec6c8b261f99427724c0c428502638daeea6fbf Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Mar 2020 16:02:22 +0100 Subject: [PATCH 17/25] Request CQI in all NFAPI modes (i.e., also for L2 sim) --- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 49 ++++++++++------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index d240e35a87..7c3b536de2 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -1496,38 +1496,33 @@ schedule_ulsch_rnti(module_id_t module_idP, if (status >= RRC_CONNECTED && UE_sched_ctrl_ptr->cqi_req_timer > 30) { if (UE_sched_ctrl_ptr->cqi_received == 0) { - if (NFAPI_MODE != NFAPI_MONOLITHIC) { - cqi_req = 0; - } else { - cqi_req = 1; - LOG_D(MAC,"Setting CQI_REQ (timer %d)\n",UE_sched_ctrl_ptr->cqi_req_timer); + cqi_req = 1; + LOG_D(MAC, + "Setting CQI_REQ (timer %d)\n", + UE_sched_ctrl_ptr->cqi_req_timer); - /* TDD: to be safe, do not ask CQI in special Subframes:36.213/7.2.3 CQI definition */ - if (cc[CC_id].tdd_Config) { - switch (cc[CC_id].tdd_Config->subframeAssignment) { - case 1: - if(subframeP == 1 || subframeP == 6) { - cqi_req=0; - } + /* TDD: to be safe, do not ask CQI in special + * Subframes:36.213/7.2.3 CQI definition */ + if (cc[CC_id].tdd_Config) { + switch (cc[CC_id].tdd_Config->subframeAssignment) { + case 1: + if (subframeP == 1 || subframeP == 6) + cqi_req = 0; + break; - break; + case 3: + if (subframeP == 1) + cqi_req = 0; + break; - case 3: - if(subframeP == 1) { - cqi_req=0; - } - - break; - - default: - LOG_E(MAC," TDD config not supported\n"); - break; - } + default: + LOG_E(MAC, " TDD config not supported\n"); + break; } + } - if(cqi_req == 1) { - UE_sched_ctrl_ptr->cqi_req_flag |= 1 << sched_subframeP; - } + if (cqi_req == 1) { + UE_sched_ctrl_ptr->cqi_req_flag |= 1 << sched_subframeP; } } else { LOG_D(MAC,"Clearing CQI request timer\n"); From 719667895c58bb691599707df0676f18d32c6a6a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Mar 2020 18:24:49 +0100 Subject: [PATCH 18/25] Prevent memory leak in L2 sim due to NFAPI --- targets/RT/USER/lte-ue.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 0b2f14d384..75ed018434 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -1288,6 +1288,13 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) } if(tx_request_pdu_list!=NULL) { + for (int i = 0; i < tx_req_num_elems; i++) { + for (int j = 0; j < tx_request_pdu_list[i].num_segments; j++) { + free(tx_request_pdu_list[i].segments[j].segment_data); + tx_request_pdu_list[i].segments[j].segment_data = NULL; + } + } + tx_req_num_elems = 0; free(tx_request_pdu_list); tx_request_pdu_list = NULL; } From 34e7952944542212e0f2043afc2889a45d3a0eb9 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 5 Mar 2020 18:49:08 +0100 Subject: [PATCH 19/25] CI: Multi. UEs handled by 1 thread (no races) in l2sim --- ci-scripts/runTestOnVM.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index d46ed07bbb..4e1734da63 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -870,9 +870,9 @@ function start_l2_sim_ue { echo "cd /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 if [ $LOC_S1_CONFIGURATION -eq 0 ] then - echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --L2-emul 3 --num-ues $LOC_NB_UES --nums_ue_thread $LOC_NB_UES --nokrnmod 1 --log_config.global_log_options level,nocolor --noS1\" > ./my-lte-softmodem-run.sh " >> $1 + echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --L2-emul 3 --num-ues $LOC_NB_UES --nums_ue_thread 1 --nokrnmod 1 --log_config.global_log_options level,nocolor --noS1\" > ./my-lte-softmodem-run.sh " >> $1 else - echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --L2-emul 3 --num-ues $LOC_NB_UES --nums_ue_thread $LOC_NB_UES --nokrnmod 1 --log_config.global_log_options level,nocolor\" > ./my-lte-softmodem-run.sh " >> $1 + echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --L2-emul 3 --num-ues $LOC_NB_UES --nums_ue_thread 1 --nokrnmod 1 --log_config.global_log_options level,nocolor\" > ./my-lte-softmodem-run.sh " >> $1 fi echo "chmod 775 ./my-lte-softmodem-run.sh" >> $1 echo "cat ./my-lte-softmodem-run.sh" >> $1 From fa7ace4b1d69ef904875246c649dae29ef1c63b3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 6 Mar 2020 19:40:38 +0100 Subject: [PATCH 20/25] Reimplement dl_config_req_UE_MAC() more concisely --- openair2/PHY_INTERFACE/phy_stub_UE.c | 256 ++++++++++++--------------- 1 file changed, 118 insertions(+), 138 deletions(-) diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index 9357e354d4..075ea30d00 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -644,154 +644,134 @@ int tx_req_UE_MAC(nfapi_tx_request_t* req) } -int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) //, nfapi_tx_request_pdu_t* tx_request_pdu_list) -{ - //if (req!=NULL && tx_request_pdu_list!=NULL){ +int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) { int sfn = NFAPI_SFNSF2SFN(req->sfn_sf); int sf = NFAPI_SFNSF2SF(req->sfn_sf); - //Mod_id = 0; // Currently static (only for one UE) but this should change. - /*struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; - L1_rxtx_proc_t *proc = &eNB->proc.L1_proc;*/ nfapi_dl_config_request_pdu_t* dl_config_pdu_list = req->dl_config_request_body.dl_config_pdu_list; - nfapi_dl_config_request_pdu_t *dl_config_pdu_tmp; - //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX:%d/%d RX:%d/%d sfn_sf:%d DCI:%d PDU:%d\n", __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->frame_rx, proc->subframe_rx, NFAPI_SFNSF2DEC(req->sfn_sf), req->dl_config_request_body.number_dci, req->dl_config_request_body.number_pdu); + for (int i = 0; i < req->dl_config_request_body.number_pdu; i++) { + if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) { + const rnti_t rnti = dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti; + const int rnti_type = dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type; + /* We assume the DCI DL PDU is followed by the DLSCH (the standard is + * more free), so advance by one more and directly process the + * following DLSCH PDU */ + i++; + AssertFatal(i < req->dl_config_request_body.number_pdu, + "Need PDU following DCI at index %d, but not found\n", + i); + nfapi_dl_config_request_pdu_t *dl_config_pdu_tmp = &dl_config_pdu_list[i]; + if (dl_config_pdu_tmp->pdu_type != NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) { + LOG_E(MAC, "expected DLSCH PDU at index %d\n", i); + continue; + } + if (rnti != dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti) { + LOG_I(MAC, + "%s(): sfn/sf %d DLSCH PDU RNTI %x does not match DCI RNTI %x\n", + __func__, + NFAPI_SFNSF2DEC(req->sfn_sf), + rnti, + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti); + continue; + } + const int pdu_index = dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index; + if (pdu_index < 0 && pdu_index >= tx_req_num_elems) { + LOG_E(MAC, + "dl_config_req_UE_MAC 2: Problem with receiving data: " + "sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d\n", + NFAPI_SFNSF2DEC(req->sfn_sf), + i, + dl_config_pdu_list[i].pdu_size, + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index); + continue; + } + if (rnti_type == 1) { + // C-RNTI (Normal DLSCH case) + if (UE_mac_inst[Mod_id].crnti != rnti) { + LOG_D(MAC, + "sfn/sf %d/%d DCI not for UE %d/RNTI %x but for RNTI %x, " + "skipping\n", + sfn, sf, Mod_id, UE_mac_inst[Mod_id].crnti, rnti); + continue; + } + LOG_D(MAC, + "%s() Received data: sfn/sf:%d PDU[%d] " + "size:%d, TX_PDU index: %d, tx_req_num_elems: %d \n", + __func__, + NFAPI_SFNSF2DEC(req->sfn_sf), + i, + dl_config_pdu_list[i].pdu_size, + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index, + tx_req_num_elems); + ue_send_sdu(Mod_id, 0, sfn, sf, + tx_request_pdu_list[pdu_index].segments[0].segment_data, + tx_request_pdu_list[pdu_index].segments[0].segment_length, + 0); + } else if (rnti_type == 2) { + if (rnti == 0xFFFF) { /* SI-RNTI */ + if (UE_mac_inst[Mod_id].UE_mode[0] == NOT_SYNCHED) { + /* this check is in the code before refactoring, but I don't know + * why. Leave it in here for the moment */ + continue; + } - - //LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SF:%d%d dl_pdu:%d tx_req:%d hi_dci0:%d ul_cfg:%d num_pdcch_symbols:%d\n", - // frame,subframe,number_dl_pdu,TX_req->tx_request_body.number_of_pdus,number_hi_dci0_pdu,number_ul_pdu, eNB->pdcch_vars[subframe&1].num_pdcch_symbols); - - for (int i=0;idl_config_request_body.number_pdu;i++) - { - //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sfn/sf:%d PDU[%d] size:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size); - //LOG_E(MAC, "dl_config_req_UE_MAC 2 Received real ones: sfn/sf:%d.%d PDU[%d] size:%d\n", sfn, sf, i, dl_config_pdu_list[i].pdu_size); - - if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) - { - if (dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == 1) { - // C-RNTI (Normal DLSCH case) - dl_config_pdu_tmp = &dl_config_pdu_list[i+1]; - if (dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE && UE_mac_inst[Mod_id].crnti == dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti){ - - /*nfapi_tx_request_pdu_t *ptr = tx_request_pdu_list; - ptr += dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index*(sizeof(nfapi_tx_request_pdu_t)); - nfapi_tx_request_pdu_t temp; - memset(&temp, 0, sizeof(nfapi_tx_request_pdu_t)); - //if (!memcmp(&temp, ptr, sizeof(temp)) ... - if( *(char*)ptr != 0){ - //if(tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data!= NULL && tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length >0){ - */ - - // to avoid unexpected error , add check pdu_index is more than 0. - if((dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index >= 0) &&(dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1)){ - //if(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL){ - - LOG_I(MAC, "dl_config_req_UE_MAC 2 Received data: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d, tx_req_num_elems: %d \n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index, tx_req_num_elems); - - ue_send_sdu(Mod_id, 0, sfn, sf, - tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data, - tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length, - 0); - i++; - } - else{ - LOG_E(MAC,"dl_config_req_UE_MAC 2: Problem with receiving data: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d\n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index); - i++; - } - } - else { - LOG_W(MAC,"[UE %d] Frame %d, subframe %d : DLSCH PDU from NFAPI not for this UE \n",Mod_id, sfn,sf); - i++; - } - } - else if (dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == 2) { - dl_config_pdu_tmp = &dl_config_pdu_list[i+1]; - if(dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE && dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti == 0xFFFF && UE_mac_inst[Mod_id].UE_mode[0] != NOT_SYNCHED){ //&& UE_mac_inst[Mod_id].UE_mode[0] != NOT_SYNCHED - - if(dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1){ - //if(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL){ - ue_decode_si(Mod_id, 0, sfn, 0, - tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data, - tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length); - i++; - } - else{ - LOG_E(MAC,"dl_config_req_UE_MAC 3: Problem with receiving SI: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d\n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index); - i++; - } - } - else if(dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE && dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti == 0xFFFE){ - // P_RNTI case - //pdu = Tx_req->tx_request_body.tx_pdu_list[dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data; - - if (dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1){ - //if(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL){ - ue_decode_p(Mod_id, 0, sfn, 0, - tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data, - tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length); - i++; - } - else{ - LOG_E(MAC,"dl_config_req_UE_MAC: Problem with receiving Paging: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d\n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index); - i++; - } - } - else if(dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) { - // RA-RNTI case - LOG_E(MAC,"dl_config_req_UE_MAC 4 Received RAR? \n"); - // RNTI parameter not actually used. Provided only to comply with existing function definition. - // Not sure about parameters to fill the preamble index. - //rnti_t c_rnti = UE_mac_inst[Mod_id].crnti; - rnti_t ra_rnti = UE_mac_inst[Mod_id].RA_prach_resources.ra_RNTI; - if ((UE_mac_inst[Mod_id].UE_mode[0] != PUSCH) && - (UE_mac_inst[Mod_id].RA_prach_resources.Msg3!=NULL) && (ra_rnti== dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti) && - //(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL)) { - (dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1)) { - LOG_E(MAC,"dl_config_req_UE_MAC 5 Received RAR, PreambleIndex: %d \n", UE_mac_inst[Mod_id].RA_prach_resources.ra_PreambleIndex); - ue_process_rar(Mod_id, 0, sfn, - ra_rnti, //RA-RNTI - tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data, - &dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti, //t-crnti - UE_mac_inst[Mod_id].RA_prach_resources.ra_PreambleIndex, - tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data); - UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE; - UE_mac_inst[Mod_id].first_ULSCH_Tx = 1; //Expecting an UL_CONFIG_ULSCH_PDU to enable Msg3 Txon (first ULSCH Txon for the UE) - } - i++; - } - else { - LOG_E(MAC,"[UE %d] Frame %d, subframe %d : Cannot extract DLSCH PDU from NFAPI 2\n",Mod_id, sfn, sf); - i++; - } - - } - } - else if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_BCH_PDU_TYPE) - { - // BCH case - // Last parameter is 1 if first time synchronization and zero otherwise. Not sure which value to put - // for our case. - //LOG_E(MAC,"dl_config_req_UE_MAC 4 Received MIB: sfn/sf: %d.%d \n", sfn, sf); - if(UE_mac_inst[Mod_id].UE_mode[0] == NOT_SYNCHED){ - dl_phy_sync_success(Mod_id,sfn,0, 1); - LOG_E(MAC,"dl_config_req_UE_MAC 5 Received MIB: UE_mode: %d, sfn/sf: %d.%d\n", UE_mac_inst[Mod_id].UE_mode[0], sfn, sf); - UE_mac_inst[Mod_id].UE_mode[0]=PRACH; - } - else - dl_phy_sync_success(Mod_id,sfn,0, 0); - - } - - else - { - //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() UNKNOWN:%d\n", __FUNCTION__, dl_config_pdu_list[i].pdu_type); + ue_decode_si(Mod_id, 0, sfn, 0, + tx_request_pdu_list[pdu_index].segments[0].segment_data, + tx_request_pdu_list[pdu_index].segments[0].segment_length); + } else if (rnti == 0xFFFE) { /* PI-RNTI */ + LOG_I(MAC, "%s() Received paging message: sfn/sf:%d PDU[%d]\n", + __func__, NFAPI_SFNSF2DEC(req->sfn_sf), i); + ue_decode_p(Mod_id, 0, sfn, 0, + tx_request_pdu_list[pdu_index].segments[0].segment_data, + tx_request_pdu_list[pdu_index].segments[0].segment_length); + } else if (rnti == 0x0002) { /* RA-RNTI */ + LOG_E(MAC, "%s(): Received RAR?\n", __func__); + // RNTI parameter not actually used. Provided only to comply with + // existing function definition. Not sure about parameters to fill + // the preamble index. + const rnti_t ra_rnti = UE_mac_inst[Mod_id].RA_prach_resources.ra_RNTI; + DevAssert(ra_rnti == 0x0002); + if (UE_mac_inst[Mod_id].UE_mode[0] != PUSCH + && UE_mac_inst[Mod_id].RA_prach_resources.Msg3 != NULL + && ra_rnti == dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti) { + LOG_E(MAC, + "dl_config_req_UE_MAC 5 Received RAR, PreambleIndex: %d \n", + UE_mac_inst[Mod_id].RA_prach_resources.ra_PreambleIndex); + ue_process_rar(Mod_id, 0, sfn, + ra_rnti, //RA-RNTI + tx_request_pdu_list[pdu_index].segments[0].segment_data, + &dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti, //t-crnti + UE_mac_inst[Mod_id].RA_prach_resources.ra_PreambleIndex, + tx_request_pdu_list[pdu_index].segments[0].segment_data); + UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE; + // Expecting an UL_CONFIG_ULSCH_PDU to enable Msg3 Txon (first + // ULSCH Txon for the UE) + UE_mac_inst[Mod_id].first_ULSCH_Tx = 1; + } + } else { + LOG_W(MAC, "can not handle special RNTI %x\n", rnti); + } + } + } else if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_BCH_PDU_TYPE) { + // BCH case: Last parameter is 1 if first time synchronization and zero + // otherwise. Not sure which value to put for our case. + if (UE_mac_inst[Mod_id].UE_mode[0] == NOT_SYNCHED){ + dl_phy_sync_success(Mod_id, sfn, 0, 1); + LOG_E(MAC, + "%s(): Received MIB: UE_mode: %d, sfn/sf: %d.%d\n", + __func__, + UE_mac_inst[Mod_id].UE_mode[0], + sfn, + sf); + UE_mac_inst[Mod_id].UE_mode[0] = PRACH; + } else { + dl_phy_sync_success(Mod_id, sfn, 0, 0); + } } } - return 0; - } From 84482489e4b393f4442747c2b766fe87c2bed761 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 8 Mar 2020 18:22:53 +0100 Subject: [PATCH 21/25] Reformat phy_stub_UE.c with clang-format --- openair2/PHY_INTERFACE/phy_stub_UE.c | 1418 ++++++++++++++------------ 1 file changed, 743 insertions(+), 675 deletions(-) diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index 075ea30d00..bf2bbf7429 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -1,14 +1,29 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ -//#include "openair1/PHY/defs.h" -//#include "openair2/PHY_INTERFACE/IF_Module.h" -//#include "openair1/PHY/extern.h" #include "openair2/LAYER2/MAC/mac_extern.h" #include "openair2/LAYER2/MAC/mac.h" #include "openair2/LAYER2/MAC/mac_proto.h" -//#include "openair2/LAYER2/MAC/vars.h" #include "openair1/SCHED_UE/sched_UE.h" #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h" -//#include "common/ran_context.h" #include "openair2/PHY_INTERFACE/phy_stub_UE.h" #include "openair2/ENB_APP/L1_paramdef.h" #include "openair2/ENB_APP/enb_paramdef.h" @@ -16,14 +31,12 @@ #include "common/config/config_load_configmodule.h" #include "common/config/config_userapi.h" -//#define DEADLINE_SCHEDULER 1 - - -extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind); -extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind); extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); -void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port); - +void configure_nfapi_pnf(char *vnf_ip_addr, + int vnf_p5_port, + char *pnf_ip_addr, + int pnf_p7_port, + int vnf_p7_port); UL_IND_t *UL_INFO = NULL; nfapi_tx_request_pdu_t* tx_request_pdu_list = NULL; @@ -31,8 +44,6 @@ nfapi_dl_config_request_t* dl_config_req = NULL; nfapi_ul_config_request_t* ul_config_req = NULL; nfapi_hi_dci0_request_t* hi_dci0_req = NULL; -//extern uint8_t nfapi_pnf; -//UL_IND_t *UL_INFO; extern nfapi_tx_request_pdu_t* tx_request_pdu[1023][10][10]; //extern int timer_subframe; //extern int timer_frame; @@ -42,608 +53,661 @@ extern uint16_t sf_ahead; void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); void Msg3_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); +void fill_rx_indication_UE_MAC(module_id_t Mod_id, + int frame, + int subframe, + UL_IND_t *UL_INFO, + uint8_t *ulsch_buffer, + uint16_t buflen, + uint16_t rnti, + int index) { + nfapi_rx_indication_pdu_t *pdu; + int timing_advance_update; + pthread_mutex_lock(&fill_ul_mutex.rx_mutex); -void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND_t* UL_INFO, uint8_t *ulsch_buffer, uint16_t buflen, uint16_t rnti, int index) -{ - nfapi_rx_indication_pdu_t *pdu; + UL_INFO->rx_ind.sfn_sf = frame << 4 | subframe; + UL_INFO->rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; + UL_INFO->rx_ind.vendor_extension = ul_config_req->vendor_extension; - int timing_advance_update; + pdu = &UL_INFO->rx_ind.rx_indication_body + .rx_pdu_list[UL_INFO->rx_ind.rx_indication_body.number_of_pdus]; + // pdu = &UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[index]; + // pdu->rx_ue_information.handle = eNB->ulsch[UE_id]->handle; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdu->rx_ue_information.rnti = rnti; + pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; + pdu->rx_indication_rel8.length = buflen; + pdu->rx_indication_rel8.offset = 1; + pdu->rx_indication_rel9.tl.tag = NFAPI_RX_INDICATION_REL9_TAG; + pdu->rx_indication_rel9.timing_advance_r9 = 0; - // pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); - // change for mutiple UE's simulation. - pthread_mutex_lock(&fill_ul_mutex.rx_mutex); + // ulsch_buffer is necessary to keep its value. + pdu->data = malloc(buflen); + memcpy(pdu->data, ulsch_buffer, buflen); + // estimate timing advance for MAC + timing_advance_update = 0; // Don't know what to put here + pdu->rx_indication_rel8.timing_advance = timing_advance_update; + int SNRtimes10 = 640; - UL_INFO->rx_ind.sfn_sf = frame<<4| subframe; - UL_INFO->rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; - UL_INFO->rx_ind.vendor_extension = ul_config_req->vendor_extension; - - - pdu = &UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[UL_INFO->rx_ind.rx_indication_body.number_of_pdus]; - //pdu = &UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[index]; - - // pdu->rx_ue_information.handle = eNB->ulsch[UE_id]->handle; - pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; - pdu->rx_ue_information.rnti = rnti; - pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; - //pdu->rx_indication_rel8.length = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3; - pdu->rx_indication_rel8.length = buflen; - pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation - pdu->rx_indication_rel9.tl.tag = NFAPI_RX_INDICATION_REL9_TAG; - pdu->rx_indication_rel9.timing_advance_r9 = 0; - - // ulsch_buffer is necessary to keep its value. - //pdu->data = ulsch_buffer; - pdu->data = malloc(buflen); - memcpy(pdu->data,ulsch_buffer,buflen); - // estimate timing advance for MAC - //sync_pos = lte_est_timing_advance_pusch(eNB,UE_id); - timing_advance_update = 0; // Don't know what to put here - pdu->rx_indication_rel8.timing_advance = timing_advance_update; - - int SNRtimes10 = 640; - - if (SNRtimes10 < -640) pdu->rx_indication_rel8.ul_cqi=0; - else if (SNRtimes10 > 635) pdu->rx_indication_rel8.ul_cqi=255; - else pdu->rx_indication_rel8.ul_cqi=(640+SNRtimes10)/5; - - - UL_INFO->rx_ind.rx_indication_body.number_of_pdus++; - UL_INFO->rx_ind.sfn_sf = frame<<4 | subframe; - // pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); - // change for mutiple UE's simulation. - pthread_mutex_unlock(&fill_ul_mutex.rx_mutex); - + if (SNRtimes10 < -640) + pdu->rx_indication_rel8.ul_cqi = 0; + else if (SNRtimes10 > 635) + pdu->rx_indication_rel8.ul_cqi = 255; + else + pdu->rx_indication_rel8.ul_cqi = (640 + SNRtimes10) / 5; + UL_INFO->rx_ind.rx_indication_body.number_of_pdus++; + UL_INFO->rx_ind.sfn_sf = frame << 4 | subframe; + pthread_mutex_unlock(&fill_ul_mutex.rx_mutex); } -void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint16_t rnti) { - - - // change for mutiple UE's simulation. - //pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); +void fill_sr_indication_UE_MAC(int Mod_id, + int frame, + int subframe, + UL_IND_t *UL_INFO, + uint16_t rnti) { pthread_mutex_lock(&fill_ul_mutex.sr_mutex); - nfapi_sr_indication_t *sr_ind = &UL_INFO->sr_ind; - nfapi_sr_indication_body_t *sr_ind_body = &sr_ind->sr_indication_body; - nfapi_sr_indication_pdu_t *pdu = &sr_ind_body->sr_pdu_list[sr_ind_body->number_of_srs]; - UL_INFO->sr_ind.vendor_extension = ul_config_req->vendor_extension; + nfapi_sr_indication_t *sr_ind = &UL_INFO->sr_ind; + nfapi_sr_indication_body_t *sr_ind_body = &sr_ind->sr_indication_body; + nfapi_sr_indication_pdu_t *pdu = &sr_ind_body->sr_pdu_list[sr_ind_body->number_of_srs]; + UL_INFO->sr_ind.vendor_extension = ul_config_req->vendor_extension; - //nfapi_sr_indication_pdu_t *pdu = &UL_INFO->sr_ind.sr_indication_body.sr_pdu_list[UL_INFO->rx_ind.rx_indication_body.number_of_pdus]; - - sr_ind->sfn_sf = frame<<4|subframe; + sr_ind->sfn_sf = frame << 4 | subframe; sr_ind->header.message_id = NFAPI_RX_SR_INDICATION; sr_ind_body->tl.tag = NFAPI_SR_INDICATION_BODY_TAG; - pdu->instance_length = 0; // don't know what to do with this + pdu->instance_length = 0; // don't know what to do with this // pdu->rx_ue_information.handle = handle; - pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; - pdu->rx_ue_information.rnti = rnti; //UE_mac_inst[Mod_id].crnti - - - // dependency from PHY not sure how to substitute this. Should we hardcode it? - //int SNRtimes10 = dB_fixed_times10(stat) - 200;//(10*eNB->measurements.n0_power_dB[0]); - int SNRtimes10 = 640; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdu->rx_ue_information.rnti = rnti; // UE_mac_inst[Mod_id].crnti pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; - - - if (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0; - else if (SNRtimes10 > 635) pdu->ul_cqi_information.ul_cqi=255; - else pdu->ul_cqi_information.ul_cqi=(640+SNRtimes10)/5; pdu->ul_cqi_information.channel = 0; - //UL_INFO->rx_ind.rx_indication_body.number_of_pdus++; + int SNRtimes10 = 640; + if (SNRtimes10 < -640) + pdu->ul_cqi_information.ul_cqi = 0; + else if (SNRtimes10 > 635) + pdu->ul_cqi_information.ul_cqi = 255; + else + pdu->ul_cqi_information.ul_cqi = (640 + SNRtimes10) / 5; + + // UL_INFO->rx_ind.rx_indication_body.number_of_pdus++; sr_ind_body->number_of_srs++; - // change for mutiple UE's simulation. - // pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); pthread_mutex_unlock(&fill_ul_mutex.sr_mutex); } - -void fill_crc_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t crc_flag, int index, uint16_t rnti) { - - // change for mutiple UE's simulation. - //pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); +void fill_crc_indication_UE_MAC(int Mod_id, + int frame, + int subframe, + UL_IND_t *UL_INFO, + uint8_t crc_flag, + int index, + uint16_t rnti) { pthread_mutex_lock(&fill_ul_mutex.crc_mutex); - // REMEMBER HAVE EXCHANGED THE FOLLOWING TWO LINES HERE! - nfapi_crc_indication_pdu_t *pdu = &UL_INFO->crc_ind.crc_indication_body.crc_pdu_list[UL_INFO->crc_ind.crc_indication_body.number_of_crcs]; + nfapi_crc_indication_pdu_t *pdu = + &UL_INFO->crc_ind.crc_indication_body + .crc_pdu_list[UL_INFO->crc_ind.crc_indication_body.number_of_crcs]; - UL_INFO->crc_ind.sfn_sf = frame<<4| subframe; - UL_INFO->crc_ind.vendor_extension = ul_config_req->vendor_extension; - UL_INFO->crc_ind.header.message_id = NFAPI_CRC_INDICATION; + UL_INFO->crc_ind.sfn_sf = frame << 4 | subframe; + UL_INFO->crc_ind.vendor_extension = ul_config_req->vendor_extension; + UL_INFO->crc_ind.header.message_id = NFAPI_CRC_INDICATION; UL_INFO->crc_ind.crc_indication_body.tl.tag = NFAPI_CRC_INDICATION_BODY_TAG; - pdu->instance_length = 0; // don't know what to do with this - // pdu->rx_ue_information.handle = handle; - pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdu->instance_length = 0; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; - //pdu->rx_ue_information.rnti = UE_mac_inst[Mod_id].crnti; - pdu->rx_ue_information.rnti = rnti; - pdu->crc_indication_rel8.tl.tag = NFAPI_CRC_INDICATION_REL8_TAG; - pdu->crc_indication_rel8.crc_flag = crc_flag; + pdu->rx_ue_information.rnti = rnti; + pdu->crc_indication_rel8.tl.tag = NFAPI_CRC_INDICATION_REL8_TAG; + pdu->crc_indication_rel8.crc_flag = crc_flag; UL_INFO->crc_ind.crc_indication_body.number_of_crcs++; - LOG_D(PHY, "%s() rnti:%04x pdus:%d\n", __FUNCTION__, pdu->rx_ue_information.rnti, UL_INFO->crc_ind.crc_indication_body.number_of_crcs); + LOG_D(PHY, + "%s() rnti:%04x pdus:%d\n", + __FUNCTION__, + pdu->rx_ue_information.rnti, + UL_INFO->crc_ind.crc_indication_body.number_of_crcs); - // change for mutiple UE's simulation. - // pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); pthread_mutex_unlock(&fill_ul_mutex.crc_mutex); } -void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t ra_PreambleIndex, uint16_t ra_RNTI) { +void fill_rach_indication_UE_MAC(int Mod_id, + int frame, + int subframe, + UL_IND_t *UL_INFO, + uint8_t ra_PreambleIndex, + uint16_t ra_RNTI) { + LOG_D(MAC, "fill_rach_indication_UE_MAC 1 \n"); - LOG_D(MAC, "fill_rach_indication_UE_MAC 1 \n"); + pthread_mutex_lock(&fill_ul_mutex.rach_mutex); - // change for mutiple UE's simulation. - // pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); - pthread_mutex_lock(&fill_ul_mutex.rach_mutex); + UL_INFO->rach_ind.rach_indication_body.number_of_preambles = 1; - // memory allocation and free memory of UL_INFO are done in UE_phy_stub_single_thread_rxn_txnp4. - // UL_INFO = (UL_IND_t*)malloc(sizeof(UL_IND_t)); + UL_INFO->rach_ind.header.message_id = NFAPI_RACH_INDICATION; + UL_INFO->rach_ind.sfn_sf = frame << 4 | subframe; + UL_INFO->rach_ind.vendor_extension = NULL; - UL_INFO->rach_ind.rach_indication_body.number_of_preambles = 1; + UL_INFO->rach_ind.rach_indication_body.tl.tag = NFAPI_RACH_INDICATION_BODY_TAG; - //eNB->UL_INFO.rach_ind.preamble_list = &eNB->preamble_list[0]; - UL_INFO->rach_ind.header.message_id = NFAPI_RACH_INDICATION; - UL_INFO->rach_ind.sfn_sf = frame<<4 | subframe; - UL_INFO->rach_ind.vendor_extension = NULL; + const int np = UL_INFO->rach_ind.rach_indication_body.number_of_preambles; + UL_INFO->rach_ind.rach_indication_body.preamble_list = + calloc(np, sizeof(nfapi_preamble_pdu_t)); + UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.tl.tag = + NFAPI_PREAMBLE_REL8_TAG; + UL_INFO->rach_ind.rach_indication_body.preamble_list[0] + .preamble_rel8.timing_advance = 0; // Not sure about that - UL_INFO->rach_ind.rach_indication_body.tl.tag = NFAPI_RACH_INDICATION_BODY_TAG; + // The two following should get extracted from the call to + // get_prach_resources(). + UL_INFO->rach_ind.rach_indication_body.preamble_list[0] + .preamble_rel8.preamble = ra_PreambleIndex; + UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti = + ra_RNTI; + // UL_INFO->rach_ind.rach_indication_body.number_of_preambles++; + UL_INFO->rach_ind.rach_indication_body.preamble_list[0] + .preamble_rel13.rach_resource_type = 0; + UL_INFO->rach_ind.rach_indication_body.preamble_list[0].instance_length = 0; - UL_INFO->rach_ind.rach_indication_body.preamble_list = (nfapi_preamble_pdu_t*)malloc(UL_INFO->rach_ind.rach_indication_body.number_of_preambles*sizeof(nfapi_preamble_pdu_t)); - UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.tl.tag = NFAPI_PREAMBLE_REL8_TAG; - UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.timing_advance = 0; // Not sure about that + LOG_I(PHY, + "UE Filling NFAPI indication for RACH : TA %d, Preamble %d, rnti %x, " + "rach_resource_type %d\n", + UL_INFO->rach_ind.rach_indication_body.preamble_list[0] + .preamble_rel8.timing_advance, + UL_INFO->rach_ind.rach_indication_body.preamble_list[0] + .preamble_rel8.preamble, + UL_INFO->rach_ind.rach_indication_body.preamble_list[0] + .preamble_rel8.rnti, + UL_INFO->rach_ind.rach_indication_body.preamble_list[0] + .preamble_rel13.rach_resource_type); - //The two following should get extracted from the call to get_prach_resources(). - UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.preamble = ra_PreambleIndex; - UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti = ra_RNTI; - //UL_INFO->rach_ind.rach_indication_body.number_of_preambles++; - - - UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel13.rach_resource_type = 0; - UL_INFO->rach_ind.rach_indication_body.preamble_list[0].instance_length = 0; - - - //LOG_E(PHY,"\n\n\n\nDJP - this needs to be sent to VNF **********************************************\n\n\n\n"); - LOG_I(PHY,"UE Filling NFAPI indication for RACH : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", - UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.timing_advance, - UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.preamble, - UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti, - UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel13.rach_resource_type); - - // This function is currently defined only in the nfapi-RU-RAU-split so we should call it when we merge - // with that branch. - oai_nfapi_rach_ind(&UL_INFO->rach_ind); - free(UL_INFO->rach_ind.rach_indication_body.preamble_list); - - // memory allocation and free memory of UL_INFO are done in UE_phy_stub_single_thread_rxn_txnp4. - //free(UL_INFO); - - //} - // change for mutiple UE's simulation. - // pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); - pthread_mutex_unlock(&fill_ul_mutex.rach_mutex); + // This function is currently defined only in the nfapi-RU-RAU-split so we + // should call it when we merge with that branch. + oai_nfapi_rach_ind(&UL_INFO->rach_ind); + free(UL_INFO->rach_ind.rach_indication_body.preamble_list); + pthread_mutex_unlock(&fill_ul_mutex.rach_mutex); } -void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint16_t frame,uint8_t subframe, UL_IND_t *UL_INFO, uint16_t rnti) { +void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, + uint16_t frame, + uint8_t subframe, + UL_IND_t *UL_INFO, + uint16_t rnti) { + pthread_mutex_lock(&fill_ul_mutex.cqi_mutex); + nfapi_cqi_indication_pdu_t *pdu = + &UL_INFO->cqi_ind.cqi_indication_body + .cqi_pdu_list[UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis]; + nfapi_cqi_indication_raw_pdu_t *raw_pdu = + &UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list + [UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis]; - // change for mutiple UE's simulation. - //pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); - pthread_mutex_lock(&fill_ul_mutex.cqi_mutex); - nfapi_cqi_indication_pdu_t *pdu = &UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list[UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis]; - nfapi_cqi_indication_raw_pdu_t *raw_pdu = &UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list[UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis]; + UL_INFO->cqi_ind.sfn_sf = frame << 4 | subframe; + // because of nfapi_vnf.c:733, set message id to 0, not + // NFAPI_RX_CQI_INDICATION; + UL_INFO->cqi_ind.header.message_id = 0; + UL_INFO->cqi_ind.cqi_indication_body.tl.tag = NFAPI_CQI_INDICATION_BODY_TAG; - UL_INFO->cqi_ind.sfn_sf = frame << 4 | subframe; - // because of nfapi_vnf.c:733, set message id to 0, not NFAPI_RX_CQI_INDICATION; - UL_INFO->cqi_ind.header.message_id = 0; - UL_INFO->cqi_ind.cqi_indication_body.tl.tag = NFAPI_CQI_INDICATION_BODY_TAG; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdu->rx_ue_information.rnti = rnti; + // Since we assume that CRC flag is always 0 (ACK) I guess that data_offset + // should always be 0. + pdu->cqi_indication_rel8.data_offset = 0; - pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; - pdu->rx_ue_information.rnti = rnti; - // Since we assume that CRC flag is always 0 (ACK) I guess that data_offset should always be 0. - pdu->cqi_indication_rel8.data_offset = 0; - - // by default set O to rank 1 value - //pdu->cqi_indication_rel8.length = (ulsch_harq->Or1>>3) + ((ulsch_harq->Or1&7) > 0 ? 1 : 0); - // Not useful field for our case - pdu->cqi_indication_rel8.tl.tag = NFAPI_CQI_INDICATION_REL8_TAG; - pdu->cqi_indication_rel8.length = 1; - pdu->cqi_indication_rel8.ri = 0; - - - pdu->cqi_indication_rel8.timing_advance = 0; - //pdu->cqi_indication_rel8.number_of_cc_reported = 1; - pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; - pdu->ul_cqi_information.channel = 1; // PUSCH - - // eNB_scheduler_primitives.c:4839: the upper four bits seem to be the CQI - const int cqi = 15; - raw_pdu->pdu[0] = cqi << 4; + pdu->cqi_indication_rel8.tl.tag = NFAPI_CQI_INDICATION_REL8_TAG; + pdu->cqi_indication_rel8.length = 1; + pdu->cqi_indication_rel8.ri = 0; + pdu->cqi_indication_rel8.timing_advance = 0; + // pdu->cqi_indication_rel8.number_of_cc_reported = 1; + pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; + pdu->ul_cqi_information.channel = 1; // PUSCH + // eNB_scheduler_primitives.c:4839: the upper four bits seem to be the CQI + const int cqi = 15; + raw_pdu->pdu[0] = cqi << 4; UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis++; - // change for mutiple UE's simulation. - //pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); pthread_mutex_unlock(&fill_ul_mutex.cqi_mutex); } -void fill_ulsch_harq_indication_UE_MAC(int Mod_id, int frame,int subframe, UL_IND_t *UL_INFO, nfapi_ul_config_ulsch_harq_information *harq_information, uint16_t rnti) -{ - - // change for mutiple UE's simulation. - //pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); +void fill_ulsch_harq_indication_UE_MAC( + int Mod_id, + int frame, + int subframe, + UL_IND_t *UL_INFO, + nfapi_ul_config_ulsch_harq_information *harq_information, + uint16_t rnti) { pthread_mutex_lock(&fill_ul_mutex.harq_mutex); - nfapi_harq_indication_pdu_t *pdu = &UL_INFO->harq_ind.harq_indication_body.harq_pdu_list[UL_INFO->harq_ind.harq_indication_body.number_of_harqs]; - int i; + nfapi_harq_indication_pdu_t *pdu = + &UL_INFO->harq_ind.harq_indication_body.harq_pdu_list + [UL_INFO->harq_ind.harq_indication_body.number_of_harqs]; UL_INFO->harq_ind.header.message_id = NFAPI_HARQ_INDICATION; - UL_INFO->harq_ind.sfn_sf = frame<<4|subframe; - UL_INFO->harq_ind.vendor_extension = ul_config_req->vendor_extension; + UL_INFO->harq_ind.sfn_sf = frame << 4 | subframe; + UL_INFO->harq_ind.vendor_extension = ul_config_req->vendor_extension; - UL_INFO->harq_ind.harq_indication_body.tl.tag = NFAPI_HARQ_INDICATION_BODY_TAG; + UL_INFO->harq_ind.harq_indication_body.tl.tag = + NFAPI_HARQ_INDICATION_BODY_TAG; - pdu->instance_length = 0; // don't know what to do with this + pdu->instance_length = 0; // don't know what to do with this // pdu->rx_ue_information.handle = handle; - pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; - pdu->rx_ue_information.rnti = rnti; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdu->rx_ue_information.rnti = rnti; // For now we consider only FDD - //if (eNB->frame_parms.frame_type == FDD) { - pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG; - pdu->harq_indication_fdd_rel13.mode = 0; - pdu->harq_indication_fdd_rel13.number_of_ack_nack = harq_information->harq_information_rel10.harq_size; + // if (eNB->frame_parms.frame_type == FDD) { + pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG; + pdu->harq_indication_fdd_rel13.mode = 0; + pdu->harq_indication_fdd_rel13.number_of_ack_nack = + harq_information->harq_information_rel10.harq_size; - // Could this be wrong? Is the number_of_ack_nack field equivalent to O_ACK? - //pdu->harq_indication_fdd_rel13.number_of_ack_nack = ulsch_harq->O_ACK; + // Could this be wrong? Is the number_of_ack_nack field equivalent to O_ACK? + // pdu->harq_indication_fdd_rel13.number_of_ack_nack = ulsch_harq->O_ACK; - for (i=0;iharq_information_rel10.harq_size;i++) { - - pdu->harq_indication_fdd_rel13.harq_tb_n[i] = 1; // Assuming always an ACK (No NACK or DTX) - - } + for (int i = 0; i < harq_information->harq_information_rel10.harq_size; i++) { + pdu->harq_indication_fdd_rel13.harq_tb_n[i] = 1; // Assume always ACK (No NACK or DTX) + } UL_INFO->harq_ind.harq_indication_body.number_of_harqs++; - // change for mutiple UE's simulation. - //pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); - pthread_mutex_unlock(&fill_ul_mutex.harq_mutex);} - + pthread_mutex_unlock(&fill_ul_mutex.harq_mutex); +} void fill_uci_harq_indication_UE_MAC(int Mod_id, int frame, int subframe, UL_IND_t *UL_INFO, nfapi_ul_config_harq_information *harq_information, - uint16_t rnti - /*uint8_t tdd_mapping_mode, - uint16_t tdd_multiplexing_mask*/) { - - - // change for mutiple UE's simulation. - //pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + uint16_t rnti) { pthread_mutex_lock(&fill_ul_mutex.harq_mutex); - nfapi_harq_indication_t *ind = &UL_INFO->harq_ind; + nfapi_harq_indication_t *ind = &UL_INFO->harq_ind; nfapi_harq_indication_body_t *body = &ind->harq_indication_body; - nfapi_harq_indication_pdu_t *pdu = &body->harq_pdu_list[UL_INFO->harq_ind.harq_indication_body.number_of_harqs]; + nfapi_harq_indication_pdu_t *pdu = + &body->harq_pdu_list[UL_INFO->harq_ind.harq_indication_body + .number_of_harqs]; - UL_INFO->harq_ind.vendor_extension = ul_config_req->vendor_extension; + UL_INFO->harq_ind.vendor_extension = ul_config_req->vendor_extension; - ind->sfn_sf = frame<<4|subframe; + ind->sfn_sf = frame << 4 | subframe; ind->header.message_id = NFAPI_HARQ_INDICATION; body->tl.tag = NFAPI_HARQ_INDICATION_BODY_TAG; - pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; - pdu->instance_length = 0; // don't know what to do with this - // pdu->rx_ue_information.handle = handle; - pdu->rx_ue_information.rnti = rnti; + pdu->instance_length = 0; // don't know what to do with this + pdu->rx_ue_information.rnti = rnti; pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; int SNRtimes10 = 640; - - if (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0; - else if (SNRtimes10 > 635) pdu->ul_cqi_information.ul_cqi=255; - else pdu->ul_cqi_information.ul_cqi=(640+SNRtimes10)/5; + if (SNRtimes10 < -640) + pdu->ul_cqi_information.ul_cqi = 0; + else if (SNRtimes10 > 635) + pdu->ul_cqi_information.ul_cqi = 255; + else + pdu->ul_cqi_information.ul_cqi = (640 + SNRtimes10) / 5; pdu->ul_cqi_information.channel = 0; - if(harq_information->harq_information_rel9_fdd.tl.tag == NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG){ - if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) && - (harq_information->harq_information_rel9_fdd.harq_size == 1)) { - - pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG; + if (harq_information->harq_information_rel9_fdd.tl.tag + == NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG) { + if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) + && (harq_information->harq_information_rel9_fdd.harq_size == 1)) { + pdu->harq_indication_fdd_rel13.tl.tag = + NFAPI_HARQ_INDICATION_FDD_REL13_TAG; pdu->harq_indication_fdd_rel13.mode = 0; pdu->harq_indication_fdd_rel13.number_of_ack_nack = 1; - //AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]); - pdu->harq_indication_fdd_rel13.harq_tb_n[0] = 1; // Assuming always an ACK (No NACK or DTX) + // AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, + // "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]); + pdu->harq_indication_fdd_rel13.harq_tb_n[0] = + 1; // Assuming always an ACK (No NACK or DTX) - - } - else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) && - (harq_information->harq_information_rel9_fdd.harq_size == 2)) { - pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG; + } else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) + && (harq_information->harq_information_rel9_fdd.harq_size + == 2)) { + pdu->harq_indication_fdd_rel13.tl.tag = + NFAPI_HARQ_INDICATION_FDD_REL13_TAG; pdu->harq_indication_fdd_rel13.mode = 0; pdu->harq_indication_fdd_rel13.number_of_ack_nack = 2; - pdu->harq_indication_fdd_rel13.harq_tb_n[0] = 1; // Assuming always an ACK (No NACK or DTX) - pdu->harq_indication_fdd_rel13.harq_tb_n[1] = 1; // Assuming always an ACK (No NACK or DTX) - + pdu->harq_indication_fdd_rel13.harq_tb_n[0] = + 1; // Assuming always an ACK (No NACK or DTX) + pdu->harq_indication_fdd_rel13.harq_tb_n[1] = + 1; // Assuming always an ACK (No NACK or DTX) } - }else if(harq_information->harq_information_rel10_tdd.tl.tag == NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG ){ - if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 0) && - (harq_information->harq_information_rel10_tdd.harq_size == 1)) { - pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; - pdu->harq_indication_tdd_rel13.mode = 0; - pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1; - pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1; - - } else if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 1) && - (harq_information->harq_information_rel10_tdd.harq_size == 2)) { - pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; - pdu->harq_indication_tdd_rel13.mode = 0; - pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1; - pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1; - pdu->harq_indication_tdd_rel13.harq_data[1].bundling.value_0 = 1; - - } - } else AssertFatal(1==0,"only format 1a/b for now, received \n"); + } else if (harq_information->harq_information_rel10_tdd.tl.tag + == NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG) { + if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 0) + && (harq_information->harq_information_rel10_tdd.harq_size == 1)) { + pdu->harq_indication_tdd_rel13.tl.tag = + NFAPI_HARQ_INDICATION_TDD_REL13_TAG; + pdu->harq_indication_tdd_rel13.mode = 0; + pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1; + pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1; + } else if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 1) + && (harq_information->harq_information_rel10_tdd.harq_size + == 2)) { + pdu->harq_indication_tdd_rel13.tl.tag = + NFAPI_HARQ_INDICATION_TDD_REL13_TAG; + pdu->harq_indication_tdd_rel13.mode = 0; + pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1; + pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1; + pdu->harq_indication_tdd_rel13.harq_data[1].bundling.value_0 = 1; + } + } else + AssertFatal(1 == 0, "only format 1a/b for now, received \n"); UL_INFO->harq_ind.harq_indication_body.number_of_harqs++; - LOG_D(PHY,"Incremented eNB->UL_INFO.harq_ind.number_of_harqs:%d\n", UL_INFO->harq_ind.harq_indication_body.number_of_harqs); - // change for mutiple UE's simulation. - //pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + LOG_D(PHY, + "Incremented eNB->UL_INFO.harq_ind.number_of_harqs:%d\n", + UL_INFO->harq_ind.harq_indication_body.number_of_harqs); pthread_mutex_unlock(&fill_ul_mutex.harq_mutex); - } - void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, - nfapi_ul_config_request_pdu_t *ul_config_pdu, - uint16_t frame,uint8_t subframe,uint8_t srs_present, int index) -{ - + nfapi_ul_config_request_pdu_t *ul_config_pdu, + uint16_t frame, + uint8_t subframe, + uint8_t srs_present, + int index) { if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) { - LOG_D(PHY,"Applying UL config for UE, rnti %x for frame %d, subframe %d\n", - (ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8).rnti,frame,subframe); - uint8_t ulsch_buffer[5477] __attribute__ ((aligned(32))); + LOG_D(PHY, + "Applying UL config for UE, rnti %x for frame %d, subframe %d\n", + (ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8).rnti, + frame, + subframe); + uint8_t ulsch_buffer[5477] __attribute__((aligned(32))); uint16_t buflen = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size; uint16_t rnti = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti; - uint8_t access_mode=SCHEDULED_ACCESS; - if(buflen>0){ - if(UE_mac_inst[Mod_id].first_ULSCH_Tx == 1){ // Msg3 case - LOG_D(MAC, "handle_nfapi_ul_pdu_UE_MAC 2.2, Mod_id:%d, SFN/SF: %d/%d \n", Mod_id, frame, subframe); - fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); - fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti, index); - Msg3_transmitted(Mod_id, 0, frame, 0); - // Modification - UE_mac_inst[Mod_id].UE_mode[0] = PUSCH; - UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + uint8_t access_mode = SCHEDULED_ACCESS; + if (buflen > 0) { + if (UE_mac_inst[Mod_id].first_ULSCH_Tx == 1) { // Msg3 case + LOG_D(MAC, + "handle_nfapi_ul_pdu_UE_MAC 2.2, Mod_id:%d, SFN/SF: %d/%d \n", + Mod_id, + frame, + subframe); + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_rx_indication_UE_MAC(Mod_id, + frame, + subframe, + UL_INFO, + UE_mac_inst[Mod_id].RA_prach_resources.Msg3, + buflen, + rnti, + index); + Msg3_transmitted(Mod_id, 0, frame, 0); + // Modification + UE_mac_inst[Mod_id].UE_mode[0] = PUSCH; + UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; - // This should be done after the reception of the respective hi_dci0 - //UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; - } - else { - ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode); - fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); - fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index); - } + // This should be done after the reception of the respective hi_dci0 + // UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + } else { + ue_get_sdu(Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode); + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_rx_indication_UE_MAC(Mod_id, + frame, + subframe, + UL_INFO, + ulsch_buffer, + buflen, + rnti, + index); + } } } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) { + // AssertFatal((UE_id = + // find_ulsch(ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0, + // "No available UE ULSCH for rnti + // %x\n",ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti); + uint8_t ulsch_buffer[5477] __attribute__((aligned(32))); + uint16_t buflen = + ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.size; + nfapi_ul_config_ulsch_harq_information *ulsch_harq_information = + &ul_config_pdu->ulsch_harq_pdu.harq_information; + uint16_t rnti = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti; + uint8_t access_mode = SCHEDULED_ACCESS; + if (buflen > 0) { + if (UE_mac_inst[Mod_id].first_ULSCH_Tx == 1) { // Msg3 case + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_rx_indication_UE_MAC(Mod_id, + frame, + subframe, + UL_INFO, + UE_mac_inst[Mod_id].RA_prach_resources.Msg3, + buflen, + rnti, + index); + Msg3_transmitted(Mod_id, 0, frame, 0); + // UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + // Modification + UE_mac_inst[Mod_id].UE_mode[0] = PUSCH; + UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + } else { + ue_get_sdu(Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode); + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_rx_indication_UE_MAC(Mod_id, + frame, + subframe, + UL_INFO, + ulsch_buffer, + buflen, + rnti, + index); + } + } + if (ulsch_harq_information != NULL) + fill_ulsch_harq_indication_UE_MAC( + Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti); - //AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0, - // "No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti); - uint8_t ulsch_buffer[5477] __attribute__ ((aligned(32))); - uint16_t buflen = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.size; - nfapi_ul_config_ulsch_harq_information *ulsch_harq_information = &ul_config_pdu->ulsch_harq_pdu.harq_information; - uint16_t rnti = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti; - uint8_t access_mode=SCHEDULED_ACCESS; - if(buflen>0){ - if(UE_mac_inst[Mod_id].first_ULSCH_Tx == 1){ // Msg3 case - fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); - fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti, index); - Msg3_transmitted(Mod_id, 0, frame, 0); - //UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; - // Modification - UE_mac_inst[Mod_id].UE_mode[0] = PUSCH; - UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; - } - else { - ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode); - fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); - fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index); - } + } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) { + uint8_t ulsch_buffer[5477] __attribute__((aligned(32))); + uint16_t buflen = ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.size; - } - if(ulsch_harq_information!=NULL) - fill_ulsch_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti); + uint16_t rnti = ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti; + uint8_t access_mode = SCHEDULED_ACCESS; + if (buflen > 0) { + if (UE_mac_inst[Mod_id].first_ULSCH_Tx == 1) { // Msg3 case + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_rx_indication_UE_MAC(Mod_id, + frame, + subframe, + UL_INFO, + UE_mac_inst[Mod_id].RA_prach_resources.Msg3, + buflen, + rnti, + index); + Msg3_transmitted(Mod_id, 0, frame, 0); + // UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + // Modification + UE_mac_inst[Mod_id].UE_mode[0] = PUSCH; + UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + } else { + ue_get_sdu(Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode); + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_rx_indication_UE_MAC(Mod_id, + frame, + subframe, + UL_INFO, + ulsch_buffer, + buflen, + rnti, + index); + } + } + } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) { + uint8_t ulsch_buffer[5477] __attribute__((aligned(32))); + uint16_t buflen = ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.size; + nfapi_ul_config_ulsch_harq_information *ulsch_harq_information = + &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information; + uint16_t rnti = ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti; + uint8_t access_mode = SCHEDULED_ACCESS; + if (buflen > 0) { + if (UE_mac_inst[Mod_id].first_ULSCH_Tx == 1) { // Msg3 case + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_rx_indication_UE_MAC(Mod_id, + frame, + subframe, + UL_INFO, + UE_mac_inst[Mod_id].RA_prach_resources.Msg3, + buflen, + rnti, + index); + Msg3_transmitted(Mod_id, 0, frame, 0); + // UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + // Modification + UE_mac_inst[Mod_id].UE_mode[0] = PUSCH; + UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + } else { + ue_get_sdu(Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode); + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_rx_indication_UE_MAC(Mod_id, + frame, + subframe, + UL_INFO, + ulsch_buffer, + buflen, + rnti, + index); + } + } + + if (ulsch_harq_information != NULL) + fill_ulsch_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti); + } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) { + uint16_t rnti = ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti; + + nfapi_ul_config_harq_information *ulsch_harq_information = &ul_config_pdu->uci_harq_pdu.harq_information; + if (ulsch_harq_information != NULL) + fill_uci_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti); + } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) { + AssertFatal(1 == 0, "NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE not handled yet\n"); + } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) { + AssertFatal(1 == 0, + "NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE not handled yet\n"); + } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) { + AssertFatal(1 == 0, + "NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE not handled yet\n"); + } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) { + uint16_t rnti = + ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti; + + if (ue_get_SR(Mod_id, 0, frame, 0, rnti, subframe)) + fill_sr_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti); + + } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) { + // AssertFatal((UE_id = + // find_uci(rel8->rnti,proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0, + // "No available UE UCI for rnti + // %x\n",ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti); + + uint16_t rnti = + ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti; + + // We fill the sr_indication only if ue_get_sr() would normally instruct PHY + // to send a SR. + if (ue_get_SR(Mod_id, 0, frame, 0, rnti, subframe)) + fill_sr_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti); + + nfapi_ul_config_harq_information *ulsch_harq_information = + &ul_config_pdu->uci_sr_harq_pdu.harq_information; + if (ulsch_harq_information != NULL) + fill_uci_harq_indication_UE_MAC( + Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti); } - else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) { - uint8_t ulsch_buffer[5477] __attribute__ ((aligned(32))); - uint16_t buflen = ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.size; - - uint16_t rnti = ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti; - uint8_t access_mode=SCHEDULED_ACCESS; - if(buflen>0){ - if(UE_mac_inst[Mod_id].first_ULSCH_Tx == 1){ // Msg3 case - fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); - fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti, index); - Msg3_transmitted(Mod_id, 0, frame, 0); - //UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; - // Modification - UE_mac_inst[Mod_id].UE_mode[0] = PUSCH; - UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; - } - else { - ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode); - fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); - fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index); - } - } - } - else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) { - - uint8_t ulsch_buffer[5477] __attribute__ ((aligned(32))); - uint16_t buflen = ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.size; - nfapi_ul_config_ulsch_harq_information *ulsch_harq_information = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information; - - uint16_t rnti = ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti; - uint8_t access_mode=SCHEDULED_ACCESS; - if(buflen>0){ - if(UE_mac_inst[Mod_id].first_ULSCH_Tx == 1){ // Msg3 case - fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); - fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti, index); - Msg3_transmitted(Mod_id, 0, frame, 0); - //UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; - // Modification - UE_mac_inst[Mod_id].UE_mode[0] = PUSCH; - UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; - } - else { - ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode); - fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); - fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index); - } - } - - if(ulsch_harq_information!=NULL) - fill_ulsch_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti); - } - else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) { - - uint16_t rnti = ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti; - - nfapi_ul_config_harq_information *ulsch_harq_information = &ul_config_pdu->uci_harq_pdu.harq_information; - if(ulsch_harq_information != NULL) - fill_uci_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO,ulsch_harq_information, rnti); - } - else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) { - AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE not handled yet\n"); - } - else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) { - AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE not handled yet\n"); - } - else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) { - AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE not handled yet\n"); - } - else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) { - - uint16_t rnti = ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti; - - if (ue_get_SR(Mod_id ,0,frame, 0, rnti, subframe)) - fill_sr_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti); - - } - else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) { - //AssertFatal((UE_id = find_uci(rel8->rnti,proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0, - // "No available UE UCI for rnti %x\n",ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti); - - uint16_t rnti = ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti; - - // We fill the sr_indication only if ue_get_sr() would normally instruct PHY to send a SR. - if (ue_get_SR(Mod_id ,0,frame, 0, rnti, subframe)) - fill_sr_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO,rnti); - - nfapi_ul_config_harq_information *ulsch_harq_information = &ul_config_pdu->uci_sr_harq_pdu.harq_information; - if (ulsch_harq_information != NULL) - fill_uci_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO,ulsch_harq_information, rnti); - - } - } - - - - - -int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req, int timer_frame, int timer_subframe, module_id_t Mod_id) -{ - //if (req!=NULL){ // && req->ul_config_request_body.ul_config_pdu_list !=NULL){ - LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n", - __FUNCTION__, - NFAPI_SFNSF2DEC(req->sfn_sf), - req->ul_config_request_body.number_of_pdus, - req->ul_config_request_body.rach_prach_frequency_resources, - req->ul_config_request_body.srs_present - ); +int ul_config_req_UE_MAC(nfapi_ul_config_request_t *req, + int timer_frame, + int timer_subframe, + module_id_t Mod_id) { + LOG_D(PHY, + "[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d " + "rach_prach_frequency_resources:%d srs_present:%u\n", + __FUNCTION__, + NFAPI_SFNSF2DEC(req->sfn_sf), + req->ul_config_request_body.number_of_pdus, + req->ul_config_request_body.rach_prach_frequency_resources, + req->ul_config_request_body.srs_present); int sfn = NFAPI_SFNSF2SFN(req->sfn_sf); int sf = NFAPI_SFNSF2SF(req->sfn_sf); + LOG_D(MAC, + "ul_config_req_UE_MAC() TOTAL NUMBER OF UL_CONFIG PDUs: %d, SFN/SF: " + "%d/%d \n", + req->ul_config_request_body.number_of_pdus, + timer_frame, + timer_subframe); - LOG_D(MAC, "ul_config_req_UE_MAC() TOTAL NUMBER OF UL_CONFIG PDUs: %d, SFN/SF: %d/%d \n", req->ul_config_request_body.number_of_pdus, timer_frame, timer_subframe); - - - - for (int i=0;iul_config_request_body.number_of_pdus;i++) - { - - if ( - (req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_mac_inst[Mod_id].crnti) || - (req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == UE_mac_inst[Mod_id].crnti) || - (req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == UE_mac_inst[Mod_id].crnti) || - (req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == UE_mac_inst[Mod_id].crnti) || - (req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].uci_cqi_harq_pdu.ue_information.ue_information_rel8.rnti == UE_mac_inst[Mod_id].crnti) || - (req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].uci_sr_pdu.ue_information.ue_information_rel8.rnti == UE_mac_inst[Mod_id].crnti) || - (req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].uci_cqi_sr_harq_pdu.ue_information.ue_information_rel8.rnti == UE_mac_inst[Mod_id].crnti) - ) - { - - handle_nfapi_ul_pdu_UE_MAC(Mod_id,&req->ul_config_request_body.ul_config_pdu_list[i],sfn,sf,req->ul_config_request_body.srs_present, i); - - } - else - { - //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() PDU:%i UNKNOWN type :%d\n", __FUNCTION__, i, ul_config_pdu_list[i].pdu_type); + const rnti_t rnti = UE_mac_inst[Mod_id].crnti; + for (int i = 0; i < req->ul_config_request_body.number_of_pdus; i++) { + nfapi_ul_config_request_pdu_t* pdu = &req->ul_config_request_body.ul_config_pdu_list[i]; + const int pdu_type = pdu->pdu_type; + if ( (pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE + && pdu->ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) + || (pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE + && pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) + || (pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE + && pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) + || (pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE + && pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) + || (pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE + && pdu->uci_cqi_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) + || (pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE + && pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti == rnti) + || (pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE + && pdu->uci_cqi_sr_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) { + handle_nfapi_ul_pdu_UE_MAC( + Mod_id, pdu, sfn, sf, req->ul_config_request_body.srs_present, i); + } else { + // NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() PDU:%i UNKNOWN type :%d\n", + // __FUNCTION__, i, ul_config_pdu_list[i].pdu_type); } } -// } - return 0; } +int tx_req_UE_MAC(nfapi_tx_request_t *req) { + LOG_D(PHY, + "%s() SFN/SF:%d/%d PDUs:%d\n", + __FUNCTION__, + NFAPI_SFNSF2SFN(req->sfn_sf), + NFAPI_SFNSF2SF(req->sfn_sf), + req->tx_request_body.number_of_pdus); - -int tx_req_UE_MAC(nfapi_tx_request_t* req) -{ - - LOG_D(PHY,"%s() SFN/SF:%d/%d PDUs:%d\n", __FUNCTION__, NFAPI_SFNSF2SFN(req->sfn_sf), NFAPI_SFNSF2SF(req->sfn_sf), req->tx_request_body.number_of_pdus); - - - for (int i=0; itx_request_body.number_of_pdus; i++) - { - LOG_D(PHY,"%s() SFN/SF:%d/%d number_of_pdus:%d [PDU:%d] pdu_length:%d pdu_index:%d num_segments:%d\n", + for (int i = 0; i < req->tx_request_body.number_of_pdus; i++) { + LOG_D(PHY, + "%s() SFN/SF:%d/%d number_of_pdus:%d [PDU:%d] pdu_length:%d " + "pdu_index:%d num_segments:%d\n", __FUNCTION__, - NFAPI_SFNSF2SFN(req->sfn_sf), NFAPI_SFNSF2SF(req->sfn_sf), + NFAPI_SFNSF2SFN(req->sfn_sf), + NFAPI_SFNSF2SF(req->sfn_sf), req->tx_request_body.number_of_pdus, i, req->tx_request_body.tx_pdu_list[i].pdu_length, req->tx_request_body.tx_pdu_list[i].pdu_index, - req->tx_request_body.tx_pdu_list[i].num_segments - ); - - } + req->tx_request_body.tx_pdu_list[i].num_segments); + } return 0; } - int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) { int sfn = NFAPI_SFNSF2SFN(req->sfn_sf); int sf = NFAPI_SFNSF2SF(req->sfn_sf); @@ -774,271 +838,272 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) { return 0; } +int hi_dci0_req_UE_MAC(nfapi_hi_dci0_request_t *req, module_id_t Mod_id) { + if (req != NULL && req->hi_dci0_request_body.hi_dci0_pdu_list != NULL) { + LOG_D(PHY, + "[UE-PHY_STUB] hi dci0 request sfn_sf:%d number_of_dci:%d " + "number_of_hi:%d\n", + NFAPI_SFNSF2DEC(req->sfn_sf), + req->hi_dci0_request_body.number_of_dci, + req->hi_dci0_request_body.number_of_hi); -int hi_dci0_req_UE_MAC(nfapi_hi_dci0_request_t* req, module_id_t Mod_id) -{ - if (req!=NULL && req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){ - LOG_D(PHY,"[UE-PHY_STUB] hi dci0 request sfn_sf:%d number_of_dci:%d number_of_hi:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), req->hi_dci0_request_body.number_of_dci, req->hi_dci0_request_body.number_of_hi); - - - - for (int i=0; ihi_dci0_request_body.number_of_dci + req->hi_dci0_request_body.number_of_hi; i++) - { - LOG_D(PHY,"[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d]\n", NFAPI_SFNSF2DEC(req->sfn_sf), i); - - if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) - { + for (int i = 0; i < req->hi_dci0_request_body.number_of_dci + + req->hi_dci0_request_body.number_of_hi; + i++) { LOG_D(PHY, - "[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - " - "NFAPI_HI_DCI0_DCI_PDU_TYPE\n", + "[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d]\n", NFAPI_SFNSF2DEC(req->sfn_sf), i); - const nfapi_hi_dci0_dci_pdu_rel8_t *dci = &req->hi_dci0_request_body.hi_dci0_pdu_list[i].dci_pdu.dci_pdu_rel8; - if (dci->rnti != UE_mac_inst[Mod_id].crnti) - continue; - const int sfn = NFAPI_SFNSF2SFN(req->sfn_sf); - const int sf = NFAPI_SFNSF2SF(req->sfn_sf); - if (dci->cqi_csi_request) - fill_ulsch_cqi_indication_UE_MAC(Mod_id, sfn, sf, UL_INFO, dci->rnti); - } - else if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type == NFAPI_HI_DCI0_HI_PDU_TYPE) - { - //LOG_I(MAC,"[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - NFAPI_HI_DCI0_HI_PDU_TYPE\n", NFAPI_SFNSF2DEC(req->sfn_sf), i); - nfapi_hi_dci0_request_pdu_t *hi_dci0_req_pdu = &req->hi_dci0_request_body.hi_dci0_pdu_list[i]; + if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type + == NFAPI_HI_DCI0_DCI_PDU_TYPE) { + LOG_D(PHY, + "[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - " + "NFAPI_HI_DCI0_DCI_PDU_TYPE\n", + NFAPI_SFNSF2DEC(req->sfn_sf), + i); + const nfapi_hi_dci0_dci_pdu_rel8_t *dci = + &req->hi_dci0_request_body.hi_dci0_pdu_list[i].dci_pdu.dci_pdu_rel8; + if (dci->rnti != UE_mac_inst[Mod_id].crnti) + continue; + const int sfn = NFAPI_SFNSF2SFN(req->sfn_sf); + const int sf = NFAPI_SFNSF2SF(req->sfn_sf); + if (dci->cqi_csi_request) + fill_ulsch_cqi_indication_UE_MAC(Mod_id, sfn, sf, UL_INFO, dci->rnti); + } else if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type + == NFAPI_HI_DCI0_HI_PDU_TYPE) { + nfapi_hi_dci0_request_pdu_t *hi_dci0_req_pdu = + &req->hi_dci0_request_body.hi_dci0_pdu_list[i]; - // This is meaningful only after ACKnowledging the first ULSCH Txon (i.e. Msg3) - if(hi_dci0_req_pdu->hi_pdu.hi_pdu_rel8.hi_value == 1 && UE_mac_inst[Mod_id].first_ULSCH_Tx == 1){ - //LOG_I(MAC,"[UE-PHY_STUB] HI_DCI0_REQ 2 sfn_sf:%d PDU[%d] - NFAPI_HI_DCI0_HI_PDU_TYPE\n", NFAPI_SFNSF2DEC(req->sfn_sf), i); - //UE_mac_inst[Mod_id].UE_mode[0] = PUSCH; - //UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + // This is meaningful only after ACKnowledging the first ULSCH Txon + // (i.e. Msg3) + if (hi_dci0_req_pdu->hi_pdu.hi_pdu_rel8.hi_value == 1 + && UE_mac_inst[Mod_id].first_ULSCH_Tx == 1) { + // LOG_I(MAC,"[UE-PHY_STUB] HI_DCI0_REQ 2 sfn_sf:%d PDU[%d] - + // NFAPI_HI_DCI0_HI_PDU_TYPE\n", NFAPI_SFNSF2DEC(req->sfn_sf), i); + // UE_mac_inst[Mod_id].UE_mode[0] = PUSCH; + // UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + } + + } else { + LOG_E(PHY, + "[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - unknown pdu " + "type:%d\n", + NFAPI_SFNSF2DEC(req->sfn_sf), + i, + req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type); } - - } - else - { - LOG_E(PHY,"[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - unknown pdu type:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), i, req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type); } } - } - - return 0; } +// The following set of memcpy functions should be getting called as callback +// functions from pnf_p7_subframe_ind. +int memcpy_dl_config_req(nfapi_pnf_p7_config_t *pnf_p7, + nfapi_dl_config_request_t *req) { + dl_config_req = (nfapi_dl_config_request_t *)malloc(sizeof(nfapi_dl_config_request_t)); + // UE_mac_inst[Mod_id].dl_config_req->header = req->header; + dl_config_req->sfn_sf = req->sfn_sf; + dl_config_req->vendor_extension = req->vendor_extension; + dl_config_req->dl_config_request_body.number_dci = req->dl_config_request_body.number_dci; + dl_config_req->dl_config_request_body.number_pdcch_ofdm_symbols = req->dl_config_request_body.number_pdcch_ofdm_symbols; + dl_config_req->dl_config_request_body.number_pdsch_rnti = req->dl_config_request_body.number_pdsch_rnti; + dl_config_req->dl_config_request_body.number_pdu = req->dl_config_request_body.number_pdu; -// The following set of memcpy functions should be getting called as callback functions from -// pnf_p7_subframe_ind. -int memcpy_dl_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request_t* req) -{ + dl_config_req->dl_config_request_body.tl.tag = req->dl_config_request_body.tl.tag; + dl_config_req->dl_config_request_body.tl.length = req->dl_config_request_body.tl.length; - //for (Mod_id=0; Mod_idheader = req->header; - dl_config_req->sfn_sf = req->sfn_sf; - - dl_config_req->vendor_extension = req->vendor_extension; - - dl_config_req->dl_config_request_body.number_dci = req->dl_config_request_body.number_dci; - dl_config_req->dl_config_request_body.number_pdcch_ofdm_symbols = req->dl_config_request_body.number_pdcch_ofdm_symbols; - dl_config_req->dl_config_request_body.number_pdsch_rnti = req->dl_config_request_body.number_pdsch_rnti; - dl_config_req->dl_config_request_body.number_pdu = req->dl_config_request_body.number_pdu; - - dl_config_req->dl_config_request_body.tl.tag = req->dl_config_request_body.tl.tag; - dl_config_req->dl_config_request_body.tl.length = req->dl_config_request_body.tl.length; - - dl_config_req->dl_config_request_body.dl_config_pdu_list = (nfapi_dl_config_request_pdu_t*) calloc(req->dl_config_request_body.number_pdu, sizeof(nfapi_dl_config_request_pdu_t)); - for(int i=0; idl_config_request_body.number_pdu; i++) { - dl_config_req->dl_config_request_body.dl_config_pdu_list[i] = req->dl_config_request_body.dl_config_pdu_list[i]; - } - - //} - - return 0; + dl_config_req->dl_config_request_body.dl_config_pdu_list = + calloc(req->dl_config_request_body.number_pdu, + sizeof(nfapi_dl_config_request_pdu_t)); + for (int i = 0; i < dl_config_req->dl_config_request_body.number_pdu; i++) { + dl_config_req->dl_config_request_body.dl_config_pdu_list[i] = + req->dl_config_request_body.dl_config_pdu_list[i]; + } + return 0; } -int memcpy_ul_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req) -{ +int memcpy_ul_config_req(nfapi_pnf_p7_config_t *pnf_p7, + nfapi_ul_config_request_t *req) { + ul_config_req = malloc(sizeof(nfapi_ul_config_request_t)); - //for (Mod_id=0; Mod_idsfn_sf = req->sfn_sf; + ul_config_req->vendor_extension = req->vendor_extension; - ul_config_req = (nfapi_ul_config_request_t*)malloc(sizeof(nfapi_ul_config_request_t)); + ul_config_req->ul_config_request_body.number_of_pdus = req->ul_config_request_body.number_of_pdus; + ul_config_req->ul_config_request_body.rach_prach_frequency_resources = req->ul_config_request_body.rach_prach_frequency_resources; + ul_config_req->ul_config_request_body.srs_present = req->ul_config_request_body.srs_present; - ul_config_req->sfn_sf = req->sfn_sf; - ul_config_req->vendor_extension = req->vendor_extension; + ul_config_req->ul_config_request_body.tl.tag = req->ul_config_request_body.tl.tag; + ul_config_req->ul_config_request_body.tl.length = req->ul_config_request_body.tl.length; + ul_config_req->ul_config_request_body.ul_config_pdu_list = + calloc(req->ul_config_request_body.number_of_pdus, + sizeof(nfapi_ul_config_request_pdu_t)); + for (int i = 0; i < ul_config_req->ul_config_request_body.number_of_pdus; i++) { + ul_config_req->ul_config_request_body.ul_config_pdu_list[i] = + req->ul_config_request_body.ul_config_pdu_list[i]; + } - ul_config_req->ul_config_request_body.number_of_pdus = req->ul_config_request_body.number_of_pdus; - ul_config_req->ul_config_request_body.rach_prach_frequency_resources = req->ul_config_request_body.rach_prach_frequency_resources; - ul_config_req->ul_config_request_body.srs_present = req->ul_config_request_body.srs_present; - - ul_config_req->ul_config_request_body.tl.tag = req->ul_config_request_body.tl.tag; - ul_config_req->ul_config_request_body.tl.length = req->ul_config_request_body.tl.length; - - //LOG_D(MAC, "memcpy_ul_config_req 1 #ofULPDUs: %d \n", UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.number_of_pdus); //req->ul_config_request_body.number_of_pdus); - ul_config_req->ul_config_request_body.ul_config_pdu_list = (nfapi_ul_config_request_pdu_t*) malloc(req->ul_config_request_body.number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t)); - for(int i=0; iul_config_request_body.number_of_pdus; i++) { - ul_config_req->ul_config_request_body.ul_config_pdu_list[i] = req->ul_config_request_body.ul_config_pdu_list[i]; - } - //} - - return 0; + return 0; } +int memcpy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) { + tx_req_num_elems = req->tx_request_body.number_of_pdus; + tx_request_pdu_list = calloc(tx_req_num_elems, sizeof(nfapi_tx_request_pdu_t)); + for (int i = 0; i < tx_req_num_elems; i++) { + tx_request_pdu_list[i].num_segments = req->tx_request_body.tx_pdu_list[i].num_segments; + tx_request_pdu_list[i].pdu_index = req->tx_request_body.tx_pdu_list[i].pdu_index; + tx_request_pdu_list[i].pdu_length = req->tx_request_body.tx_pdu_list[i].pdu_length; + for (int j = 0; j < req->tx_request_body.tx_pdu_list[i].num_segments; j++) { + tx_request_pdu_list[i].segments[j].segment_length = req->tx_request_body.tx_pdu_list[i].segments[j].segment_length; + if (tx_request_pdu_list[i].segments[j].segment_length > 0) { + tx_request_pdu_list[i].segments[j].segment_data = calloc( + tx_request_pdu_list[i].segments[j].segment_length, sizeof(uint8_t)); + memcpy(tx_request_pdu_list[i].segments[j].segment_data, + req->tx_request_body.tx_pdu_list[i].segments[j].segment_data, + tx_request_pdu_list[i].segments[j].segment_length); + } + } + } - - -int memcpy_tx_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req) -{ - - tx_req_num_elems = req->tx_request_body.number_of_pdus; - tx_request_pdu_list = (nfapi_tx_request_pdu_t*) calloc(tx_req_num_elems, sizeof(nfapi_tx_request_pdu_t)); - for (int i=0; itx_request_body.tx_pdu_list[i].num_segments; - tx_request_pdu_list[i].pdu_index = req->tx_request_body.tx_pdu_list[i].pdu_index; - tx_request_pdu_list[i].pdu_length = req->tx_request_body.tx_pdu_list[i].pdu_length; - for (int j=0; jtx_request_body.tx_pdu_list[i].num_segments; j++){ - //*tx_request_pdu_list[i].segments[j].segment_data = *req->tx_request_body.tx_pdu_list[i].segments[j].segment_data; - tx_request_pdu_list[i].segments[j].segment_length = req->tx_request_body.tx_pdu_list[i].segments[j].segment_length; - if(tx_request_pdu_list[i].segments[j].segment_length > 0){ - tx_request_pdu_list[i].segments[j].segment_data = (uint8_t*)malloc(tx_request_pdu_list[i].segments[j].segment_length*sizeof (uint8_t)); - memcpy(tx_request_pdu_list[i].segments[j].segment_data, req->tx_request_body.tx_pdu_list[i].segments[j].segment_data, tx_request_pdu_list[i].segments[j].segment_length); - } - } - - } - - return 0; + return 0; } -int memcpy_hi_dci0_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t* req) -{ +int memcpy_hi_dci0_req(nfapi_pnf_p7_config_t *pnf_p7, + nfapi_hi_dci0_request_t *req) { + hi_dci0_req = (nfapi_hi_dci0_request_t *)malloc(sizeof(nfapi_hi_dci0_request_t)); - //if(req!=0){ + hi_dci0_req->sfn_sf = req->sfn_sf; + hi_dci0_req->vendor_extension = req->vendor_extension; - //for (Mod_id=0; Mod_idhi_dci0_request_body.number_of_dci = req->hi_dci0_request_body.number_of_dci; + hi_dci0_req->hi_dci0_request_body.number_of_hi = req->hi_dci0_request_body.number_of_hi; + hi_dci0_req->hi_dci0_request_body.sfnsf = req->hi_dci0_request_body.sfnsf; - hi_dci0_req->sfn_sf = req->sfn_sf; - hi_dci0_req->vendor_extension = req->vendor_extension; + // UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.tl = + // req->hi_dci0_request_body.tl; + hi_dci0_req->hi_dci0_request_body.tl.tag = req->hi_dci0_request_body.tl.tag; + hi_dci0_req->hi_dci0_request_body.tl.length = req->hi_dci0_request_body.tl.length; - hi_dci0_req->hi_dci0_request_body.number_of_dci = req->hi_dci0_request_body.number_of_dci; - hi_dci0_req->hi_dci0_request_body.number_of_hi = req->hi_dci0_request_body.number_of_hi; - hi_dci0_req->hi_dci0_request_body.sfnsf = req->hi_dci0_request_body.sfnsf; + int total_pdus = hi_dci0_req->hi_dci0_request_body.number_of_dci + + hi_dci0_req->hi_dci0_request_body.number_of_hi; - //UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.tl = req->hi_dci0_request_body.tl; - hi_dci0_req->hi_dci0_request_body.tl.tag = req->hi_dci0_request_body.tl.tag; - hi_dci0_req->hi_dci0_request_body.tl.length = req->hi_dci0_request_body.tl.length; + hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = + calloc(total_pdus, sizeof(nfapi_hi_dci0_request_pdu_t)); - int total_pdus = hi_dci0_req->hi_dci0_request_body.number_of_dci + hi_dci0_req->hi_dci0_request_body.number_of_hi; - - hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = (nfapi_hi_dci0_request_pdu_t*) malloc(total_pdus*sizeof(nfapi_hi_dci0_request_pdu_t)); - - for(int i=0; ihi_dci0_request_body.hi_dci0_pdu_list[i] = req->hi_dci0_request_body.hi_dci0_pdu_list[i]; - //LOG_I(MAC, "Original hi_dci0 req. type:%d, Copy type: %d \n",req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type, UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type); - } - - //} - return 0; + for (int i = 0; i < total_pdus; i++) { + hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list[i] = req->hi_dci0_request_body.hi_dci0_pdu_list[i]; + // LOG_I(MAC, "Original hi_dci0 req. type:%d, Copy type: %d + // \n",req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type, + // UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type); + } + return 0; } - - void UE_config_stub_pnf(void) { - int j; + int j; paramdef_t L1_Params[] = L1PARAMS_DESC; - paramlist_def_t L1_ParamList = {CONFIG_STRING_L1_LIST,NULL,0}; + paramlist_def_t L1_ParamList = {CONFIG_STRING_L1_LIST, NULL, 0}; - config_getlist( &L1_ParamList,L1_Params,sizeof(L1_Params)/sizeof(paramdef_t), NULL); + config_getlist(&L1_ParamList, L1_Params, sizeof(L1_Params) / sizeof(paramdef_t), NULL); if (L1_ParamList.numelt > 0) { - for (j=0; j Date: Fri, 6 Mar 2020 15:15:02 +0100 Subject: [PATCH 22/25] CI: adding back more testing (ping and iperf) to L2 simulator Signed-off-by: Raphael Defosseux --- ci-scripts/runTestOnVM.sh | 86 ++++++++++++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 14 deletions(-) diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 4e1734da63..09859133cc 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -613,8 +613,11 @@ function start_epc { echo "############################################################" echo "echo \"cd /opt/hss_sim0609\"" > $LOC_EPC_VM_CMDS echo "cd /opt/hss_sim0609" >> $LOC_EPC_VM_CMDS - echo "echo \"sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real\"" >> $LOC_EPC_VM_CMDS - echo "sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real" >> $LOC_EPC_VM_CMDS + echo "sudo rm -f hss.log" >> $LOC_EPC_VM_CMDS + #echo "echo \"sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real\"" >> $LOC_EPC_VM_CMDS + #echo "sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real" >> $LOC_EPC_VM_CMDS + echo "echo \"screen -dm -S simulated_hss ./starthss_real\"" >> $LOC_EPC_VM_CMDS + echo "sudo su -c \"screen -dm -S simulated_hss ./starthss_real\"" >> $LOC_EPC_VM_CMDS echo "echo \"cd /opt/ltebox/tools/\"" >> $LOC_EPC_VM_CMDS echo "cd /opt/ltebox/tools/" >> $LOC_EPC_VM_CMDS @@ -905,8 +908,9 @@ function start_l2_sim_ue { else echo "L2-SIM UE is sync'ed w/ eNB" fi - local max_interfaces_to_check=1 - if [ $LOC_S1_CONFIGURATION -eq 0 ]; then max_interfaces_to_check=$LOC_NB_UES; fi + local max_interfaces_to_check=$LOC_NB_UES + #local max_interfaces_to_check=1 + #if [ $LOC_S1_CONFIGURATION -eq 0 ]; then max_interfaces_to_check=$LOC_NB_UES; fi local j="1" while [ $j -le $max_interfaces_to_check ] do @@ -2214,15 +2218,41 @@ function run_test_on_vm { if [ $S1_NOS1_CFG -eq 1 ] then - get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR 1 echo "############################################################" echo "${CN_CONFIG} : Pinging the EPC from UE(s)" echo "############################################################" - PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_epc.log - ping_epc_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $REAL_EPC_IP_ADDR $PING_LOG_FILE 1 0 - scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC - check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + echo " --- Sequentially ---" + local j="1" + while [ $j -le $INT_NB_UES ] + do + PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_epc_seq_from_ue${j}.log + ping_epc_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $REAL_EPC_IP_ADDR $PING_LOG_FILE ${j} 0 + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + j=$[$j+1] + done + if [ $INT_NB_UES -gt 1 ] + then + echo " --- In parallel ---" + j="1" + while [ $j -le $INT_NB_UES ] + do + PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_epc_para_from_ue${j}.log + ping_epc_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $REAL_EPC_IP_ADDR $PING_LOG_FILE ${j} 1 + j=$[$j+1] + done + sleep 25 + j="1" + while [ $j -le $INT_NB_UES ] + do + PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_epc_para_from_ue${j}.log + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + tail -3 $ARCHIVES_LOC/$PING_LOG_FILE + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + j=$[$j+1] + done + fi else get_enb_noS1_ip_addr $ENB_VM_CMDS $ENB_VM_IP_ADDR @@ -2267,10 +2297,38 @@ function run_test_on_vm { echo "############################################################" echo "${CN_CONFIG} : Pinging the UE(s) from EPC" echo "############################################################" - PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_ue.log - ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE 0 - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC - check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + echo " --- Sequentially ---" + local j="1" + while [ $j -le $INT_NB_UES ] + do + get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $j + PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_from_epc_seq_ue${j}.log + ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE 0 + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + j=$[$j+1] + done + if [ $INT_NB_UES -gt 1 ] + then + echo " --- In parallel ---" + j="1" + while [ $j -le $INT_NB_UES ] + do + get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $j + PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_from_epc_para_ue${j}.log + ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE 1 + j=$[$j+1] + done + sleep 25 + j="1" + while [ $j -le $INT_NB_UES ] + do + PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_from_epc_para_ue${j}.log + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + j=$[$j+1] + done + fi else echo "############################################################" echo "${CN_CONFIG} : Pinging the UE(s) from eNB" @@ -2310,7 +2368,7 @@ function run_test_on_vm { fi fi - if [ $S1_NOS1_CFG -eq 2 ] + if [ $S1_NOS1_CFG -eq 0 ] then get_enb_noS1_ip_addr $ENB_VM_CMDS $ENB_VM_IP_ADDR echo "############################################################" From 0de3c7347527fcf28712a4cbf0277da35b4104f3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 9 Mar 2020 14:25:19 +0100 Subject: [PATCH 23/25] Place MBMS tun fd into single int --- .../SIMULATION/ETH_TRANSPORT/netlink_init.c | 20 +++++++++---------- openair1/SIMULATION/ETH_TRANSPORT/proto.h | 2 +- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 6 +++--- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 6 +++--- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c index dfb5578ba6..9b4aba46c3 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c @@ -58,7 +58,7 @@ struct iovec nas_iov_rx = {nl_rx_buf, sizeof(nl_rx_buf)}; int nas_sock_fd[MAX_MOBILES_PER_ENB]; -int nas_sock_mbms_fd[8]; +int nas_sock_mbms_fd; struct msghdr nas_msg_tx; struct msghdr nas_msg_rx; @@ -95,21 +95,20 @@ static int tun_alloc(char *dev) { } -int netlink_init_mbms_tun(char *ifprefix, int num_if) { +int netlink_init_mbms_tun(char *ifprefix) { int ret; char ifname[64]; - int i= num_if-1; - sprintf(ifname, "oaitun_%.3s%d",ifprefix,i+1); - nas_sock_mbms_fd[i] = tun_alloc(ifname); + sprintf(ifname, "oaitun_%.3s1",ifprefix); // added "1": for historical reasons + nas_sock_mbms_fd = tun_alloc(ifname); - if (nas_sock_mbms_fd[i] == -1) { + if (nas_sock_mbms_fd == -1) { printf("[NETLINK] Error opening socket %s (%d:%s)\n",ifname,errno, strerror(errno)); exit(1); } - printf("[NETLINK]Opened socket %s with fd %d\n",ifname,nas_sock_mbms_fd[i]); - ret = fcntl(nas_sock_mbms_fd[i],F_SETFL,O_NONBLOCK); + printf("[NETLINK]Opened socket %s with fd %d\n",ifname,nas_sock_mbms_fd); + ret = fcntl(nas_sock_mbms_fd,F_SETFL,O_NONBLOCK); if (ret == -1) { printf("[NETLINK] Error fcntl (%d:%s)\n",errno, strerror(errno)); @@ -123,7 +122,7 @@ int netlink_init_mbms_tun(char *ifprefix, int num_if) { nas_src_addr.nl_family = AF_NETLINK; nas_src_addr.nl_pid = 1;//getpid(); /* self pid */ nas_src_addr.nl_groups = 0; /* not in mcast groups */ - ret = bind(nas_sock_mbms_fd[i], (struct sockaddr *)&nas_src_addr, sizeof(nas_src_addr)); + ret = bind(nas_sock_mbms_fd, (struct sockaddr *)&nas_src_addr, sizeof(nas_src_addr)); memset(&nas_dest_addr, 0, sizeof(nas_dest_addr)); nas_dest_addr.nl_family = AF_NETLINK; nas_dest_addr.nl_pid = 0; /* For Linux Kernel */ @@ -165,7 +164,8 @@ int netlink_init_tun(char *ifprefix, int num_if) { exit(1); } - printf("[NETLINK]Opened socket %s with fd %d\n",ifname,nas_sock_fd[i]); + printf("[NETLINK]Opened socket %s with fd nas_sock_fd[%d]=%d\n", + ifname, i, nas_sock_fd[i]); ret = fcntl(nas_sock_fd[i],F_SETFL,O_NONBLOCK); if (ret == -1) { diff --git a/openair1/SIMULATION/ETH_TRANSPORT/proto.h b/openair1/SIMULATION/ETH_TRANSPORT/proto.h index 02f7925d93..e6159199d4 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/proto.h +++ b/openair1/SIMULATION/ETH_TRANSPORT/proto.h @@ -63,6 +63,6 @@ void clear_eNB_transport_info(uint8_t); void clear_UE_transport_info(uint8_t); int netlink_init(void); int netlink_init_tun(char *ifsuffix, int num_if); -int netlink_init_mbms_tun(char *ifsuffix, int num_if); +int netlink_init_mbms_tun(char *ifsuffix); #endif /* EMU_PROTO_H_ */ diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 254d741ae8..b0e6143de1 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -2299,14 +2299,14 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) { netlink_init_tun("ue",num_if); if (IS_SOFTMODEM_NOS1) nas_config(1, 1, 2, "ue"); - netlink_init_mbms_tun("uem",num_if); + netlink_init_mbms_tun("uem"); nas_config_mbms(1, 2, 2, "uem"); LOG_I(PDCP, "UE pdcp will use tun interface\n"); } else if(ENB_NAS_USE_TUN) { netlink_init_tun("enb",1); nas_config(1, 1, 1, "enb"); if(pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT){ - netlink_init_mbms_tun("enm",1); + netlink_init_mbms_tun("enm"); nas_config_mbms(1, 2, 1, "enm"); LOG_I(PDCP, "ENB pdcp will use mbms tun interface\n"); } @@ -2318,7 +2318,7 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) { }else{ if(pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT){ LOG_W(PDCP, "ENB pdcp will use tun interface for MBMS\n"); - netlink_init_mbms_tun("enm",1); + netlink_init_mbms_tun("enm"); nas_config_mbms_s1(1, 2, 1, "enm"); }else LOG_E(PDCP, "ENB pdcp will not use tun interface\n"); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index a441ff220e..d203408e55 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -77,7 +77,7 @@ extern struct iovec nas_iov_rx; extern int nas_sock_fd[MAX_MOBILES_PER_ENB]; -extern int nas_sock_mbms_fd[8]; +extern int nas_sock_mbms_fd; extern int mbms_rab_id; @@ -133,7 +133,7 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) { } else if (UE_NAS_USE_TUN) { //ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); if(rb_id == mbms_rab_id){ - ret = write(nas_sock_mbms_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); + ret = write(nas_sock_mbms_fd, &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH MBMS DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite); } else @@ -299,7 +299,7 @@ int pdcp_fifo_read_input_mbms_sdus_fromtun (const protocol_ctxt_t *const ctxt_p do { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ_BUFFER, 1 ); - len = read(UE_NAS_USE_TUN?nas_sock_mbms_fd[0]:nas_sock_mbms_fd[0], &nl_rx_buf, NL_MAX_PAYLOAD); + len = read(nas_sock_mbms_fd, &nl_rx_buf, NL_MAX_PAYLOAD); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ_BUFFER, 0 ); if (len<=0) continue; From 8928cfe57d9f7100c7902a44a6fa853cc24543c5 Mon Sep 17 00:00:00 2001 From: frtabu Date: Wed, 11 Mar 2020 17:32:13 +0100 Subject: [PATCH 24/25] move ldpc coder/decoder into a shared lib dymically loaded. Also fix a record player bug --- cmake_targets/CMakeLists.txt | 39 +- common/config/config_userapi.c | 3 +- common/utils/telnetsrv/telnetsrv.c | 20 +- openair1/PHY/CODING/TESTBENCH/ldpctest.c | 22 +- .../CODING/nrLDPC_decoder/nrLDPC_decoder.c | 4 +- .../PHY/CODING/nrLDPC_decoder/nrLDPC_init.h | 2 +- .../CODING/nrLDPC_decoder/nrLDPC_init_mem.h | 1 - .../PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h | 2 +- .../PHY/CODING/nrLDPC_decoder/nrLDPC_types.h | 5 +- .../{nrLDPC_defs.h => nrLDPCdecoder_defs.h} | 2 +- openair1/PHY/CODING/nrLDPC_defs.h | 59 ++ openair1/PHY/CODING/nrLDPC_encoder/defs.h | 54 -- .../nrLDPC_encoder/ldpc_encode_parity_check.c | 201 ++++++ .../PHY/CODING/nrLDPC_encoder/ldpc_encoder.c | 252 +++++-- .../PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c | 667 ------------------ .../nrLDPC_encoder/ldpc_encoder_optim.c | 146 ++++ .../ldpc_generate_coefficient.c | 244 +------ .../nrLDPC_decoder.h => nrLDPC_extern.h} | 39 +- openair1/PHY/CODING/nrLDPC_load.c | 76 ++ openair1/PHY/INIT/nr_init.c | 2 + openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c | 9 +- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 3 +- .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 3 +- .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 7 +- openair1/PHY/defs_gNB.h | 2 +- targets/ARCH/COMMON/common_lib.c | 35 +- targets/ARCH/COMMON/common_lib.h | 18 + targets/ARCH/COMMON/record_player.h | 15 +- targets/ARCH/iqplayer/iqplayer_lib.c | 14 +- targets/RT/USER/lte-ru.c | 4 +- 30 files changed, 888 insertions(+), 1062 deletions(-) rename openair1/PHY/CODING/nrLDPC_decoder/{nrLDPC_defs.h => nrLDPCdecoder_defs.h} (99%) create mode 100644 openair1/PHY/CODING/nrLDPC_defs.h delete mode 100644 openair1/PHY/CODING/nrLDPC_encoder/defs.h create mode 100644 openair1/PHY/CODING/nrLDPC_encoder/ldpc_encode_parity_check.c delete mode 100644 openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c create mode 100644 openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c rename openair1/PHY/CODING/{nrLDPC_decoder/nrLDPC_decoder.h => nrLDPC_extern.h} (60%) create mode 100644 openair1/PHY/CODING/nrLDPC_load.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index c4d3d7e62e..496417936a 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1298,14 +1298,35 @@ set(PHY_SMALLBLOCKSRC set(PHY_TURBOIF ${OPENAIR1_DIR}/PHY/CODING/coding_load.c ) -set(PHY_LDPCSRC + +set(PHY_LDPC_ORIG_SRC ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c - ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c - ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c ) +set(PHY_LDPC_OPTIM_SRC + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c +) +set(PHY_LDPC_OPTIM8SEG_SRC + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8seg.c +) +set(PHY_LDPC_OPTIM8SEGMULTI_SRC + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c +) +set(PHY_NR_CODINGIF + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_load.c; +) + +add_library(ldpc_orig MODULE ${PHY_LDPC_ORIG_SRC} ) +add_library(ldpc_optim MODULE ${PHY_LDPC_OPTIM_SRC} ) +add_library(ldpc_optim8seg MODULE ${PHY_LDPC_OPTIM8SEG_SRC} ) +add_library(ldpc MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} ) + add_library(coding MODULE ${PHY_TURBOSRC} ) + set(PHY_SRC_COMMON ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci_tools_common.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/lte_mcs.c @@ -1484,10 +1505,9 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/TOOLS/lut.c ${PHY_POLARSRC} ${PHY_SMALLBLOCKSRC} - ${PHY_LDPCSRC} + ${PHY_NR_CODINGIF} ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/pucch_rx.c ) - set(PHY_NR_UE_SRC ${OPENAIR1_DIR}/PHY/INIT/nr_parms.c ${OPENAIR1_DIR}/PHY/MODULATION/nr_modulation.c @@ -1535,7 +1555,7 @@ set(PHY_SRC_UE # ${OPENAIR1_DIR}/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c ${PHY_POLARSRC} ${PHY_SMALLBLOCKSRC} - ${PHY_LDPCSRC} + ${PHY_NR_CODINGIF} ) @@ -2588,7 +2608,7 @@ target_link_libraries (nr-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LI target_link_libraries (nr-softmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-softmodem ${T_LIB}) - +add_dependencies( nr-softmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) # nr-uesoftmodem is UE implementation ####################################### @@ -2629,7 +2649,7 @@ target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_ target_link_libraries (nr-uesoftmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-uesoftmodem ${T_LIB}) - +add_dependencies( nr-uesoftmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) # USIM process ################# @@ -2696,10 +2716,13 @@ target_link_libraries(smallblocktest ) add_executable(ldpctest + ${PHY_NR_CODINGIF} ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c ${T_SOURCE} ${SHLIB_LOADER_SOURCES} ) +add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) + target_link_libraries(ldpctest -Wl,--start-group UTIL SIMU PHY_NR CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} dl diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index 67fdc2c920..c951905101 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -45,7 +45,8 @@ configmodule_interface_t *config_get_if(void) { if (cfgptr == NULL) { - CONFIG_PRINTF_ERROR("[CONFIG] %s %d config module not initialized\n",__FILE__,__LINE__); + if (isLogInitDone()) + LOG_W(ENB_APP,"[CONFIG] %s %d config module not initialized\n",__FILE__,__LINE__); } return cfgptr; diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index 10163b22b5..06a5d350c7 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -377,6 +377,14 @@ int setgetvar(int moduleindex,char getorset,char *params) { client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); break; + case TELNET_VARTYPE_INT8: + client_printf("%i\n",(int)(*(int8_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr))); + break; + + case TELNET_VARTYPE_UINT: + client_printf("%u\n",*(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + break; + case TELNET_VARTYPE_DOUBLE: client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); break; @@ -405,7 +413,17 @@ int setgetvar(int moduleindex,char getorset,char *params) { *(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (short)strtol(varval,NULL,0); client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); break; - + + case TELNET_VARTYPE_INT8: + *(char *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (char)strtol(varval,NULL,0); + client_printf("%i\n",*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + break; + + case TELNET_VARTYPE_UINT: + *(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (unsigned int)strtol(varval,NULL,0); + client_printf("%u\n",*(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + break; + case TELNET_VARTYPE_DOUBLE: *(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = strtod(varval,NULL); client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c index 95ee3fed17..552af99c41 100644 --- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c +++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c @@ -25,8 +25,7 @@ #include #include "assertions.h" #include "SIMULATION/TOOLS/sim.h" -#include "PHY/CODING/nrLDPC_encoder/defs.h" -#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h" +#include "PHY/CODING/nrLDPC_extern.h" #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" #define MAX_NUM_DLSCH_SEGMENTS 16 @@ -85,6 +84,7 @@ typedef struct { RAN_CONTEXT_t RC; PHY_VARS_UE ***PHY_vars_UE_g; uint16_t NB_UE_INST = 1; +nrLDPC_encoderfunc_t encoder_orig; short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; @@ -286,16 +286,19 @@ int test_ldpc(short No_iteration, no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*(1/((float)nom_rate/(float)denom_rate)))/Zc; // printf("puncture:%d\n",no_punctured_columns); removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/((float)nom_rate/(float)denom_rate)); + encoder_implemparams_t impp=INIT0_LDPCIMPLEMPARAMS; + + impp.gen_code=1; if (ntrials==0) - ldpc_encoder_orig(test_input[0],channel_input[0], Zc, BG, block_length, BG, 1); - + encoder_orig(test_input,channel_input, Zc, BG, block_length, BG, &impp); + impp.gen_code=0; for (trial=0; trial < ntrials; trial++) { segment_bler = 0; //// encoder start_meas(&time); for(j=0;j #include -#include "nrLDPC_defs.h" +#include "nrLDPCdecoder_defs.h" #include "nrLDPC_types.h" #include "nrLDPC_init.h" #include "nrLDPC_mPass.h" @@ -47,7 +47,7 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, uint32_t numLLR, t_nrLDPC_lut* p_lut, t_nrLDPC_dec_params* p_decParams, t_nrLDPC_time_stats* p_profiler); -int32_t nrLDPC_decoder(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats* p_profiler) +int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats* p_profiler) { uint32_t numLLR; uint32_t numIter = 0; diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init.h index 82462c6d95..ea031dc2da 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init.h @@ -32,7 +32,7 @@ #define __NR_LDPC_INIT__H__ #include "nrLDPC_lut.h" -#include "nrLDPC_defs.h" +#include "nrLDPCdecoder_defs.h" /** \brief Initializes the decoder and sets correct LUTs diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h index bdaa118e1f..3292c0debe 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h @@ -32,7 +32,6 @@ #define __NR_LDPC_INIT_MEM__H__ #include -#include "nrLDPC_defs.h" #include "nrLDPC_types.h" #ifndef malloc32_clear diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h index 66715618d0..7d0f5f077a 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h @@ -32,7 +32,7 @@ #define __NR_LDPC_MPASS__H__ #include -#include "nrLDPC_defs.h" +#include "nrLDPCdecoder_defs.h" /** \brief Circular memcpy diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h index 34322a7780..e5b99246d5 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h @@ -32,8 +32,7 @@ #define __NR_LDPC_TYPES__H__ #include "PHY/TOOLS/time_meas.h" -#include "nrLDPC_defs.h" - +#include "nrLDPCdecoder_defs.h" // ============================================================================== // TYPES @@ -103,4 +102,6 @@ typedef struct nrLDPC_procBuf { int8_t* llrProcBuf; /**< LLR processing buffer */ } t_nrLDPC_procBuf; + + #endif diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_defs.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h similarity index 99% rename from openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_defs.h rename to openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h index 940d842550..69fc88752f 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_defs.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h @@ -19,7 +19,7 @@ * contact@openairinterface.org */ -/*!\file nrLDPC_defs.h +/*!\file nrLDPCdecoder_defs.h * \brief Defines all constants and buffers for the LDPC decoder * \author Sebastian Wagner (TCL Communications) Email: * \date 27-03-2018 diff --git a/openair1/PHY/CODING/nrLDPC_defs.h b/openair1/PHY/CODING/nrLDPC_defs.h new file mode 100644 index 0000000000..b96067f4b6 --- /dev/null +++ b/openair1/PHY/CODING/nrLDPC_defs.h @@ -0,0 +1,59 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ +//============================================================================================================================ +// encoder interface +#ifndef __NRLDPC_DEFS__H__ +#define __NRLDPC_DEFS__H__ +#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" +/** + \brief LDPC encoder + \param 1 input + \param 2 channel_input + \param 3 int Zc + \param 4 int Kb + \param 5 short block_length + \param 6 short BG + \param 7 int n_segment + \param 8 unsigned int macro_num + \param 9-12 time_stats_t *tinput,*tprep, *tparity,*toutput +*/ +typedef struct { + int n_segments; // optim8seg + unsigned int macro_num; // optim8segmulti + unsigned char gen_code; //orig + time_stats_t *tinput; + time_stats_t *tprep; + time_stats_t *tparity; + time_stats_t *toutput; +}encoder_implemparams_t; +#define INIT0_LDPCIMPLEMPARAMS {0,0,0,NULL,NULL,NULL,NULL} +typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,short, short, encoder_implemparams_t*); +//============================================================================================================================ +// decoder interface +/** + \brief LDPC decoder API type definition + \param p_decParams LDPC decoder parameters + \param p_llr Input LLRs + \param p_llrOut Output vector + \param p_profiler LDPC profiler statistics +*/ +typedef int32_t(*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params* , int8_t*, int8_t* , t_nrLDPC_procBuf* , t_nrLDPC_time_stats* ); +#endif \ No newline at end of file diff --git a/openair1/PHY/CODING/nrLDPC_encoder/defs.h b/openair1/PHY/CODING/nrLDPC_encoder/defs.h deleted file mode 100644 index 85cb852fe5..0000000000 --- a/openair1/PHY/CODING/nrLDPC_encoder/defs.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*!\file defs.h - * \brief LDPC encoder forward declarations - * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom) - * \email openair_tech@eurecom.fr - * \date 27-03-2018 - * \version 1.0 - * \note - * \warning - */ - -#include "PHY/TOOLS/time_meas.h" - -/*ldpc_encoder.c*/ -int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb,short block_length); - -/*ldpc_encoder2.c*/ -void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,short Kb); -int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length,short BG,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput); -int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length,short BG,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput); -int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput); - -/*ldpc_generate_coefficient.c*/ -int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length,short BG,unsigned char gen_code); - -/* -int encode_parity_check_part(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb); -int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb,short block_length); -int ldpc_encoder(unsigned char *test_input,unsigned char *channel_input,short block_length, double rate); -int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,short block_length,int nom_rate,int denom_rate,unsigned char gen_code); -int ldpc_encoder_multi_segment(unsigned char **test_input,unsigned char **channel_input,short block_length,double rate,uint8_t n_segments); -int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,short block_length,int nom_rate,int denom_rate,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput); -int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,short block_length,int nom_rate,int denom_rate,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput); -*/ diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encode_parity_check.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encode_parity_check.c new file mode 100644 index 0000000000..738fd49b7d --- /dev/null +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encode_parity_check.c @@ -0,0 +1,201 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*!\file ldpc_encode_parity_check.c + * \brief Parity check function used by ldpc encoders + * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom) + * \email openair_tech@eurecom.fr + * \date 27-03-2018 + * \version 1.0 + * \note + * \warning + */ + +#include +#include +#include +#include +#include +#include "assertions.h" +#include "common/utils/LOG/log.h" + + +//#define DEBUG_LDPC + +#include "ldpc384_byte.c" +#include "ldpc352_byte.c" +#include "ldpc320_byte.c" +#include "ldpc288_byte.c" +#include "ldpc256_byte.c" +#include "ldpc240_byte.c" +#include "ldpc224_byte.c" +#include "ldpc208_byte.c" +#include "ldpc192_byte.c" +#include "ldpc176_byte.c" +#include "ldpc_BG2_Zc384_byte.c" +#include "ldpc_BG2_Zc352_byte.c" +#include "ldpc_BG2_Zc320_byte.c" +#include "ldpc_BG2_Zc288_byte.c" +#include "ldpc_BG2_Zc256_byte.c" +#include "ldpc_BG2_Zc240_byte.c" +#include "ldpc_BG2_Zc224_byte.c" +#include "ldpc_BG2_Zc208_byte.c" +#include "ldpc_BG2_Zc192_byte.c" +#include "ldpc_BG2_Zc176_byte.c" +#include "ldpc_BG2_Zc160_byte.c" +#include "ldpc_BG2_Zc144_byte.c" +#include "ldpc_BG2_Zc128_byte.c" +#include "ldpc_BG2_Zc120_byte.c" +#include "ldpc_BG2_Zc112_byte.c" +#include "ldpc_BG2_Zc104_byte.c" +#include "ldpc_BG2_Zc96_byte.c" +#include "ldpc_BG2_Zc88_byte.c" +#include "ldpc_BG2_Zc80_byte.c" +#include "ldpc_BG2_Zc72_byte.c" + + + +static inline void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,short Kb) +{ + + if (BG==1) + { + switch (Zc) + { + case 2: break; + case 3: break; + case 4: break; + case 5: break; + case 6: break; + case 7: break; + case 8: break; + case 9: break; + case 10: break; + case 11: break; + case 12: break; + case 13: break; + case 14: break; + case 15: break; + case 16: break; + case 18: break; + case 20: break; + case 22: break; + case 24: break; + case 26: break; + case 28: break; + case 30: break; + case 32: break; + case 36: break; + case 40: break; + case 44: break; + case 48: break; + case 52: break; + case 56: break; + case 60: break; + case 64: break; + case 72: break; + case 80: break; + case 88: break; + case 96: break; + case 104: break; + case 112: break; + case 120: break; + case 128: break; + case 144: break; + case 160: break; + case 176: ldpc176_byte(c,d); break; + case 192: ldpc192_byte(c,d); break; + case 208: ldpc208_byte(c,d); break; + case 224: ldpc224_byte(c,d); break; + case 240: ldpc240_byte(c,d); break; + case 256: ldpc256_byte(c,d); break; + case 288: ldpc288_byte(c,d); break; + case 320: ldpc320_byte(c,d); break; + case 352: ldpc352_byte(c,d); break; + case 384: ldpc384_byte(c,d); break; + default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break; + } + } + else if (BG==2) { + switch (Zc) + { + case 2: break; + case 3: break; + case 4: break; + case 5: break; + case 6: break; + case 7: break; + case 8: break; + case 9: break; + case 10: break; + case 11: break; + case 12: break; + case 13: break; + case 14: break; + case 15: break; + case 16: break; + case 18: break; + case 20: break; + case 22: break; + case 24: break; + case 26: break; + case 28: break; + case 30: break; + case 32: break; + case 36: break; + case 40: break; + case 44: break; + case 48: break; + case 52: break; + case 56: break; + case 60: break; + case 64: break; + case 72: ldpc_BG2_Zc72_byte(c,d); break; + case 80: ldpc_BG2_Zc80_byte(c,d); break; + case 88: ldpc_BG2_Zc88_byte(c,d); break; + case 96: ldpc_BG2_Zc96_byte(c,d); break; + case 104: ldpc_BG2_Zc104_byte(c,d); break; + case 112: ldpc_BG2_Zc112_byte(c,d); break; + case 120: ldpc_BG2_Zc120_byte(c,d); break; + case 128: ldpc_BG2_Zc128_byte(c,d); break; + case 144: ldpc_BG2_Zc144_byte(c,d); break; + case 160: ldpc_BG2_Zc160_byte(c,d); break; + case 176: ldpc_BG2_Zc176_byte(c,d); break; + case 192: ldpc_BG2_Zc192_byte(c,d); break; + case 208: ldpc_BG2_Zc208_byte(c,d); break; + case 224: ldpc_BG2_Zc224_byte(c,d); break; + case 240: ldpc_BG2_Zc240_byte(c,d); break; + case 256: ldpc_BG2_Zc256_byte(c,d); break; + case 288: ldpc_BG2_Zc288_byte(c,d); break; + case 320: ldpc_BG2_Zc320_byte(c,d); break; + case 352: ldpc_BG2_Zc352_byte(c,d); break; + case 384: ldpc_BG2_Zc384_byte(c,d); break; + default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break; + } + } + else { + AssertFatal(0,"BG %d is not supported yet\n",BG); + } + +} + + + diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c index 6ded22d8ca..76f92574ba 100644 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c @@ -37,77 +37,247 @@ #include #include #include "defs.h" +#include "assertions.h" +#include "openair1/PHY/CODING/nrLDPC_defs.h" +#include "ldpc_generate_coefficient.c" -short *choose_generator_matrix(short BG,short Zc); -extern short no_shift_values_BG1[1012],pointer_shift_values_BG1[1012],no_shift_values_BG2[2109],pointer_shift_values_BG2[2019]; -int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb,short block_length) +int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length, short BG,unsigned char gen_code) { - short *Gen_shift_values=choose_generator_matrix(BG,Zc); - short *no_shift_values, *pointer_shift_values; - int no_punctured_columns; - short nrows,ncols,rate=3; - int i1,i2,i3,i4,i5,temp_prime; + unsigned char c[22*384]; //padded input, unpacked, max size + unsigned char d[68*384]; //coded output, unpacked, max size unsigned char channel_temp,temp; + short *Gen_shift_values, *no_shift_values, *pointer_shift_values; + short nrows = 46;//parity check bits + short ncols = 22;//info bits + + + int i,i1,i2,i3,i4,i5,temp_prime,var; + int no_punctured_columns,removed_bit,rate=3; + int nind=0; + int indlist[1000]; + int indlist2[1000]; + + //determine number of bits in codeword + //if (block_length>3840) + if (BG==1) + { + nrows=46; //parity check bits + ncols=22; //info bits + rate=3; + } + //else if (block_length<=3840) + else if (BG==2) + { + //BG=2; + nrows=42; //parity check bits + ncols=10; // info bits + rate=5; + } + + Gen_shift_values=choose_generator_matrix(BG,Zc); + if (Gen_shift_values==NULL) { + printf("ldpc_encoder_orig: could not find generator matrix\n"); + return(-1); + } + + //printf("ldpc_encoder_orig: BG %d, Zc %d, Kb %d\n",BG, Zc, Kb); + + // load base graph of generator matrix if (BG==1) { no_shift_values=(short *) no_shift_values_BG1; pointer_shift_values=(short *) pointer_shift_values_BG1; - nrows=46; //parity check bits - ncols=22; //info bits - rate=3; } else if (BG==2) { no_shift_values=(short *) no_shift_values_BG2; pointer_shift_values=(short *) pointer_shift_values_BG2; - nrows=42; //parity check bits - ncols=10; //info bits - rate=5; } else { - printf("problem with BG\n"); - return(-1); + AssertFatal(0,"BG %d is not supported yet\n",BG); } - - + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; + removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*rate); + //printf("%d\n",no_punctured_columns); + //printf("%d\n",removed_bit); + // unpack input + memset(c,0,sizeof(unsigned char) * ncols * Zc); + memset(d,0,sizeof(unsigned char) * nrows * Zc); - //printf("no_punctured_columns = %d\n",no_punctured_columns); - - for (i2=0; i2 < Zc; i2++) + for (i=0; i>7&1; + c[i]=(test_input[i/8]&(128>>(i&7)))>>(7-(i&7)); + } - //rotate matrix here - for (i5=0; i5 < Kb; i5++) - { - temp = c[i5*Zc]; - memmove(&c[i5*Zc], &c[i5*Zc+1], (Zc-1)*sizeof(unsigned char)); - c[i5*Zc+Zc-1] = temp; + // parity check part + + if (gen_code==1) + { + char fname[100]; + sprintf(fname,"ldpc_BG%d_Zc%d_byte.c",BG,Zc); + FILE *fd=fopen(fname,"w"); + AssertFatal(fd!=NULL,"cannot open %s\n",fname); + sprintf(fname,"ldpc_BG%d_Zc%d_16bit.c",BG,Zc); + FILE *fd2=fopen(fname,"w"); + AssertFatal(fd2!=NULL,"cannot open %s\n",fname); + + int shift; + char data_type[100]; + char xor_command[100]; + int mask; + + + + + fprintf(fd,"#include \"PHY/sse_intrin.h\"\n"); + fprintf(fd2,"#include \"PHY/sse_intrin.h\"\n"); + + if ((Zc&31)==0) { + shift=5; // AVX2 - 256-bit SIMD + mask=31; + strcpy(data_type,"__m256i"); + strcpy(xor_command,"_mm256_xor_si256"); } + else if ((Zc&15)==0) { + shift=4; // SSE4 - 128-bit SIMD + mask=15; + strcpy(data_type,"__m128i"); + strcpy(xor_command,"_mm_xor_si128"); - // calculate each row in base graph - for (i1=0; i1 < nrows-no_punctured_columns; i1++) + } + else if ((Zc&7)==0) { + shift=3; // MMX - 64-bit SIMD + mask=7; + strcpy(data_type,"__m64"); + strcpy(xor_command,"_mm_xor_si64"); + } + else { + shift=0; // no SIMD + mask=0; + strcpy(data_type,"uint8_t"); + strcpy(xor_command,"scalar_xor"); + fprintf(fd,"#define scalar_xor(a,b) ((a)^(b))\n"); + fprintf(fd2,"#define scalar_xor(a,b) ((a)^(b))\n"); + } + fprintf(fd,"// generated code for Zc=%d, byte encoding\n",Zc); + fprintf(fd2,"// generated code for Zc=%d, 16bit encoding\n",Zc); + fprintf(fd,"static inline void ldpc_BG%d_Zc%d_byte(uint8_t *c,uint8_t *d) {\n",BG,Zc); + fprintf(fd2,"static inline void ldpc_BG%d_Zc%d_16bit(uint16_t *c,uint16_t *d) {\n",BG,Zc); + fprintf(fd," %s *csimd=(%s *)c,*dsimd=(%s *)d;\n\n",data_type,data_type,data_type); + fprintf(fd2," %s *csimd=(%s *)c,*dsimd=(%s *)d;\n\n",data_type,data_type,data_type); + fprintf(fd," %s *c2,*d2;\n\n",data_type); + fprintf(fd2," %s *c2,*d2;\n\n",data_type); + fprintf(fd," int i2;\n"); + fprintf(fd2," int i2;\n"); + fprintf(fd," for (i2=0; i2<%d; i2++) {\n",Zc>>shift); + if (shift > 0) + fprintf(fd2," for (i2=0; i2<%d; i2++) {\n",Zc>>(shift-1)); + for (i2=0; i2 < 1; i2++) { - channel_temp=0; - for (i3=0; i3 < Kb; i3++) - { - temp_prime=i1 * ncols + i3; + //t=Kb*Zc+i2; + + // calculate each row in base graph + - for (i4=0; i4 < no_shift_values[temp_prime]; i4++) + fprintf(fd," c2=&csimd[i2];\n"); + fprintf(fd," d2=&dsimd[i2];\n"); + fprintf(fd2," c2=&csimd[i2];\n"); + fprintf(fd2," d2=&dsimd[i2];\n"); + + for (i1=0; i1 < nrows; i1++) + + { + channel_temp=0; + fprintf(fd,"\n//row: %d\n",i1); + fprintf(fd2,"\n//row: %d\n",i1); + fprintf(fd," d2[%d]=",(Zc*i1)>>shift); + fprintf(fd2," d2[%d]=",(Zc*i1)>>(shift-1)); + + nind=0; + + for (i3=0; i3 < ncols; i3++) { - channel_temp = channel_temp ^ c[ i3*Zc + Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ] ]; + temp_prime=i1 * ncols + i3; + + + for (i4=0; i4 < no_shift_values[temp_prime]; i4++) + { + + var=(int)((i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc)/Zc); + int index =var*2*Zc + (i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc) % Zc; + + indlist[nind] = ((index&mask)*((2*Zc)>>shift)*Kb)+(index>>shift); + indlist2[nind++] = ((index&(mask>>1))*((2*Zc)>>(shift-1))*Kb)+(index>>(shift-1)); + + } + + } + for (i4=0;i4gen_code); +} \ No newline at end of file diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c deleted file mode 100644 index ef207b6cdc..0000000000 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c +++ /dev/null @@ -1,667 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*!\file ldpc_encoder2.c - * \brief Defines the optimized LDPC encoder - * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom) - * \email openair_tech@eurecom.fr - * \date 27-03-2018 - * \version 1.0 - * \note - * \warning - */ - -#include -#include -#include -#include -#include -#include "assertions.h" -#include "common/utils/LOG/log.h" -#include "PHY/TOOLS/time_meas.h" -#include "defs.h" - -//#define DEBUG_LDPC - -#include "ldpc384_byte.c" -#include "ldpc352_byte.c" -#include "ldpc320_byte.c" -#include "ldpc288_byte.c" -#include "ldpc256_byte.c" -#include "ldpc240_byte.c" -#include "ldpc224_byte.c" -#include "ldpc208_byte.c" -#include "ldpc192_byte.c" -#include "ldpc176_byte.c" -#include "ldpc_BG2_Zc384_byte.c" -#include "ldpc_BG2_Zc352_byte.c" -#include "ldpc_BG2_Zc320_byte.c" -#include "ldpc_BG2_Zc288_byte.c" -#include "ldpc_BG2_Zc256_byte.c" -#include "ldpc_BG2_Zc240_byte.c" -#include "ldpc_BG2_Zc224_byte.c" -#include "ldpc_BG2_Zc208_byte.c" -#include "ldpc_BG2_Zc192_byte.c" -#include "ldpc_BG2_Zc176_byte.c" -#include "ldpc_BG2_Zc160_byte.c" -#include "ldpc_BG2_Zc144_byte.c" -#include "ldpc_BG2_Zc128_byte.c" -#include "ldpc_BG2_Zc120_byte.c" -#include "ldpc_BG2_Zc112_byte.c" -#include "ldpc_BG2_Zc104_byte.c" -#include "ldpc_BG2_Zc96_byte.c" -#include "ldpc_BG2_Zc88_byte.c" -#include "ldpc_BG2_Zc80_byte.c" -#include "ldpc_BG2_Zc72_byte.c" - - - -void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,short Kb) -{ - - if (BG==1) - { - switch (Zc) - { - case 2: break; - case 3: break; - case 4: break; - case 5: break; - case 6: break; - case 7: break; - case 8: break; - case 9: break; - case 10: break; - case 11: break; - case 12: break; - case 13: break; - case 14: break; - case 15: break; - case 16: break; - case 18: break; - case 20: break; - case 22: break; - case 24: break; - case 26: break; - case 28: break; - case 30: break; - case 32: break; - case 36: break; - case 40: break; - case 44: break; - case 48: break; - case 52: break; - case 56: break; - case 60: break; - case 64: break; - case 72: break; - case 80: break; - case 88: break; - case 96: break; - case 104: break; - case 112: break; - case 120: break; - case 128: break; - case 144: break; - case 160: break; - case 176: ldpc176_byte(c,d); break; - case 192: ldpc192_byte(c,d); break; - case 208: ldpc208_byte(c,d); break; - case 224: ldpc224_byte(c,d); break; - case 240: ldpc240_byte(c,d); break; - case 256: ldpc256_byte(c,d); break; - case 288: ldpc288_byte(c,d); break; - case 320: ldpc320_byte(c,d); break; - case 352: ldpc352_byte(c,d); break; - case 384: ldpc384_byte(c,d); break; - default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break; - } - } - else if (BG==2) { - switch (Zc) - { - case 2: break; - case 3: break; - case 4: break; - case 5: break; - case 6: break; - case 7: break; - case 8: break; - case 9: break; - case 10: break; - case 11: break; - case 12: break; - case 13: break; - case 14: break; - case 15: break; - case 16: break; - case 18: break; - case 20: break; - case 22: break; - case 24: break; - case 26: break; - case 28: break; - case 30: break; - case 32: break; - case 36: break; - case 40: break; - case 44: break; - case 48: break; - case 52: break; - case 56: break; - case 60: break; - case 64: break; - case 72: ldpc_BG2_Zc72_byte(c,d); break; - case 80: ldpc_BG2_Zc80_byte(c,d); break; - case 88: ldpc_BG2_Zc88_byte(c,d); break; - case 96: ldpc_BG2_Zc96_byte(c,d); break; - case 104: ldpc_BG2_Zc104_byte(c,d); break; - case 112: ldpc_BG2_Zc112_byte(c,d); break; - case 120: ldpc_BG2_Zc120_byte(c,d); break; - case 128: ldpc_BG2_Zc128_byte(c,d); break; - case 144: ldpc_BG2_Zc144_byte(c,d); break; - case 160: ldpc_BG2_Zc160_byte(c,d); break; - case 176: ldpc_BG2_Zc176_byte(c,d); break; - case 192: ldpc_BG2_Zc192_byte(c,d); break; - case 208: ldpc_BG2_Zc208_byte(c,d); break; - case 224: ldpc_BG2_Zc224_byte(c,d); break; - case 240: ldpc_BG2_Zc240_byte(c,d); break; - case 256: ldpc_BG2_Zc256_byte(c,d); break; - case 288: ldpc_BG2_Zc288_byte(c,d); break; - case 320: ldpc_BG2_Zc320_byte(c,d); break; - case 352: ldpc_BG2_Zc352_byte(c,d); break; - case 384: ldpc_BG2_Zc384_byte(c,d); break; - default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break; - } - } - else { - AssertFatal(0,"BG %d is not supported yet\n",BG); - } - -} - - -int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length,short BG,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) -{ - - short nrows=0,ncols=0; - int i,i1,rate=3; - int no_punctured_columns,removed_bit; - - int simd_size; - - //determine number of bits in codeword - //if (block_length>3840) - if (BG==1) - { - //BG=1; - nrows=46; //parity check bits - ncols=22; //info bits - rate=3; - } - //else if (block_length<=3840) - else if (BG==2) - { - //BG=2; - nrows=42; //parity check bits - ncols=10; // info bits - rate=5; - - } - - -#ifdef DEBUG_LDPC - LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d\n",BG,Zc,Kb,block_length); - LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU %x %x %x %x\n",test_input[0],test_input[1],test_input[2],test_input[3]); -#endif - - if ((Zc&31) > 0) simd_size = 16; - else simd_size = 32; - - unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size - unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size - - unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c - - // calculate number of punctured bits - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); - // printf("%d\n",no_punctured_columns); - // printf("%d\n",removed_bit); - // unpack input - memset(c,0,sizeof(unsigned char) * ncols * Zc); - memset(d,0,sizeof(unsigned char) * nrows * Zc); - - if(tinput != NULL) start_meas(tinput); - for (i=0; i>(i&7)))>>(7-(i&7)); - //printf("c(%d,%d)=%d\n",j,i,temp); - } - - if(tinput != NULL) stop_meas(tinput); - - if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { - // extend matrix - if(tprep != NULL) start_meas(tprep); - for (i1=0; i1 < ncols; i1++) - { - memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); - memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); - } - for (i1=1;i1 8 bytes, pattern repeats. - __m256i zero256 = _mm256_setzero_si256(); - __m256i masks[8]; - register __m256i c256; - masks[0] = _mm256_set1_epi8(0x1); - masks[1] = _mm256_set1_epi8(0x2); - masks[2] = _mm256_set1_epi8(0x4); - masks[3] = _mm256_set1_epi8(0x8); - masks[4] = _mm256_set1_epi8(0x10); - masks[5] = _mm256_set1_epi8(0x20); - masks[6] = _mm256_set1_epi8(0x40); - masks[7] = _mm256_set1_epi8(0x80); -#endif - - AssertFatal(n_segments>0&&n_segments<=8,"0 < n_segments %d <= 8\n",n_segments); - - //determine number of bits in codeword - //if (block_length>3840) - if (BG==1) - { - nrows=46; //parity check bits - ncols=22; //info bits - rate=3; - } - //else if (block_length<=3840) - else if (BG==2) - { - //BG=2; - nrows=42; //parity check bits - ncols=10; // info bits - rate=5; - - } - -#ifdef DEBUG_LDPC - LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments); - LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]); -#endif - - AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length); - - if ((Zc&31) > 0) simd_size = 16; - else simd_size = 32; - - unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size - unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size - - unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c - - // calculate number of punctured bits - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); - // printf("%d\n",no_punctured_columns); - // printf("%d\n",removed_bit); - // unpack input - memset(c,0,sizeof(unsigned char) * ncols * Zc); - memset(d,0,sizeof(unsigned char) * nrows * Zc); - - if(tinput != NULL) start_meas(tinput); -#if 0 - for (i=0; i>(i&7)))>>(7-(i&7)); - //printf("c(%d,%d)=%d\n",j,i,temp); - c[i] |= (temp << j); - } - } -#else -#ifdef __AVX2__ - for (i=0; i>5; i++) { - c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[0])[i]), shufmask),andmask),zero256),masks[0]); - for (j=1; j>5)<<5;i>(i&7)))>>(7-(i&7)); - //printf("c(%d,%d)=%d\n",j,i,temp); - c[i] |= (temp << j); - } - } -#else - AssertFatal(1==0,"Need AVX2 for this\n"); -#endif -#endif - - if(tinput != NULL) stop_meas(tinput); - - if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { - // extend matrix - if(tprep != NULL) start_meas(tprep); - for (i1=0; i1 < ncols; i1++) - { - memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); - memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); - } - for (i1=1;i1>5; - uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5; - __m256i *c256p = (__m256i *)&c[2*Zc]; - __m256i *d256p = (__m256i *)&d[0]; - // if (((block_length-(2*Zc))&31)>0) l1++; - - for (i=0;i0) l2++; - - for (i1=0;i1>j)&1; - for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++) - for (j=0; j>j)&1; - } - -#else - AssertFatal(1==0,"Need AVX2 for now\n"); -#endif - - if(toutput != NULL) stop_meas(toutput); - return 0; -} - -int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) -{ - - short nrows=0,ncols=0; - int i,i1,j,rate=3; - int no_punctured_columns,removed_bit; - //Table of possible lifting sizes - char temp; - int simd_size; - unsigned int macro_segment, macro_segment_end; - - - macro_segment = 8*macro_num; - // macro_segment_end = (n_segments > 8*(macro_num+1)) ? 8*(macro_num+1) : n_segments; - macro_segment_end = macro_segment + (n_segments > 8 ? 8 : n_segments); - ///printf("macro_segment: %d\n", macro_segment); - ///printf("macro_segment_end: %d\n", macro_segment_end ); - -#ifdef __AVX2__ - __m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000); - __m256i andmask = _mm256_set1_epi64x(0x0102040810204080); // every 8 bits -> 8 bytes, pattern repeats. - __m256i zero256 = _mm256_setzero_si256(); - __m256i masks[8]; - register __m256i c256; - masks[0] = _mm256_set1_epi8(0x1); - masks[1] = _mm256_set1_epi8(0x2); - masks[2] = _mm256_set1_epi8(0x4); - masks[3] = _mm256_set1_epi8(0x8); - masks[4] = _mm256_set1_epi8(0x10); - masks[5] = _mm256_set1_epi8(0x20); - masks[6] = _mm256_set1_epi8(0x40); - masks[7] = _mm256_set1_epi8(0x80); -#endif - - - - //determine number of bits in codeword - if (BG==1) - { - nrows=46; //parity check bits - ncols=22; //info bits - rate=3; - } - else if (BG==2) - { - nrows=42; //parity check bits - ncols=10; // info bits - rate=5; - } - -#ifdef DEBUG_LDPC - LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments); - LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]); -#endif - - AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length); - - if ((Zc&31) > 0) simd_size = 16; - else simd_size = 32; - - unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size - unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size - - unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c - - // calculate number of punctured bits - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); - //printf("%d\n",no_punctured_columns); - //printf("%d\n",removed_bit); - // unpack input - memset(c,0,sizeof(unsigned char) * ncols * Zc); - memset(d,0,sizeof(unsigned char) * nrows * Zc); - - if(tinput != NULL) start_meas(tinput); -#if 0 - for (i=0; i>(i&7); - //printf("c(%d,%d)=%d\n",j,i,temp); - c[i] |= (temp << (j-macro_segment)); - } - } -#else -#ifdef __AVX2__ - for (i=0; i>5; i++) { - c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[macro_segment])[i]), shufmask),andmask),zero256),masks[0]); - //for (j=1; j>5)<<5;i>(i&7)))>>(7-(i&7)); - //printf("c(%d,%d)=%d\n",j,i,temp); - c[i] |= (temp << (j-macro_segment)); - } - } -#else - AssertFatal(1==0,"Need AVX2 for this\n"); -#endif -#endif - - if(tinput != NULL) stop_meas(tinput); - - if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { - // extend matrix - if(tprep != NULL) start_meas(tprep); - for (i1=0; i1 < ncols; i1++) - { - memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); - memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); - } - for (i1=1;i1>5; - uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5; - __m256i *c256p = (__m256i *)&c[2*Zc]; - __m256i *d256p = (__m256i *)&d[0]; - // if (((block_length-(2*Zc))&31)>0) l1++; - - for (i=0;i0) l2++; - - for (i1=0;i1>(j-macro_segment))&1; - for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++) - //for (j=0; j>(j-macro_segment))&1; - } - -#else - AssertFatal(1==0,"Need AVX2 for now\n"); -#endif - - if(toutput != NULL) stop_meas(toutput); - return 0; -} - diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c new file mode 100644 index 0000000000..7da265494a --- /dev/null +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c @@ -0,0 +1,146 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*!\file ldpc_encoder2.c + * \brief Defines the optimized LDPC encoder + * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom) + * \email openair_tech@eurecom.fr + * \date 27-03-2018 + * \version 1.0 + * \note + * \warning + */ + +#include +#include +#include +#include +#include +#include "assertions.h" +#include "common/utils/LOG/log.h" +#include "PHY/TOOLS/time_meas.h" +#include "openair1/PHY/CODING/nrLDPC_defs.h" +#include "ldpc_encode_parity_check.c" +#include "ldpc_generate_coefficient.c" +//#define DEBUG_LDPC + + + + + +int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, encoder_implemparams_t *impp) +{ + + short nrows=0,ncols=0; + int i,i1,rate=3; + int no_punctured_columns,removed_bit; + + int simd_size; + + //determine number of bits in codeword + //if (block_length>3840) + if (BG==1) + { + //BG=1; + nrows=46; //parity check bits + ncols=22; //info bits + rate=3; + } + //else if (block_length<=3840) + else if (BG==2) + { + //BG=2; + nrows=42; //parity check bits + ncols=10; // info bits + rate=5; + + } + + +#ifdef DEBUG_LDPC + LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d\n",BG,Zc,Kb,block_length); + LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]); +#endif + + if ((Zc&31) > 0) simd_size = 16; + else simd_size = 32; + + unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size + unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size + + unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c + + // calculate number of punctured bits + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; + removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); + // printf("%d\n",no_punctured_columns); + // printf("%d\n",removed_bit); + // unpack input + memset(c,0,sizeof(unsigned char) * ncols * Zc); + memset(d,0,sizeof(unsigned char) * nrows * Zc); + + if(impp->tinput != NULL) start_meas(impp->tinput); + for (i=0; i>(i&7)))>>(7-(i&7)); + //printf("c(%d,%d)=%d\n",j,i,temp); + } + + if(impp->tinput != NULL) stop_meas(impp->tinput); + + if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { + // extend matrix + if(impp->tprep != NULL) start_meas(impp->tprep); + for (i1=0; i1 < ncols; i1++) + { + memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); + memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); + } + for (i1=1;i1tprep != NULL) stop_meas(impp->tprep); + //parity check part + if(impp->tparity != NULL) start_meas(impp->tparity); + encode_parity_check_part_optim(c_extension, d, BG, Zc, Kb); + if(impp->tparity != NULL) stop_meas(impp->tparity); + } + else { + if (encode_parity_check_part_orig(c, d, BG, Zc, Kb, block_length)!=0) { + printf("Problem with encoder\n"); + return(-1); + } + } + if(impp->toutput != NULL) start_meas(impp->toutput); + // information part and puncture columns + memcpy(&channel_input[0][0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char)); + memcpy(&channel_input[0][block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char)); + + if(impp->toutput != NULL) stop_meas(impp->toutput); + return 0; +} + + diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c index 5988c9067d..3d26a19063 100644 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c @@ -35,9 +35,8 @@ #include #include "Gen_shift_value.h" #include "assertions.h" -#include "defs.h" -short *choose_generator_matrix(short BG,short Zc) +static inline short *choose_generator_matrix(short BG,short Zc) { short *Gen_shift_values = NULL; @@ -361,237 +360,70 @@ short *choose_generator_matrix(short BG,short Zc) return Gen_shift_values; } -int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length, short BG,unsigned char gen_code) +static inline int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb,short block_length) { - unsigned char c[22*384]; //padded input, unpacked, max size - unsigned char d[68*384]; //coded output, unpacked, max size + short *Gen_shift_values=choose_generator_matrix(BG,Zc); + short *no_shift_values, *pointer_shift_values; + int no_punctured_columns; + short nrows,ncols,rate=3; + int i1,i2,i3,i4,i5,temp_prime; unsigned char channel_temp,temp; - short *Gen_shift_values, *no_shift_values, *pointer_shift_values; - short nrows = 46;//parity check bits - short ncols = 22;//info bits - - - int i,i1,i2,i3,i4,i5,temp_prime,var; - int no_punctured_columns,removed_bit,rate=3; - int nind=0; - int indlist[1000]; - int indlist2[1000]; - - //determine number of bits in codeword - //if (block_length>3840) - if (BG==1) - { - nrows=46; //parity check bits - ncols=22; //info bits - rate=3; - } - //else if (block_length<=3840) - else if (BG==2) - { - //BG=2; - nrows=42; //parity check bits - ncols=10; // info bits - rate=5; - } - - Gen_shift_values=choose_generator_matrix(BG,Zc); - if (Gen_shift_values==NULL) { - printf("ldpc_encoder_orig: could not find generator matrix\n"); - return(-1); - } - - //printf("ldpc_encoder_orig: BG %d, Zc %d, Kb %d\n",BG, Zc, Kb); - - // load base graph of generator matrix if (BG==1) { no_shift_values=(short *) no_shift_values_BG1; pointer_shift_values=(short *) pointer_shift_values_BG1; + nrows=46; //parity check bits + ncols=22; //info bits + rate=3; } else if (BG==2) { no_shift_values=(short *) no_shift_values_BG2; pointer_shift_values=(short *) pointer_shift_values_BG2; + nrows=42; //parity check bits + ncols=10; //info bits + rate=5; } else { - AssertFatal(0,"BG %d is not supported yet\n",BG); + printf("problem with BG\n"); + return(-1); } - + + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*rate); - //printf("%d\n",no_punctured_columns); - //printf("%d\n",removed_bit); - // unpack input - memset(c,0,sizeof(unsigned char) * ncols * Zc); - memset(d,0,sizeof(unsigned char) * nrows * Zc); - for (i=0; i>7&1; - c[i]=(test_input[i/8]&(128>>(i&7)))>>(7-(i&7)); - } + //t=Kb*Zc+i2; - // parity check part - - if (gen_code==1) - { - char fname[100]; - sprintf(fname,"ldpc_BG%d_Zc%d_byte.c",BG,Zc); - FILE *fd=fopen(fname,"w"); - AssertFatal(fd!=NULL,"cannot open %s\n",fname); - sprintf(fname,"ldpc_BG%d_Zc%d_16bit.c",BG,Zc); - FILE *fd2=fopen(fname,"w"); - AssertFatal(fd2!=NULL,"cannot open %s\n",fname); - - int shift; - char data_type[100]; - char xor_command[100]; - int mask; - - - - - fprintf(fd,"#include \"PHY/sse_intrin.h\"\n"); - fprintf(fd2,"#include \"PHY/sse_intrin.h\"\n"); - - if ((Zc&31)==0) { - shift=5; // AVX2 - 256-bit SIMD - mask=31; - strcpy(data_type,"__m256i"); - strcpy(xor_command,"_mm256_xor_si256"); - } - else if ((Zc&15)==0) { - shift=4; // SSE4 - 128-bit SIMD - mask=15; - strcpy(data_type,"__m128i"); - strcpy(xor_command,"_mm_xor_si128"); - - } - else if ((Zc&7)==0) { - shift=3; // MMX - 64-bit SIMD - mask=7; - strcpy(data_type,"__m64"); - strcpy(xor_command,"_mm_xor_si64"); - } - else { - shift=0; // no SIMD - mask=0; - strcpy(data_type,"uint8_t"); - strcpy(xor_command,"scalar_xor"); - fprintf(fd,"#define scalar_xor(a,b) ((a)^(b))\n"); - fprintf(fd2,"#define scalar_xor(a,b) ((a)^(b))\n"); - } - fprintf(fd,"// generated code for Zc=%d, byte encoding\n",Zc); - fprintf(fd2,"// generated code for Zc=%d, 16bit encoding\n",Zc); - fprintf(fd,"static inline void ldpc_BG%d_Zc%d_byte(uint8_t *c,uint8_t *d) {\n",BG,Zc); - fprintf(fd2,"static inline void ldpc_BG%d_Zc%d_16bit(uint16_t *c,uint16_t *d) {\n",BG,Zc); - fprintf(fd," %s *csimd=(%s *)c,*dsimd=(%s *)d;\n\n",data_type,data_type,data_type); - fprintf(fd2," %s *csimd=(%s *)c,*dsimd=(%s *)d;\n\n",data_type,data_type,data_type); - fprintf(fd," %s *c2,*d2;\n\n",data_type); - fprintf(fd2," %s *c2,*d2;\n\n",data_type); - fprintf(fd," int i2;\n"); - fprintf(fd2," int i2;\n"); - fprintf(fd," for (i2=0; i2<%d; i2++) {\n",Zc>>shift); - if (shift > 0) - fprintf(fd2," for (i2=0; i2<%d; i2++) {\n",Zc>>(shift-1)); - for (i2=0; i2 < 1; i2++) + //rotate matrix here + for (i5=0; i5 < Kb; i5++) { - //t=Kb*Zc+i2; - - // calculate each row in base graph - - - fprintf(fd," c2=&csimd[i2];\n"); - fprintf(fd," d2=&dsimd[i2];\n"); - fprintf(fd2," c2=&csimd[i2];\n"); - fprintf(fd2," d2=&dsimd[i2];\n"); - - for (i1=0; i1 < nrows; i1++) - - { - channel_temp=0; - fprintf(fd,"\n//row: %d\n",i1); - fprintf(fd2,"\n//row: %d\n",i1); - fprintf(fd," d2[%d]=",(Zc*i1)>>shift); - fprintf(fd2," d2[%d]=",(Zc*i1)>>(shift-1)); - - nind=0; - - for (i3=0; i3 < ncols; i3++) - { - temp_prime=i1 * ncols + i3; - - - for (i4=0; i4 < no_shift_values[temp_prime]; i4++) - { - - var=(int)((i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc)/Zc); - int index =var*2*Zc + (i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc) % Zc; - - indlist[nind] = ((index&mask)*((2*Zc)>>shift)*Kb)+(index>>shift); - indlist2[nind++] = ((index&(mask>>1))*((2*Zc)>>(shift-1))*Kb)+(index>>(shift-1)); - - } - - - } - for (i4=0;i4 - * \date 27-03-2018 - * \version 1.0 - * \note - * \warning - */ - -#ifndef __NR_LDPC_DECODER__H__ -#define __NR_LDPC_DECODER__H__ - -#include "nrLDPC_types.h" -#include "nrLDPC_init_mem.h" - -/** - \brief LDPC decoder - \param p_decParams LDPC decoder parameters - \param p_llr Input LLRs - \param p_llrOut Output vector - \param p_profiler LDPC profiler statistics -*/ -int32_t nrLDPC_decoder(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_llrOut, t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats* p_profiler); - -#endif +#ifdef LDPC_LOADER +nrLDPC_decoderfunc_t nrLDPC_decoder; +nrLDPC_encoderfunc_t nrLDPC_encoder; +#else +/* functions to load the LDPC shared lib, implemented in openair1/PHY/CODING/nrLDPC_load.c */ +extern int load_nrLDPClib(void) ; +extern int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_ptr); // for ldpctest +/* ldpc coder/decoder functions, as loaded by load_nrLDPClib(). */ +extern nrLDPC_decoderfunc_t nrLDPC_decoder; +extern nrLDPC_encoderfunc_t nrLDPC_encoder; +// inline functions: +#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h" +#endif \ No newline at end of file diff --git a/openair1/PHY/CODING/nrLDPC_load.c b/openair1/PHY/CODING/nrLDPC_load.c new file mode 100644 index 0000000000..a74bdf7bd1 --- /dev/null +++ b/openair1/PHY/CODING/nrLDPC_load.c @@ -0,0 +1,76 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair1/PHY/CODING/coding_nr_load.c + * \brief: load library implementing coding/decoding algorithms + * \author Francois TABURET + * \date 2020 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ +#define _GNU_SOURCE +#include +#include +#include +#include "assertions.h" +#include "common/utils/LOG/log.h" +#define LDPC_LOADER +#include "PHY/CODING/nrLDPC_extern.h" +#include "common/config/config_userapi.h" +#include "common/utils/load_module_shlib.h" + + +/* function description array, to be used when loading the encoding/decoding shared lib */ +static loader_shlibfunc_t shlib_fdesc[2]; + +char *arg[64]={"ldpctest","-O","cmdlineonly::dbgl0"}; + +int load_nrLDPClib(void) { + char *ptr = (char*)config_get_if(); + if ( ptr==NULL ) {// phy simulators, config module possibly not loaded + load_configmodule(3,(char **)arg,CONFIG_ENABLECMDLINEONLY) ; + logInit(); + } + shlib_fdesc[0].fname = "nrLDPC_decod"; + shlib_fdesc[1].fname = "nrLDPC_encod"; + int ret=load_module_shlib("ldpc",shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t),NULL); + AssertFatal( (ret >= 0),"Error loading ldpc decoder"); + nrLDPC_decoder = (nrLDPC_decoderfunc_t)shlib_fdesc[0].fptr; + nrLDPC_encoder = (nrLDPC_encoderfunc_t)shlib_fdesc[1].fptr; +return 0; +} + +int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_ptr) { + loader_shlibfunc_t shlib_encoder_fdesc; + + shlib_encoder_fdesc.fname = "nrLDPC_encod"; + char libpath[64]; + sprintf(libpath,"ldpc%s",libversion); + int ret=load_module_shlib(libpath,&shlib_encoder_fdesc,1,NULL); + AssertFatal( (ret >= 0),"Error loading ldpc encoder %s\n",libpath); + *nrLDPC_encoder_ptr = (nrLDPC_encoderfunc_t)shlib_encoder_fdesc.fptr; +return 0; +} + + diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index f0ad3cbaae..4798f9a9e4 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -31,6 +31,7 @@ #include "TDD-Config.h" #include "MBSFN-SubframeConfigList.h"*/ #include "openair1/PHY/defs_RU.h" +#include "openair1/PHY/CODING/nrLDPC_extern.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "assertions.h" #include @@ -115,6 +116,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_gNB][MOD %02"PRIu8"][]\n", gNB->Mod_id); crcTableInit(); init_dfts(); + load_nrLDPClib(); // PBCH DMRS gold sequences generation nr_init_pbch_dmrs(gNB); //PDCCH DMRS init diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index dae5586224..17de9c02af 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -35,12 +35,11 @@ #include "PHY/CODING/coding_extern.h" #include "PHY/CODING/coding_defs.h" #include "PHY/CODING/lte_interleaver_inline.h" -#include "PHY/CODING/nrLDPC_encoder/defs.h" +#include "PHY/CODING/nrLDPC_extern.h" #include "PHY/NR_TRANSPORT/nr_transport.h" #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "SCHED_NR/sched_nr.h" -#include "defs.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "common/utils/LOG/log.h" #include @@ -404,9 +403,11 @@ int nr_dlsch_encoding(unsigned char *a, //ldpc_encoder_orig((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],dlsch->harq_processes[harq_pid]->d[r],*Zc,Kb,Kr,BG,0); //ldpc_encoder_optim((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],(unsigned char*)&dlsch->harq_processes[harq_pid]->d[r][0],*Zc,Kb,Kr,BG,NULL,NULL,NULL,NULL); } - + encoder_implemparams_t impp; + impp.n_segments=dlsch->harq_processes[harq_pid]->C; for(int j=0;j<(dlsch->harq_processes[harq_pid]->C/8+1);j++) { - ldpc_encoder_optim_8seg_multi(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,dlsch->harq_processes[harq_pid]->C,j,NULL,NULL,NULL,NULL); + impp.macro_num=j; + nrLDPC_encoder(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,&impp); } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 3945439a45..c58941b077 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -37,8 +37,7 @@ #include "PHY/CODING/coding_extern.h" #include "PHY/CODING/coding_defs.h" #include "PHY/CODING/lte_interleaver_inline.h" -#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h" -#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" +#include "PHY/CODING/nrLDPC_extern.h" #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "PHY/NR_TRANSPORT/nr_ulsch.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index b3a95e313e..b81c01114d 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -41,8 +41,7 @@ #include "SCHED_NR_UE/defs.h" #include "SIMULATION/TOOLS/sim.h" #include "executables/nr-uesoftmodem.h" -#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h" -#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" +#include "PHY/CODING/nrLDPC_extern.h" //#define DEBUG_DLSCH_DECODING //#define ENABLE_PHY_PAYLOAD_DEBUG 1 diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 2eb6dcd7fe..8b80b1b219 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -36,7 +36,7 @@ #include "PHY/CODING/coding_defs.h" #include "PHY/CODING/coding_extern.h" #include "PHY/CODING/lte_interleaver_inline.h" -#include "PHY/CODING/nrLDPC_encoder/defs.h" +#include "PHY/CODING/nrLDPC_extern.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h" #include "common/utils/LOG/vcd_signal_dumper.h" @@ -353,8 +353,11 @@ opp_enabled=0; printf("%d \n", harq_process->d[0][cnt]); } printf("\n");*/ + encoder_implemparams_t impp; + impp.n_segments=harq_process->C; + impp.macro_num=0; - ldpc_encoder_optim_8seg(harq_process->c,harq_process->d,*pz,Kb,Kr,BG,harq_process->C,NULL,NULL,NULL,NULL); + nrLDPC_encoder(harq_process->c,harq_process->d,*pz,Kb,Kr,BG,&impp); //stop_meas(te_stats); //printf("end ldpc encoder -- output\n"); diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 3c0f0db8da..fc81f4d74b 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -40,7 +40,7 @@ #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "PHY/impl_defs_top.h" #include "PHY/defs_common.h" -#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h" +#include "PHY/CODING/nrLDPC_extern.h" #include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" #define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c index 757ad6f75d..3066f0906f 100644 --- a/targets/ARCH/COMMON/common_lib.c +++ b/targets/ARCH/COMMON/common_lib.c @@ -37,6 +37,7 @@ #include #include "common_lib.h" +#include "assertions.h" #include "common/utils/load_module_shlib.h" #include "common/utils/LOG/log.h" #include "targets/RT/USER/lte-softmodem.h" @@ -91,38 +92,44 @@ int load_lib(openair0_device *device, { loader_shlibfunc_t shlib_fdesc[1]; int ret=0; - char *libname; + char *deflibname=OAI_RF_LIBNAME; openair0_cfg->recplay_mode = read_recplayconfig(&(openair0_cfg->recplay_conf),&(device->recplay_state)); if ( openair0_cfg->recplay_mode == RECPLAY_REPLAYMODE ) { - libname=OAI_IQPLAYER_LIBNAME; + deflibname=OAI_IQPLAYER_LIBNAME; shlib_fdesc[0].fname="device_init"; set_softmodem_optmask(SOFTMODEM_RECPLAY_BIT); // softmodem has to know we use the iqplayer to workaround randomized algorithms } else if ( IS_SOFTMODEM_BASICSIM ) { - libname=OAI_BASICSIM_LIBNAME; + deflibname=OAI_BASICSIM_LIBNAME; shlib_fdesc[0].fname="device_init"; } else if (IS_SOFTMODEM_RFSIM && flag == RAU_LOCAL_RADIO_HEAD) { - libname=OAI_RFSIM_LIBNAME; + deflibname=OAI_RFSIM_LIBNAME; shlib_fdesc[0].fname="device_init"; } else if (flag == RAU_LOCAL_RADIO_HEAD) { if (IS_SOFTMODEM_RFSIM) - libname="rfsimulator"; + deflibname="rfsimulator"; else - libname=OAI_RF_LIBNAME; + deflibname=OAI_RF_LIBNAME; shlib_fdesc[0].fname="device_init"; } else { - libname=OAI_TP_LIBNAME; + deflibname=OAI_TP_LIBNAME; shlib_fdesc[0].fname="transport_init"; } - ret=load_module_shlib(libname,shlib_fdesc,1,NULL); + + char *devname=NULL; + paramdef_t device_params[]=DEVICE_PARAMS_DESC ; + int numparams = sizeof(device_params)/sizeof(paramdef_t); + int devname_pidx = config_paramidx_fromname(device_params,numparams, CONFIG_DEVICEOPT_NAME); + device_params[devname_pidx].defstrval=deflibname; + + config_get(device_params,numparams,DEVICE_SECTION); + + ret=load_module_shlib(devname,shlib_fdesc,1,NULL); + AssertFatal( (ret >= 0), + "Library %s couldn't be loaded\n",devname); - if (ret < 0) { - LOG_E(HW,"Library %s couldn't be loaded\n",libname); - } else { - ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg); - } - return ret; + return ((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg); } diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 7e51bdc81a..ecadb68c0c 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -448,6 +448,24 @@ typedef struct { extern "C" { #endif + + +#define DEVICE_SECTION "device" +#define CONFIG_HLP_DEVICE "Identifies the oai device (the interface to RF) to use, the shared lib \"lib_.so\" will be loaded" + +#define CONFIG_DEVICEOPT_NAME "name" + +/* inclusion for device configuration */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* config parameters for oai device */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define DEVICE_PARAMS_DESC {\ + { CONFIG_DEVICEOPT_NAME, CONFIG_HLP_DEVICE, 0, strptr:&devname, defstrval:NULL, TYPE_STRING, 0}\ +} + + + /*! \brief get device name from device type */ char *get_devname(int devtype); /*! \brief Initialize openair RF target. It returns 0 if OK */ diff --git a/targets/ARCH/COMMON/record_player.h b/targets/ARCH/COMMON/record_player.h index 903dda006b..500acdd709 100644 --- a/targets/ARCH/COMMON/record_player.h +++ b/targets/ARCH/COMMON/record_player.h @@ -37,19 +37,6 @@ extern "C" { #endif -#define CONFIG_OPT_RECPLAY "enable_recplay" - -#define CONFIG_HLP_RECPLAY "Allow record player" -#define USRP_SECTION "device.usrp" -/* inclusion for device configuration */ -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters for USRP record/playback */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define DEVICE_PARAMS_DESC { \ - {CONFIG_OPT_RECPLAY, CONFIG_HLP_RECPLAY, PARAMFLAG_BOOL, uptr:&enable_recplay, defuintval:0, TYPE_UINT, 0} \ - } - /* inclusions for record player */ #define RECPLAY_DISABLED 0 @@ -114,7 +101,7 @@ typedef struct { {CONFIG_OPT_SF_LOOPS, CONFIG_HLP_SF_LOOPS, 0, uptr:&((*recplay_conf)->u_sf_loops), defintval:DEF_SF_NB_LOOP, TYPE_UINT, 0}, \ {CONFIG_OPT_SF_RDELAY, CONFIG_HLP_SF_RDELAY, 0, uptr:&((*recplay_conf)->u_sf_read_delay), defintval:DEF_SF_DELAY_READ, TYPE_UINT, 0}, \ {CONFIG_OPT_SF_WDELAY, CONFIG_HLP_SF_WDELAY, 0, uptr:&((*recplay_conf)->u_sf_write_delay), defintval:DEF_SF_DELAY_WRITE, TYPE_UINT, 0}, \ - }/*! \brief USRP Configuration and state */ + }/*! \brief Record Player Configuration and state */ typedef struct { char u_sf_filename[1024]; // subframes file path unsigned int u_sf_max ; // max number of recorded subframes diff --git a/targets/ARCH/iqplayer/iqplayer_lib.c b/targets/ARCH/iqplayer/iqplayer_lib.c index beb05de3fd..c4133d1b11 100644 --- a/targets/ARCH/iqplayer/iqplayer_lib.c +++ b/targets/ARCH/iqplayer/iqplayer_lib.c @@ -25,6 +25,7 @@ */ #define _LARGEFILE_SOURCE #define _FILE_OFFSET_BITS 64 +#define NB_ANTENNAS_RX 2 #include #include #include @@ -45,7 +46,9 @@ static void parse_iqfile_header(openair0_device *device, iqfile_header_t *iq_fh) { - AssertFatal((memcmp(iq_fh->oaiid,OAIIQFILE_ID,sizeof(OAIIQFILE_ID)) == 0),"iqfile doesn't seem to be compatible with oai (invalid id in header)\n"); + AssertFatal((memcmp(iq_fh->oaiid,OAIIQFILE_ID,sizeof(OAIIQFILE_ID)) == 0), + "iqfile doesn't seem to be compatible with oai (invalid id %.4s in header)\n", + iq_fh->oaiid); device->type = iq_fh->devtype; device->openair0_cfg[0].tx_sample_advance=iq_fh->tx_sample_advance; device->openair0_cfg[0].tx_bw = device->openair0_cfg[0].rx_bw = iq_fh->bw; @@ -138,6 +141,13 @@ static int iqplayer_loadfile(openair0_device *device, openair0_config_t *openair return 0; } +/*! \brief start the oai iq player + * \param device, the hardware used + */ +static int trx_iqplayer_start(openair0_device *device){ + return 0; +} + /*! \brief Terminate operation of the oai iq player * \param device, the hardware used */ @@ -287,7 +297,7 @@ static int trx_iqplayer_read(openair0_device *device, openair0_timestamp *ptimes int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { device->openair0_cfg = openair0_cfg; - device->trx_start_func = NULL; + device->trx_start_func = trx_iqplayer_start; device->trx_get_stats_func = NULL; device->trx_reset_stats_func = NULL; device->trx_end_func = trx_iqplayer_end; diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index f88d98536d..6d1a3b8cb2 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -2194,7 +2194,9 @@ int start_rf(RU_t *ru) { } int stop_rf(RU_t *ru) { - ru->rfdevice.trx_end_func(&ru->rfdevice); + if(ru->rfdevice.trx_end_func != NULL) { + ru->rfdevice.trx_end_func(&ru->rfdevice); + } return 0; } From 3b3d2322141959cdaf5e97296b590cef7ff6ab9e Mon Sep 17 00:00:00 2001 From: frtabu Date: Wed, 11 Mar 2020 17:32:13 +0100 Subject: [PATCH 25/25] move ldpc coder/decoder into a shared lib dymically loaded. Also fix a record player bug --- cmake_targets/CMakeLists.txt | 39 +- common/config/config_userapi.c | 3 +- common/utils/telnetsrv/telnetsrv.c | 20 +- openair1/PHY/CODING/TESTBENCH/ldpctest.c | 22 +- .../CODING/nrLDPC_decoder/nrLDPC_decoder.c | 4 +- .../PHY/CODING/nrLDPC_decoder/nrLDPC_init.h | 2 +- .../CODING/nrLDPC_decoder/nrLDPC_init_mem.h | 1 - .../PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h | 2 +- .../PHY/CODING/nrLDPC_decoder/nrLDPC_types.h | 5 +- .../{nrLDPC_defs.h => nrLDPCdecoder_defs.h} | 2 +- openair1/PHY/CODING/nrLDPC_defs.h | 59 ++ openair1/PHY/CODING/nrLDPC_encoder/defs.h | 54 -- .../nrLDPC_encoder/ldpc_encode_parity_check.c | 201 ++++++ .../PHY/CODING/nrLDPC_encoder/ldpc_encoder.c | 252 +++++-- .../PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c | 667 ------------------ .../nrLDPC_encoder/ldpc_encoder_optim.c | 146 ++++ .../nrLDPC_encoder/ldpc_encoder_optim8seg.c | 225 ++++++ .../ldpc_encoder_optim8segmulti.c | 238 +++++++ .../ldpc_generate_coefficient.c | 244 +------ .../nrLDPC_decoder.h => nrLDPC_extern.h} | 39 +- openair1/PHY/CODING/nrLDPC_load.c | 76 ++ openair1/PHY/INIT/nr_init.c | 2 + openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c | 9 +- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 3 +- .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 3 +- .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 7 +- openair1/PHY/defs_gNB.h | 2 +- targets/ARCH/COMMON/common_lib.c | 35 +- targets/ARCH/COMMON/common_lib.h | 18 + targets/ARCH/COMMON/record_player.h | 15 +- targets/ARCH/iqplayer/iqplayer_lib.c | 14 +- targets/RT/USER/lte-ru.c | 4 +- 32 files changed, 1351 insertions(+), 1062 deletions(-) rename openair1/PHY/CODING/nrLDPC_decoder/{nrLDPC_defs.h => nrLDPCdecoder_defs.h} (99%) create mode 100644 openair1/PHY/CODING/nrLDPC_defs.h delete mode 100644 openair1/PHY/CODING/nrLDPC_encoder/defs.h create mode 100644 openair1/PHY/CODING/nrLDPC_encoder/ldpc_encode_parity_check.c delete mode 100644 openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c create mode 100644 openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c create mode 100644 openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8seg.c create mode 100644 openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c rename openair1/PHY/CODING/{nrLDPC_decoder/nrLDPC_decoder.h => nrLDPC_extern.h} (60%) create mode 100644 openair1/PHY/CODING/nrLDPC_load.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index c4d3d7e62e..496417936a 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1298,14 +1298,35 @@ set(PHY_SMALLBLOCKSRC set(PHY_TURBOIF ${OPENAIR1_DIR}/PHY/CODING/coding_load.c ) -set(PHY_LDPCSRC + +set(PHY_LDPC_ORIG_SRC ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c - ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c - ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c ) +set(PHY_LDPC_OPTIM_SRC + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c +) +set(PHY_LDPC_OPTIM8SEG_SRC + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8seg.c +) +set(PHY_LDPC_OPTIM8SEGMULTI_SRC + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c +) +set(PHY_NR_CODINGIF + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_load.c; +) + +add_library(ldpc_orig MODULE ${PHY_LDPC_ORIG_SRC} ) +add_library(ldpc_optim MODULE ${PHY_LDPC_OPTIM_SRC} ) +add_library(ldpc_optim8seg MODULE ${PHY_LDPC_OPTIM8SEG_SRC} ) +add_library(ldpc MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} ) + add_library(coding MODULE ${PHY_TURBOSRC} ) + set(PHY_SRC_COMMON ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci_tools_common.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/lte_mcs.c @@ -1484,10 +1505,9 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/TOOLS/lut.c ${PHY_POLARSRC} ${PHY_SMALLBLOCKSRC} - ${PHY_LDPCSRC} + ${PHY_NR_CODINGIF} ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/pucch_rx.c ) - set(PHY_NR_UE_SRC ${OPENAIR1_DIR}/PHY/INIT/nr_parms.c ${OPENAIR1_DIR}/PHY/MODULATION/nr_modulation.c @@ -1535,7 +1555,7 @@ set(PHY_SRC_UE # ${OPENAIR1_DIR}/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c ${PHY_POLARSRC} ${PHY_SMALLBLOCKSRC} - ${PHY_LDPCSRC} + ${PHY_NR_CODINGIF} ) @@ -2588,7 +2608,7 @@ target_link_libraries (nr-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LI target_link_libraries (nr-softmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-softmodem ${T_LIB}) - +add_dependencies( nr-softmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) # nr-uesoftmodem is UE implementation ####################################### @@ -2629,7 +2649,7 @@ target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_ target_link_libraries (nr-uesoftmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-uesoftmodem ${T_LIB}) - +add_dependencies( nr-uesoftmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) # USIM process ################# @@ -2696,10 +2716,13 @@ target_link_libraries(smallblocktest ) add_executable(ldpctest + ${PHY_NR_CODINGIF} ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c ${T_SOURCE} ${SHLIB_LOADER_SOURCES} ) +add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) + target_link_libraries(ldpctest -Wl,--start-group UTIL SIMU PHY_NR CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} dl diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index 67fdc2c920..c951905101 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -45,7 +45,8 @@ configmodule_interface_t *config_get_if(void) { if (cfgptr == NULL) { - CONFIG_PRINTF_ERROR("[CONFIG] %s %d config module not initialized\n",__FILE__,__LINE__); + if (isLogInitDone()) + LOG_W(ENB_APP,"[CONFIG] %s %d config module not initialized\n",__FILE__,__LINE__); } return cfgptr; diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index 10163b22b5..06a5d350c7 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -377,6 +377,14 @@ int setgetvar(int moduleindex,char getorset,char *params) { client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); break; + case TELNET_VARTYPE_INT8: + client_printf("%i\n",(int)(*(int8_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr))); + break; + + case TELNET_VARTYPE_UINT: + client_printf("%u\n",*(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + break; + case TELNET_VARTYPE_DOUBLE: client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); break; @@ -405,7 +413,17 @@ int setgetvar(int moduleindex,char getorset,char *params) { *(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (short)strtol(varval,NULL,0); client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); break; - + + case TELNET_VARTYPE_INT8: + *(char *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (char)strtol(varval,NULL,0); + client_printf("%i\n",*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + break; + + case TELNET_VARTYPE_UINT: + *(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (unsigned int)strtol(varval,NULL,0); + client_printf("%u\n",*(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + break; + case TELNET_VARTYPE_DOUBLE: *(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = strtod(varval,NULL); client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c index 95ee3fed17..552af99c41 100644 --- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c +++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c @@ -25,8 +25,7 @@ #include #include "assertions.h" #include "SIMULATION/TOOLS/sim.h" -#include "PHY/CODING/nrLDPC_encoder/defs.h" -#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h" +#include "PHY/CODING/nrLDPC_extern.h" #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" #define MAX_NUM_DLSCH_SEGMENTS 16 @@ -85,6 +84,7 @@ typedef struct { RAN_CONTEXT_t RC; PHY_VARS_UE ***PHY_vars_UE_g; uint16_t NB_UE_INST = 1; +nrLDPC_encoderfunc_t encoder_orig; short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; @@ -286,16 +286,19 @@ int test_ldpc(short No_iteration, no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*(1/((float)nom_rate/(float)denom_rate)))/Zc; // printf("puncture:%d\n",no_punctured_columns); removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/((float)nom_rate/(float)denom_rate)); + encoder_implemparams_t impp=INIT0_LDPCIMPLEMPARAMS; + + impp.gen_code=1; if (ntrials==0) - ldpc_encoder_orig(test_input[0],channel_input[0], Zc, BG, block_length, BG, 1); - + encoder_orig(test_input,channel_input, Zc, BG, block_length, BG, &impp); + impp.gen_code=0; for (trial=0; trial < ntrials; trial++) { segment_bler = 0; //// encoder start_meas(&time); for(j=0;j #include -#include "nrLDPC_defs.h" +#include "nrLDPCdecoder_defs.h" #include "nrLDPC_types.h" #include "nrLDPC_init.h" #include "nrLDPC_mPass.h" @@ -47,7 +47,7 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, uint32_t numLLR, t_nrLDPC_lut* p_lut, t_nrLDPC_dec_params* p_decParams, t_nrLDPC_time_stats* p_profiler); -int32_t nrLDPC_decoder(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats* p_profiler) +int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats* p_profiler) { uint32_t numLLR; uint32_t numIter = 0; diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init.h index 82462c6d95..ea031dc2da 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init.h @@ -32,7 +32,7 @@ #define __NR_LDPC_INIT__H__ #include "nrLDPC_lut.h" -#include "nrLDPC_defs.h" +#include "nrLDPCdecoder_defs.h" /** \brief Initializes the decoder and sets correct LUTs diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h index bdaa118e1f..3292c0debe 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h @@ -32,7 +32,6 @@ #define __NR_LDPC_INIT_MEM__H__ #include -#include "nrLDPC_defs.h" #include "nrLDPC_types.h" #ifndef malloc32_clear diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h index 66715618d0..7d0f5f077a 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h @@ -32,7 +32,7 @@ #define __NR_LDPC_MPASS__H__ #include -#include "nrLDPC_defs.h" +#include "nrLDPCdecoder_defs.h" /** \brief Circular memcpy diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h index 34322a7780..e5b99246d5 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h @@ -32,8 +32,7 @@ #define __NR_LDPC_TYPES__H__ #include "PHY/TOOLS/time_meas.h" -#include "nrLDPC_defs.h" - +#include "nrLDPCdecoder_defs.h" // ============================================================================== // TYPES @@ -103,4 +102,6 @@ typedef struct nrLDPC_procBuf { int8_t* llrProcBuf; /**< LLR processing buffer */ } t_nrLDPC_procBuf; + + #endif diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_defs.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h similarity index 99% rename from openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_defs.h rename to openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h index 940d842550..69fc88752f 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_defs.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h @@ -19,7 +19,7 @@ * contact@openairinterface.org */ -/*!\file nrLDPC_defs.h +/*!\file nrLDPCdecoder_defs.h * \brief Defines all constants and buffers for the LDPC decoder * \author Sebastian Wagner (TCL Communications) Email: * \date 27-03-2018 diff --git a/openair1/PHY/CODING/nrLDPC_defs.h b/openair1/PHY/CODING/nrLDPC_defs.h new file mode 100644 index 0000000000..b96067f4b6 --- /dev/null +++ b/openair1/PHY/CODING/nrLDPC_defs.h @@ -0,0 +1,59 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ +//============================================================================================================================ +// encoder interface +#ifndef __NRLDPC_DEFS__H__ +#define __NRLDPC_DEFS__H__ +#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" +/** + \brief LDPC encoder + \param 1 input + \param 2 channel_input + \param 3 int Zc + \param 4 int Kb + \param 5 short block_length + \param 6 short BG + \param 7 int n_segment + \param 8 unsigned int macro_num + \param 9-12 time_stats_t *tinput,*tprep, *tparity,*toutput +*/ +typedef struct { + int n_segments; // optim8seg + unsigned int macro_num; // optim8segmulti + unsigned char gen_code; //orig + time_stats_t *tinput; + time_stats_t *tprep; + time_stats_t *tparity; + time_stats_t *toutput; +}encoder_implemparams_t; +#define INIT0_LDPCIMPLEMPARAMS {0,0,0,NULL,NULL,NULL,NULL} +typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,short, short, encoder_implemparams_t*); +//============================================================================================================================ +// decoder interface +/** + \brief LDPC decoder API type definition + \param p_decParams LDPC decoder parameters + \param p_llr Input LLRs + \param p_llrOut Output vector + \param p_profiler LDPC profiler statistics +*/ +typedef int32_t(*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params* , int8_t*, int8_t* , t_nrLDPC_procBuf* , t_nrLDPC_time_stats* ); +#endif \ No newline at end of file diff --git a/openair1/PHY/CODING/nrLDPC_encoder/defs.h b/openair1/PHY/CODING/nrLDPC_encoder/defs.h deleted file mode 100644 index 85cb852fe5..0000000000 --- a/openair1/PHY/CODING/nrLDPC_encoder/defs.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*!\file defs.h - * \brief LDPC encoder forward declarations - * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom) - * \email openair_tech@eurecom.fr - * \date 27-03-2018 - * \version 1.0 - * \note - * \warning - */ - -#include "PHY/TOOLS/time_meas.h" - -/*ldpc_encoder.c*/ -int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb,short block_length); - -/*ldpc_encoder2.c*/ -void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,short Kb); -int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length,short BG,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput); -int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length,short BG,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput); -int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput); - -/*ldpc_generate_coefficient.c*/ -int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length,short BG,unsigned char gen_code); - -/* -int encode_parity_check_part(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb); -int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb,short block_length); -int ldpc_encoder(unsigned char *test_input,unsigned char *channel_input,short block_length, double rate); -int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,short block_length,int nom_rate,int denom_rate,unsigned char gen_code); -int ldpc_encoder_multi_segment(unsigned char **test_input,unsigned char **channel_input,short block_length,double rate,uint8_t n_segments); -int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,short block_length,int nom_rate,int denom_rate,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput); -int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,short block_length,int nom_rate,int denom_rate,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput); -*/ diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encode_parity_check.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encode_parity_check.c new file mode 100644 index 0000000000..738fd49b7d --- /dev/null +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encode_parity_check.c @@ -0,0 +1,201 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*!\file ldpc_encode_parity_check.c + * \brief Parity check function used by ldpc encoders + * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom) + * \email openair_tech@eurecom.fr + * \date 27-03-2018 + * \version 1.0 + * \note + * \warning + */ + +#include +#include +#include +#include +#include +#include "assertions.h" +#include "common/utils/LOG/log.h" + + +//#define DEBUG_LDPC + +#include "ldpc384_byte.c" +#include "ldpc352_byte.c" +#include "ldpc320_byte.c" +#include "ldpc288_byte.c" +#include "ldpc256_byte.c" +#include "ldpc240_byte.c" +#include "ldpc224_byte.c" +#include "ldpc208_byte.c" +#include "ldpc192_byte.c" +#include "ldpc176_byte.c" +#include "ldpc_BG2_Zc384_byte.c" +#include "ldpc_BG2_Zc352_byte.c" +#include "ldpc_BG2_Zc320_byte.c" +#include "ldpc_BG2_Zc288_byte.c" +#include "ldpc_BG2_Zc256_byte.c" +#include "ldpc_BG2_Zc240_byte.c" +#include "ldpc_BG2_Zc224_byte.c" +#include "ldpc_BG2_Zc208_byte.c" +#include "ldpc_BG2_Zc192_byte.c" +#include "ldpc_BG2_Zc176_byte.c" +#include "ldpc_BG2_Zc160_byte.c" +#include "ldpc_BG2_Zc144_byte.c" +#include "ldpc_BG2_Zc128_byte.c" +#include "ldpc_BG2_Zc120_byte.c" +#include "ldpc_BG2_Zc112_byte.c" +#include "ldpc_BG2_Zc104_byte.c" +#include "ldpc_BG2_Zc96_byte.c" +#include "ldpc_BG2_Zc88_byte.c" +#include "ldpc_BG2_Zc80_byte.c" +#include "ldpc_BG2_Zc72_byte.c" + + + +static inline void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,short Kb) +{ + + if (BG==1) + { + switch (Zc) + { + case 2: break; + case 3: break; + case 4: break; + case 5: break; + case 6: break; + case 7: break; + case 8: break; + case 9: break; + case 10: break; + case 11: break; + case 12: break; + case 13: break; + case 14: break; + case 15: break; + case 16: break; + case 18: break; + case 20: break; + case 22: break; + case 24: break; + case 26: break; + case 28: break; + case 30: break; + case 32: break; + case 36: break; + case 40: break; + case 44: break; + case 48: break; + case 52: break; + case 56: break; + case 60: break; + case 64: break; + case 72: break; + case 80: break; + case 88: break; + case 96: break; + case 104: break; + case 112: break; + case 120: break; + case 128: break; + case 144: break; + case 160: break; + case 176: ldpc176_byte(c,d); break; + case 192: ldpc192_byte(c,d); break; + case 208: ldpc208_byte(c,d); break; + case 224: ldpc224_byte(c,d); break; + case 240: ldpc240_byte(c,d); break; + case 256: ldpc256_byte(c,d); break; + case 288: ldpc288_byte(c,d); break; + case 320: ldpc320_byte(c,d); break; + case 352: ldpc352_byte(c,d); break; + case 384: ldpc384_byte(c,d); break; + default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break; + } + } + else if (BG==2) { + switch (Zc) + { + case 2: break; + case 3: break; + case 4: break; + case 5: break; + case 6: break; + case 7: break; + case 8: break; + case 9: break; + case 10: break; + case 11: break; + case 12: break; + case 13: break; + case 14: break; + case 15: break; + case 16: break; + case 18: break; + case 20: break; + case 22: break; + case 24: break; + case 26: break; + case 28: break; + case 30: break; + case 32: break; + case 36: break; + case 40: break; + case 44: break; + case 48: break; + case 52: break; + case 56: break; + case 60: break; + case 64: break; + case 72: ldpc_BG2_Zc72_byte(c,d); break; + case 80: ldpc_BG2_Zc80_byte(c,d); break; + case 88: ldpc_BG2_Zc88_byte(c,d); break; + case 96: ldpc_BG2_Zc96_byte(c,d); break; + case 104: ldpc_BG2_Zc104_byte(c,d); break; + case 112: ldpc_BG2_Zc112_byte(c,d); break; + case 120: ldpc_BG2_Zc120_byte(c,d); break; + case 128: ldpc_BG2_Zc128_byte(c,d); break; + case 144: ldpc_BG2_Zc144_byte(c,d); break; + case 160: ldpc_BG2_Zc160_byte(c,d); break; + case 176: ldpc_BG2_Zc176_byte(c,d); break; + case 192: ldpc_BG2_Zc192_byte(c,d); break; + case 208: ldpc_BG2_Zc208_byte(c,d); break; + case 224: ldpc_BG2_Zc224_byte(c,d); break; + case 240: ldpc_BG2_Zc240_byte(c,d); break; + case 256: ldpc_BG2_Zc256_byte(c,d); break; + case 288: ldpc_BG2_Zc288_byte(c,d); break; + case 320: ldpc_BG2_Zc320_byte(c,d); break; + case 352: ldpc_BG2_Zc352_byte(c,d); break; + case 384: ldpc_BG2_Zc384_byte(c,d); break; + default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break; + } + } + else { + AssertFatal(0,"BG %d is not supported yet\n",BG); + } + +} + + + diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c index 6ded22d8ca..76f92574ba 100644 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c @@ -37,77 +37,247 @@ #include #include #include "defs.h" +#include "assertions.h" +#include "openair1/PHY/CODING/nrLDPC_defs.h" +#include "ldpc_generate_coefficient.c" -short *choose_generator_matrix(short BG,short Zc); -extern short no_shift_values_BG1[1012],pointer_shift_values_BG1[1012],no_shift_values_BG2[2109],pointer_shift_values_BG2[2019]; -int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb,short block_length) +int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length, short BG,unsigned char gen_code) { - short *Gen_shift_values=choose_generator_matrix(BG,Zc); - short *no_shift_values, *pointer_shift_values; - int no_punctured_columns; - short nrows,ncols,rate=3; - int i1,i2,i3,i4,i5,temp_prime; + unsigned char c[22*384]; //padded input, unpacked, max size + unsigned char d[68*384]; //coded output, unpacked, max size unsigned char channel_temp,temp; + short *Gen_shift_values, *no_shift_values, *pointer_shift_values; + short nrows = 46;//parity check bits + short ncols = 22;//info bits + + + int i,i1,i2,i3,i4,i5,temp_prime,var; + int no_punctured_columns,removed_bit,rate=3; + int nind=0; + int indlist[1000]; + int indlist2[1000]; + + //determine number of bits in codeword + //if (block_length>3840) + if (BG==1) + { + nrows=46; //parity check bits + ncols=22; //info bits + rate=3; + } + //else if (block_length<=3840) + else if (BG==2) + { + //BG=2; + nrows=42; //parity check bits + ncols=10; // info bits + rate=5; + } + + Gen_shift_values=choose_generator_matrix(BG,Zc); + if (Gen_shift_values==NULL) { + printf("ldpc_encoder_orig: could not find generator matrix\n"); + return(-1); + } + + //printf("ldpc_encoder_orig: BG %d, Zc %d, Kb %d\n",BG, Zc, Kb); + + // load base graph of generator matrix if (BG==1) { no_shift_values=(short *) no_shift_values_BG1; pointer_shift_values=(short *) pointer_shift_values_BG1; - nrows=46; //parity check bits - ncols=22; //info bits - rate=3; } else if (BG==2) { no_shift_values=(short *) no_shift_values_BG2; pointer_shift_values=(short *) pointer_shift_values_BG2; - nrows=42; //parity check bits - ncols=10; //info bits - rate=5; } else { - printf("problem with BG\n"); - return(-1); + AssertFatal(0,"BG %d is not supported yet\n",BG); } - - + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; + removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*rate); + //printf("%d\n",no_punctured_columns); + //printf("%d\n",removed_bit); + // unpack input + memset(c,0,sizeof(unsigned char) * ncols * Zc); + memset(d,0,sizeof(unsigned char) * nrows * Zc); - //printf("no_punctured_columns = %d\n",no_punctured_columns); - - for (i2=0; i2 < Zc; i2++) + for (i=0; i>7&1; + c[i]=(test_input[i/8]&(128>>(i&7)))>>(7-(i&7)); + } - //rotate matrix here - for (i5=0; i5 < Kb; i5++) - { - temp = c[i5*Zc]; - memmove(&c[i5*Zc], &c[i5*Zc+1], (Zc-1)*sizeof(unsigned char)); - c[i5*Zc+Zc-1] = temp; + // parity check part + + if (gen_code==1) + { + char fname[100]; + sprintf(fname,"ldpc_BG%d_Zc%d_byte.c",BG,Zc); + FILE *fd=fopen(fname,"w"); + AssertFatal(fd!=NULL,"cannot open %s\n",fname); + sprintf(fname,"ldpc_BG%d_Zc%d_16bit.c",BG,Zc); + FILE *fd2=fopen(fname,"w"); + AssertFatal(fd2!=NULL,"cannot open %s\n",fname); + + int shift; + char data_type[100]; + char xor_command[100]; + int mask; + + + + + fprintf(fd,"#include \"PHY/sse_intrin.h\"\n"); + fprintf(fd2,"#include \"PHY/sse_intrin.h\"\n"); + + if ((Zc&31)==0) { + shift=5; // AVX2 - 256-bit SIMD + mask=31; + strcpy(data_type,"__m256i"); + strcpy(xor_command,"_mm256_xor_si256"); } + else if ((Zc&15)==0) { + shift=4; // SSE4 - 128-bit SIMD + mask=15; + strcpy(data_type,"__m128i"); + strcpy(xor_command,"_mm_xor_si128"); - // calculate each row in base graph - for (i1=0; i1 < nrows-no_punctured_columns; i1++) + } + else if ((Zc&7)==0) { + shift=3; // MMX - 64-bit SIMD + mask=7; + strcpy(data_type,"__m64"); + strcpy(xor_command,"_mm_xor_si64"); + } + else { + shift=0; // no SIMD + mask=0; + strcpy(data_type,"uint8_t"); + strcpy(xor_command,"scalar_xor"); + fprintf(fd,"#define scalar_xor(a,b) ((a)^(b))\n"); + fprintf(fd2,"#define scalar_xor(a,b) ((a)^(b))\n"); + } + fprintf(fd,"// generated code for Zc=%d, byte encoding\n",Zc); + fprintf(fd2,"// generated code for Zc=%d, 16bit encoding\n",Zc); + fprintf(fd,"static inline void ldpc_BG%d_Zc%d_byte(uint8_t *c,uint8_t *d) {\n",BG,Zc); + fprintf(fd2,"static inline void ldpc_BG%d_Zc%d_16bit(uint16_t *c,uint16_t *d) {\n",BG,Zc); + fprintf(fd," %s *csimd=(%s *)c,*dsimd=(%s *)d;\n\n",data_type,data_type,data_type); + fprintf(fd2," %s *csimd=(%s *)c,*dsimd=(%s *)d;\n\n",data_type,data_type,data_type); + fprintf(fd," %s *c2,*d2;\n\n",data_type); + fprintf(fd2," %s *c2,*d2;\n\n",data_type); + fprintf(fd," int i2;\n"); + fprintf(fd2," int i2;\n"); + fprintf(fd," for (i2=0; i2<%d; i2++) {\n",Zc>>shift); + if (shift > 0) + fprintf(fd2," for (i2=0; i2<%d; i2++) {\n",Zc>>(shift-1)); + for (i2=0; i2 < 1; i2++) { - channel_temp=0; - for (i3=0; i3 < Kb; i3++) - { - temp_prime=i1 * ncols + i3; + //t=Kb*Zc+i2; + + // calculate each row in base graph + - for (i4=0; i4 < no_shift_values[temp_prime]; i4++) + fprintf(fd," c2=&csimd[i2];\n"); + fprintf(fd," d2=&dsimd[i2];\n"); + fprintf(fd2," c2=&csimd[i2];\n"); + fprintf(fd2," d2=&dsimd[i2];\n"); + + for (i1=0; i1 < nrows; i1++) + + { + channel_temp=0; + fprintf(fd,"\n//row: %d\n",i1); + fprintf(fd2,"\n//row: %d\n",i1); + fprintf(fd," d2[%d]=",(Zc*i1)>>shift); + fprintf(fd2," d2[%d]=",(Zc*i1)>>(shift-1)); + + nind=0; + + for (i3=0; i3 < ncols; i3++) { - channel_temp = channel_temp ^ c[ i3*Zc + Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ] ]; + temp_prime=i1 * ncols + i3; + + + for (i4=0; i4 < no_shift_values[temp_prime]; i4++) + { + + var=(int)((i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc)/Zc); + int index =var*2*Zc + (i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc) % Zc; + + indlist[nind] = ((index&mask)*((2*Zc)>>shift)*Kb)+(index>>shift); + indlist2[nind++] = ((index&(mask>>1))*((2*Zc)>>(shift-1))*Kb)+(index>>(shift-1)); + + } + + } + for (i4=0;i4gen_code); +} \ No newline at end of file diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c deleted file mode 100644 index ef207b6cdc..0000000000 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c +++ /dev/null @@ -1,667 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*!\file ldpc_encoder2.c - * \brief Defines the optimized LDPC encoder - * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom) - * \email openair_tech@eurecom.fr - * \date 27-03-2018 - * \version 1.0 - * \note - * \warning - */ - -#include -#include -#include -#include -#include -#include "assertions.h" -#include "common/utils/LOG/log.h" -#include "PHY/TOOLS/time_meas.h" -#include "defs.h" - -//#define DEBUG_LDPC - -#include "ldpc384_byte.c" -#include "ldpc352_byte.c" -#include "ldpc320_byte.c" -#include "ldpc288_byte.c" -#include "ldpc256_byte.c" -#include "ldpc240_byte.c" -#include "ldpc224_byte.c" -#include "ldpc208_byte.c" -#include "ldpc192_byte.c" -#include "ldpc176_byte.c" -#include "ldpc_BG2_Zc384_byte.c" -#include "ldpc_BG2_Zc352_byte.c" -#include "ldpc_BG2_Zc320_byte.c" -#include "ldpc_BG2_Zc288_byte.c" -#include "ldpc_BG2_Zc256_byte.c" -#include "ldpc_BG2_Zc240_byte.c" -#include "ldpc_BG2_Zc224_byte.c" -#include "ldpc_BG2_Zc208_byte.c" -#include "ldpc_BG2_Zc192_byte.c" -#include "ldpc_BG2_Zc176_byte.c" -#include "ldpc_BG2_Zc160_byte.c" -#include "ldpc_BG2_Zc144_byte.c" -#include "ldpc_BG2_Zc128_byte.c" -#include "ldpc_BG2_Zc120_byte.c" -#include "ldpc_BG2_Zc112_byte.c" -#include "ldpc_BG2_Zc104_byte.c" -#include "ldpc_BG2_Zc96_byte.c" -#include "ldpc_BG2_Zc88_byte.c" -#include "ldpc_BG2_Zc80_byte.c" -#include "ldpc_BG2_Zc72_byte.c" - - - -void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,short Kb) -{ - - if (BG==1) - { - switch (Zc) - { - case 2: break; - case 3: break; - case 4: break; - case 5: break; - case 6: break; - case 7: break; - case 8: break; - case 9: break; - case 10: break; - case 11: break; - case 12: break; - case 13: break; - case 14: break; - case 15: break; - case 16: break; - case 18: break; - case 20: break; - case 22: break; - case 24: break; - case 26: break; - case 28: break; - case 30: break; - case 32: break; - case 36: break; - case 40: break; - case 44: break; - case 48: break; - case 52: break; - case 56: break; - case 60: break; - case 64: break; - case 72: break; - case 80: break; - case 88: break; - case 96: break; - case 104: break; - case 112: break; - case 120: break; - case 128: break; - case 144: break; - case 160: break; - case 176: ldpc176_byte(c,d); break; - case 192: ldpc192_byte(c,d); break; - case 208: ldpc208_byte(c,d); break; - case 224: ldpc224_byte(c,d); break; - case 240: ldpc240_byte(c,d); break; - case 256: ldpc256_byte(c,d); break; - case 288: ldpc288_byte(c,d); break; - case 320: ldpc320_byte(c,d); break; - case 352: ldpc352_byte(c,d); break; - case 384: ldpc384_byte(c,d); break; - default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break; - } - } - else if (BG==2) { - switch (Zc) - { - case 2: break; - case 3: break; - case 4: break; - case 5: break; - case 6: break; - case 7: break; - case 8: break; - case 9: break; - case 10: break; - case 11: break; - case 12: break; - case 13: break; - case 14: break; - case 15: break; - case 16: break; - case 18: break; - case 20: break; - case 22: break; - case 24: break; - case 26: break; - case 28: break; - case 30: break; - case 32: break; - case 36: break; - case 40: break; - case 44: break; - case 48: break; - case 52: break; - case 56: break; - case 60: break; - case 64: break; - case 72: ldpc_BG2_Zc72_byte(c,d); break; - case 80: ldpc_BG2_Zc80_byte(c,d); break; - case 88: ldpc_BG2_Zc88_byte(c,d); break; - case 96: ldpc_BG2_Zc96_byte(c,d); break; - case 104: ldpc_BG2_Zc104_byte(c,d); break; - case 112: ldpc_BG2_Zc112_byte(c,d); break; - case 120: ldpc_BG2_Zc120_byte(c,d); break; - case 128: ldpc_BG2_Zc128_byte(c,d); break; - case 144: ldpc_BG2_Zc144_byte(c,d); break; - case 160: ldpc_BG2_Zc160_byte(c,d); break; - case 176: ldpc_BG2_Zc176_byte(c,d); break; - case 192: ldpc_BG2_Zc192_byte(c,d); break; - case 208: ldpc_BG2_Zc208_byte(c,d); break; - case 224: ldpc_BG2_Zc224_byte(c,d); break; - case 240: ldpc_BG2_Zc240_byte(c,d); break; - case 256: ldpc_BG2_Zc256_byte(c,d); break; - case 288: ldpc_BG2_Zc288_byte(c,d); break; - case 320: ldpc_BG2_Zc320_byte(c,d); break; - case 352: ldpc_BG2_Zc352_byte(c,d); break; - case 384: ldpc_BG2_Zc384_byte(c,d); break; - default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break; - } - } - else { - AssertFatal(0,"BG %d is not supported yet\n",BG); - } - -} - - -int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length,short BG,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) -{ - - short nrows=0,ncols=0; - int i,i1,rate=3; - int no_punctured_columns,removed_bit; - - int simd_size; - - //determine number of bits in codeword - //if (block_length>3840) - if (BG==1) - { - //BG=1; - nrows=46; //parity check bits - ncols=22; //info bits - rate=3; - } - //else if (block_length<=3840) - else if (BG==2) - { - //BG=2; - nrows=42; //parity check bits - ncols=10; // info bits - rate=5; - - } - - -#ifdef DEBUG_LDPC - LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d\n",BG,Zc,Kb,block_length); - LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU %x %x %x %x\n",test_input[0],test_input[1],test_input[2],test_input[3]); -#endif - - if ((Zc&31) > 0) simd_size = 16; - else simd_size = 32; - - unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size - unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size - - unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c - - // calculate number of punctured bits - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); - // printf("%d\n",no_punctured_columns); - // printf("%d\n",removed_bit); - // unpack input - memset(c,0,sizeof(unsigned char) * ncols * Zc); - memset(d,0,sizeof(unsigned char) * nrows * Zc); - - if(tinput != NULL) start_meas(tinput); - for (i=0; i>(i&7)))>>(7-(i&7)); - //printf("c(%d,%d)=%d\n",j,i,temp); - } - - if(tinput != NULL) stop_meas(tinput); - - if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { - // extend matrix - if(tprep != NULL) start_meas(tprep); - for (i1=0; i1 < ncols; i1++) - { - memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); - memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); - } - for (i1=1;i1 8 bytes, pattern repeats. - __m256i zero256 = _mm256_setzero_si256(); - __m256i masks[8]; - register __m256i c256; - masks[0] = _mm256_set1_epi8(0x1); - masks[1] = _mm256_set1_epi8(0x2); - masks[2] = _mm256_set1_epi8(0x4); - masks[3] = _mm256_set1_epi8(0x8); - masks[4] = _mm256_set1_epi8(0x10); - masks[5] = _mm256_set1_epi8(0x20); - masks[6] = _mm256_set1_epi8(0x40); - masks[7] = _mm256_set1_epi8(0x80); -#endif - - AssertFatal(n_segments>0&&n_segments<=8,"0 < n_segments %d <= 8\n",n_segments); - - //determine number of bits in codeword - //if (block_length>3840) - if (BG==1) - { - nrows=46; //parity check bits - ncols=22; //info bits - rate=3; - } - //else if (block_length<=3840) - else if (BG==2) - { - //BG=2; - nrows=42; //parity check bits - ncols=10; // info bits - rate=5; - - } - -#ifdef DEBUG_LDPC - LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments); - LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]); -#endif - - AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length); - - if ((Zc&31) > 0) simd_size = 16; - else simd_size = 32; - - unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size - unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size - - unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c - - // calculate number of punctured bits - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); - // printf("%d\n",no_punctured_columns); - // printf("%d\n",removed_bit); - // unpack input - memset(c,0,sizeof(unsigned char) * ncols * Zc); - memset(d,0,sizeof(unsigned char) * nrows * Zc); - - if(tinput != NULL) start_meas(tinput); -#if 0 - for (i=0; i>(i&7)))>>(7-(i&7)); - //printf("c(%d,%d)=%d\n",j,i,temp); - c[i] |= (temp << j); - } - } -#else -#ifdef __AVX2__ - for (i=0; i>5; i++) { - c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[0])[i]), shufmask),andmask),zero256),masks[0]); - for (j=1; j>5)<<5;i>(i&7)))>>(7-(i&7)); - //printf("c(%d,%d)=%d\n",j,i,temp); - c[i] |= (temp << j); - } - } -#else - AssertFatal(1==0,"Need AVX2 for this\n"); -#endif -#endif - - if(tinput != NULL) stop_meas(tinput); - - if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { - // extend matrix - if(tprep != NULL) start_meas(tprep); - for (i1=0; i1 < ncols; i1++) - { - memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); - memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); - } - for (i1=1;i1>5; - uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5; - __m256i *c256p = (__m256i *)&c[2*Zc]; - __m256i *d256p = (__m256i *)&d[0]; - // if (((block_length-(2*Zc))&31)>0) l1++; - - for (i=0;i0) l2++; - - for (i1=0;i1>j)&1; - for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++) - for (j=0; j>j)&1; - } - -#else - AssertFatal(1==0,"Need AVX2 for now\n"); -#endif - - if(toutput != NULL) stop_meas(toutput); - return 0; -} - -int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) -{ - - short nrows=0,ncols=0; - int i,i1,j,rate=3; - int no_punctured_columns,removed_bit; - //Table of possible lifting sizes - char temp; - int simd_size; - unsigned int macro_segment, macro_segment_end; - - - macro_segment = 8*macro_num; - // macro_segment_end = (n_segments > 8*(macro_num+1)) ? 8*(macro_num+1) : n_segments; - macro_segment_end = macro_segment + (n_segments > 8 ? 8 : n_segments); - ///printf("macro_segment: %d\n", macro_segment); - ///printf("macro_segment_end: %d\n", macro_segment_end ); - -#ifdef __AVX2__ - __m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000); - __m256i andmask = _mm256_set1_epi64x(0x0102040810204080); // every 8 bits -> 8 bytes, pattern repeats. - __m256i zero256 = _mm256_setzero_si256(); - __m256i masks[8]; - register __m256i c256; - masks[0] = _mm256_set1_epi8(0x1); - masks[1] = _mm256_set1_epi8(0x2); - masks[2] = _mm256_set1_epi8(0x4); - masks[3] = _mm256_set1_epi8(0x8); - masks[4] = _mm256_set1_epi8(0x10); - masks[5] = _mm256_set1_epi8(0x20); - masks[6] = _mm256_set1_epi8(0x40); - masks[7] = _mm256_set1_epi8(0x80); -#endif - - - - //determine number of bits in codeword - if (BG==1) - { - nrows=46; //parity check bits - ncols=22; //info bits - rate=3; - } - else if (BG==2) - { - nrows=42; //parity check bits - ncols=10; // info bits - rate=5; - } - -#ifdef DEBUG_LDPC - LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments); - LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]); -#endif - - AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length); - - if ((Zc&31) > 0) simd_size = 16; - else simd_size = 32; - - unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size - unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size - - unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c - - // calculate number of punctured bits - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); - //printf("%d\n",no_punctured_columns); - //printf("%d\n",removed_bit); - // unpack input - memset(c,0,sizeof(unsigned char) * ncols * Zc); - memset(d,0,sizeof(unsigned char) * nrows * Zc); - - if(tinput != NULL) start_meas(tinput); -#if 0 - for (i=0; i>(i&7); - //printf("c(%d,%d)=%d\n",j,i,temp); - c[i] |= (temp << (j-macro_segment)); - } - } -#else -#ifdef __AVX2__ - for (i=0; i>5; i++) { - c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[macro_segment])[i]), shufmask),andmask),zero256),masks[0]); - //for (j=1; j>5)<<5;i>(i&7)))>>(7-(i&7)); - //printf("c(%d,%d)=%d\n",j,i,temp); - c[i] |= (temp << (j-macro_segment)); - } - } -#else - AssertFatal(1==0,"Need AVX2 for this\n"); -#endif -#endif - - if(tinput != NULL) stop_meas(tinput); - - if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { - // extend matrix - if(tprep != NULL) start_meas(tprep); - for (i1=0; i1 < ncols; i1++) - { - memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); - memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); - } - for (i1=1;i1>5; - uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5; - __m256i *c256p = (__m256i *)&c[2*Zc]; - __m256i *d256p = (__m256i *)&d[0]; - // if (((block_length-(2*Zc))&31)>0) l1++; - - for (i=0;i0) l2++; - - for (i1=0;i1>(j-macro_segment))&1; - for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++) - //for (j=0; j>(j-macro_segment))&1; - } - -#else - AssertFatal(1==0,"Need AVX2 for now\n"); -#endif - - if(toutput != NULL) stop_meas(toutput); - return 0; -} - diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c new file mode 100644 index 0000000000..7da265494a --- /dev/null +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c @@ -0,0 +1,146 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*!\file ldpc_encoder2.c + * \brief Defines the optimized LDPC encoder + * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom) + * \email openair_tech@eurecom.fr + * \date 27-03-2018 + * \version 1.0 + * \note + * \warning + */ + +#include +#include +#include +#include +#include +#include "assertions.h" +#include "common/utils/LOG/log.h" +#include "PHY/TOOLS/time_meas.h" +#include "openair1/PHY/CODING/nrLDPC_defs.h" +#include "ldpc_encode_parity_check.c" +#include "ldpc_generate_coefficient.c" +//#define DEBUG_LDPC + + + + + +int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, encoder_implemparams_t *impp) +{ + + short nrows=0,ncols=0; + int i,i1,rate=3; + int no_punctured_columns,removed_bit; + + int simd_size; + + //determine number of bits in codeword + //if (block_length>3840) + if (BG==1) + { + //BG=1; + nrows=46; //parity check bits + ncols=22; //info bits + rate=3; + } + //else if (block_length<=3840) + else if (BG==2) + { + //BG=2; + nrows=42; //parity check bits + ncols=10; // info bits + rate=5; + + } + + +#ifdef DEBUG_LDPC + LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d\n",BG,Zc,Kb,block_length); + LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]); +#endif + + if ((Zc&31) > 0) simd_size = 16; + else simd_size = 32; + + unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size + unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size + + unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c + + // calculate number of punctured bits + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; + removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); + // printf("%d\n",no_punctured_columns); + // printf("%d\n",removed_bit); + // unpack input + memset(c,0,sizeof(unsigned char) * ncols * Zc); + memset(d,0,sizeof(unsigned char) * nrows * Zc); + + if(impp->tinput != NULL) start_meas(impp->tinput); + for (i=0; i>(i&7)))>>(7-(i&7)); + //printf("c(%d,%d)=%d\n",j,i,temp); + } + + if(impp->tinput != NULL) stop_meas(impp->tinput); + + if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { + // extend matrix + if(impp->tprep != NULL) start_meas(impp->tprep); + for (i1=0; i1 < ncols; i1++) + { + memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); + memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); + } + for (i1=1;i1tprep != NULL) stop_meas(impp->tprep); + //parity check part + if(impp->tparity != NULL) start_meas(impp->tparity); + encode_parity_check_part_optim(c_extension, d, BG, Zc, Kb); + if(impp->tparity != NULL) stop_meas(impp->tparity); + } + else { + if (encode_parity_check_part_orig(c, d, BG, Zc, Kb, block_length)!=0) { + printf("Problem with encoder\n"); + return(-1); + } + } + if(impp->toutput != NULL) start_meas(impp->toutput); + // information part and puncture columns + memcpy(&channel_input[0][0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char)); + memcpy(&channel_input[0][block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char)); + + if(impp->toutput != NULL) stop_meas(impp->toutput); + return 0; +} + + diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8seg.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8seg.c new file mode 100644 index 0000000000..a974e86e27 --- /dev/null +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8seg.c @@ -0,0 +1,225 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*!\file ldpc_encoder2.c + * \brief Defines the optimized LDPC encoder + * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom) + * \email openair_tech@eurecom.fr + * \date 27-03-2018 + * \version 1.0 + * \note + * \warning + */ + +#include +#include +#include +#include +#include +#include "assertions.h" +#include "common/utils/LOG/log.h" +#include "PHY/TOOLS/time_meas.h" +#include "openair1/PHY/CODING/nrLDPC_defs.h" +//#define DEBUG_LDPC +#include "ldpc_encode_parity_check.c" +#include "ldpc_generate_coefficient.c" + + + +int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, encoder_implemparams_t *impp) +{ + + short nrows=0,ncols=0; + int i,i1,j,rate=3; + int no_punctured_columns,removed_bit; + char temp; + int simd_size; + +#ifdef __AVX2__ + __m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000); + __m256i andmask = _mm256_set1_epi64x(0x0102040810204080); // every 8 bits -> 8 bytes, pattern repeats. + __m256i zero256 = _mm256_setzero_si256(); + __m256i masks[8]; + register __m256i c256; + masks[0] = _mm256_set1_epi8(0x1); + masks[1] = _mm256_set1_epi8(0x2); + masks[2] = _mm256_set1_epi8(0x4); + masks[3] = _mm256_set1_epi8(0x8); + masks[4] = _mm256_set1_epi8(0x10); + masks[5] = _mm256_set1_epi8(0x20); + masks[6] = _mm256_set1_epi8(0x40); + masks[7] = _mm256_set1_epi8(0x80); +#endif + + AssertFatal((impp->n_segments>0&&impp->n_segments<=8),"0 < n_segments %d <= 8\n",impp->n_segments); + + //determine number of bits in codeword + //if (block_length>3840) + if (BG==1) + { + nrows=46; //parity check bits + ncols=22; //info bits + rate=3; + } + //else if (block_length<=3840) + else if (BG==2) + { + //BG=2; + nrows=42; //parity check bits + ncols=10; // info bits + rate=5; + + } + +#ifdef DEBUG_LDPC + LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments); + LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]); +#endif + + AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length); + + if ((Zc&31) > 0) simd_size = 16; + else simd_size = 32; + + unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size + unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size + + unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c + + // calculate number of punctured bits + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; + removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); + // printf("%d\n",no_punctured_columns); + // printf("%d\n",removed_bit); + // unpack input + memset(c,0,sizeof(unsigned char) * ncols * Zc); + memset(d,0,sizeof(unsigned char) * nrows * Zc); + + if(impp->tinput != NULL) start_meas(impp->tinput); +#if 0 + for (i=0; i>(i&7)))>>(7-(i&7)); + //printf("c(%d,%d)=%d\n",j,i,temp); + c[i] |= (temp << j); + } + } +#else +#ifdef __AVX2__ + for (i=0; i>5; i++) { + c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[0])[i]), shufmask),andmask),zero256),masks[0]); + for (j=1; jn_segments; j++) { + c256 = _mm256_or_si256(_mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[j])[i]), shufmask),andmask),zero256),masks[j]),c256); + } + ((__m256i *)c)[i] = c256; + } + + for (i=(block_length>>5)<<5;in_segments; j++) { + + temp = (test_input[j][i/8]&(128>>(i&7)))>>(7-(i&7)); + //printf("c(%d,%d)=%d\n",j,i,temp); + c[i] |= (temp << j); + } + } +#else + AssertFatal(1==0,"Need AVX2 for this\n"); +#endif +#endif + + if(impp->tinput != NULL) stop_meas(impp->tinput); + + if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { + // extend matrix + if(impp->tprep != NULL) start_meas(impp->tprep); + for (i1=0; i1 < ncols; i1++) + { + memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); + memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); + } + for (i1=1;i1tprep != NULL) stop_meas(impp->tprep); + //parity check part + if(impp->tparity != NULL) start_meas(impp->tparity); + encode_parity_check_part_optim(c_extension, d, BG, Zc, Kb); + if(impp->tparity != NULL) stop_meas(impp->tparity); + } + else { + if (encode_parity_check_part_orig(c, d, BG, Zc, Kb, block_length)!=0) { + printf("Problem with encoder\n"); + return(-1); + } + } + if(impp->toutput != NULL) start_meas(impp->toutput); + // information part and puncture columns + /* + memcpy(&channel_input[0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char)); + memcpy(&channel_input[block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char)); + */ +#ifdef __AVX2__ + if ((((2*Zc)&31) == 0) && (((block_length-(2*Zc))&31) == 0)) { + //AssertFatal(((2*Zc)&31) == 0,"2*Zc needs to be a multiple of 32 for now\n"); + //AssertFatal(((block_length-(2*Zc))&31) == 0,"block_length-(2*Zc) needs to be a multiple of 32 for now\n"); + uint32_t l1 = (block_length-(2*Zc))>>5; + uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5; + __m256i *c256p = (__m256i *)&c[2*Zc]; + __m256i *d256p = (__m256i *)&d[0]; + // if (((block_length-(2*Zc))&31)>0) l1++; + + for (i=0;in_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(c256p[i],j),masks[0]); + + // if ((((nrows-no_punctured_columns) * Zc-removed_bit)&31)>0) l2++; + + for (i1=0;i1n_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(d256p[i1],j),masks[0]); + } + else { +#ifdef DEBUG_LDPC + LOG_W(PHY,"using non-optimized version\n"); +#endif + // do non-SIMD version + for (i=0;i<(block_length-2*Zc);i++) + for (j=0; jn_segments; j++) + channel_input[j][i] = (c[2*Zc+i]>>j)&1; + for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++) + for (j=0; jn_segments; j++) + channel_input[j][block_length-2*Zc+i] = (d[i]>>j)&1; + } + +#else + AssertFatal(1==0,"Need AVX2 for now\n"); +#endif + + if(impp->toutput != NULL) stop_meas(impp->toutput); + return 0; +} + + diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c new file mode 100644 index 0000000000..28ab5b5029 --- /dev/null +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c @@ -0,0 +1,238 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*!\file ldpc_encoder2.c + * \brief Defines the optimized LDPC encoder + * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom) + * \email openair_tech@eurecom.fr + * \date 27-03-2018 + * \version 1.0 + * \note + * \warning + */ + +#include +#include +#include +#include +#include +#include "assertions.h" +#include "common/utils/LOG/log.h" +#include "PHY/TOOLS/time_meas.h" +#include "openair1/PHY/CODING/nrLDPC_defs.h" + +//#define DEBUG_LDPC + +#include "ldpc_encode_parity_check.c" +#include "ldpc_generate_coefficient.c" + + +int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, encoder_implemparams_t *impp) +{ + + short nrows=0,ncols=0; + int i,i1,j,rate=3; + int no_punctured_columns,removed_bit; + //Table of possible lifting sizes + char temp; + int simd_size; + unsigned int macro_segment, macro_segment_end; + + + macro_segment = 8*impp->macro_num; + // macro_segment_end = (n_segments > 8*(macro_num+1)) ? 8*(macro_num+1) : n_segments; + macro_segment_end = macro_segment + (impp->n_segments > 8 ? 8 : impp->n_segments); + ///printf("macro_segment: %d\n", macro_segment); + ///printf("macro_segment_end: %d\n", macro_segment_end ); + +#ifdef __AVX2__ + __m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000); + __m256i andmask = _mm256_set1_epi64x(0x0102040810204080); // every 8 bits -> 8 bytes, pattern repeats. + __m256i zero256 = _mm256_setzero_si256(); + __m256i masks[8]; + register __m256i c256; + masks[0] = _mm256_set1_epi8(0x1); + masks[1] = _mm256_set1_epi8(0x2); + masks[2] = _mm256_set1_epi8(0x4); + masks[3] = _mm256_set1_epi8(0x8); + masks[4] = _mm256_set1_epi8(0x10); + masks[5] = _mm256_set1_epi8(0x20); + masks[6] = _mm256_set1_epi8(0x40); + masks[7] = _mm256_set1_epi8(0x80); +#endif + + + + //determine number of bits in codeword + if (BG==1) + { + nrows=46; //parity check bits + ncols=22; //info bits + rate=3; + } + else if (BG==2) + { + nrows=42; //parity check bits + ncols=10; // info bits + rate=5; + } + +#ifdef DEBUG_LDPC + LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments); + LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]); +#endif + + AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length); + + if ((Zc&31) > 0) simd_size = 16; + else simd_size = 32; + + unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size + unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size + + unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c + + // calculate number of punctured bits + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; + removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); + //printf("%d\n",no_punctured_columns); + //printf("%d\n",removed_bit); + // unpack input + memset(c,0,sizeof(unsigned char) * ncols * Zc); + memset(d,0,sizeof(unsigned char) * nrows * Zc); + + if(impp->tinput != NULL) start_meas(impp->tinput); +#if 0 + for (i=0; i>(i&7); + //printf("c(%d,%d)=%d\n",j,i,temp); + c[i] |= (temp << (j-macro_segment)); + } + } +#else +#ifdef __AVX2__ + for (i=0; i>5; i++) { + c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[macro_segment])[i]), shufmask),andmask),zero256),masks[0]); + //for (j=1; j>5)<<5;i>(i&7)))>>(7-(i&7)); + //printf("c(%d,%d)=%d\n",j,i,temp); + c[i] |= (temp << (j-macro_segment)); + } + } +#else + AssertFatal(1==0,"Need AVX2 for this\n"); +#endif +#endif + + if(impp->tinput != NULL) stop_meas(impp->tinput); + + if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { + // extend matrix + if(impp->tprep != NULL) start_meas(impp->tprep); + for (i1=0; i1 < ncols; i1++) + { + memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); + memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); + } + for (i1=1;i1tprep != NULL) stop_meas(impp->tprep); + //parity check part + if(impp->tparity != NULL) start_meas(impp->tparity); + encode_parity_check_part_optim(c_extension, d, BG, Zc, Kb); + if(impp->tparity != NULL) stop_meas(impp->tparity); + } + else { + if (encode_parity_check_part_orig(c, d, BG, Zc, Kb, block_length)!=0) { + printf("Problem with encoder\n"); + return(-1); + } + } + if(impp->toutput != NULL) start_meas(impp->toutput); + // information part and puncture columns + /* + memcpy(&channel_input[0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char)); + memcpy(&channel_input[block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char)); + */ +#ifdef __AVX2__ + if ((((2*Zc)&31) == 0) && (((block_length-(2*Zc))&31) == 0)) { + //AssertFatal(((2*Zc)&31) == 0,"2*Zc needs to be a multiple of 32 for now\n"); + //AssertFatal(((block_length-(2*Zc))&31) == 0,"block_length-(2*Zc) needs to be a multiple of 32 for now\n"); + uint32_t l1 = (block_length-(2*Zc))>>5; + uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5; + __m256i *c256p = (__m256i *)&c[2*Zc]; + __m256i *d256p = (__m256i *)&d[0]; + // if (((block_length-(2*Zc))&31)>0) l1++; + + for (i=0;i0) l2++; + + for (i1=0;i1>(j-macro_segment))&1; + for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++) + //for (j=0; j>(j-macro_segment))&1; + } + +#else + AssertFatal(1==0,"Need AVX2 for now\n"); +#endif + + if(impp->toutput != NULL) stop_meas(impp->toutput); + return 0; +} + diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c index 5988c9067d..3d26a19063 100644 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c @@ -35,9 +35,8 @@ #include #include "Gen_shift_value.h" #include "assertions.h" -#include "defs.h" -short *choose_generator_matrix(short BG,short Zc) +static inline short *choose_generator_matrix(short BG,short Zc) { short *Gen_shift_values = NULL; @@ -361,237 +360,70 @@ short *choose_generator_matrix(short BG,short Zc) return Gen_shift_values; } -int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length, short BG,unsigned char gen_code) +static inline int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb,short block_length) { - unsigned char c[22*384]; //padded input, unpacked, max size - unsigned char d[68*384]; //coded output, unpacked, max size + short *Gen_shift_values=choose_generator_matrix(BG,Zc); + short *no_shift_values, *pointer_shift_values; + int no_punctured_columns; + short nrows,ncols,rate=3; + int i1,i2,i3,i4,i5,temp_prime; unsigned char channel_temp,temp; - short *Gen_shift_values, *no_shift_values, *pointer_shift_values; - short nrows = 46;//parity check bits - short ncols = 22;//info bits - - - int i,i1,i2,i3,i4,i5,temp_prime,var; - int no_punctured_columns,removed_bit,rate=3; - int nind=0; - int indlist[1000]; - int indlist2[1000]; - - //determine number of bits in codeword - //if (block_length>3840) - if (BG==1) - { - nrows=46; //parity check bits - ncols=22; //info bits - rate=3; - } - //else if (block_length<=3840) - else if (BG==2) - { - //BG=2; - nrows=42; //parity check bits - ncols=10; // info bits - rate=5; - } - - Gen_shift_values=choose_generator_matrix(BG,Zc); - if (Gen_shift_values==NULL) { - printf("ldpc_encoder_orig: could not find generator matrix\n"); - return(-1); - } - - //printf("ldpc_encoder_orig: BG %d, Zc %d, Kb %d\n",BG, Zc, Kb); - - // load base graph of generator matrix if (BG==1) { no_shift_values=(short *) no_shift_values_BG1; pointer_shift_values=(short *) pointer_shift_values_BG1; + nrows=46; //parity check bits + ncols=22; //info bits + rate=3; } else if (BG==2) { no_shift_values=(short *) no_shift_values_BG2; pointer_shift_values=(short *) pointer_shift_values_BG2; + nrows=42; //parity check bits + ncols=10; //info bits + rate=5; } else { - AssertFatal(0,"BG %d is not supported yet\n",BG); + printf("problem with BG\n"); + return(-1); } - + + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*rate); - //printf("%d\n",no_punctured_columns); - //printf("%d\n",removed_bit); - // unpack input - memset(c,0,sizeof(unsigned char) * ncols * Zc); - memset(d,0,sizeof(unsigned char) * nrows * Zc); - for (i=0; i>7&1; - c[i]=(test_input[i/8]&(128>>(i&7)))>>(7-(i&7)); - } + //t=Kb*Zc+i2; - // parity check part - - if (gen_code==1) - { - char fname[100]; - sprintf(fname,"ldpc_BG%d_Zc%d_byte.c",BG,Zc); - FILE *fd=fopen(fname,"w"); - AssertFatal(fd!=NULL,"cannot open %s\n",fname); - sprintf(fname,"ldpc_BG%d_Zc%d_16bit.c",BG,Zc); - FILE *fd2=fopen(fname,"w"); - AssertFatal(fd2!=NULL,"cannot open %s\n",fname); - - int shift; - char data_type[100]; - char xor_command[100]; - int mask; - - - - - fprintf(fd,"#include \"PHY/sse_intrin.h\"\n"); - fprintf(fd2,"#include \"PHY/sse_intrin.h\"\n"); - - if ((Zc&31)==0) { - shift=5; // AVX2 - 256-bit SIMD - mask=31; - strcpy(data_type,"__m256i"); - strcpy(xor_command,"_mm256_xor_si256"); - } - else if ((Zc&15)==0) { - shift=4; // SSE4 - 128-bit SIMD - mask=15; - strcpy(data_type,"__m128i"); - strcpy(xor_command,"_mm_xor_si128"); - - } - else if ((Zc&7)==0) { - shift=3; // MMX - 64-bit SIMD - mask=7; - strcpy(data_type,"__m64"); - strcpy(xor_command,"_mm_xor_si64"); - } - else { - shift=0; // no SIMD - mask=0; - strcpy(data_type,"uint8_t"); - strcpy(xor_command,"scalar_xor"); - fprintf(fd,"#define scalar_xor(a,b) ((a)^(b))\n"); - fprintf(fd2,"#define scalar_xor(a,b) ((a)^(b))\n"); - } - fprintf(fd,"// generated code for Zc=%d, byte encoding\n",Zc); - fprintf(fd2,"// generated code for Zc=%d, 16bit encoding\n",Zc); - fprintf(fd,"static inline void ldpc_BG%d_Zc%d_byte(uint8_t *c,uint8_t *d) {\n",BG,Zc); - fprintf(fd2,"static inline void ldpc_BG%d_Zc%d_16bit(uint16_t *c,uint16_t *d) {\n",BG,Zc); - fprintf(fd," %s *csimd=(%s *)c,*dsimd=(%s *)d;\n\n",data_type,data_type,data_type); - fprintf(fd2," %s *csimd=(%s *)c,*dsimd=(%s *)d;\n\n",data_type,data_type,data_type); - fprintf(fd," %s *c2,*d2;\n\n",data_type); - fprintf(fd2," %s *c2,*d2;\n\n",data_type); - fprintf(fd," int i2;\n"); - fprintf(fd2," int i2;\n"); - fprintf(fd," for (i2=0; i2<%d; i2++) {\n",Zc>>shift); - if (shift > 0) - fprintf(fd2," for (i2=0; i2<%d; i2++) {\n",Zc>>(shift-1)); - for (i2=0; i2 < 1; i2++) + //rotate matrix here + for (i5=0; i5 < Kb; i5++) { - //t=Kb*Zc+i2; - - // calculate each row in base graph - - - fprintf(fd," c2=&csimd[i2];\n"); - fprintf(fd," d2=&dsimd[i2];\n"); - fprintf(fd2," c2=&csimd[i2];\n"); - fprintf(fd2," d2=&dsimd[i2];\n"); - - for (i1=0; i1 < nrows; i1++) - - { - channel_temp=0; - fprintf(fd,"\n//row: %d\n",i1); - fprintf(fd2,"\n//row: %d\n",i1); - fprintf(fd," d2[%d]=",(Zc*i1)>>shift); - fprintf(fd2," d2[%d]=",(Zc*i1)>>(shift-1)); - - nind=0; - - for (i3=0; i3 < ncols; i3++) - { - temp_prime=i1 * ncols + i3; - - - for (i4=0; i4 < no_shift_values[temp_prime]; i4++) - { - - var=(int)((i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc)/Zc); - int index =var*2*Zc + (i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc) % Zc; - - indlist[nind] = ((index&mask)*((2*Zc)>>shift)*Kb)+(index>>shift); - indlist2[nind++] = ((index&(mask>>1))*((2*Zc)>>(shift-1))*Kb)+(index>>(shift-1)); - - } - - - } - for (i4=0;i4 - * \date 27-03-2018 - * \version 1.0 - * \note - * \warning - */ - -#ifndef __NR_LDPC_DECODER__H__ -#define __NR_LDPC_DECODER__H__ - -#include "nrLDPC_types.h" -#include "nrLDPC_init_mem.h" - -/** - \brief LDPC decoder - \param p_decParams LDPC decoder parameters - \param p_llr Input LLRs - \param p_llrOut Output vector - \param p_profiler LDPC profiler statistics -*/ -int32_t nrLDPC_decoder(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_llrOut, t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats* p_profiler); - -#endif +#ifdef LDPC_LOADER +nrLDPC_decoderfunc_t nrLDPC_decoder; +nrLDPC_encoderfunc_t nrLDPC_encoder; +#else +/* functions to load the LDPC shared lib, implemented in openair1/PHY/CODING/nrLDPC_load.c */ +extern int load_nrLDPClib(void) ; +extern int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_ptr); // for ldpctest +/* ldpc coder/decoder functions, as loaded by load_nrLDPClib(). */ +extern nrLDPC_decoderfunc_t nrLDPC_decoder; +extern nrLDPC_encoderfunc_t nrLDPC_encoder; +// inline functions: +#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h" +#endif \ No newline at end of file diff --git a/openair1/PHY/CODING/nrLDPC_load.c b/openair1/PHY/CODING/nrLDPC_load.c new file mode 100644 index 0000000000..a74bdf7bd1 --- /dev/null +++ b/openair1/PHY/CODING/nrLDPC_load.c @@ -0,0 +1,76 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair1/PHY/CODING/coding_nr_load.c + * \brief: load library implementing coding/decoding algorithms + * \author Francois TABURET + * \date 2020 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ +#define _GNU_SOURCE +#include +#include +#include +#include "assertions.h" +#include "common/utils/LOG/log.h" +#define LDPC_LOADER +#include "PHY/CODING/nrLDPC_extern.h" +#include "common/config/config_userapi.h" +#include "common/utils/load_module_shlib.h" + + +/* function description array, to be used when loading the encoding/decoding shared lib */ +static loader_shlibfunc_t shlib_fdesc[2]; + +char *arg[64]={"ldpctest","-O","cmdlineonly::dbgl0"}; + +int load_nrLDPClib(void) { + char *ptr = (char*)config_get_if(); + if ( ptr==NULL ) {// phy simulators, config module possibly not loaded + load_configmodule(3,(char **)arg,CONFIG_ENABLECMDLINEONLY) ; + logInit(); + } + shlib_fdesc[0].fname = "nrLDPC_decod"; + shlib_fdesc[1].fname = "nrLDPC_encod"; + int ret=load_module_shlib("ldpc",shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t),NULL); + AssertFatal( (ret >= 0),"Error loading ldpc decoder"); + nrLDPC_decoder = (nrLDPC_decoderfunc_t)shlib_fdesc[0].fptr; + nrLDPC_encoder = (nrLDPC_encoderfunc_t)shlib_fdesc[1].fptr; +return 0; +} + +int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_ptr) { + loader_shlibfunc_t shlib_encoder_fdesc; + + shlib_encoder_fdesc.fname = "nrLDPC_encod"; + char libpath[64]; + sprintf(libpath,"ldpc%s",libversion); + int ret=load_module_shlib(libpath,&shlib_encoder_fdesc,1,NULL); + AssertFatal( (ret >= 0),"Error loading ldpc encoder %s\n",libpath); + *nrLDPC_encoder_ptr = (nrLDPC_encoderfunc_t)shlib_encoder_fdesc.fptr; +return 0; +} + + diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index f0ad3cbaae..4798f9a9e4 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -31,6 +31,7 @@ #include "TDD-Config.h" #include "MBSFN-SubframeConfigList.h"*/ #include "openair1/PHY/defs_RU.h" +#include "openair1/PHY/CODING/nrLDPC_extern.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "assertions.h" #include @@ -115,6 +116,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_gNB][MOD %02"PRIu8"][]\n", gNB->Mod_id); crcTableInit(); init_dfts(); + load_nrLDPClib(); // PBCH DMRS gold sequences generation nr_init_pbch_dmrs(gNB); //PDCCH DMRS init diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index dae5586224..17de9c02af 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -35,12 +35,11 @@ #include "PHY/CODING/coding_extern.h" #include "PHY/CODING/coding_defs.h" #include "PHY/CODING/lte_interleaver_inline.h" -#include "PHY/CODING/nrLDPC_encoder/defs.h" +#include "PHY/CODING/nrLDPC_extern.h" #include "PHY/NR_TRANSPORT/nr_transport.h" #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "SCHED_NR/sched_nr.h" -#include "defs.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "common/utils/LOG/log.h" #include @@ -404,9 +403,11 @@ int nr_dlsch_encoding(unsigned char *a, //ldpc_encoder_orig((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],dlsch->harq_processes[harq_pid]->d[r],*Zc,Kb,Kr,BG,0); //ldpc_encoder_optim((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],(unsigned char*)&dlsch->harq_processes[harq_pid]->d[r][0],*Zc,Kb,Kr,BG,NULL,NULL,NULL,NULL); } - + encoder_implemparams_t impp; + impp.n_segments=dlsch->harq_processes[harq_pid]->C; for(int j=0;j<(dlsch->harq_processes[harq_pid]->C/8+1);j++) { - ldpc_encoder_optim_8seg_multi(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,dlsch->harq_processes[harq_pid]->C,j,NULL,NULL,NULL,NULL); + impp.macro_num=j; + nrLDPC_encoder(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,&impp); } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 3945439a45..c58941b077 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -37,8 +37,7 @@ #include "PHY/CODING/coding_extern.h" #include "PHY/CODING/coding_defs.h" #include "PHY/CODING/lte_interleaver_inline.h" -#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h" -#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" +#include "PHY/CODING/nrLDPC_extern.h" #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "PHY/NR_TRANSPORT/nr_ulsch.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index b3a95e313e..b81c01114d 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -41,8 +41,7 @@ #include "SCHED_NR_UE/defs.h" #include "SIMULATION/TOOLS/sim.h" #include "executables/nr-uesoftmodem.h" -#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h" -#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" +#include "PHY/CODING/nrLDPC_extern.h" //#define DEBUG_DLSCH_DECODING //#define ENABLE_PHY_PAYLOAD_DEBUG 1 diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 2eb6dcd7fe..8b80b1b219 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -36,7 +36,7 @@ #include "PHY/CODING/coding_defs.h" #include "PHY/CODING/coding_extern.h" #include "PHY/CODING/lte_interleaver_inline.h" -#include "PHY/CODING/nrLDPC_encoder/defs.h" +#include "PHY/CODING/nrLDPC_extern.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h" #include "common/utils/LOG/vcd_signal_dumper.h" @@ -353,8 +353,11 @@ opp_enabled=0; printf("%d \n", harq_process->d[0][cnt]); } printf("\n");*/ + encoder_implemparams_t impp; + impp.n_segments=harq_process->C; + impp.macro_num=0; - ldpc_encoder_optim_8seg(harq_process->c,harq_process->d,*pz,Kb,Kr,BG,harq_process->C,NULL,NULL,NULL,NULL); + nrLDPC_encoder(harq_process->c,harq_process->d,*pz,Kb,Kr,BG,&impp); //stop_meas(te_stats); //printf("end ldpc encoder -- output\n"); diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 3c0f0db8da..fc81f4d74b 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -40,7 +40,7 @@ #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "PHY/impl_defs_top.h" #include "PHY/defs_common.h" -#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h" +#include "PHY/CODING/nrLDPC_extern.h" #include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" #define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c index 757ad6f75d..3066f0906f 100644 --- a/targets/ARCH/COMMON/common_lib.c +++ b/targets/ARCH/COMMON/common_lib.c @@ -37,6 +37,7 @@ #include #include "common_lib.h" +#include "assertions.h" #include "common/utils/load_module_shlib.h" #include "common/utils/LOG/log.h" #include "targets/RT/USER/lte-softmodem.h" @@ -91,38 +92,44 @@ int load_lib(openair0_device *device, { loader_shlibfunc_t shlib_fdesc[1]; int ret=0; - char *libname; + char *deflibname=OAI_RF_LIBNAME; openair0_cfg->recplay_mode = read_recplayconfig(&(openair0_cfg->recplay_conf),&(device->recplay_state)); if ( openair0_cfg->recplay_mode == RECPLAY_REPLAYMODE ) { - libname=OAI_IQPLAYER_LIBNAME; + deflibname=OAI_IQPLAYER_LIBNAME; shlib_fdesc[0].fname="device_init"; set_softmodem_optmask(SOFTMODEM_RECPLAY_BIT); // softmodem has to know we use the iqplayer to workaround randomized algorithms } else if ( IS_SOFTMODEM_BASICSIM ) { - libname=OAI_BASICSIM_LIBNAME; + deflibname=OAI_BASICSIM_LIBNAME; shlib_fdesc[0].fname="device_init"; } else if (IS_SOFTMODEM_RFSIM && flag == RAU_LOCAL_RADIO_HEAD) { - libname=OAI_RFSIM_LIBNAME; + deflibname=OAI_RFSIM_LIBNAME; shlib_fdesc[0].fname="device_init"; } else if (flag == RAU_LOCAL_RADIO_HEAD) { if (IS_SOFTMODEM_RFSIM) - libname="rfsimulator"; + deflibname="rfsimulator"; else - libname=OAI_RF_LIBNAME; + deflibname=OAI_RF_LIBNAME; shlib_fdesc[0].fname="device_init"; } else { - libname=OAI_TP_LIBNAME; + deflibname=OAI_TP_LIBNAME; shlib_fdesc[0].fname="transport_init"; } - ret=load_module_shlib(libname,shlib_fdesc,1,NULL); + + char *devname=NULL; + paramdef_t device_params[]=DEVICE_PARAMS_DESC ; + int numparams = sizeof(device_params)/sizeof(paramdef_t); + int devname_pidx = config_paramidx_fromname(device_params,numparams, CONFIG_DEVICEOPT_NAME); + device_params[devname_pidx].defstrval=deflibname; + + config_get(device_params,numparams,DEVICE_SECTION); + + ret=load_module_shlib(devname,shlib_fdesc,1,NULL); + AssertFatal( (ret >= 0), + "Library %s couldn't be loaded\n",devname); - if (ret < 0) { - LOG_E(HW,"Library %s couldn't be loaded\n",libname); - } else { - ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg); - } - return ret; + return ((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg); } diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 7e51bdc81a..ecadb68c0c 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -448,6 +448,24 @@ typedef struct { extern "C" { #endif + + +#define DEVICE_SECTION "device" +#define CONFIG_HLP_DEVICE "Identifies the oai device (the interface to RF) to use, the shared lib \"lib_.so\" will be loaded" + +#define CONFIG_DEVICEOPT_NAME "name" + +/* inclusion for device configuration */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* config parameters for oai device */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define DEVICE_PARAMS_DESC {\ + { CONFIG_DEVICEOPT_NAME, CONFIG_HLP_DEVICE, 0, strptr:&devname, defstrval:NULL, TYPE_STRING, 0}\ +} + + + /*! \brief get device name from device type */ char *get_devname(int devtype); /*! \brief Initialize openair RF target. It returns 0 if OK */ diff --git a/targets/ARCH/COMMON/record_player.h b/targets/ARCH/COMMON/record_player.h index 903dda006b..500acdd709 100644 --- a/targets/ARCH/COMMON/record_player.h +++ b/targets/ARCH/COMMON/record_player.h @@ -37,19 +37,6 @@ extern "C" { #endif -#define CONFIG_OPT_RECPLAY "enable_recplay" - -#define CONFIG_HLP_RECPLAY "Allow record player" -#define USRP_SECTION "device.usrp" -/* inclusion for device configuration */ -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters for USRP record/playback */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define DEVICE_PARAMS_DESC { \ - {CONFIG_OPT_RECPLAY, CONFIG_HLP_RECPLAY, PARAMFLAG_BOOL, uptr:&enable_recplay, defuintval:0, TYPE_UINT, 0} \ - } - /* inclusions for record player */ #define RECPLAY_DISABLED 0 @@ -114,7 +101,7 @@ typedef struct { {CONFIG_OPT_SF_LOOPS, CONFIG_HLP_SF_LOOPS, 0, uptr:&((*recplay_conf)->u_sf_loops), defintval:DEF_SF_NB_LOOP, TYPE_UINT, 0}, \ {CONFIG_OPT_SF_RDELAY, CONFIG_HLP_SF_RDELAY, 0, uptr:&((*recplay_conf)->u_sf_read_delay), defintval:DEF_SF_DELAY_READ, TYPE_UINT, 0}, \ {CONFIG_OPT_SF_WDELAY, CONFIG_HLP_SF_WDELAY, 0, uptr:&((*recplay_conf)->u_sf_write_delay), defintval:DEF_SF_DELAY_WRITE, TYPE_UINT, 0}, \ - }/*! \brief USRP Configuration and state */ + }/*! \brief Record Player Configuration and state */ typedef struct { char u_sf_filename[1024]; // subframes file path unsigned int u_sf_max ; // max number of recorded subframes diff --git a/targets/ARCH/iqplayer/iqplayer_lib.c b/targets/ARCH/iqplayer/iqplayer_lib.c index beb05de3fd..c4133d1b11 100644 --- a/targets/ARCH/iqplayer/iqplayer_lib.c +++ b/targets/ARCH/iqplayer/iqplayer_lib.c @@ -25,6 +25,7 @@ */ #define _LARGEFILE_SOURCE #define _FILE_OFFSET_BITS 64 +#define NB_ANTENNAS_RX 2 #include #include #include @@ -45,7 +46,9 @@ static void parse_iqfile_header(openair0_device *device, iqfile_header_t *iq_fh) { - AssertFatal((memcmp(iq_fh->oaiid,OAIIQFILE_ID,sizeof(OAIIQFILE_ID)) == 0),"iqfile doesn't seem to be compatible with oai (invalid id in header)\n"); + AssertFatal((memcmp(iq_fh->oaiid,OAIIQFILE_ID,sizeof(OAIIQFILE_ID)) == 0), + "iqfile doesn't seem to be compatible with oai (invalid id %.4s in header)\n", + iq_fh->oaiid); device->type = iq_fh->devtype; device->openair0_cfg[0].tx_sample_advance=iq_fh->tx_sample_advance; device->openair0_cfg[0].tx_bw = device->openair0_cfg[0].rx_bw = iq_fh->bw; @@ -138,6 +141,13 @@ static int iqplayer_loadfile(openair0_device *device, openair0_config_t *openair return 0; } +/*! \brief start the oai iq player + * \param device, the hardware used + */ +static int trx_iqplayer_start(openair0_device *device){ + return 0; +} + /*! \brief Terminate operation of the oai iq player * \param device, the hardware used */ @@ -287,7 +297,7 @@ static int trx_iqplayer_read(openair0_device *device, openair0_timestamp *ptimes int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { device->openair0_cfg = openair0_cfg; - device->trx_start_func = NULL; + device->trx_start_func = trx_iqplayer_start; device->trx_get_stats_func = NULL; device->trx_reset_stats_func = NULL; device->trx_end_func = trx_iqplayer_end; diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index f88d98536d..6d1a3b8cb2 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -2194,7 +2194,9 @@ int start_rf(RU_t *ru) { } int stop_rf(RU_t *ru) { - ru->rfdevice.trx_end_func(&ru->rfdevice); + if(ru->rfdevice.trx_end_func != NULL) { + ru->rfdevice.trx_end_func(&ru->rfdevice); + } return 0; }