Merge remote-tracking branch 'origin/NR_MAC_SSB_RO_GlobalEdge' into integration_2020_wk42

Solved Conflicts in:
	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
	openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
This commit is contained in:
hardy
2020-10-19 11:18:30 +02:00
32 changed files with 1150 additions and 472 deletions
+1 -1
View File
@@ -179,7 +179,7 @@ void prach_eNB_tosplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB, L1_r
ru=eNB->RU_list[i];
for (ru_aa=0,aa=0; ru_aa<ru->nb_rx; ru_aa++,aa++) {
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa];
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[0][ru_aa];
int ce_level;
for (ce_level=0; ce_level<4; ce_level++)
+2 -2
View File
@@ -228,7 +228,7 @@ void init_eNB_afterRU(void) {
for (int i=0; i<eNB->RU_list[ru_id]->nb_rx; aa++,i++) {
LOG_I(PHY,"Attaching RU %d antenna %d to eNB antenna %d\n",eNB->RU_list[ru_id]->idx,i,aa);
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[i];
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[0][i];
for (int ce_level=0; ce_level<4; ce_level++)
eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[ru_id]->prach_rxsigF_br[ce_level][i];
@@ -483,7 +483,7 @@ void prach_procedures_ocp(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int br_flag)
ru=eNB->RU_list[i];
for (ru_aa=0,aa=0; ru_aa<ru->nb_rx; ru_aa++,aa++) {
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa];
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[0][ru_aa];
int ce_level;
if (br_flag==1)
+2 -6
View File
@@ -255,11 +255,7 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
// TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT
// Do PRACH RU processing
int prach_id=find_nr_prach(gNB,frame_rx,slot_rx,0,SEARCH_EXIST);
if (prach_id>=0) {
L1_nr_prach_procedures(gNB,frame_rx,slot_rx,&gNB->prach_vars.list[prach_id].pdu);
gNB->prach_vars.list[prach_id].frame=-1;
}
L1_nr_prach_procedures(gNB,frame_rx,slot_rx);
phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
}
@@ -981,7 +977,7 @@ void init_eNB_afterRU(void) {
for (i=0; i<gNB->RU_list[ru_id]->nb_rx; aa++,i++) {
LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa);
gNB->prach_vars.rxsigF[aa] = gNB->RU_list[ru_id]->prach_rxsigF[i];
gNB->prach_vars.rxsigF[aa] = gNB->RU_list[ru_id]->prach_rxsigF[0][i];
gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i];
}
}
+28 -5
View File
@@ -1594,13 +1594,36 @@ void *ru_thread( void *param ) {
(void*)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t));
// Do PRACH RU processing
int prach_id=find_nr_prach_ru(ru,proc->frame_rx,proc->tti_rx,SEARCH_EXIST);
uint8_t prachStartSymbol,N_dur;
if (prach_id>=0) {
rx_nr_prach_ru(ru,
ru->prach_list[prach_id].fmt,
ru->prach_list[prach_id].numRA,
ru->prach_list[prach_id].prachStartSymbol,
proc->frame_rx,proc->tti_rx);
N_dur = get_nr_prach_duration(ru->prach_list[prach_id].fmt);
/*
get_nr_prach_info_from_index(ru->config.prach_config.prach_ConfigurationIndex.value,
proc->frame_rx,proc->tti_rx,
ru->config.carrier_config.dl_frequency.value,
fp->numerology_index,
fp->frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur,
&RA_sfn_index,
&N_RA_slot,
&config_period);
*/
for (int prach_oc = 0; prach_oc<ru->prach_list[prach_id].num_prach_ocas; prach_oc++) {
prachStartSymbol = ru->prach_list[prach_id].prachStartSymbol+prach_oc*N_dur;
//comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}.
rx_nr_prach_ru(ru,
ru->prach_list[prach_id].fmt, //could also use format
ru->prach_list[prach_id].numRA,
prachStartSymbol,
prach_oc,
proc->frame_rx,proc->tti_rx);
}
free_nr_ru_prach_entry(ru,prach_id);
}
}
@@ -321,6 +321,7 @@ typedef enum {
#define NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG 0x1012
#define NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG 0x1013
#define NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG 0x1014
#define NFAPI_NR_CONFIG_PRACH_CONFIG_INDEX_TAG 0x1029
#define NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG 0x1015
#define NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG 0x1016
#define NFAPI_NR_CONFIG_K1_TAG 0x1017
@@ -385,7 +386,6 @@ typedef struct
typedef struct
{
uint8_t num_prach_fd_occasions;
nfapi_uint16_tlv_t prach_root_sequence_index;//Starting logical root sequence index, 𝑖, equivalent to higher layer parameter prach-RootSequenceIndex [38.211, sec 6.3.3.1] Value: 0 -> 837
nfapi_uint8_tlv_t num_root_sequences;//Number of root sequences for a particular FD occasion that are required to generate the necessary number of preambles
nfapi_uint16_tlv_t k1;//Frequency offset (from UL bandwidth part) for each FD. [38.211, sec 6.3.3.2] Value: from 0 to 272
@@ -401,7 +401,9 @@ typedef struct
nfapi_uint8_tlv_t prach_sub_c_spacing;//Subcarrier spacing of PRACH. [38.211 sec 4.2] Value:0->4
nfapi_uint8_tlv_t restricted_set_config;//PRACH restricted set config Value: 0: unrestricted 1: restricted set type A 2: restricted set type B
nfapi_uint8_tlv_t num_prach_fd_occasions;//Corresponds to the parameter 𝑀 in [38.211, sec 6.3.3.2] which equals the higher layer parameter msg1FDM Value: 1,2,4,8
nfapi_uint8_tlv_t prach_ConfigurationIndex;//PRACH configuration index. Value:0->255
nfapi_nr_num_prach_fd_occasions_t* num_prach_fd_occasions_list;
nfapi_uint8_tlv_t ssb_per_rach;//SSB-per-RACH-occasion Value: 0: 1/8 1:1/4, 2:1/2 3:1 4:2 5:4, 6:8 7:16
nfapi_uint8_tlv_t prach_multiple_carriers_in_a_band;//0 = disabled 1 = enabled
+5 -5
View File
@@ -121,13 +121,13 @@ int phy_init_RU(RU_t *ru) {
/* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */
//AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]),
//"nb_antennas_rx too large");
ru->prach_rxsigF = (int16_t **)malloc(ru->nb_rx * sizeof(int16_t *));
ru->prach_rxsigF[0] = (int16_t **)malloc(ru->nb_rx * sizeof(int16_t *));
for (j=0; j<4; j++) ru->prach_rxsigF_br[j] = (int16_t **)malloc(ru->nb_rx * sizeof(int16_t *));
for (i=0; i<ru->nb_rx; i++) {
ru->prach_rxsigF[i] = (int16_t *)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[i]);
ru->prach_rxsigF[0][i] = (int16_t *)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[0][i]);
for (j=0; j<4; j++) {
ru->prach_rxsigF_br[j][i] = (int16_t *)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
@@ -230,14 +230,14 @@ void phy_free_RU(RU_t *ru) {
}
for (i = 0; i < ru->nb_rx; i++) {
free_and_zero(ru->prach_rxsigF[i]);
free_and_zero(ru->prach_rxsigF[0][i]);
for (j = 0; j < 4; j++) free_and_zero(ru->prach_rxsigF_br[j][i]);
}
for (j = 0; j < 4; j++) free_and_zero(ru->prach_rxsigF_br[j]);
free_and_zero(ru->prach_rxsigF);
free_and_zero(ru->prach_rxsigF[0]);
/* ru->prach_rxsigF_br is not allocated -> don't free */
for (i = 0; i < RC.nb_L1_inst; i++) {
+2 -1
View File
@@ -497,11 +497,12 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
fd_occasion = 0;
nfapi_nr_prach_config_t *prach_config = &gNB_config->prach_config;
short_sequence = prach_config->prach_sequence_length.value;
// for(fd_occasion = 0; fd_occasion <= prach_config->num_prach_fd_occasions.value ; fd_occasion) { // TODO Need to handle for msg1-fdm > 1
num_sequences = prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value;
rootSequenceIndex = prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index.value;
compute_nr_prach_seq(short_sequence, num_sequences, rootSequenceIndex, RC.gNB[Mod_id]->X_u);
// }
RC.gNB[Mod_id]->configured = 1;
init_symbol_rotation(fp,fp->dl_CarrierFreq);
+13 -9
View File
@@ -107,12 +107,14 @@ int nr_phy_init_RU(RU_t *ru) {
/* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */
// AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]),
// "nb_antennas_rx too large");
ru->prach_rxsigF = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*));
for (i=0; i<ru->nb_rx; i++) {
// largest size for PRACH FFT is 4x98304 (16*24576)
ru->prach_rxsigF[i] = (int16_t*)malloc16_clear( 4*98304*2*sizeof(int16_t) );
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[i]);
for (j=0;j<NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX;j++) {
ru->prach_rxsigF[j] = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*));
for (i=0; i<ru->nb_rx; i++) {
// largest size for PRACH FFT is 4x98304 (16*24576)
ru->prach_rxsigF[j][i] = (int16_t*)malloc16_clear( 4*98304*2*sizeof(int16_t) );
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[j][i]);
}
}
AssertFatal(RC.nb_nr_L1_inst <= NUMBER_OF_eNB_MAX,"gNB instances %d > %d\n",
@@ -186,10 +188,12 @@ void nr_phy_free_RU(RU_t *ru)
for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdataF[i]);
free_and_zero(ru->common.rxdataF);
for (i = 0; i < ru->nb_rx; i++) {
free_and_zero(ru->prach_rxsigF[i]);
for (j=0;j<NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX;j++) {
for (i = 0; i < ru->nb_rx; i++) {
free_and_zero(ru->prach_rxsigF[j][i]);
}
}
for (i = 0; i < RC.nb_nr_L1_inst; i++) {
for (p = 0; p < 15; p++) {
for (j=0; j<ru->nb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]);
+2 -2
View File
@@ -49,7 +49,7 @@ void send_IF4p5(RU_t *ru,
LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
int32_t **txdataF = ru->common.txdataF_BF;
int32_t **rxdataF = ru->common.rxdataF;
int16_t **prach_rxsigF = ru->prach_rxsigF;
int16_t **prach_rxsigF = ru->prach_rxsigF[0];
int16_t ***prach_rxsigF_br = ru->prach_rxsigF_br;
void *tx_buffer = ru->ifbuffer.tx[subframe&1];
void *tx_buffer_prach = ru->ifbuffer.tx_prach;
@@ -276,7 +276,7 @@ void recv_IF4p5(RU_t *ru,
LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
int32_t **txdataF = ru->common.txdataF_BF;
int32_t **rxdataF = ru->common.rxdataF;
int16_t **prach_rxsigF = ru->prach_rxsigF;
int16_t **prach_rxsigF = ru->prach_rxsigF[0];
int16_t ***prach_rxsigF_br = ru->prach_rxsigF_br;
void *rx_buffer = ru->ifbuffer.rx;
uint16_t element_id;
+1 -1
View File
@@ -167,7 +167,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
br_flag,ce_level,frame_prach,subframe,fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],prach_ConfigIndex);
}
} else {
rxsigF = ru->prach_rxsigF;
rxsigF = ru->prach_rxsigF[0];
if (LOG_DEBUGFLAG(PRACH)) {
if (((frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
+90 -65
View File
@@ -37,31 +37,42 @@
extern uint16_t prach_root_sequence_map_0_3[838];
extern uint16_t prach_root_sequence_map_abc[138];
extern uint16_t nr_du[838];
extern const char *prachfmt[9];
extern const char *prachfmt[];
void init_prach_list(PHY_VARS_gNB *gNB) {
AssertFatal(gNB!=NULL,"gNB is null\n");
for (int i=0; i<NUMBER_OF_NR_PRACH_MAX; i++) gNB->prach_vars.list[i].frame=-1;
for (int i=0; i<NUMBER_OF_NR_PRACH_MAX; i++){
gNB->prach_vars.list[i].frame = -1;
gNB->prach_vars.list[i].slot = -1;
}
}
int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame,int slot, int numRA, find_type_t type) {
void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id) {
uint16_t i;
int16_t first_free_index=-1;
gNB->prach_vars.list[prach_id].frame = -1;
gNB->prach_vars.list[prach_id].slot = -1;
}
int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame, int slot, find_type_t type) {
AssertFatal(gNB!=NULL,"gNB is null\n");
for (i=0; i<NUMBER_OF_NR_PRACH_MAX; i++) {
LOG_D(PHY,"searching for PRACH in %d.%d with numRA %d: prach_index %d=> %d.%d numRA %d\n", frame,slot,numRA,i,
gNB->prach_vars.list[i].frame,gNB->prach_vars.list[i].slot,gNB->prach_vars.list[i].pdu.num_ra);
if ((gNB->prach_vars.list[i].frame == frame) &&
(gNB->prach_vars.list[i].slot == slot) &&
(gNB->prach_vars.list[i].pdu.num_ra == numRA)) return i;
else if ((gNB->prach_vars.list[i].frame == -1) && (first_free_index==-1)) first_free_index=i;
for (uint16_t i=0; i<NUMBER_OF_NR_PRACH_MAX; i++) {
LOG_D(PHY,"searching for PRACH in %d.%d prach_index %d=> %d.%d\n", frame,slot,i,
gNB->prach_vars.list[i].frame,gNB->prach_vars.list[i].slot);
if((type == SEARCH_EXIST_OR_FREE) &&
(gNB->prach_vars.list[i].frame == -1) &&
(gNB->prach_vars.list[i].slot == -1)) {
return i;
}
else if ((type == SEARCH_EXIST) &&
(gNB->prach_vars.list[i].frame == frame) &&
(gNB->prach_vars.list[i].slot == slot)) {
return i;
}
}
if (type == SEARCH_EXIST) return -1;
return first_free_index;
return -1;
}
void nr_fill_prach(PHY_VARS_gNB *gNB,
@@ -69,9 +80,9 @@ void nr_fill_prach(PHY_VARS_gNB *gNB,
int Slot,
nfapi_nr_prach_pdu_t *prach_pdu) {
int prach_id = find_nr_prach(gNB,SFN,Slot,prach_pdu->num_ra,SEARCH_EXIST_OR_FREE);
AssertFatal( (prach_id>=0) && (prach_id<NUMBER_OF_NR_PRACH_MAX),
"illegal or no prach_id found!!! numRA %d prach_id %d\n",prach_pdu->num_ra,prach_id);
int prach_id = find_nr_prach(gNB,SFN,Slot,SEARCH_EXIST_OR_FREE);
AssertFatal( ((prach_id>=0) && (prach_id<NUMBER_OF_NR_PRACH_MAX)) || (prach_id < 0),
"illegal or no prach_id found!!! prach_id %d\n",prach_id);
gNB->prach_vars.list[prach_id].frame=SFN;
gNB->prach_vars.list[prach_id].slot=Slot;
@@ -82,31 +93,35 @@ void nr_fill_prach(PHY_VARS_gNB *gNB,
void init_prach_ru_list(RU_t *ru) {
AssertFatal(ru!=NULL,"ruis null\n");
for (int i=0; i<NUMBER_OF_NR_RU_PRACH_MAX; i++) ru->prach_list[i].frame=-1;
for (int i=0; i<NUMBER_OF_NR_RU_PRACH_MAX; i++) {
ru->prach_list[i].frame = -1;
ru->prach_list[i].slot = -1;
}
pthread_mutex_init(&ru->prach_list_mutex,NULL);
}
int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type) {
uint16_t i;
int16_t first_free_index=-1;
AssertFatal(ru!=NULL,"ru is null\n");
pthread_mutex_lock(&ru->prach_list_mutex);
for (i=0; i<NUMBER_OF_NR_RU_PRACH_MAX; i++) {
for (uint16_t i=0; i<NUMBER_OF_NR_RU_PRACH_MAX; i++) {
LOG_D(PHY,"searching for PRACH in %d.%d : prach_index %d=> %d.%d\n", frame,slot,i,
ru->prach_list[i].frame,ru->prach_list[i].slot);
if ((ru->prach_list[i].frame == frame) &&
(ru->prach_list[i].slot == slot)) {
if((type == SEARCH_EXIST_OR_FREE) &&
(ru->prach_list[i].frame == -1) &&
(ru->prach_list[i].slot == -1)) {
pthread_mutex_unlock(&ru->prach_list_mutex);
return i;
}
else if ((type == SEARCH_EXIST) &&
(ru->prach_list[i].frame == frame) &&
(ru->prach_list[i].slot == slot)) {
pthread_mutex_unlock(&ru->prach_list_mutex);
return i;
}
else if ((ru->prach_list[i].frame == -1) && (first_free_index==-1)) first_free_index=i;
}
pthread_mutex_unlock(&ru->prach_list_mutex);
if (type == SEARCH_EXIST) return -1;
return first_free_index;
return -1;
}
void nr_fill_prach_ru(RU_t *ru,
@@ -115,7 +130,7 @@ void nr_fill_prach_ru(RU_t *ru,
nfapi_nr_prach_pdu_t *prach_pdu) {
int prach_id = find_nr_prach_ru(ru,SFN,Slot,SEARCH_EXIST_OR_FREE);
AssertFatal( (prach_id>=0) && (prach_id<NUMBER_OF_NR_PRACH_MAX),
AssertFatal( ((prach_id>=0) && (prach_id<NUMBER_OF_NR_PRACH_MAX)) || (prach_id < 0) ,
"illegal or no prach_id found!!! prach_id %d\n",prach_id);
pthread_mutex_lock(&ru->prach_list_mutex);
@@ -124,6 +139,7 @@ void nr_fill_prach_ru(RU_t *ru,
ru->prach_list[prach_id].fmt = prach_pdu->prach_format;
ru->prach_list[prach_id].numRA = prach_pdu->num_ra;
ru->prach_list[prach_id].prachStartSymbol = prach_pdu->prach_start_symbol;
ru->prach_list[prach_id].num_prach_ocas = prach_pdu->num_prach_ocas;
pthread_mutex_unlock(&ru->prach_list_mutex);
}
@@ -132,7 +148,8 @@ void free_nr_ru_prach_entry(RU_t *ru,
int prach_id) {
pthread_mutex_lock(&ru->prach_list_mutex);
ru->prach_list[prach_id].frame=-1;
ru->prach_list[prach_id].frame = -1;
ru->prach_list[prach_id].slot = -1;
pthread_mutex_unlock(&ru->prach_list_mutex);
}
@@ -142,6 +159,7 @@ void rx_nr_prach_ru(RU_t *ru,
int prachFormat,
int numRA,
int prachStartSymbol,
int prachOccasion,
int frame,
int slot) {
@@ -156,15 +174,21 @@ void rx_nr_prach_ru(RU_t *ru,
int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value;
rxsigF = ru->prach_rxsigF;
int sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1));
//to be checked for mu=0;
LOG_D(PHY,"frame %d, slot %d: doing rx_nr_prach_ru for format %d, numRA %d, prachStartSymbol %d, prachOccasion %d\n",frame,slot,prachFormat,numRA,prachStartSymbol,prachOccasion);
rxsigF = ru->prach_rxsigF[prachOccasion];
AssertFatal(ru->if_south == LOCAL_RF,"we shouldn't call this if if_south != LOCAL_RF\n");
for (int aa=0; aa<ru->nb_rx; aa++){
if (prach_sequence_length == 0) slot2=(slot/fp->slots_per_subframe)*fp->slots_per_subframe;
prach[aa] = (int16_t*)&ru->common.rxdata[aa][(slot2*fp->get_samples_per_slot(slot,fp))-ru->N_TA_offset];
prach[aa] = (int16_t*)&ru->common.rxdata[aa][(slot2*fp->get_samples_per_slot(slot,fp))+sample_offset_slot-ru->N_TA_offset];
}
int dftlen=0;
int mu = fp->numerology_index;
int Ncp = 0;
@@ -198,22 +222,24 @@ void rx_nr_prach_ru(RU_t *ru,
ru->idx,frame,slot,prachfmt[prachFormat],msg1_frequencystart,prachStartSymbol);
switch (prachFormat) {
case 0: //A1
case 4: //A1
Ncp = 288/(1<<mu);
break;
case 1: //A2
case 5: //A2
Ncp = 576/(1<<mu);
break;
case 2: //A3
case 6: //A3
Ncp = 864/(1<<mu);
break;
case 3: //B1
case 7: //B1
Ncp = 216/(1<<mu);
break;
/*
// B2 and B3 do not exist in FAPI
case 4: //B2
Ncp = 360/(1<<mu);
break;
@@ -221,16 +247,16 @@ void rx_nr_prach_ru(RU_t *ru,
case 5: //B3
Ncp = 504/(1<<mu);
break;
case 6: //B4
*/
case 8: //B4
Ncp = 936/(1<<mu);
break;
case 7: //C0
case 9: //C0
Ncp = 1240/(1<<mu);
break;
case 8: //C2
case 10: //C2
Ncp = 2048/(1<<mu);
break;
@@ -265,7 +291,8 @@ void rx_nr_prach_ru(RU_t *ru,
if (k<0) k+=(fp->ofdm_symbol_size);
k*=K;
k+=kbar;
k+=kbar;
int reps=1;
for (int aa=0; aa<ru->nb_rx; aa++) {
@@ -308,21 +335,21 @@ void rx_nr_prach_ru(RU_t *ru,
else if (mu==1) {
dftlen=2048;
dft(DFT_2048,prach2,rxsigF[aa],1);
if (prachFormat != 7) { // !=C0
if (prachFormat != 9/*C0*/) {
dft(DFT_2048,prach2+4096,rxsigF[aa]+4096,1);
reps++;
}
if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
dft(DFT_2048,prach2+4096*2,rxsigF[aa]+4096*2,1);
dft(DFT_2048,prach2+4096*3,rxsigF[aa]+4096*3,1);
reps+=2;
}
if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
dft(DFT_2048,prach2+4096*4,rxsigF[aa]+4096*4,1);
dft(DFT_2048,prach2+4096*5,rxsigF[aa]+4096*5,1);
reps+=2;
}
if (prachFormat == 6) {
if (prachFormat == 8/*B4*/) {
for (int i=6;i<12;i++) dft(DFT_2048,prach2+(4096*i),rxsigF[aa]+(4096*i),1);
reps+=6;
}
@@ -363,22 +390,22 @@ void rx_nr_prach_ru(RU_t *ru,
else if (mu==1) {
dftlen=1536;
dft(DFT_1536,prach2,rxsigF[aa],1);
if (prachFormat != 7) {
if (prachFormat != 9/*C0*/) {
dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1);
reps++;
}
if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
dft(DFT_1536,prach2+3072*2,rxsigF[aa]+3072*2,1);
dft(DFT_1536,prach2+3072*3,rxsigF[aa]+3072*3,1);
reps+=2;
}
if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
dft(DFT_1536,prach2+3072*4,rxsigF[aa]+3072*4,1);
dft(DFT_1536,prach2+3072*5,rxsigF[aa]+3072*5,1);
reps+=2;
}
if (prachFormat == 6) {
if (prachFormat == 8/*B4*/) {
for (int i=6;i<12;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1);
reps+=6;
}
@@ -423,22 +450,22 @@ void rx_nr_prach_ru(RU_t *ru,
else if (mu==1) {
dftlen=4096;
dft(DFT_4096,prach2,rxsigF[aa],1);
if (prachFormat != 7) { //!=C0
if (prachFormat != 9/*C0*/) {
dft(DFT_4096,prach2+8192,rxsigF[aa]+8192,1);
reps++;
}
if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
dft(DFT_4096,prach2+8192*2,rxsigF[aa]+8192*2,1);
dft(DFT_4096,prach2+8192*3,rxsigF[aa]+8192*3,1);
reps+=2;
}
if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
dft(DFT_4096,prach2+8192*4,rxsigF[aa]+8192*4,1);
dft(DFT_4096,prach2+8192*5,rxsigF[aa]+8192*5,1);
reps+=2;
}
if (prachFormat == 6) {
if (prachFormat == 8/*B4*/) {
for (int i=6;i<12;i++) dft(DFT_4096,prach2+(8192*i),rxsigF[aa]+(8192*i),1);
reps+=6;
}
@@ -475,22 +502,22 @@ void rx_nr_prach_ru(RU_t *ru,
else if (mu==1) {
dftlen=3072;
dft(DFT_3072,prach2,rxsigF[aa],1);
if (prachFormat != 7) { //!=C0
if (prachFormat != 9/*C0*/) {
dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1);
reps++;
}
if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
dft(DFT_3072,prach2+6144*2,rxsigF[aa]+6144*2,1);
dft(DFT_3072,prach2+6144*3,rxsigF[aa]+6144*3,1);
reps+=2;
}
if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
dft(DFT_3072,prach2+6144*4,rxsigF[aa]+6144*4,1);
dft(DFT_3072,prach2+6144*5,rxsigF[aa]+6144*5,1);
reps+=2;
}
if (prachFormat == 6) {
if (prachFormat == 8/*B4*/) {
for (int i=6;i<12;i++) dft(DFT_3072,prach2+(6144*i),rxsigF[aa]+(6144*i),1);
reps+=6;
}
@@ -515,13 +542,13 @@ void rx_nr_prach_ru(RU_t *ru,
for (int i=1;i<reps;i++) rxsigF_tmp[j] += rxsigF2[k2+(i*dftlen<<1)];
}
memcpy((void*)rxsigF2,(void *)rxsigF_tmp,N_ZC<<2);
}
}
void rx_nr_prach(PHY_VARS_gNB *gNB,
nfapi_nr_prach_pdu_t *prach_pdu,
int prachOccasion,
int frame,
int subframe,
uint16_t *max_preamble,
@@ -570,13 +597,11 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
fp = &gNB->frame_parms;
nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value;
rootSequenceIndex = cfg->num_prach_fd_occasions_list[0].prach_root_sequence_index.value;
numrootSequenceIndex = cfg->num_prach_fd_occasions_list[0].num_root_sequences.value;
rootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].prach_root_sequence_index.value;
numrootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].num_root_sequences.value;
NCS = prach_pdu->num_cs;//cfg->num_prach_fd_occasions_list[0].prach_zero_corr_conf.value;
int prach_sequence_length = cfg->prach_sequence_length.value;
int msg1_frequencystart = cfg->num_prach_fd_occasions_list[0].k1.value;
int msg1_frequencystart = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].k1.value;
// int num_unused_root_sequences = cfg->num_prach_fd_occasions_list[0].num_unused_root_sequences.value;
// cfg->num_prach_fd_occasions_list[0].unused_root_sequences_list
@@ -585,7 +610,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
uint8_t prach_fmt = prach_pdu->prach_format;
uint16_t N_ZC = (prach_sequence_length==0)?839:139;
LOG_D(PHY,"L1 PRACH RX: rooSequenceIndex %d, numRootSeqeuences %d, NCS %d, N_ZC %d \n", rootSequenceIndex,numrootSequenceIndex,NCS,N_ZC);
LOG_D(PHY,"L1 PRACH RX: rooSequenceIndex %d, numRootSeqeuences %d, NCS %d, N_ZC %d, format %d \n",rootSequenceIndex,numrootSequenceIndex,NCS,N_ZC,prach_fmt);
prach_ifft = gNB->prach_vars.prach_ifft;
prachF = gNB->prach_vars.prachF;
@@ -288,6 +288,7 @@ void nr_fill_prach(PHY_VARS_gNB *gNB,
void rx_nr_prach(PHY_VARS_gNB *gNB,
nfapi_nr_prach_pdu_t *prach_pdu,
int prachOccasion,
int frame,
int subframe,
uint16_t *max_preamble,
@@ -298,6 +299,7 @@ void rx_nr_prach_ru(RU_t *ru,
int prach_fmt,
int numRA,
int prachStartSymbol,
int prachOccasion,
int frame,
int subframe);
@@ -306,7 +308,7 @@ void nr_fill_prach_ru(RU_t *ru,
int Slot,
nfapi_nr_prach_pdu_t *prach_pdu);
int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame,int slot, int numRA, find_type_t type);
int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame,int slot, find_type_t type);
int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type);
NR_gNB_PUCCH_t *new_gNB_pucch(void);
@@ -325,7 +327,7 @@ int nr_find_pucch(uint16_t rnti,
void init_prach_list(PHY_VARS_gNB *gNB);
void init_prach_ru_list(RU_t *ru);
void free_nr_ru_prach_entry(RU_t *ru, int prach_id);
void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id);
void nr_decode_pucch1(int32_t **rxdataF,
pucch_GroupHopping_t pucch_GroupHopping,
+31 -30
View File
@@ -48,8 +48,7 @@ extern uint16_t prach_root_sequence_map_0_3[838];
extern uint16_t prach_root_sequence_map_abc[138];
extern uint16_t nr_du[838];
extern int16_t nr_ru[2*839];
extern const char *prachfmt[9];
extern const char *prachfmt03[4];
extern const char *prachfmt[];
// Note:
// - prach_fmt_id is an ID used to map to the corresponding PRACH format value in prachfmt
@@ -181,14 +180,14 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
}
// now generate PRACH signal
#ifdef NR_PRACH_DEBUG
#ifdef NR_PRACH_DEBUG
if (NCS>0)
LOG_I(PHY, "PRACH [UE %d] generate PRACH in slot %d for RootSeqIndex %d, Preamble Index %d, PRACH Format %s, NCS %d (N_ZC %d): Preamble_offset %d, Preamble_shift %d msg1 frequency start %d\n",
Mod_id,
slot,
rootSequenceIndex,
preamble_index,
prach_sequence_length == 0 ? prachfmt03[prach_fmt_id] : prachfmt[prach_fmt_id],
prachfmt[prach_fmt_id],
NCS,
N_ZC,
preamble_offset,
@@ -362,31 +361,33 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
} else {
switch (prach_fmt_id) {
case 0: //A1
case 4: //A1
Ncp = 288/(1<<mu);
break;
case 1: //A2
case 5: //A2
Ncp = 576/(1<<mu);
break;
case 2: //A3
case 6: //A3
Ncp = 864/(1<<mu);
break;
case 3: //B1
case 7: //B1
Ncp = 216/(1<<mu);
break;
/*
case 4: //B2
Ncp = 360/(1<<mu);
break;
case 5: //B3
Ncp = 504/(1<<mu);
break;
case 6: //B4
*/
case 8: //B4
Ncp = 936/(1<<mu);
break;
case 7: //C0
case 9: //C0
Ncp = 1240/(1<<mu);
break;
case 8: //C2
case 10: //C2
Ncp = 2048/(1<<mu);
break;
default:
@@ -440,19 +441,19 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
prach_len = (12288*4)+Ncp;
}
} else { // short PRACH sequence
if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) {
Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft(IDFT_2048,prachF,prach2,1);
// here we have |empty | Prach2048 |
if (prach_fmt_id != 7) {
if (prach_fmt_id != 9) {
memmove(prach2+(2048<<1),prach2,(2048<<2));
prach_len = (2048*2)+Ncp;
}
else prach_len = (2048*1)+Ncp;
memmove(prach,prach+(2048<<1),(Ncp<<2));
// here we have |Prefix | Prach2048 | Prach2048 (if ! 0xc0) |
} else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 6x2048
} else if (prach_fmt_id == 5) { // 6x2048
Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft(IDFT_2048,prachF,prach2,1);
@@ -464,7 +465,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
memmove(prach,prach+(2048<<1),(Ncp<<2));
// here we have |Prefix | Prach2048 |
prach_len = (2048*4)+Ncp;
} else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x2048
} else if (prach_fmt_id == 6) { // 6x2048
Ncp+=32;
prach2 = prach+(Ncp<<1);
idft(IDFT_2048,prachF,prach2,1);
@@ -478,7 +479,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
memmove(prach,prach+(2048<<1),(Ncp<<2));
// here we have |Prefix | Prach2048 |
prach_len = (2048*6)+Ncp;
} else if (prach_fmt_id == 6) { // 12x2048
} else if (prach_fmt_id == 8) { // 12x2048
Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft(IDFT_2048,prachF,prach2,1);
@@ -533,12 +534,12 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
prach_len = (9216*4)+Ncp;
}
} else { // short sequence
if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) {
Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft(IDFT_1536,prachF,prach2,1);
// here we have |empty | Prach1536 |
if (prach_fmt_id != 7) {
if (prach_fmt_id != 9) {
memmove(prach2+(1536<<1),prach2,(1536<<2));
prach_len = (1536*2)+Ncp;
} else prach_len = (1536*1)+Ncp;
@@ -546,7 +547,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
memmove(prach,prach+(1536<<1),(Ncp<<2));
// here we have |Prefix | Prach1536 | Prach1536 (if ! 0xc0) |
} else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 6x1536
} else if (prach_fmt_id == 5) { // 6x1536
Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
@@ -559,7 +560,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
memmove(prach,prach+(1536<<1),(Ncp<<2));
// here we have |Prefix | Prach1536 |
prach_len = (1536*4)+Ncp;
} else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x1536
} else if (prach_fmt_id == 6) { // 6x1536
Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft(IDFT_1536,prachF,prach2,1);
@@ -573,7 +574,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
memmove(prach,prach+(1536<<1),(Ncp<<2));
// here we have |Prefix | Prach1536 |
prach_len = (1536*6)+Ncp;
} else if (prach_fmt_id == 6) { // 12x1536
} else if (prach_fmt_id == 8) { // 12x1536
Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft(IDFT_1536,prachF,prach2,1);
@@ -630,18 +631,18 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
prach_len = (24576*4)+Ncp;
}
} else { // short sequence
if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) {
Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft(IDFT_4096,prachF,prach2,1);
// here we have |empty | Prach4096 |
if (prach_fmt_id != 7) {
if (prach_fmt_id != 9) {
memmove(prach2+(4096<<1),prach2,(4096<<2));
prach_len = (4096*2)+Ncp;
} else prach_len = (4096*1)+Ncp;
memmove(prach,prach+(4096<<1),(Ncp<<2));
// here we have |Prefix | Prach4096 | Prach4096 (if ! 0xc0) |
} else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 4x4096
} else if (prach_fmt_id == 5) { // 4x4096
Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft(IDFT_4096,prachF,prach2,1);
@@ -653,7 +654,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
memmove(prach,prach+(4096<<1),(Ncp<<2));
// here we have |Prefix | Prach4096 |
prach_len = (4096*4)+Ncp;
} else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x4096
} else if (prach_fmt_id == 6) { // 6x4096
Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft(IDFT_4096,prachF,prach2,1);
@@ -667,7 +668,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
memmove(prach,prach+(4096<<1),(Ncp<<2));
// here we have |Prefix | Prach4096 |
prach_len = (4096*6)+Ncp;
} else if (prach_fmt_id == 6) { // 12x4096
} else if (prach_fmt_id == 8) { // 12x4096
Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft(IDFT_4096,prachF,prach2,1);
@@ -722,18 +723,18 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
prach_len = (18432*4)+Ncp;
}
} else { // short sequence
if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) {
Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft(IDFT_3072,prachF,prach2,1);
// here we have |empty | Prach3072 |
if (prach_fmt_id != 7) {
if (prach_fmt_id != 9) {
memmove(prach2+(3072<<1),prach2,(3072<<2));
prach_len = (3072*2)+Ncp;
} else prach_len = (3072*1)+Ncp;
memmove(prach,prach+(3072<<1),(Ncp<<2));
// here we have |Prefix | Prach3072 | Prach3072 (if ! 0xc0) |
} else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x3072
} else if (prach_fmt_id == 6) { // 6x3072
Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft(IDFT_3072,prachF,prach2,1);
@@ -747,7 +748,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
memmove(prach,prach+(3072<<1),(Ncp<<2));
// here we have |Prefix | Prach3072 |
prach_len = (3072*6)+Ncp;
} else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 4x3072
} else if (prach_fmt_id == 5) { // 4x3072
Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1);
idft(IDFT_3072,prachF,prach2,1);
+4 -2
View File
@@ -191,9 +191,11 @@ typedef struct {
int fmt;
int numRA;
int prachStartSymbol;
int num_prach_ocas;
} RU_PRACH_list_t;
#define NUMBER_OF_NR_RU_PRACH_MAX 8
#define NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX 12
typedef struct RU_proc_t_s {
/// Pointer to associated RU descriptor
@@ -594,8 +596,8 @@ typedef struct RU_t_s {
RU_PRACH_list_t prach_list[NUMBER_OF_NR_RU_PRACH_MAX];
/// mutex for prach_list access
pthread_mutex_t prach_list_mutex;
/// received frequency-domain signal for PRACH (IF4p5 RRU)
int16_t **prach_rxsigF;
/// received frequency-domain signal for PRACH (IF4p5 RRU)
int16_t **prach_rxsigF[NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX];
/// received frequency-domain signal for PRACH BR (IF4p5 RRU)
int16_t **prach_rxsigF_br[4];
/// sequence number for IF5
+1 -1
View File
@@ -80,7 +80,7 @@ void prach_procedures(PHY_VARS_eNB *eNB,
ru=eNB->RU_list[i];
for (ru_aa=0,aa=0; ru_aa<ru->nb_rx; ru_aa++,aa++) {
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa];
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[0][ru_aa];
int ce_level;
if (br_flag==1)
+92 -65
View File
@@ -52,87 +52,114 @@ extern uint8_t nfapi_mode;
extern int oai_nfapi_nr_rach_ind(nfapi_rach_indication_t *rach_ind);
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot,
nfapi_nr_prach_pdu_t *prach_pdu) {
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) {
uint16_t max_preamble[4]={0},max_preamble_energy[4]={0},max_preamble_delay[4]={0};
uint16_t i;
gNB->UL_INFO.rach_ind.number_of_pdus=0;
uint8_t pdu_index = 0;
RU_t *ru;
int aa=0;
int ru_aa;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1);
gNB->UL_INFO.rach_ind.sfn = frame;
gNB->UL_INFO.rach_ind.slot = slot;
gNB->UL_INFO.rach_ind.pdu_list = gNB->prach_pdu_indication_list;
gNB->UL_INFO.rach_ind.number_of_pdus = 0;
ru=gNB->RU_list[0];
int prach_id=find_nr_prach(gNB,frame,slot,SEARCH_EXIST);
if (prach_id>=0) {
nfapi_nr_prach_pdu_t *prach_pdu = &gNB->prach_vars.list[prach_id].pdu;
uint8_t prachStartSymbol;
uint8_t N_dur = get_nr_prach_duration(prach_pdu->prach_format);
/*
uint16_t format,RA_sfn_index;
uint8_t start_symbol,N_t_slot,N_dur,N_RA_slot,config_period;
for (i=0;i<gNB->num_RU;i++) {
ru=gNB->RU_list[i];
for (ru_aa=0,aa=0;ru_aa<ru->nb_rx;ru_aa++,aa++) {
gNB->prach_vars.rxsigF[aa] = gNB->RU_list[i]->prach_rxsigF[ru_aa];
}
}
get_nr_prach_info_from_index(gNB->gNB_config.prach_config.prach_ConfigurationIndex.value,
frame,slot,
gNB->gNB_config.carrier_config.dl_frequency.value,
gNB->frame_parms.numerology_index,
gNB->frame_parms.frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur,
&RA_sfn_index,
&N_RA_slot,
&config_period);
*/
for(int prach_oc = 0; prach_oc < prach_pdu->num_prach_ocas; prach_oc++) {
for (ru_aa=0,aa=0;ru_aa<ru->nb_rx;ru_aa++,aa++) {
gNB->prach_vars.rxsigF[aa] = ru->prach_rxsigF[prach_oc][ru_aa];
}
rx_nr_prach(gNB,
prach_pdu,
prachStartSymbol = prach_pdu->prach_start_symbol+prach_oc*N_dur;
//comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}.
rx_nr_prach(gNB,
prach_pdu,
prach_oc,
frame,
slot,
&max_preamble[0],
&max_preamble_energy[0],
&max_preamble_delay[0]
);
free_nr_prach_entry(gNB,prach_id);
LOG_D(PHY,"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n",
frame,slot,prach_oc,prachStartSymbol,
max_preamble[0],
max_preamble_energy[0]/10,
max_preamble_delay[0],
gNB->prach_energy_counter);
if ((gNB->prach_energy_counter == 100) &&
(max_preamble_energy[0] > gNB->measurements.prach_I0+100)) {
LOG_I(PHY,"[gNB %d][RAPROC] Frame %d, slot %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d start symbol %u freq index %u\n",
gNB->Mod_id,
frame,
slot,
&max_preamble[0],
&max_preamble_energy[0],
&max_preamble_delay[0]
);
LOG_D(PHY,"[RAPROC] Frame %d, slot %d : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n",
frame,slot,
max_preamble[0],
max_preamble_energy[0]/10,
max_preamble_delay[0],
gNB->prach_energy_counter);
if ((gNB->prach_energy_counter == 100) &&
(max_preamble_energy[0] > gNB->measurements.prach_I0+100)) {
LOG_I(PHY,"[gNB %d][RAPROC] Frame %d, slot %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n",
gNB->Mod_id,
frame,
slot,
max_preamble[0],
max_preamble_energy[0]/10,
max_preamble_energy[0]%10,
max_preamble_delay[0]);
T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(gNB->Mod_id), T_INT(frame), T_INT(slot),
T_INT(max_preamble[0]), T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0]));
gNB->UL_INFO.rach_ind.number_of_pdus = 1;
gNB->UL_INFO.rach_ind.pdu_list = &gNB->prach_pdu_indication_list[0];
gNB->UL_INFO.rach_ind.sfn = frame;
gNB->UL_INFO.rach_ind.slot = slot;
gNB->prach_pdu_indication_list[0].phy_cell_id = gNB->gNB_config.cell_config.phy_cell_id.value;
gNB->prach_pdu_indication_list[0].symbol_index = prach_pdu->prach_start_symbol; // FIXME to be changed for multi-ssb (this is only the start symbol of first occasion)
gNB->prach_pdu_indication_list[0].slot_index = slot;
gNB->prach_pdu_indication_list[0].freq_index = prach_pdu->num_ra;
gNB->prach_pdu_indication_list[0].avg_rssi = (max_preamble_energy[0]<631) ? (128+(max_preamble_energy[0]/5)) : 254;
gNB->prach_pdu_indication_list[0].avg_snr = 0xff; // invalid for now
gNB->prach_pdu_indication_list[0].num_preamble = 1;
gNB->prach_pdu_indication_list[0].preamble_list = gNB->preamble_list;
gNB->prach_pdu_indication_list[0].preamble_list[0].preamble_index = max_preamble[0];
gNB->prach_pdu_indication_list[0].preamble_list[0].timing_advance = max_preamble_delay[0];
gNB->prach_pdu_indication_list[0].preamble_list[0].preamble_pwr = 0xffffffff;
}
gNB->measurements.prach_I0 = ((gNB->measurements.prach_I0*900)>>10) + ((max_preamble_energy[0]*124)>>10);
if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10);
if (gNB->prach_energy_counter < 100) gNB->prach_energy_counter++;
max_preamble[0],
max_preamble_energy[0]/10,
max_preamble_energy[0]%10,
max_preamble_delay[0],
prachStartSymbol,
prach_pdu->num_ra);
T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(gNB->Mod_id), T_INT(frame), T_INT(slot),
T_INT(max_preamble[0]), T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0]));
gNB->UL_INFO.rach_ind.number_of_pdus += 1;
gNB->prach_pdu_indication_list[pdu_index].phy_cell_id = gNB->gNB_config.cell_config.phy_cell_id.value;
gNB->prach_pdu_indication_list[pdu_index].symbol_index = prachStartSymbol;
gNB->prach_pdu_indication_list[pdu_index].slot_index = slot;
gNB->prach_pdu_indication_list[pdu_index].freq_index = prach_pdu->num_ra;
gNB->prach_pdu_indication_list[pdu_index].avg_rssi = (max_preamble_energy[0]<631) ? (128+(max_preamble_energy[0]/5)) : 254;
gNB->prach_pdu_indication_list[pdu_index].avg_snr = 0xff; // invalid for now
gNB->prach_pdu_indication_list[pdu_index].num_preamble = 1;
gNB->prach_pdu_indication_list[pdu_index].preamble_list = gNB->preamble_list;
gNB->prach_pdu_indication_list[pdu_index].preamble_list[0].preamble_index = max_preamble[0];
gNB->prach_pdu_indication_list[pdu_index].preamble_list[0].timing_advance = max_preamble_delay[0];
gNB->prach_pdu_indication_list[pdu_index].preamble_list[0].preamble_pwr = 0xffffffff;
pdu_index++;
}
gNB->measurements.prach_I0 = ((gNB->measurements.prach_I0*900)>>10) + ((max_preamble_energy[0]*124)>>10);
if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10);
if (gNB->prach_energy_counter < 100) gNB->prach_energy_counter++;
} //if prach_id>0
} //for NUMBER_OF_NR_PRACH_OCCASION_MAX
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0);
}
+1 -1
View File
@@ -39,7 +39,7 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_meas);
void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_prach_pdu_t *prach_pdu);
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot);
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot);
void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx);
void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx);
+57 -56
View File
@@ -113,6 +113,10 @@ int main(int argc, char **argv){
uint16_t Nid_cell = 0, preamble_tx = 0, preamble_delay, format, format0, format1;
uint32_t tx_lev = 10000, prach_errors = 0, samp_count; //,tx_lev_dB;
uint64_t SSB_positions = 0x01, absoluteFrequencyPointA = 640000;
uint16_t RA_sfn_index;
uint8_t N_RA_slot;
uint8_t config_period;
int prachOccasion = 0;
double DS_TDL = .03;
// int8_t interf1=-19,interf2=-19;
@@ -428,15 +432,18 @@ int main(int argc, char **argv){
gNB->proc.slot_rx = slot;
int ret = get_nr_prach_info_from_index(config_index,
(int)frame,
(int)slot_gNB,
absoluteFrequencyPointA,
mu,
frame_parms->frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur);
(int)frame,
(int)slot_gNB,
absoluteFrequencyPointA,
mu,
frame_parms->frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur,
&RA_sfn_index,
&N_RA_slot,
&config_period);
if (ret == 0) {printf("No prach in %d.%d, mu %d, config_index %d\n",frame,slot,mu,config_index); exit(-1);}
format0 = format&0xff; // first column of format from table
@@ -445,60 +452,54 @@ int main(int argc, char **argv){
if (format1 != 0xff) {
switch(format0) {
case 0xa1:
prach_format = 9;
prach_format = 11;
break;
case 0xa2:
prach_format = 10;
prach_format = 12;
break;
case 0xa3:
prach_format = 11;
prach_format = 13;
break;
default:
AssertFatal(1==0, "Only formats A1/B1 A2/B2 A3/B3 are valid for dual format");
}
} else {
switch(format0) {
case 0xa1:
prach_format = 0;
break;
case 0xa2:
prach_format = 1;
break;
case 0xa3:
prach_format = 2;
break;
case 0xb1:
prach_format = 3;
break;
case 0xb2:
prach_format = 4;
break;
case 0xb3:
prach_format = 5;
break;
case 0xb4:
prach_format = 6;
break;
case 0xc0:
prach_format = 7;
break;
case 0xc2:
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;
switch(format0) { // single PRACH format
case 0:
prach_format = 0;
break;
case 1:
prach_format = 1;
break;
case 2:
prach_format = 2;
break;
case 3:
prach_format = 3;
break;
case 0xa1:
prach_format = 4;
break;
case 0xa2:
prach_format = 5;
break;
case 0xa3:
prach_format = 6;
break;
case 0xb1:
prach_format = 7;
break;
case 0xb4:
prach_format = 8;
break;
case 0xc0:
prach_format = 9;
break;
case 0xc2:
prach_format = 10;
break;
default:
AssertFatal(1==0, "Invalid PRACH format");
AssertFatal(1 == 0, "Invalid PRACH format");
}
}
@@ -721,11 +722,11 @@ int main(int argc, char **argv){
}
rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, frame, slot);
rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, prachOccasion, frame, slot);
gNB->prach_vars.rxsigF = ru->prach_rxsigF;
gNB->prach_vars.rxsigF = ru->prach_rxsigF[prachOccasion];
if (n_frames == 1) printf("ncs %d,num_seq %d\n",prach_pdu->num_cs, prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value);
rx_nr_prach(gNB, prach_pdu, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay);
rx_nr_prach(gNB, prach_pdu, prachOccasion, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay);
// printf(" preamble_energy %d preamble_rx %d preamble_tx %d \n", preamble_energy, preamble_rx, preamble_tx);
+1 -1
View File
@@ -153,7 +153,7 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) {
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon = CALLOC(1,sizeof(NR_SetupRelease_RACH_ConfigCommon_t));
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->present = NR_SetupRelease_RACH_ConfigCommon_PR_setup;
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_RACH_ConfigCommon));
// scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles = CALLOC(1,sizeof(long));
// scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles = CALLOC(1,sizeof(long));
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB = CALLOC(1,sizeof(struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB));
// scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->groupBconfigured = CALLOC(1,sizeof(struct NR_RACH_ConfigCommon__groupBconfigured));
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB = CALLOC(1,sizeof(NR_RSRP_Range_t));
+283 -35
View File
@@ -48,8 +48,7 @@ uint16_t NCS_restricted_TypeB_delta_f_RA_5[14] = {36,57,60,63,65,68,71,77,81,8
// Table 6.3.3.1-7 (38.211) NCS for preamble formats with delta_f_RA = 15 * 2mu KHz where mu = {0,1,2,3}
uint16_t NCS_unrestricted_delta_f_RA_15[16] = {0,2,4,6,8,10,12,13,15,17,19,23,27,34,46,69};
const char *prachfmt[]={"A1","A2","A3","B1","B2","B3","B4","C0","C2"};
const char *prachfmt03[]={"0","1","2","3"};
const char *prachfmt[]={"0","1","2","3", "A1","A2","A3","B1","B4","C0","C2","A1/B1","A2/B2","A3/B3"};
uint16_t get_NCS(uint8_t index, uint16_t format0, uint8_t restricted_set_config) {
@@ -86,7 +85,71 @@ uint16_t get_NCS(uint8_t index, uint16_t format0, uint8_t restricted_set_config)
}
}
//38.211 Table 6.3.3.2-1
int16_t table_6_3_3_2_1[16][5] = {
//Length_RA, delta_f_RA_PRACH, delta_f_PUSCH, N_RA_RB, kbar
{ 839, 1.25, 15, 6, 7},
{ 839, 1.25, 30, 3, 1},
{ 839, 1.25, 60, 2, 133},
{ 839, 5, 15, 24, 12},
{ 839, 5, 30, 12, 10},
{ 839, 5, 60, 6, 7},
{ 139, 15, 15, 12, 2},
{ 139, 15, 30, 6, 2},
{ 139, 15, 60, 3, 2},
{ 139, 30, 15, 24, 2},
{ 139, 30, 30, 12, 2},
{ 139, 30, 60, 6, 2},
{ 139, 60, 60, 12, 2},
{ 139, 60, 120, 6, 2},
{ 139, 120, 60, 24, 2},
{ 139, 120, 120, 12, 2}
};
/* Function to get number of RBs required for prach occasion based on
* 38.211 Table 6.3.3.2-1 */
int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH) {
int8_t index = 0;
switch(delta_f_RA_PRACH) {
case 0 : index = 6;
if (delta_f_PUSCH == 0)
index += 0;
else if(delta_f_PUSCH == 1)
index += 1;
else
index += 2;
break;
case 1 : index = 9;
if (delta_f_PUSCH == 0)
index += 0;
else if(delta_f_PUSCH == 1)
index += 1;
else
index += 2;
break;
case 2 : index = 11;
if (delta_f_PUSCH == 2)
index += 0;
else
index += 1;
break;
case 3: index = 13;
if (delta_f_PUSCH == 2)
index += 0;
else
index += 1;
break;
default : index = 10;/*30khz prach scs and 30khz pusch scs*/
}
return table_6_3_3_2_1[index][3];
}
// Table 6.3.3.2-2: Random access configurations for FR1 and paired spectrum/supplementary uplink
// the column 5, (SFN_nbr is a bitmap where we set bit to '1' in the position of the subframe where the RACH can be sent.
// E.g. in row 4, and column 5 we have set value 512 ('1000000000') which means RACH can be sent at subframe 9.
@@ -955,6 +1018,162 @@ void find_monitoring_periodicity_offset_common(NR_SearchSpace_t *ss,
}
}
int get_nr_prach_occasion_info_from_index(uint8_t index,
uint32_t pointa,
uint8_t mu,
uint8_t unpaired,
uint16_t *format,
uint8_t *start_symbol,
uint8_t *N_t_slot,
uint8_t *N_dur,
uint8_t *N_RA_slot,
uint16_t *N_RA_sfn,
uint8_t *max_association_period) {
int x;
int64_t s_map;
uint8_t format2 = 0xff;
if (pointa > 2016666) { //FR2
x = table_6_3_3_2_4_prachConfig_Index[index][2];
s_map = table_6_3_3_2_4_prachConfig_Index[index][5];
for(int i = 0; i < 64 ;i++) {
if ( (s_map >> i) & 0x01) {
(*N_RA_sfn)++;
}
}
*N_RA_slot = table_6_3_3_2_4_prachConfig_Index[index][7]; // Number of RACH slots within a subframe
*max_association_period = 160/(x * 10);
if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
*start_symbol = table_6_3_3_2_4_prachConfig_Index[index][6];//multiple prach occasions in diff slot
*N_t_slot = table_6_3_3_2_4_prachConfig_Index[index][8];
*N_dur = table_6_3_3_2_4_prachConfig_Index[index][9];
if (table_6_3_3_2_4_prachConfig_Index[index][1] != -1)
format2 = (uint8_t) table_6_3_3_2_4_prachConfig_Index[index][1];
*format = ((uint8_t) table_6_3_3_2_4_prachConfig_Index[index][0]) | (format2<<8);
LOG_D(MAC,"Getting Total PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u N_RA_sfn = %u\n",
index,
pointa,
mu,
unpaired,
*start_symbol,
*N_t_slot,
*N_dur,
*N_RA_sfn);
}
return 1;
}
else {
if (unpaired) {
x = table_6_3_3_2_3_prachConfig_Index[index][2];
s_map = table_6_3_3_2_3_prachConfig_Index[index][4];
for(int i = 0; i < 64 ;i++) {
if ( (s_map >> i) & 0x01) {
(*N_RA_sfn)++;
}
}
*N_RA_slot = table_6_3_3_2_3_prachConfig_Index[index][6]; // Number of RACH slots within a subframe
*max_association_period = 160/(x * 10);
if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
*start_symbol = table_6_3_3_2_3_prachConfig_Index[index][5];
*N_t_slot = table_6_3_3_2_3_prachConfig_Index[index][7];
*N_dur = table_6_3_3_2_3_prachConfig_Index[index][8];
if (table_6_3_3_2_3_prachConfig_Index[index][1] != -1)
format2 = (uint8_t) table_6_3_3_2_3_prachConfig_Index[index][1];
*format = ((uint8_t) table_6_3_3_2_3_prachConfig_Index[index][0]) | (format2<<8);
LOG_I(MAC,"Getting Total PRACH info from index %d (col %lu ) absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u N_RA_sfn = %u\n",
index, table_6_3_3_2_3_prachConfig_Index[index][6],
pointa,
mu,
unpaired,
*start_symbol,
*N_t_slot,
*N_dur,
*N_RA_sfn);
}
return 1;
}
else { // FDD
x = table_6_3_3_2_2_prachConfig_Index[index][2];
s_map = table_6_3_3_2_2_prachConfig_Index[index][4];
*N_RA_slot = table_6_3_3_2_2_prachConfig_Index[index][6];
if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
*start_symbol = table_6_3_3_2_2_prachConfig_Index[index][5];
*N_t_slot = table_6_3_3_2_2_prachConfig_Index[index][7];
*N_dur = table_6_3_3_2_2_prachConfig_Index[index][8];
if (table_6_3_3_2_2_prachConfig_Index[index][1] != -1)
format2 = (uint8_t) table_6_3_3_2_2_prachConfig_Index[index][1];
*format = ((uint8_t) table_6_3_3_2_2_prachConfig_Index[index][0]) | (format2<<8);
LOG_D(MAC,"Getting Total PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n",
index,
pointa,
mu,
unpaired,
*start_symbol,
*N_t_slot,
*N_dur);
}
return 1;
}
}
}
uint8_t get_nr_prach_duration(uint8_t prach_format){
switch(prach_format){
case 0: // format 0
return 0;
case 1: // format 1
return 0;
case 2: // format 2
return 0;
case 3: // format 3
return 0;
case 4: // format A1
return 2;
case 5: // format A2
return 4;
case 6: // format A3
return 6;
case 7: // format B1
return 2;
case 8: // format B4
return 12;
case 9: // format C0
return 2;
case 10: // format C2
return 6;
case 11: // format A1/B1
return 2;
case 12: // format A2/B2
return 4;
case 13: // format A3/B3
return 6;
default :
AssertFatal(1==0,"Invalid Prach format\n");
break;
}
}
int get_nr_prach_info_from_index(uint8_t index,
int frame,
int slot,
@@ -964,7 +1183,10 @@ int get_nr_prach_info_from_index(uint8_t index,
uint16_t *format,
uint8_t *start_symbol,
uint8_t *N_t_slot,
uint8_t *N_dur) {
uint8_t *N_dur,
uint16_t *RA_sfn_index,
uint8_t *N_RA_slot,
uint8_t *config_period) {
int x,y;
int64_t s_map;
@@ -980,27 +1202,39 @@ int get_nr_prach_info_from_index(uint8_t index,
if ( (frame%x)==y || (frame%x)==y2 ) {
slot_60khz = slot >> (mu-2); // in table slots are numbered wrt 60kHz
s_map = table_6_3_3_2_4_prachConfig_Index[index][5];
if ((s_map >> slot_60khz) & 0x01 ) {
for(int i = 0; i <= slot_60khz ;i++) {
if ( (s_map >> i) & 0x01) {
(*RA_sfn_index)++;
}
}
}
if ( ((s_map>>slot_60khz)&0x01) ) {
*N_RA_slot = table_6_3_3_2_4_prachConfig_Index[index][7]; // Number of RACH slots within a subframe
if (mu == 3) {
if ( (table_6_3_3_2_4_prachConfig_Index[index][7] == 1) && (slot%2 == 0) )
if ( (*N_RA_slot == 1) && (slot%2 == 0) )
return 0; // no prach in even slots @ 120kHz for 1 prach per 60khz slot
}
if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
*config_period = x;
*start_symbol = table_6_3_3_2_4_prachConfig_Index[index][6];
*N_t_slot = table_6_3_3_2_4_prachConfig_Index[index][8];
*N_dur = table_6_3_3_2_4_prachConfig_Index[index][9];
if (table_6_3_3_2_4_prachConfig_Index[index][1] != -1)
format2 = (uint8_t) table_6_3_3_2_4_prachConfig_Index[index][1];
*format = ((uint8_t) table_6_3_3_2_4_prachConfig_Index[index][0]) | (format2<<8);
LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n", frame,
slot,
index,
pointa,
mu,
unpaired,
*start_symbol,
*N_t_slot,
*N_dur);
LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u N_RA_slot %u RA_sfn_index %u\n",
frame,
slot,
index,
pointa,
mu,
unpaired,
*start_symbol,
*N_t_slot,
*N_dur,
*N_RA_slot,
*RA_sfn_index);
}
return 1;
}
@@ -1018,27 +1252,40 @@ int get_nr_prach_info_from_index(uint8_t index,
if ( (frame%x)==y ) {
subframe = slot >> mu;
s_map = table_6_3_3_2_3_prachConfig_Index[index][4];
if ( (s_map>>subframe)&0x01 ) {
if (mu == 1) {
if ( (table_6_3_3_2_3_prachConfig_Index[index][6] <= 1) && (slot%2 == 0) )
return 0; // no prach in even slots @ 30kHz for 1 prach per subframe
if ((s_map >> subframe) & 0x01 ) {
for(int i = 0; i <= subframe ;i++) {
if ( (s_map >> i) & 0x01) {
(*RA_sfn_index)++;
}
}
}
if ( (s_map>>subframe)&0x01 ) {
*N_RA_slot = table_6_3_3_2_3_prachConfig_Index[index][6]; // Number of RACH slots within a subframe
if (mu == 1) {
if ( (*N_RA_slot <= 1) && (slot%2 == 0) )
return 0; // no prach in even slots @ 30kHz for 1 prach per subframe
}
if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
*config_period = x;
*start_symbol = table_6_3_3_2_3_prachConfig_Index[index][5];
*N_t_slot = table_6_3_3_2_3_prachConfig_Index[index][7];
*N_dur = table_6_3_3_2_3_prachConfig_Index[index][8];
if (table_6_3_3_2_3_prachConfig_Index[index][1] != -1)
format2 = (uint8_t) table_6_3_3_2_3_prachConfig_Index[index][1];
*format = ((uint8_t) table_6_3_3_2_3_prachConfig_Index[index][0]) | (format2<<8);
LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d (col 6 %ld) absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n", frame,
slot,
index, table_6_3_3_2_3_prachConfig_Index[index][6],
pointa,
mu,
unpaired,
*start_symbol,
*N_t_slot,
*N_dur);
LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d (col 6 %lu) absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u N_RA_slot %u RA_sfn_index %u \n",
frame,
slot,
index,
table_6_3_3_2_3_prachConfig_Index[index][6],
pointa,
mu,
unpaired,
*start_symbol,
*N_t_slot,
*N_dur,
*N_RA_slot,
*RA_sfn_index);
}
return 1;
}
@@ -1066,15 +1313,16 @@ int get_nr_prach_info_from_index(uint8_t index,
if (table_6_3_3_2_2_prachConfig_Index[index][1] != -1)
format2 = (uint8_t) table_6_3_3_2_2_prachConfig_Index[index][1];
*format = ((uint8_t) table_6_3_3_2_2_prachConfig_Index[index][0]) | (format2<<8);
LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n", frame,
slot,
index,
pointa,
mu,
unpaired,
*start_symbol,
*N_t_slot,
*N_dur);
LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n",
frame,
slot,
index,
pointa,
mu,
unpaired,
*start_symbol,
*N_t_slot,
*N_dur);
}
return 1;
}
+19 -1
View File
@@ -99,7 +99,24 @@ int get_nr_prach_info_from_index(uint8_t index,
uint16_t *format,
uint8_t *start_symbol,
uint8_t *N_t_slot,
uint8_t *N_dur);
uint8_t *N_dur,
uint16_t *RA_sfn_index,
uint8_t *N_RA_slot,
uint8_t *config_period);
int get_nr_prach_occasion_info_from_index(uint8_t index,
uint32_t pointa,
uint8_t mu,
uint8_t unpaired,
uint16_t *format,
uint8_t *start_symbol,
uint8_t *N_t_slot,
uint8_t *N_dur,
uint8_t *N_RA_slot,
uint16_t *N_RA_sfn,
uint8_t *max_association_period);
uint8_t get_nr_prach_duration(uint8_t prach_format);
uint8_t get_pusch_mcs_table(long *mcs_Table,
int is_tp,
@@ -125,4 +142,5 @@ int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmr
uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint8_t mcs_table);
uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB);
int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH);
#endif
+23 -23
View File
@@ -1073,6 +1073,9 @@ void nr_ue_msg3_scheduler(NR_UE_MAC_INST_t *mac,
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 RA_sfn_index;
uint8_t N_RA_slot;
uint8_t config_period;
uint16_t format, format0, format1, ncs;
int msg1_FDM, is_nr_prach_slot, fdm;
@@ -1109,7 +1112,10 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
&format,
&start_symbol,
&N_t_slot,
&N_dur);
&N_dur,
&RA_sfn_index,
&N_RA_slot,
&config_period);
if (is_nr_prach_slot && mac->ra_state == RA_UE_IDLE) {
@@ -1156,57 +1162,51 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
if (format1 != 0xff) {
switch(format0) { // dual PRACH format
case 0xa1:
prach_config_pdu->prach_format = 9;
prach_config_pdu->prach_format = 11;
break;
case 0xa2:
prach_config_pdu->prach_format = 10;
prach_config_pdu->prach_format = 12;
break;
case 0xa3:
prach_config_pdu->prach_format = 11;
prach_config_pdu->prach_format = 13;
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:
case 0:
prach_config_pdu->prach_format = 0;
break;
case 0xa2:
case 1:
prach_config_pdu->prach_format = 1;
break;
case 0xa3:
case 2:
prach_config_pdu->prach_format = 2;
break;
case 0xb1:
case 3:
prach_config_pdu->prach_format = 3;
break;
case 0xb2:
case 0xa1:
prach_config_pdu->prach_format = 4;
break;
case 0xb3:
case 0xa2:
prach_config_pdu->prach_format = 5;
break;
case 0xb4:
case 0xa3:
prach_config_pdu->prach_format = 6;
break;
case 0xc0:
case 0xb1:
prach_config_pdu->prach_format = 7;
break;
case 0xc2:
case 0xb4:
prach_config_pdu->prach_format = 8;
break;
case 0:
// long formats are handled @ PHY
case 0xc0:
prach_config_pdu->prach_format = 9;
break;
case 1:
// long formats are handled @ PHY
break;
case 2:
// long formats are handled @ PHY
break;
case 3:
// long formats are handled @ PHY
case 0xc2:
prach_config_pdu->prach_format = 10;
break;
default:
AssertFatal(1 == 0, "Invalid PRACH format");
+20 -6
View File
@@ -150,6 +150,10 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
cfg->ssb_config.ss_pbch_power.tl.tag = NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG;
cfg->num_tlv++;
cfg->ssb_config.bch_payload.value = 1;
cfg->ssb_config.bch_payload.tl.tag = NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG;
cfg->num_tlv++;
cfg->ssb_config.scs_common.value = *scc->ssbSubcarrierSpacing;
cfg->ssb_config.scs_common.tl.tag = NFAPI_NR_CONFIG_SCS_COMMON_TAG;
cfg->num_tlv++;
@@ -173,6 +177,9 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
cfg->prach_config.restricted_set_config.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig;
cfg->prach_config.restricted_set_config.tl.tag = NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG;
cfg->num_tlv++;
cfg->prach_config.prach_ConfigurationIndex.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
cfg->prach_config.prach_ConfigurationIndex.tl.tag = NFAPI_NR_CONFIG_PRACH_CONFIG_INDEX_TAG;
cfg->num_tlv++;
switch (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM) {
case 0 :
@@ -193,26 +200,30 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
cfg->prach_config.num_prach_fd_occasions.tl.tag = NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG;
cfg->num_tlv++;
cfg->prach_config.prach_ConfigurationIndex.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
cfg->prach_config.prach_ConfigurationIndex.tl.tag = NFAPI_NR_CONFIG_PRACH_CONFIG_INDEX_TAG;
cfg->num_tlv++;
cfg->prach_config.num_prach_fd_occasions_list = (nfapi_nr_num_prach_fd_occasions_t *) malloc(cfg->prach_config.num_prach_fd_occasions.value*sizeof(nfapi_nr_num_prach_fd_occasions_t));
for (i=0; i<cfg->prach_config.num_prach_fd_occasions.value; i++) {
cfg->prach_config.num_prach_fd_occasions_list[i].num_prach_fd_occasions = i;
// cfg->prach_config.num_prach_fd_occasions_list[i].num_prach_fd_occasions = i;
if (cfg->prach_config.prach_sequence_length.value)
cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139;
else
cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l839;
cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index.tl.tag = NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG;
cfg->num_tlv++;
cfg->prach_config.num_prach_fd_occasions_list[i].k1.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart;
cfg->prach_config.num_prach_fd_occasions_list[i].k1.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB( cfg->prach_config.prach_sub_c_spacing.value, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i);
//k1= msg1_FrequencyStart + 12 (no. of FDM)(RB for PRACH occasion);
cfg->prach_config.num_prach_fd_occasions_list[i].k1.tl.tag = NFAPI_NR_CONFIG_K1_TAG;
cfg->num_tlv++;
cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf.tl.tag = NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG;
cfg->num_tlv++;
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences.value = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup,
nb_preambles, frame_type);
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences.value = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup,nb_preambles, frame_type);
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences.tl.tag = NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG;
cfg->num_tlv++;
//cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences.value = ???
cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences.value = 1;
}
cfg->prach_config.ssb_per_rach.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1;
@@ -344,7 +355,10 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
phycfg.cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG;
phycfg.cfg->num_tlv++;
if (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req) RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req(&phycfg);
if (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req) RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req(&phycfg);
find_SSB_and_RO_available(Mod_idP);
}
if (secondaryCellGroup) {
+313 -126
View File
@@ -46,121 +46,295 @@ extern const uint8_t nr_slots_per_frame[5];
uint8_t DELTA[4]= {2,3,4,6};
#define MAX_NUMBER_OF_SSB 64
float ssb_per_rach_occasion[8] = {0.125,0.25,0.5,1,2,4,8};
int16_t ssb_index_from_prach(module_id_t module_idP,
frame_t frameP,
sub_frame_t slotP,
uint16_t preamble_index,
uint8_t freq_index,
uint8_t symbol) {
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &gNB->common_channels[0];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
uint8_t total_RApreambles = 64;
if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value];
uint16_t start_symbol_index = 0;
uint8_t mu,N_dur,N_t_slot,start_symbol = 0, temp_start_symbol = 0, N_RA_slot;
uint16_t format,RA_sfn_index = -1;
uint8_t config_period = 1;
uint16_t prach_occasion_id = -1;
uint8_t num_active_ssb = cc->num_active_ssb;
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
else
mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
get_nr_prach_info_from_index(config_index,
(int)frameP,
(int)slotP,
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
mu,
cc->frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur,
&RA_sfn_index,
&N_RA_slot,
&config_period);
uint8_t index = 0,slot_index = 0;
for (slot_index = 0;slot_index < N_RA_slot; slot_index++) {
if (N_RA_slot <= 1) { //1 PRACH slot in a subframe
if((mu == 1) || (mu == 3))
slot_index = 1; //For scs = 30khz and 120khz
}
for (int i=0; i< N_t_slot; i++) {
temp_start_symbol = (start_symbol + i * N_dur + 14 * slot_index) % 14;
if(symbol == temp_start_symbol) {
start_symbol_index = i;
break;
}
}
}
if (N_RA_slot <= 1) { //1 PRACH slot in a subframe
if((mu == 1) || (mu == 3))
slot_index = 0; //For scs = 30khz and 120khz
}
// prach_occasion_id = subframe_index * N_t_slot * N_RA_slot * fdm + N_RA_slot_index * N_t_slot * fdm + freq_index + fdm * start_symbol_index;
prach_occasion_id = (((frameP % (cc->max_association_period * config_period))/config_period)*cc->total_prach_occasions_per_config_period) + (RA_sfn_index + slot_index) * N_t_slot * fdm + start_symbol_index * fdm + freq_index;
//one RO is shared by one or more SSB
if(num_ssb_per_RO <= 1 )
index = (int) (prach_occasion_id / (int)(1/num_ssb_per_RO)) % num_active_ssb;
//one SSB have more than one continuous RO
else if ( num_ssb_per_RO > 1) {
index = (prach_occasion_id * (int)num_ssb_per_RO)% num_active_ssb ;
for(int j = 0;j < num_ssb_per_RO;j++) {
if(preamble_index < (((j+1) * total_RApreambles) / num_ssb_per_RO))
index = index + j;
}
}
LOG_D(MAC, "Frame %d, Slot %d: Prach Occasion id = %d ssb per RO = %f number of active SSB %u index = %d fdm %u symbol index %u freq_index %u total_RApreambles %u\n", frameP, slotP, prach_occasion_id, num_ssb_per_RO, num_active_ssb, index, fdm, start_symbol_index, freq_index, total_RApreambles);
return index;
}
//Compute Total active SSBs and RO available
void find_SSB_and_RO_available(module_id_t module_idP) {
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &gNB->common_channels[0];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
uint8_t mu,N_dur,N_t_slot,start_symbol,N_RA_slot = 0;
uint16_t format,N_RA_sfn = 0,unused_RA_occasion,repetition = 0;
uint8_t num_active_ssb = 0;
uint8_t max_association_period = 1;
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
else
mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
// prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4
get_nr_prach_occasion_info_from_index(config_index,
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
mu,
cc->frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur,
&N_RA_slot,
&N_RA_sfn,
&max_association_period);
float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value];
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
uint64_t L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[0].ssb_mask.value)<<32) | cfg->ssb_table.ssb_mask_list[1].ssb_mask.value ;
uint32_t total_RA_occasions = N_RA_sfn * N_t_slot * N_RA_slot * fdm;
for(int i = 0;i < 64;i++) {
if ((L_ssb >> (63-i)) & 0x01) { // only if the bit of L_ssb at current ssb index is 1
cc->ssb_index[num_active_ssb] = i;
num_active_ssb++;
}
}
for(int i = 1; (1 << (i-1)) <= max_association_period;i++) {
if(total_RA_occasions >= (int) (num_active_ssb/num_ssb_per_RO)) {
repetition = (uint16_t)((total_RA_occasions * num_ssb_per_RO )/num_active_ssb);
break;
}
else {
total_RA_occasions = total_RA_occasions * i;
cc->max_association_period = i;
}
}
if(cc->max_association_period == 0)
cc->max_association_period = 1;
unused_RA_occasion = total_RA_occasions - (int)((num_active_ssb * repetition)/num_ssb_per_RO);
cc->total_prach_occasions = total_RA_occasions - unused_RA_occasion;
cc->num_active_ssb = num_active_ssb;
LOG_I(MAC, "Total available RO %d, num of active SSB %d: unused RO = %d max_association_period %u N_RA_sfn %u \n", cc->total_prach_occasions, cc->num_active_ssb, unused_RA_occasion, max_association_period, N_RA_sfn);
}
void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = gNB->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req[0];
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
if (is_nr_UL_slot(scc,slotP)) {
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
uint8_t mu,N_dur,N_t_slot,start_symbol = 0,N_RA_slot;
uint16_t RA_sfn_index = -1;
uint8_t config_period = 1;
uint16_t format;
int slot_index = 0;
uint16_t prach_occasion_id = -1;
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
uint8_t mu,N_dur,N_t_slot,start_symbol;
uint16_t format;
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
else
mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
else
mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
// prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4
if ( get_nr_prach_info_from_index(config_index,
(int)frameP,
(int)slotP,
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
mu,
cc->frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur,
&RA_sfn_index,
&N_RA_slot,
&config_period) ) {
uint16_t format0 = format&0xff; // first column of format from table
uint16_t format1 = (format>>8)&0xff; // second column of format from table
// prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4
if ( get_nr_prach_info_from_index(config_index,
(int)frameP,
(int)slotP,
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
mu,
cc->frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur) ) {
if (N_RA_slot > 1) { //more than 1 PRACH slot in a subframe
if (slotP%2 == 1){
slot_index = 1;
}
else {
slot_index = 0;
}
}else if (N_RA_slot <= 1) { //1 PRACH slot in a subframe
slot_index = 0;
}
int fdm = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM;
uint16_t format0 = format&0xff; // first column of format from table
uint16_t format1 = (format>>8)&0xff; // second column of format from table
UL_tti_req->SFN = frameP;
UL_tti_req->Slot = slotP;
for (int n=0; n<(1<<fdm); n++) { // one structure per frequency domain occasion
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t);
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].prach_pdu;
memset(prach_pdu,0,sizeof(nfapi_nr_prach_pdu_t));
UL_tti_req->n_pdus+=1;
UL_tti_req->SFN = frameP;
UL_tti_req->Slot = slotP;
for (int fdm_index=0; fdm_index < fdm; fdm_index++) { // one structure per frequency domain occasion
for (int td_index=0; td_index<N_t_slot; td_index++) {
// filling the prach fapi structure
prach_pdu->phys_cell_id = *scc->physCellId;
prach_pdu->num_prach_ocas = N_t_slot;
prach_pdu->prach_start_symbol = start_symbol;
prach_pdu->num_ra = n;
prach_pdu->num_cs = get_NCS(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig,
format0,
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig);
// SCF PRACH PDU format field does not consider A1/B1 etc. possibilities
// We added 9 = A1/B1 10 = A2/B2 11 A3/B3
if (format1!=0xff) {
switch(format0) {
case 0xa1:
prach_pdu->prach_format = 9;
break;
case 0xa2:
prach_pdu->prach_format = 10;
break;
case 0xa3:
prach_pdu->prach_format = 11;
break;
default:
AssertFatal(1==0,"Only formats A1/B1 A2/B2 A3/B3 are valid for dual format");
}
}
else{
switch(format0) {
case 0xa1:
prach_pdu->prach_format = 0;
break;
case 0xa2:
prach_pdu->prach_format = 1;
break;
case 0xa3:
prach_pdu->prach_format = 2;
break;
case 0xb1:
prach_pdu->prach_format = 3;
break;
case 0xb2:
prach_pdu->prach_format = 4;
break;
case 0xb3:
prach_pdu->prach_format = 5;
break;
case 0xb4:
prach_pdu->prach_format = 6;
break;
case 0xc0:
prach_pdu->prach_format = 7;
break;
case 0xc2:
prach_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");
}
prach_occasion_id = (((frameP % (cc->max_association_period * config_period))/config_period) * cc->total_prach_occasions_per_config_period) + (RA_sfn_index + slot_index) * N_t_slot * fdm + td_index * fdm + fdm_index;
if((prach_occasion_id < cc->total_prach_occasions) && (td_index == 0)){
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t);
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].prach_pdu;
memset(prach_pdu,0,sizeof(nfapi_nr_prach_pdu_t));
UL_tti_req->n_pdus+=1;
// filling the prach fapi structure
prach_pdu->phys_cell_id = *scc->physCellId;
prach_pdu->num_prach_ocas = N_t_slot;
prach_pdu->prach_start_symbol = start_symbol;
prach_pdu->num_ra = fdm_index;
prach_pdu->num_cs = get_NCS(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig,
format0,
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig);
LOG_D(MAC, "Frame %d, Slot %d: Prach Occasion id = %u fdm index = %u start symbol = %u slot index = %u subframe index = %u \n",
frameP, slotP,
prach_occasion_id, prach_pdu->num_ra,
prach_pdu->prach_start_symbol,
slot_index, RA_sfn_index);
// SCF PRACH PDU format field does not consider A1/B1 etc. possibilities
// We added 9 = A1/B1 10 = A2/B2 11 A3/B3
if (format1!=0xff) {
switch(format0) {
case 0xa1:
prach_pdu->prach_format = 11;
break;
case 0xa2:
prach_pdu->prach_format = 12;
break;
case 0xa3:
prach_pdu->prach_format = 13;
break;
default:
AssertFatal(1==0,"Only formats A1/B1 A2/B2 A3/B3 are valid for dual format");
}
}
else{
switch(format0) {
case 0:
prach_pdu->prach_format = 0;
break;
case 1:
prach_pdu->prach_format = 1;
break;
case 2:
prach_pdu->prach_format = 2;
break;
case 3:
prach_pdu->prach_format = 3;
break;
case 0xa1:
prach_pdu->prach_format = 4;
break;
case 0xa2:
prach_pdu->prach_format = 5;
break;
case 0xa3:
prach_pdu->prach_format = 6;
break;
case 0xb1:
prach_pdu->prach_format = 7;
break;
case 0xb4:
prach_pdu->prach_format = 8;
break;
case 0xc0:
prach_pdu->prach_format = 9;
break;
case 0xc2:
prach_pdu->prach_format = 10;
break;
default:
AssertFatal(1==0,"Invalid PRACH format");
}
}
}
}
}
}
}
}
@@ -168,7 +342,7 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
uint16_t *msg2_frame, uint16_t *msg2_slot,
NR_ServingCellConfigCommon_t *scc,
uint16_t monitoring_slot_period,
uint16_t monitoring_offset){
uint16_t monitoring_offset,uint8_t index,uint8_t num_active_ssb){
// preferentially we schedule the msg2 in the mixed slot or in the last dl slot
// if they are allowed by search space configuration
@@ -189,7 +363,7 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
uint8_t start_next_period = (rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot)%nr_slots_per_frame[mu];
*msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot
*msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1);
switch(response_window){
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1:
slot_window = 1;
@@ -255,7 +429,6 @@ void nr_initiate_ra_proc(module_id_t module_idP,
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_RA_t *ra = &cc->ra[0];
// if the preamble received correspond to one of the listed
// the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries
int pr_found=0;
@@ -270,7 +443,6 @@ void nr_initiate_ra_proc(module_id_t module_idP,
module_idP, preamble_index);
return; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc
}
// This should be handled differently when we use the initialBWP for RA
ra->bwp_id=1;
NR_BWP_Downlink_t *bwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1];
@@ -280,6 +452,13 @@ void nr_initiate_ra_proc(module_id_t module_idP,
LOG_I(MAC, "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, slotP, preamble_index);
if (ra->state == RA_IDLE) {
uint8_t beam_index = ssb_index_from_prach(module_idP,
frameP,
slotP,
preamble_index,
freq_index,
symbol);
int loop = 0;
LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP);
ra->state = Msg2;
@@ -301,34 +480,34 @@ void nr_initiate_ra_proc(module_id_t module_idP,
&monitoring_slot_period,
&monitoring_offset);
nr_schedule_msg2(frameP, slotP, &msg2_frame, &msg2_slot, scc, monitoring_slot_period, monitoring_offset);
nr_schedule_msg2(frameP, slotP, &msg2_frame, &msg2_slot, scc, monitoring_slot_period, monitoring_offset,beam_index,cc->num_active_ssb);
ra->Msg2_frame = msg2_frame;
ra->Msg2_slot = msg2_slot;
LOG_D(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP);
if (!ra->cfra) {
LOG_I(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP);
if(pr_found)
do {
ra->rnti = (taus() % 65518) + 1;
loop++;
}
while (loop != 100 && !(find_nr_UE_id(module_idP, ra->rnti) == -1 && ra->rnti >= 1 && ra->rnti <= 65519));
if (loop == 100) {
LOG_E(MAC,"%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__);
abort();
}
while (loop != 100 && !((find_nr_UE_id(module_idP, ra->rnti) == -1) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1) && ra->rnti >= 1 && ra->rnti <= 65519));
if (loop == 100) {
LOG_E(MAC,"%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__);
abort();
}
ra->RA_rnti = ra_rnti;
ra->preamble_index = preamble_index;
ra->beam_id = beam_index;
LOG_I(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x\n",
LOG_I(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB index %u\n",
module_idP,
CC_id,
frameP,
ra->Msg2_frame,
ra->Msg2_slot,
ra->RA_rnti);
ra->RA_rnti,
cc->ssb_index[beam_index]);
return;
}
@@ -343,26 +522,31 @@ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
int CC_id = 0;
gNB_MAC_INST *mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
NR_RA_t *ra = &cc->ra[0];
start_meas(&mac->schedule_ra);
//for (i = 0; i < NR_NB_RA_PROC_MAX; i++) {
// for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
// for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
// NR_RA_t *ra = &cc->ra[i];
NR_RA_t *ra = &cc->ra[0];
LOG_D(MAC,"RA[state:%d]\n",ra->state);
switch (ra->state){
case Msg2:
nr_generate_Msg2(module_idP, CC_id, frameP, slotP);
break;
case Msg4:
//generate_Msg4(module_idP, CC_id, frameP, slotP, ra);
//generate_Msg4(module_idP, CC_id, frameP, slotP);
break;
case WAIT_Msg4_ACK:
//check_Msg4_retransmission(module_idP, CC_id, frameP, slotP, ra);
//check_Msg4_retransmission(module_idP, CC_id, frameP, slotP);
break;
default:
break;
}
//}
// }
// }
stop_meas(&mac->schedule_ra);
}
@@ -399,6 +583,7 @@ void nr_get_Msg3alloc(NR_ServingCellConfigCommon_t *scc,
else
ra->Msg3_frame = current_frame + (temp_slot/nr_slots_per_frame[mu]);
LOG_I(MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u start symbol index %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id, StartSymbolIndex);
ra->msg3_nb_rb = 18;
ra->msg3_first_rb = 0;
}
@@ -434,7 +619,7 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
return;
}
LOG_D(MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot);
LOG_I(MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot);
nfapi_nr_pusch_pdu_t *pusch_pdu = &ra->pusch_pdu;
memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
@@ -531,13 +716,14 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
void nr_generate_Msg2(module_id_t module_idP,
int CC_id,
frame_t frameP,
sub_frame_t slotP){
sub_frame_t slotP)
{
int dci_formats[2], rnti_types[2], mcsIndex;
int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment = 0;
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[0];
NR_RA_t *ra = &cc->ra[0];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
NR_RA_t *ra = &cc->ra[CC_id];
NR_SearchSpace_t *ss = ra->ra_ss;
uint16_t RA_rnti = ra->RA_rnti;
@@ -594,7 +780,7 @@ void nr_generate_Msg2(module_id_t module_idP,
NR_BWP_Downlink_t *bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
NR_BWP_Uplink_t *ubwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
LOG_D(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw);
LOG_I(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw);
// Qm>2 not allowed for RAR
if (get_softmodem_params()->do_ra)
@@ -702,7 +888,7 @@ void nr_generate_Msg2(module_id_t module_idP,
dci_formats[0] = NR_DL_DCI_FORMAT_1_0;
rnti_types[0] = NR_RNTI_RA;
LOG_D(MAC, "[RAPROC] DCI params: rnti %d, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n",
LOG_I(MAC, "[RAPROC] DCI params: rnti %d, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n",
pdcch_pdu_rel15->dci_pdu.RNTI[0],
rnti_types[0],
dci_formats[0],
@@ -719,7 +905,7 @@ void nr_generate_Msg2(module_id_t module_idP,
LOG_I(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
nr_add_msg3(module_idP, CC_id, frameP, slotP);
ra->state = WAIT_Msg3;
LOG_D(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state);
LOG_I(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state);
x_Overhead = 0;
nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, dci_pdu_rel15[0].tb_scaling);
@@ -742,6 +928,7 @@ void nr_generate_Msg2(module_id_t module_idP,
}
void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP){
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[0];
LOG_D(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra->rnti);
ra->state = IDLE;
@@ -787,7 +974,7 @@ void nr_fill_rar(uint8_t Mod_idP,
uint8_t * dlsch_buffer,
nfapi_nr_pusch_pdu_t *pusch_pdu){
LOG_D(MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d ", ra->Msg2_frame, ra-> Msg2_slot);
LOG_I(MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d preamble index %u", ra->Msg2_frame, ra-> Msg2_slot, ra->preamble_index);
NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer;
NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1);
unsigned char csi_req = 0, tpc_command;
+14 -4
View File
@@ -54,6 +54,7 @@
#include "common/ran_context.h"
extern RAN_CONTEXT_t RC;
extern uint8_t SSB_Table[38];
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
@@ -66,15 +67,24 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
int mib_sdu_length;
int CC_id;
AssertFatal(slotP == 0, "Subframe must be 0\n");
AssertFatal((frameP & 7) == 0, "Frame must be a multiple of 8\n");
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
dl_tti_request = &gNB->DL_req[CC_id];
dl_req = &dl_tti_request->dl_tti_request_body;
cc = &gNB->common_channels[CC_id];
#if 0
//SSB is transmitted based on SSB periodicity
if((frameP % cfg->ssb_table.ssb_period.value) == 0) {
uint64_t L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[0].ssb_mask.value)<<32) | cfg->ssb_table.ssb_mask_list[1].ssb_mask.value ;
uint32_t ssb_index = -1;
for (int i=0; i<2; i++) { // max two SSB per slot
ssb_index = i + SSB_Table[slotP]; // computing the ssb_index
if ((ssb_index<64) && ((L_ssb >> (63-ssb_index)) & 0x01)) { // generating the ssb only if the bit of L_ssb at current ssb index is 1
#endif
mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0]); // not used in this case
@@ -96,7 +106,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
AssertFatal(cc->ServingCellConfigCommon->physCellId!=NULL,"cc->ServingCellConfigCommon->physCellId is null\n");
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId = *cc->ServingCellConfigCommon->physCellId;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss = 0;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0;//ssb_index ;//SSB index for each SSB
AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon!=NULL,"scc->downlinkConfigCommonL is null\n");
AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n");
AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n");
@@ -132,8 +142,8 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
default:
AssertFatal(1==0,"SCS %ld not allowed for SSB \n", *cc->ServingCellConfigCommon->ssbSubcarrierSpacing);
}
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = 0; //kSSB
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = ssb_offset0/(ratio*12) - 10; // absoluteFrequencySSB is the center of SSB
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = cfg->ssb_table.ssb_subcarrier_offset.value; //kSSB
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = ssb_offset0/(ratio*12) - 10;/*cfg->ssb_table.ssb_offset_point_a.value;*/ // absoluteFrequencySSB is the center of SSB
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1);
dl_req->nPDUs++;
@@ -1640,6 +1640,25 @@ void set_Y(int Y[3][160], rnti_t rnti) {
}
}
int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP) {
//------------------------------------------------------------------------------
int RA_id;
RA_t *ra = (RA_t *) &RC.nrmac[mod_idP]->common_channels[CC_idP].ra[0];
for (RA_id = 0; RA_id < NB_RA_PROC_MAX; RA_id++) {
LOG_D(MAC, "Checking RA_id %d for %x : state %d\n",
RA_id,
rntiP,
ra[RA_id].state);
if (ra[RA_id].state != IDLE && ra[RA_id].rnti == rntiP)
return RA_id;
}
return -1;
}
//------------------------------------------------------------------------------
int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
NR_UE_info_t *UE_info = &RC.nrmac[mod_idP]->UE_info;
@@ -401,5 +401,45 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
}
}
else if (sduP != NULL) { // if the CRC passed
// random access pusch with TC-RNTI
NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[0];
if (ra->state != WAIT_Msg3) {
LOG_E(MAC,
"expected RA state WAIT_Msg3/%d (but is %d) for RA-RNTI %04x\n",
WAIT_Msg3,
ra->state,
ra->rnti);
return;
}
if (ra->rnti != current_rnti) {
LOG_E(MAC,
"expected RA-RNTI %04x (C-RNTI %04x) to match current RNTI %04x\n",
ra->rnti,
ra->crnti,
current_rnti);
return;
}
free(ra->preambles.preamble_list);
ra->state = RA_IDLE;
LOG_I(MAC, "reset RA state information for RA-RNTI %04x\n", ra->rnti);
const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->crnti);
UE_info->secondaryCellGroup[UE_id] = ra->secondaryCellGroup;
UE_info->UE_beam_index[UE_id] = ra->beam_id;
struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList =
ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList;
AssertFatal(bwpList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n",
bwpList->list.count);
const int bwp_id = 1;
UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1];
LOG_W(MAC,
"[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, "
"adding UE MAC Context UE_id %d/RNTI %04x\n",
gnb_mod_idP,
current_rnti,
UE_id,
ra->crnti);
}
}
+11
View File
@@ -306,6 +306,8 @@ void add_nr_ue_list(NR_UE_list_t *listP, int UE_id);
int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP);
int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP);
int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP);
void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti);
@@ -387,5 +389,14 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
void handle_nr_ul_harq(uint16_t slot, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, nfapi_nr_crc_t crc_pdu);
int16_t ssb_index_from_prach(module_id_t module_idP,
frame_t frameP,
sub_frame_t slotP,
uint16_t preamble_index,
uint8_t freq_index,
uint8_t symbol);
void find_SSB_and_RO_available(module_id_t module_idP);
void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, int target_snrx10);
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
+15
View File
@@ -74,6 +74,7 @@
#define MAX_NUM_CCE 90
/*!\brief Maximum number of random access process */
#define NR_NB_RA_PROC_MAX 4
#define MAX_NUM_OF_SSB 64
typedef enum {
RA_IDLE = 0,
@@ -146,6 +147,8 @@ typedef struct {
int msg4_mcs;
/// RA search space
NR_SearchSpace_t *ra_ss;
// Beam index
uint8_t beam_id;
/// secondaryCellGroup for UE in NSA that is to come
NR_CellGroupConfig_t *secondaryCellGroup;
/// Preambles for contention-free access
@@ -190,6 +193,16 @@ typedef struct {
uint8_t vrb_map_UL[275];
/// number of subframe allocation pattern available for MBSFN sync area
uint8_t num_sf_allocation_pattern;
///Number of active SSBs
uint8_t num_active_ssb;
//Total available prach occasions per configuration period
uint32_t total_prach_occasions_per_config_period;
//Total available prach occasions
uint32_t total_prach_occasions;
//Max Association period
uint8_t max_association_period;
//SSB index
uint8_t ssb_index[MAX_NUM_OF_SSB];
} NR_COMMON_channels_t;
@@ -386,6 +399,8 @@ typedef struct {
int Y[MAX_MOBILES_PER_GNB][3][160];
int m[MAX_MOBILES_PER_GNB];
int num_pdcch_cand[MAX_MOBILES_PER_GNB][MAX_NUM_CORESET];
// UE selected beam index
uint8_t UE_beam_index[MAX_MOBILES_PER_GNB];
} NR_UE_info_t;
/*! \brief top level eNB MAC structure */
+17 -16
View File
@@ -56,24 +56,25 @@ extern uint16_t sf_ahead;
extern uint16_t sl_ahead;
void handle_nr_rach(NR_UL_IND_t *UL_info) {
if (UL_info->rach_ind.number_of_pdus>0) {
AssertFatal(UL_info->rach_ind.number_of_pdus==1,"More than 1 RACH pdu not supported\n");
UL_info->rach_ind.number_of_pdus=0;
LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot);
if (UL_info->rach_ind.pdu_list[0].num_preamble>0)
AssertFatal(UL_info->rach_ind.pdu_list[0].num_preamble==1,
"More than 1 preamble not supported\n");
LOG_I(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot);
int npdus = UL_info->rach_ind.number_of_pdus;
for(int i = 0; i < npdus; i++) {
UL_info->rach_ind.number_of_pdus--;
if (UL_info->rach_ind.pdu_list[i].num_preamble>0)
AssertFatal(UL_info->rach_ind.pdu_list[i].num_preamble==1,
"More than 1 preamble not supported\n");
nr_initiate_ra_proc(UL_info->module_id,
UL_info->CC_id,
UL_info->rach_ind.sfn,
UL_info->rach_ind.slot,
UL_info->rach_ind.pdu_list[0].preamble_list[0].preamble_index,
UL_info->rach_ind.pdu_list[0].freq_index,
UL_info->rach_ind.pdu_list[0].symbol_index,
UL_info->rach_ind.pdu_list[0].preamble_list[0].timing_advance);
nr_initiate_ra_proc(UL_info->module_id,
UL_info->CC_id,
UL_info->rach_ind.sfn,
UL_info->rach_ind.slot,
UL_info->rach_ind.pdu_list[i].preamble_list[0].preamble_index,
UL_info->rach_ind.pdu_list[i].freq_index,
UL_info->rach_ind.pdu_list[i].symbol_index,
UL_info->rach_ind.pdu_list[i].preamble_list[0].timing_advance);
}
}
}
+35 -4
View File
@@ -174,10 +174,41 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.present = NR_CFRA__resources_PR_ssb;
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb = calloc(1,sizeof(struct NR_CFRA__resources__ssb));
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ra_ssb_OccasionMaskIndex = 0;
struct NR_CFRA_SSB_Resource *ssbElem = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem->ssb = 0;
ssbElem->ra_PreambleIndex= 63;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem);
struct NR_CFRA_SSB_Resource *ssbElem[8];
ssbElem[0] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem[0]->ssb = 0;
ssbElem[0]->ra_PreambleIndex = 63;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[0]);
#if 0
ssbElem[1] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem[1]->ssb = 1;
ssbElem[1]->ra_PreambleIndex = 62;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[1]);
ssbElem[2] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem[2]->ssb = 2;
ssbElem[2]->ra_PreambleIndex = 63;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[2]);
ssbElem[3] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem[3]->ssb = 3;
ssbElem[3]->ra_PreambleIndex = 63;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[3]);
ssbElem[4] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem[4]->ssb = 4;
ssbElem[4]->ra_PreambleIndex = 63;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[4]);
ssbElem[5] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem[5]->ssb = 5;
ssbElem[5]->ra_PreambleIndex = 63;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[5]);
ssbElem[6] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem[6]->ssb = 6;
ssbElem[6]->ra_PreambleIndex = 63;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[6]);
ssbElem[7] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem[7]->ssb = 7;
ssbElem[7]->ra_PreambleIndex = 63;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[7]);
#endif
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->ext1 = NULL;
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants));
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->present = NR_SetupRelease_RLF_TimersAndConstants_PR_setup;
+1 -1
View File
@@ -1177,7 +1177,7 @@ void init_eNB_afterRU(void) {
for (i=0; i<eNB->RU_list[ru_id]->nb_rx; aa++,i++) {
LOG_I(PHY,"Attaching RU %d antenna %d to eNB antenna %d\n",eNB->RU_list[ru_id]->idx,i,aa);
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[i];
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[0][i];
for (int ce_level=0; ce_level<4; ce_level++)
eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[ru_id]->prach_rxsigF_br[ce_level][i];