Commit 3c16ad56 authored by cig's avatar cig Committed by Thomas Schlichter

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
parent f1e6a34f
...@@ -359,6 +359,7 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { ...@@ -359,6 +359,7 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
uint32_t nb_rb, start_rb; uint32_t nb_rb, start_rb;
uint8_t nb_symb_sch, start_symbol, mcs, precod_nbr_layers, harq_pid, rvidx; uint8_t nb_symb_sch, start_symbol, mcs, precod_nbr_layers, harq_pid, rvidx;
uint16_t n_rnti; uint16_t n_rnti;
module_id_t mod_id;
nr_dcireq_t dcireq; nr_dcireq_t dcireq;
nr_scheduled_response_t scheduled_response; nr_scheduled_response_t scheduled_response;
...@@ -366,7 +367,9 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { ...@@ -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 // 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){ 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.gNB_index = 0;
dcireq.cc_id = 0; dcireq.cc_id = 0;
dcireq.frame = proc->frame_rx; dcireq.frame = proc->frame_rx;
...@@ -375,7 +378,7 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { ...@@ -375,7 +378,7 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
scheduled_response.dl_config = NULL; scheduled_response.dl_config = NULL;
scheduled_response.ul_config = &dcireq.ul_config_req; scheduled_response.ul_config = &dcireq.ul_config_req;
scheduled_response.tx_request = NULL; 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.CC_id = 0;
scheduled_response.frame = proc->frame_rx; scheduled_response.frame = proc->frame_rx;
scheduled_response.slot = proc->nr_tti_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) { ...@@ -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.n_layers = precod_nbr_layers;
scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.harq_process_nbr = harq_pid; 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); nr_ue_scheduled_response(&scheduled_response);
if (UE->mode != loop_through_memory) { 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]; 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); phy_procedures_nrUE_TX(UE,proc,0,thread_id);
......
...@@ -156,22 +156,18 @@ typedef struct { ...@@ -156,22 +156,18 @@ typedef struct {
fapi_nr_tx_request_body_t *tx_request_body; fapi_nr_tx_request_body_t *tx_request_body;
} fapi_nr_tx_request_t; } fapi_nr_tx_request_t;
typedef struct { typedef struct {
uint8_t preamble_index; uint16_t phys_cell_id;
uint8_t prach_configuration_index; uint8_t num_prach_ocas;
uint16_t preamble_length; uint8_t prach_format;
uint8_t power_ramping_step; uint8_t num_ra;
uint16_t preamble_received_target_power; uint8_t prach_start_symbol;
uint8_t msg1_fdm; uint16_t num_cs;
uint8_t msg1_frequency_start; uint16_t root_seq_id;
uint8_t zero_correlation_zone_config; uint8_t restricted_set;
uint8_t subcarrier_spacing; uint16_t freq_msg1;
uint8_t restrictedset_config; //nfapi_nr_ul_beamforming_t beamforming;
uint16_t root_sequence_index; } fapi_nr_ul_config_prach_pdu;
uint16_t rsrp_threshold_ssb;
uint16_t rsrp_threshold_sul;
uint16_t prach_freq_offset;
} fapi_nr_ul_config_prach_pdu;
typedef struct { typedef struct {
......
...@@ -165,16 +165,16 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response) ...@@ -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->hoppingId = pucch_config_pdu->hoppingId;
pucch_config_common->p0_nominal = pucch_config_pdu->p0_nominal;*/ 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){ if (ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PRACH) {
// prach config pdu // prach config pdu
fapi_nr_ul_config_prach_pdu *prach_config_pdu = &ul_config->ul_config_list[i].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.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.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.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.highSpeedFlag = prach_config_pdu->restrictedset_config;
frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset = prach_config_pdu->prach_freq_offset;*/ frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset = prach_config_pdu->prach_freq_offset;*/
prach_resources->ra_PreambleIndex = prach_config_pdu->preamble_index; ////prach_resources->ra_PreambleIndex = prach_config_pdu->preamble_index;
} }
} }
}else{ }else{
......
...@@ -39,6 +39,9 @@ ...@@ -39,6 +39,9 @@
/* RRC*/ /* RRC*/
#include "RRC/NR_UE/rrc_proto.h" #include "RRC/NR_UE/rrc_proto.h"
#include "NR_RACH-ConfigCommon.h"
#include "NR_RACH-ConfigGeneric.h"
#include "NR_FrequencyInfoDL.h"
/* MAC */ /* MAC */
#include "mac_defs.h" #include "mac_defs.h"
...@@ -738,6 +741,154 @@ NR_UE_L2_STATE_t nr_ue_scheduler(const module_id_t module_id, ...@@ -738,6 +741,154 @@ NR_UE_L2_STATE_t nr_ue_scheduler(const module_id_t module_id,
return UE_CONNECTION_OK; 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) *///////// /////////* 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, ...@@ -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){ 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_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->RA_contention_resolution_timer_active == 1) {
if (mac->nr_rach_ConfigCommon) { if (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){
LOG_I(MAC, "Frame %d: Contention resolution timer %d/%ld\n", LOG_I(MAC, "Frame %d: Contention resolution timer %d/%ld\n",
tx_frame, tx_frame,
mac->RA_contention_resolution_cnt, mac->RA_contention_resolution_cnt,
((1 + rach_ConfigCommon->ra_ContentionResolutionTimer) << 3)); ((1 + nr_rach_ConfigCommon->ra_ContentionResolutionTimer) << 3));
mac->RA_contention_resolution_cnt++; 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->t_crnti = 0;
mac->RA_active = 0; mac->RA_active = 0;
mac->RA_contention_resolution_timer_active = 0; mac->RA_contention_resolution_timer_active = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment