From 3c16ad56434259cce313b53584cbe04789f57723 Mon Sep 17 00:00:00 2001 From: cig Date: Thu, 20 Feb 2020 15:35:06 +0100 Subject: [PATCH] NR UE PRACH scheduler to fill up UL config request with PRACH PDU - takes in input configuration index and TS 38.211 PRACH tables (6.3.3.2.x) - using FAPI NR UL config request struct, derived from SCF standard for gNB --- executables/nr-ue.c | 11 +- .../nfapi/public_inc/fapi_nr_ue_interface.h | 28 ++- openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 20 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 172 ++++++++++++++++-- 4 files changed, 186 insertions(+), 45 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index bbdcd0c29c..239f4aa4bc 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -359,6 +359,7 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { uint32_t nb_rb, start_rb; uint8_t nb_symb_sch, start_symbol, mcs, precod_nbr_layers, harq_pid, rvidx; uint16_t n_rnti; + module_id_t mod_id; nr_dcireq_t dcireq; nr_scheduled_response_t scheduled_response; @@ -366,7 +367,9 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { // program PUSCH. this should actually be done by the MAC upon reception of an UL DCI if (proc->nr_tti_tx == 8 || UE->frame_parms.frame_type == FDD){ - dcireq.module_id = UE->Mod_id; + mod_id = UE->Mod_id; + + dcireq.module_id = mod_id; dcireq.gNB_index = 0; dcireq.cc_id = 0; dcireq.frame = proc->frame_rx; @@ -375,7 +378,7 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { scheduled_response.dl_config = NULL; scheduled_response.ul_config = &dcireq.ul_config_req; scheduled_response.tx_request = NULL; - scheduled_response.module_id = UE->Mod_id; + scheduled_response.module_id = mod_id; scheduled_response.CC_id = 0; scheduled_response.frame = proc->frame_rx; scheduled_response.slot = proc->nr_tti_rx; @@ -405,8 +408,10 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.n_layers = precod_nbr_layers; scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.harq_process_nbr = harq_pid; + //nr_ue_prach_scheduler(mod_id, proc->frame_rx, proc->nr_tti_rx); + nr_ue_scheduled_response(&scheduled_response); - + if (UE->mode != loop_through_memory) { uint8_t thread_id = PHY_vars_UE_g[UE->Mod_id][0]->current_thread_id[proc->nr_tti_tx]; phy_procedures_nrUE_TX(UE,proc,0,thread_id); diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 576144e1df..7caeecdc4c 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -156,22 +156,18 @@ typedef struct { fapi_nr_tx_request_body_t *tx_request_body; } fapi_nr_tx_request_t; - typedef struct { - uint8_t preamble_index; - uint8_t prach_configuration_index; - uint16_t preamble_length; - uint8_t power_ramping_step; - uint16_t preamble_received_target_power; - uint8_t msg1_fdm; - uint8_t msg1_frequency_start; - uint8_t zero_correlation_zone_config; - uint8_t subcarrier_spacing; - uint8_t restrictedset_config; - uint16_t root_sequence_index; - uint16_t rsrp_threshold_ssb; - uint16_t rsrp_threshold_sul; - uint16_t prach_freq_offset; - } fapi_nr_ul_config_prach_pdu; +typedef struct { + uint16_t phys_cell_id; + uint8_t num_prach_ocas; + uint8_t prach_format; + uint8_t num_ra; + uint8_t prach_start_symbol; + uint16_t num_cs; + uint16_t root_seq_id; + uint8_t restricted_set; + uint16_t freq_msg1; + //nfapi_nr_ul_beamforming_t beamforming; +} fapi_nr_ul_config_prach_pdu; typedef struct { diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 7dbb68cf31..612a4b2db9 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -165,16 +165,16 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response) pucch_config_common->hoppingId = pucch_config_pdu->hoppingId; pucch_config_common->p0_nominal = pucch_config_pdu->p0_nominal;*/ } - if(ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PRACH){ - // prach config pdu - fapi_nr_ul_config_prach_pdu *prach_config_pdu = &ul_config->ul_config_list[i].prach_config_pdu; - /*frame_parms.prach_config_common.rootSequenceIndex = prach_config_pdu->root_sequence_index; - frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex = prach_config_pdu->prach_configuration_index; - frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig = prach_config_pdu->zero_correlation_zone_config; - frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag = prach_config_pdu->restrictedset_config; - frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset = prach_config_pdu->prach_freq_offset;*/ - prach_resources->ra_PreambleIndex = prach_config_pdu->preamble_index; - } + if (ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PRACH) { + // prach config pdu + fapi_nr_ul_config_prach_pdu *prach_config_pdu = &ul_config->ul_config_list[i].prach_config_pdu; + /*frame_parms.prach_config_common.rootSequenceIndex = prach_config_pdu->root_sequence_index; + frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex = prach_config_pdu->prach_configuration_index; + frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig = prach_config_pdu->zero_correlation_zone_config; + frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag = prach_config_pdu->restrictedset_config; + frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset = prach_config_pdu->prach_freq_offset;*/ + ////prach_resources->ra_PreambleIndex = prach_config_pdu->preamble_index; + } } }else{ diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 0cd4c27c30..64ce5388b9 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -39,6 +39,9 @@ /* RRC*/ #include "RRC/NR_UE/rrc_proto.h" +#include "NR_RACH-ConfigCommon.h" +#include "NR_RACH-ConfigGeneric.h" +#include "NR_FrequencyInfoDL.h" /* MAC */ #include "mac_defs.h" @@ -738,6 +741,154 @@ NR_UE_L2_STATE_t nr_ue_scheduler(const module_id_t module_id, return UE_CONNECTION_OK; } +// This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x +// It fills the PRACH PDU per each FD occasion. +// PRACH formats 9, 10, 11 are corresponding to dual PRACH format configurations A1/B1, A2/B2, A3/B3. +// - todo: +// - Partial configuration is actually already stored in (fapi_nr_prach_config_t) &mac->phy_config.config_req->prach_config +//// however we need rach_ConfigGeneric to retrieve the config_index +void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { + + uint8_t config_index, mu, N_dur, N_t_slot, start_symbol; + uint16_t format, format0, format1, ncs; + int msg1_FDM, is_nr_prach_slot, fdm; + + NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); + + fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request; + fapi_nr_ul_config_prach_pdu *prach_config_pdu; + fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; + fapi_nr_prach_config_t *prach_config = &cfg->prach_config; + + NR_ServingCellConfigCommon_t *scc = mac->scc; + NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; + NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; + config_index = rach_ConfigGeneric->prach_ConfigurationIndex; + + ////nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req[0]; + + if (is_nr_DL_slot(scc, slotP) == 1) { + + if (setup->msg1_SubcarrierSpacing) + mu = *setup->msg1_SubcarrierSpacing; + else + mu = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + + is_nr_prach_slot = get_nr_prach_info_from_index(config_index, + (int)frameP, + (int)slotP, + frequencyInfoDL->absoluteFrequencyPointA, + mu, + cfg->cell_config.frame_duplex_type, + &format, + &start_symbol, + &N_t_slot, + &N_dur); + if (is_nr_prach_slot) { + + fdm = rach_ConfigGeneric->msg1_FDM; + + switch (fdm){ + case 0: + case 1: + case 2: + case 3: + msg1_FDM = 1 << fdm; + break; + default: + AssertFatal(1 == 0, "Unknown msg1_FDM from rach_ConfigGeneric %d\n", fdm); + } + + format0 = format & 0xff; // single PRACH format + format1 = (format >> 8) & 0xff; // dual PRACH format + + ul_config->sfn = frameP; + ul_config->slot = slotP; + + for (int n = 0; n < msg1_FDM; n++) { // one structure per frequency domain occasion + + ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PRACH; + prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; + memset(prach_config_pdu,0,sizeof(fapi_nr_ul_config_prach_pdu)); + ul_config->number_pdus += 1; + + ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig); + + // filling PRACH PDU for FAPI config request + prach_config_pdu->phys_cell_id = *scc->physCellId; + prach_config_pdu->num_prach_ocas = N_t_slot; + prach_config_pdu->prach_start_symbol = start_symbol; + prach_config_pdu->num_ra = n; + prach_config_pdu->num_cs = ncs; + prach_config_pdu->root_seq_id = prach_config->num_prach_fd_occasions_list[n].prach_root_sequence_index; + prach_config_pdu->restricted_set = prach_config->restricted_set_config; + prach_config_pdu->freq_msg1 = prach_config->num_prach_fd_occasions_list[n].k1; + + if (format1 != 0xff) { + switch(format0) { // dual PRACH format + case 0xa1: + prach_config_pdu->prach_format = 9; + break; + case 0xa2: + prach_config_pdu->prach_format = 10; + break; + case 0xa3: + prach_config_pdu->prach_format = 10; + break; + default: + AssertFatal(1 == 0, "Only formats A1/B1 A2/B2 A3/B3 are valid for dual format"); + } + } else { + switch(format0) { // single PRACH format + case 0xa1: + prach_config_pdu->prach_format = 0; + break; + case 0xa2: + prach_config_pdu->prach_format = 1; + break; + case 0xa3: + prach_config_pdu->prach_format = 2; + break; + case 0xb1: + prach_config_pdu->prach_format = 3; + break; + case 0xb2: + prach_config_pdu->prach_format = 4; + break; + case 0xb3: + prach_config_pdu->prach_format = 5; + break; + case 0xb4: + prach_config_pdu->prach_format = 6; + break; + case 0xc0: + prach_config_pdu->prach_format = 7; + break; + case 0xc2: + prach_config_pdu->prach_format = 8; + break; + case 0: + // long formats are handled @ PHY + break; + case 1: + // long formats are handled @ PHY + break; + case 2: + // long formats are handled @ PHY + break; + case 3: + // long formats are handled @ PHY + break; + default: + AssertFatal(1 == 0, "Invalid PRACH format"); + } + } + } + } + } +} + //////////////////////////////////////////////////////////////////////////// /////////* Random Access Contention Resolution (5.1.35 TS 38.321) *///////// //////////////////////////////////////////////////////////////////////////// @@ -749,29 +900,18 @@ NR_UE_L2_STATE_t nr_ue_scheduler(const module_id_t module_id, void ue_contention_resolution(module_id_t module_id, uint8_t gNB_index, int cc_id, frame_t tx_frame){ NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - NR_RACH_ConfigCommon_t *rach_ConfigCommon = (NR_RACH_ConfigCommon_t *) NULL; + NR_ServingCellConfigCommon_t *scc = mac->scc; + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; if (mac->RA_contention_resolution_timer_active == 1) { - if (mac->nr_rach_ConfigCommon) { - rach_ConfigCommon = mac->nr_rach_ConfigCommon; - } else { - // LOG_E(MAC, "FATAL: radioResourceConfigCommon is NULL!!!\n"); - // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER,VCD_FUNCTION_OUT); - // stop_meas(&mac->ue_scheduler); - // AssertFatal(1 == 0, ""); - // #if UE_TIMING_TRACE - // stop_meas(&mac->ue_scheduler); - // #endif - } - - if (rach_ConfigCommon){ + if (nr_rach_ConfigCommon){ LOG_I(MAC, "Frame %d: Contention resolution timer %d/%ld\n", tx_frame, mac->RA_contention_resolution_cnt, - ((1 + rach_ConfigCommon->ra_ContentionResolutionTimer) << 3)); + ((1 + nr_rach_ConfigCommon->ra_ContentionResolutionTimer) << 3)); mac->RA_contention_resolution_cnt++; - if (mac->RA_contention_resolution_cnt == ((1 + rach_ConfigCommon->ra_ContentionResolutionTimer) << 3)) { + if (mac->RA_contention_resolution_cnt == ((1 + nr_rach_ConfigCommon->ra_ContentionResolutionTimer) << 3)) { mac->t_crnti = 0; mac->RA_active = 0; mac->RA_contention_resolution_timer_active = 0;