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
This commit is contained in:
+8
-3
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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{
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user