replace fix array index by pointers for prach lists in gNB

This commit is contained in:
Laurent THOMAS
2025-10-30 11:54:18 +01:00
committed by Robert Schmidt
parent f5c1d18638
commit a4d3eb9fad
6 changed files with 137 additions and 131 deletions
+4 -5
View File
@@ -1208,8 +1208,8 @@ void *ru_thread(void *param)
proc->tti_rx * gNB->frame_parms.samples_per_slot_wCP);
// Do PRACH RU processing
int prach_id = find_nr_prach_ru(ru, proc->frame_rx, proc->tti_rx, SEARCH_EXIST);
if (prach_id >= 0) {
RU_PRACH_list_t *p = find_nr_prach_ru(ru, proc->frame_rx, proc->tti_rx, SEARCH_EXIST);
if (p) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 );
T(T_GNB_PHY_PRACH_INPUT_SIGNAL,
@@ -1218,12 +1218,11 @@ void *ru_thread(void *param)
T_INT(0),
T_BUFFER(&ru->common.rxdata[0][fp->get_samples_slot_timestamp(proc->tti_rx - 1, fp, 0) /*-ru->N_TA_offset*/],
(fp->get_samples_per_slot(proc->tti_rx - 1, fp) + fp->get_samples_per_slot(proc->tti_rx, fp)) * 4));
RU_PRACH_list_t *p = ru->prach_list + prach_id;
int N_dur = get_nr_prach_duration(p->fmt);
for (int prach_oc = 0; prach_oc < p->num_prach_ocas; prach_oc++) {
int prachStartSymbol = p->prachStartSymbol + prach_oc * N_dur;
int beam_id = ru->prach_list[prach_id].beam ? ru->prach_list[prach_id].beam[prach_oc] : 0;
int beam_id = p->beam ? p->beam[prach_oc] : 0;
//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,
p->fmt, // could also use format
@@ -1235,7 +1234,7 @@ void *ru_thread(void *param)
proc->frame_rx,
proc->tti_rx);
}
free_nr_ru_prach_entry(ru,prach_id);
free_nr_ru_prach_entry(ru, p);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0);
} // end if (prach_id >= 0)
} // end if (ru->feprx)
+42 -36
View File
@@ -46,34 +46,38 @@ void init_prach_list(PHY_VARS_gNB *gNB)
}
}
void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id)
void free_nr_prach_entry(PHY_VARS_gNB *gNB, gNB_PRACH_list_t *p)
{
gNB->prach_vars.list[prach_id].frame = -1;
gNB->prach_vars.list[prach_id].slot = -1;
gNB->prach_vars.list[prach_id].num_slots = -1;
free_and_zero(gNB->prach_vars.list[prach_id].beam_nb);
for (uint16_t i = 0; i < NUMBER_OF_NR_PRACH_MAX; i++) {
if (p == gNB->prach_vars.list + i) {
p->frame = -1;
p->slot = -1;
p->num_slots = -1;
free_and_zero(p->beam_nb);
break;
}
}
}
int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame, int slot, find_type_t type) {
gNB_PRACH_list_t *find_nr_prach(PHY_VARS_gNB *gNB, int frame, int slot, find_type_t type)
{
AssertFatal(gNB!=NULL,"gNB is null\n");
for (uint16_t i=0; i<NUMBER_OF_NR_PRACH_MAX; i++) {
gNB_PRACH_list_t *p = gNB->prach_vars.list + i;
LOG_D(PHY, "searching for PRACH in %d.%d prach_index %d=> %d.%d\n", frame, slot, i, p->frame, p->slot);
if ((type == SEARCH_EXIST_OR_FREE) && (p->frame == -1) && (p->slot == -1)) {
return i;
return p;
} else if ((type == SEARCH_EXIST) && (p->frame == frame) && (p->slot + p->num_slots - 1 == slot)) {
return i;
return p;
}
}
return -1;
return NULL;
}
int nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu)
gNB_PRACH_list_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu)
{
int prach_id = find_nr_prach(gNB, SFN, Slot, SEARCH_EXIST_OR_FREE);
AssertFatal(((prach_id >= 0) && (prach_id < NUMBER_OF_NR_PRACH_MAX)), "illegal or no prach_id found!!! prach_id %d\n", prach_id);
gNB_PRACH_list_t *prach = &gNB->prach_vars.list[prach_id];
gNB_PRACH_list_t *prach = find_nr_prach(gNB, SFN, Slot, SEARCH_EXIST_OR_FREE);
AssertFatal(prach, "prach list full!!!\n");
prach->frame = SFN;
prach->slot = Slot;
const int format = prach_pdu->prach_format;
@@ -94,9 +98,8 @@ int nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *pr
bitmap);
}
}
LOG_D(NR_PHY,"Copying prach pdu %d bytes to index %d\n", (int)sizeof(*prach_pdu), prach_id);
memcpy(&prach->pdu, prach_pdu, sizeof(*prach_pdu));
return prach_id;
prach->pdu = *prach_pdu;
return prach;
}
void init_prach_ru_list(RU_t *ru)
@@ -110,7 +113,7 @@ void init_prach_ru_list(RU_t *ru)
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)
RU_PRACH_list_t *find_nr_prach_ru(RU_t *ru, int frame, int slot, find_type_t type)
{
AssertFatal(ru != NULL, "ru is null\n");
pthread_mutex_lock(&ru->prach_list_mutex);
@@ -119,41 +122,44 @@ int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type)
LOG_D(PHY, "searching for PRACH in %d.%d : prach_index %d=> %d.%d\n", frame, slot, i, p->frame, p->slot);
if ((type == SEARCH_EXIST_OR_FREE) && (p->frame == -1) && (p->slot == -1)) {
pthread_mutex_unlock(&ru->prach_list_mutex);
return i;
return p;
} else if ((type == SEARCH_EXIST) && (p->frame == frame) && (p->slot + p->num_slots - 1 == slot)) {
pthread_mutex_unlock(&ru->prach_list_mutex);
return i;
return p;
}
}
pthread_mutex_unlock(&ru->prach_list_mutex);
return -1;
return NULL;
}
void nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu, int *beam_id)
{
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),
"illegal or no prach_id found!!! prach_id %d\n",
prach_id);
RU_PRACH_list_t *prach = find_nr_prach_ru(ru, SFN, Slot, SEARCH_EXIST_OR_FREE);
AssertFatal(prach, "ru prach list full\n");
pthread_mutex_lock(&ru->prach_list_mutex);
ru->prach_list[prach_id].frame = SFN;
ru->prach_list[prach_id].slot = Slot;
prach->frame = SFN;
prach->slot = Slot;
const int fmt = prach_pdu->prach_format;
ru->prach_list[prach_id].num_slots = (fmt < 4) ? get_long_prach_dur(fmt, ru->nr_frame_parms->numerology_index) : 1;
ru->prach_list[prach_id].fmt = fmt;
ru->prach_list[prach_id].numRA = prach_pdu->num_ra;
ru->prach_list[prach_id].beam = beam_id;
ru->prach_list[prach_id].prachStartSymbol = prach_pdu->prach_start_symbol;
ru->prach_list[prach_id].num_prach_ocas = prach_pdu->num_prach_ocas;
prach->num_slots = (fmt < 4) ? get_long_prach_dur(fmt, ru->nr_frame_parms->numerology_index) : 1;
prach->fmt = fmt;
prach->numRA = prach_pdu->num_ra;
prach->beam = beam_id;
prach->prachStartSymbol = prach_pdu->prach_start_symbol;
prach->num_prach_ocas = prach_pdu->num_prach_ocas;
pthread_mutex_unlock(&ru->prach_list_mutex);
}
void free_nr_ru_prach_entry(RU_t *ru, int prach_id)
void free_nr_ru_prach_entry(RU_t *ru, RU_PRACH_list_t *p)
{
pthread_mutex_lock(&ru->prach_list_mutex);
ru->prach_list[prach_id].frame = -1;
ru->prach_list[prach_id].slot = -1;
for (int i = 0; i < NUMBER_OF_NR_RU_PRACH_MAX; i++) {
if (p == ru->prach_list + i) {
p->frame = -1;
p->slot = -1;
break;
}
}
pthread_mutex_unlock(&ru->prach_list_mutex);
}
@@ -200,7 +200,7 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB,
int slot,
nfapi_nr_pusch_pdu_t *ulsch_pdu);
int nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu);
gNB_PRACH_list_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu);
void rx_nr_prach(PHY_VARS_gNB *gNB,
nfapi_nr_prach_pdu_t *prach_pdu,
@@ -223,8 +223,8 @@ void rx_nr_prach_ru(RU_t *ru,
void nr_fill_prach_ru(RU_t *ru,int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu, int *beam_nb);
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);
gNB_PRACH_list_t *find_nr_prach(PHY_VARS_gNB *gNB, int frame, int slot, find_type_t type);
RU_PRACH_list_t *find_nr_prach_ru(RU_t *ru, int frame, int slot, find_type_t type);
void nr_fill_pucch(PHY_VARS_gNB *gNB,
int frame,
@@ -247,10 +247,10 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB,
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_ru_prach_entry(RU_t *ru, RU_PRACH_list_t *p);
int get_nr_prach_duration(uint8_t prach_format);
void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id);
void free_nr_prach_entry(PHY_VARS_gNB *gNB, gNB_PRACH_list_t *);
void nr_decode_pucch1(c16_t **rxdataF,
pucch_GroupHopping_t pucch_GroupHopping,
+7 -9
View File
@@ -37,15 +37,13 @@ void nr_fill_pucch(PHY_VARS_gNB *gNB,
int frame,
int slot,
nfapi_nr_pucch_pdu_t *pucch_pdu){}
void nr_fill_prach(PHY_VARS_gNB *gNB,
int SFN,
int Slot,
nfapi_nr_prach_pdu_t *prach_pdu){}
void nr_fill_prach_ru(RU_t *ru,
int SFN,
int Slot,
nfapi_nr_prach_pdu_t *prach_pdu){}
gNB_PRACH_list_t nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu)
{
}
RU_PRACH_list_t nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu)
{
}
void nr_phy_config_request(NR_PHY_Config_t *gNB){}
void install_nr_schedule_handlers(NR_IF_Module_t *if_inst){}
+3 -3
View File
@@ -154,9 +154,9 @@ void nr_schedule_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti
UL_tti_req->SFN,
UL_tti_req->Slot);
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu;
int id = nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
if (gNB->RU_list[0]->if_south == LOCAL_RF || gNB->RU_list[0]->if_south == REMOTE_IF5)
nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu, gNB->prach_vars.list[id].beam_nb);
gNB_PRACH_list_t *prach = nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
if (prach && (gNB->RU_list[0]->if_south == LOCAL_RF || gNB->RU_list[0]->if_south == REMOTE_IF5))
nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu, prach->beam_nb);
break;
case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE:
LOG_D(NR_PHY,
+76 -73
View File
@@ -63,85 +63,88 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac
ru=gNB->RU_list[0];
int prach_id = find_nr_prach(gNB, frame, slot, SEARCH_EXIST);
if (prach_id >= 0) {
LOG_D(NR_PHY,"%d.%d Got prach entry id %d\n",frame,slot,prach_id);
nfapi_nr_prach_pdu_t *prach_pdu = &gNB->prach_vars.list[prach_id].pdu;
const int prach_start_slot = gNB->prach_vars.list[prach_id].slot;
uint8_t prachStartSymbol;
int N_dur = get_nr_prach_duration(prach_pdu->prach_format);
gNB_PRACH_list_t *prach_id = find_nr_prach(gNB, frame, slot, SEARCH_EXIST);
if (!prach_id) {
return;
}
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];
}
LOG_D(NR_PHY, "%d.%d Got prach entry\n", frame, slot);
nfapi_nr_prach_pdu_t *prach_pdu = &prach_id->pdu;
const int prach_start_slot = prach_id->slot;
uint8_t prachStartSymbol;
int N_dur = get_nr_prach_duration(prach_pdu->prach_format);
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}.
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,
prach_oc,
frame,
slot,
&max_preamble[0],
&max_preamble_energy[0],
&max_preamble_delay[0]);
LOG_D(NR_PHY,"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d.%d dB delay %d (prach_energy counter %d)\n",
frame,slot,prach_oc,prachStartSymbol,
max_preamble[0],
max_preamble_energy[0]/10,
max_preamble_energy[0]%10,
max_preamble_delay[0],
gNB->prach_energy_counter);
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}.
if ((gNB->prach_energy_counter == NUM_PRACH_RX_FOR_NOISE_ESTIMATE)
&& (max_preamble_energy[0] > gNB->measurements.prach_I0 + gNB->prach_thres)
&& (rach_ind->number_of_pdus < MAX_NUM_NR_RX_RACH_PDUS)) {
LOG_A(NR_PHY,
"[RAPROC] %d.%d Initiating RA procedure with preamble %d, energy %d.%d dB (I0 %d, thres %d), delay %d start symbol "
"%u freq index %u\n",
frame,
prach_start_slot,
max_preamble[0],
max_preamble_energy[0] / 10,
max_preamble_energy[0] % 10,
gNB->measurements.prach_I0,
gNB->prach_thres,
max_preamble_delay[0],
prachStartSymbol,
prach_pdu->num_ra);
rx_nr_prach(gNB, prach_pdu, prach_oc, frame, slot, &max_preamble[0], &max_preamble_energy[0], &max_preamble_delay[0]);
LOG_D(NR_PHY,
"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d.%d dB delay %d "
"(prach_energy counter %d)\n",
frame,
slot,
prach_oc,
prachStartSymbol,
max_preamble[0],
max_preamble_energy[0] / 10,
max_preamble_energy[0] % 10,
max_preamble_delay[0],
gNB->prach_energy_counter);
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]));
if ((gNB->prach_energy_counter == NUM_PRACH_RX_FOR_NOISE_ESTIMATE)
&& (max_preamble_energy[0] > gNB->measurements.prach_I0 + gNB->prach_thres)
&& (rach_ind->number_of_pdus < MAX_NUM_NR_RX_RACH_PDUS)) {
LOG_A(NR_PHY,
"[RAPROC] %d.%d Initiating RA procedure with preamble %d, energy %d.%d dB (I0 %d, thres %d), delay %d start symbol "
"%u freq index %u\n",
frame,
prach_start_slot,
max_preamble[0],
max_preamble_energy[0] / 10,
max_preamble_energy[0] % 10,
gNB->measurements.prach_I0,
gNB->prach_thres,
max_preamble_delay[0],
prachStartSymbol,
prach_pdu->num_ra);
nfapi_nr_prach_indication_pdu_t *ind = rach_ind->pdu_list + rach_ind->number_of_pdus;
ind->phy_cell_id = gNB->gNB_config.cell_config.phy_cell_id.value;
ind->symbol_index = prachStartSymbol;
ind->slot_index = slot;
ind->freq_index = prach_pdu->num_ra;
ind->avg_rssi = (max_preamble_energy[0] < 631) ? (128 + (max_preamble_energy[0] / 5)) : 254;
ind->avg_snr = 0xff; // invalid for now
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]));
ind->num_preamble = 1;
ind->preamble_list[0].preamble_index = max_preamble[0];
ind->preamble_list[0].timing_advance = max_preamble_delay[0];
ind->preamble_list[0].preamble_pwr = 0xffffffff;
rach_ind->number_of_pdus++;
}
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 < NUM_PRACH_RX_FOR_NOISE_ESTIMATE)
gNB->prach_energy_counter++;
} //if prach_id>0
rach_ind->slot = prach_start_slot;
LOG_D(NR_PHY,"Freeing PRACH entry %d\n",prach_id);
free_nr_prach_entry(gNB,prach_id);
} // for NUMBER_OF_NR_PRACH_OCCASION_MAX
nfapi_nr_prach_indication_pdu_t *ind = rach_ind->pdu_list + rach_ind->number_of_pdus;
ind->phy_cell_id = gNB->gNB_config.cell_config.phy_cell_id.value;
ind->symbol_index = prachStartSymbol;
ind->slot_index = slot;
ind->freq_index = prach_pdu->num_ra;
ind->avg_rssi = (max_preamble_energy[0] < 631) ? (128 + (max_preamble_energy[0] / 5)) : 254;
ind->avg_snr = 0xff; // invalid for now
ind->num_preamble = 1;
ind->preamble_list[0].preamble_index = max_preamble[0];
ind->preamble_list[0].timing_advance = max_preamble_delay[0];
ind->preamble_list[0].preamble_pwr = 0xffffffff;
rach_ind->number_of_pdus++;
}
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 < NUM_PRACH_RX_FOR_NOISE_ESTIMATE)
gNB->prach_energy_counter++;
} // if prach_id>0
rach_ind->slot = prach_start_slot;
LOG_D(NR_PHY, "Freeing PRACH entry\n");
free_nr_prach_entry(gNB, prach_id);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0);
}