remove permanent prach rxsigF in gNB and simplify the data structure
This commit is contained in:
committed by
Robert Schmidt
parent
4dd340b6bb
commit
cffb07d798
@@ -389,8 +389,7 @@ void init_eNB_afterRU(void)
|
||||
AssertFatal(gNB->RU_list[ru_id]->common.rxdataF != NULL, "RU %d : common.rxdataF is NULL\n", gNB->RU_list[ru_id]->idx);
|
||||
AssertFatal(gNB->RU_list[ru_id]->prach_rxsigF != NULL, "RU %d : prach_rxsigF is NULL\n", gNB->RU_list[ru_id]->idx);
|
||||
for (int 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[0][i];
|
||||
LOG_I(PHY, "Attaching RU %d antenna %d to gNB antenna %d\n", gNB->RU_list[ru_id]->idx, i, aa);
|
||||
for (int b = 0; b < gNB->RU_list[ru_id]->num_beams_period; b++) {
|
||||
int idx = i + b * gNB->RU_list[ru_id]->nb_rx;
|
||||
gNB->common_vars.rxdataF[b][aa] = (c16_t *)gNB->RU_list[ru_id]->common.rxdataF[idx];
|
||||
|
||||
@@ -104,9 +104,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
// shortcuts
|
||||
NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms;
|
||||
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
|
||||
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
|
||||
NR_gNB_PRACH *const prach_vars = &gNB->prach_vars;
|
||||
|
||||
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
|
||||
common_vars->analog_bf = cfg->analog_beamforming_ve.analog_bf_vendor_ext.value;
|
||||
LOG_I(PHY, "L1 configured with%s analog beamforming\n", common_vars->analog_bf ? "" : "out");
|
||||
if (common_vars->analog_bf) {
|
||||
@@ -190,9 +188,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
common_vars->debugBuff_sample_offset = 0;
|
||||
|
||||
// PRACH
|
||||
prach_vars->rxsigF = (int16_t **)malloc16_clear(Prx * sizeof(int16_t *));
|
||||
|
||||
init_prach_list(&gNB->prach_vars.list, prach_upper);
|
||||
init_prach_list(&gNB->prach_list, prach_upper);
|
||||
|
||||
int N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value;
|
||||
int n_buf = Prx*max_ul_mimo_layers;
|
||||
|
||||
@@ -116,12 +116,12 @@ void nr_phy_init_RU(RU_t *ru)
|
||||
// AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]),
|
||||
// "nb_antennas_rx too large");
|
||||
for (int j = 0; j < NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX; j++) {
|
||||
ru->prach_rxsigF[j] = (int16_t**)malloc(nb_rx_streams * sizeof(int16_t*));
|
||||
|
||||
ru->prach_rxsigF[j] = malloc(nb_rx_streams * sizeof(*ru->prach_rxsigF));
|
||||
|
||||
for (int i = 0; i < nb_rx_streams; 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]);
|
||||
ru->prach_rxsigF[j][i] = malloc16_clear(4 * 98304 * 2 * sizeof(**ru->prach_rxsigF));
|
||||
LOG_D(PHY, "[INIT] prach_vars->rxsigF[%d] = %p\n", i, ru->prach_rxsigF[j][i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ prach_item_t *find_nr_prach(prach_list_t *l, int frame, int slot, find_type_t ty
|
||||
|
||||
prach_item_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu)
|
||||
{
|
||||
prach_item_t *prach = find_nr_prach(&gNB->prach_vars.list, SFN, Slot, SEARCH_EXIST_OR_FREE);
|
||||
prach_item_t *prach = find_nr_prach(&gNB->prach_list, SFN, Slot, SEARCH_EXIST_OR_FREE);
|
||||
if (!prach) {
|
||||
LOG_W(PHY, "no free space for a new detected rach, discarding\n");
|
||||
return NULL;
|
||||
@@ -171,7 +171,7 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
prachStartSymbol,
|
||||
prachOccasion);
|
||||
|
||||
int16_t **rxsigF = ru->prach_rxsigF[prachOccasion];
|
||||
c16_t **rxsigF = (c16_t **)ru->prach_rxsigF[prachOccasion];
|
||||
|
||||
AssertFatal(ru->if_south == LOCAL_RF || ru->if_south == REMOTE_IF5,
|
||||
"we shouldn't call this if if_south != LOCAL_RF or REMOTE_IF5\n");
|
||||
@@ -392,23 +392,25 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
// do DFT
|
||||
int16_t *prach2 = prach[aa] + (2*Ncp); // times 2 for complex samples
|
||||
for (int i = 0; i < reps; i++)
|
||||
dft(dftsize, prach2 + 2*dftlen*i, rxsigF[aa] + 2*dftlen*i, 1);
|
||||
dft(dftsize, prach2 + 2 * dftlen * i, (int16_t *)rxsigF[aa] + 2 * dftlen * i, 1);
|
||||
|
||||
//LOG_M("ru_rxsigF_tmp.m","rxsFtmp", rxsigF[aa], dftlen*2*reps, 1, 1);
|
||||
|
||||
//Coherent combining of PRACH repetitions (assumes channel does not change, to be revisted for "long" PRACH)
|
||||
LOG_D(PHY,"Doing PRACH combining of %d reptitions N_ZC %d\n",reps,N_ZC);
|
||||
int16_t rxsigF_tmp[N_ZC<<1];
|
||||
// if (k+N_ZC > dftlen) { // PRACH signal is split around DC
|
||||
int16_t *rxsigF2=rxsigF[aa];
|
||||
int k2=k<<1;
|
||||
c16_t rxsigF_tmp[N_ZC];
|
||||
// if (k+N_ZC > dftlen) { // PRACH signal is split around DC
|
||||
c16_t *rxsigF2 = rxsigF[aa];
|
||||
int k2 = k;
|
||||
|
||||
for (int j=0;j<N_ZC<<1;j++,k2++) {
|
||||
if (k2==(dftlen<<1)) k2=0;
|
||||
for (int j = 0; j < N_ZC; j++, k2++) {
|
||||
if (k2 == dftlen)
|
||||
k2 = 0;
|
||||
rxsigF_tmp[j] = rxsigF2[k2];
|
||||
for (int i=1;i<reps;i++) rxsigF_tmp[j] += rxsigF2[k2+(i*dftlen<<1)];
|
||||
for (int i = 1; i < reps; i++)
|
||||
rxsigF_tmp[j] = c16add(rxsigF_tmp[j], rxsigF2[k2 + i * dftlen]);
|
||||
}
|
||||
memcpy((void*)rxsigF2,(void *)rxsigF_tmp,N_ZC<<2);
|
||||
memcpy(rxsigF2, rxsigF_tmp, N_ZC * sizeof(*rxsigF2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,11 +421,11 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
int slot,
|
||||
uint16_t *max_preamble,
|
||||
uint16_t *max_preamble_energy,
|
||||
uint16_t *max_preamble_delay)
|
||||
uint16_t *max_preamble_delay,
|
||||
c16_t **rxsigF)
|
||||
{
|
||||
AssertFatal(gNB != NULL, "Can only be called from gNB\n");
|
||||
nfapi_nr_prach_config_t *cfg = &gNB->gNB_config.prach_config;
|
||||
c16_t **rxsigF = (c16_t **)gNB->prach_vars.rxsigF;
|
||||
uint16_t preamble_index0 = 0;
|
||||
uint16_t numshift = 0;
|
||||
int first_nonzero_root_idx = 0;
|
||||
|
||||
@@ -209,7 +209,8 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
int subframe,
|
||||
uint16_t *max_preamble,
|
||||
uint16_t *max_preamble_energy,
|
||||
uint16_t *max_preamble_delay);
|
||||
uint16_t *max_preamble_delay,
|
||||
c16_t **rxsigF);
|
||||
|
||||
void rx_nr_prach_ru(RU_t *ru,
|
||||
int prach_fmt,
|
||||
|
||||
@@ -593,7 +593,7 @@ typedef struct RU_t_s {
|
||||
/// beamforming weight vectors
|
||||
int32_t **beam_weights[NUMBER_OF_eNB_MAX+1][15];
|
||||
prach_list_t prach_list;
|
||||
/// received frequency-domain signal for PRACH (IF4p5 RRU)
|
||||
/// 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];
|
||||
|
||||
@@ -134,14 +134,6 @@ typedef struct {
|
||||
nfapi_nr_dl_tti_ssb_pdu ssb_pdu;
|
||||
} NR_gNB_SSB_t;
|
||||
|
||||
typedef struct {
|
||||
/// \brief ?.
|
||||
/// second index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx.
|
||||
/// third index: frequency-domain sample [0..ofdm_symbol_size*12[
|
||||
int16_t **rxsigF;
|
||||
prach_list_t list;
|
||||
} NR_gNB_PRACH;
|
||||
|
||||
typedef struct {
|
||||
uint8_t NumPRSResources;
|
||||
prs_config_t prs_cfg[NR_MAX_PRS_RESOURCES_PER_SET];
|
||||
@@ -416,7 +408,7 @@ typedef struct PHY_VARS_gNB_s {
|
||||
int max_nb_pusch;
|
||||
|
||||
NR_gNB_COMMON common_vars;
|
||||
NR_gNB_PRACH prach_vars;
|
||||
prach_list_t prach_list;
|
||||
NR_gNB_PRS prs_vars;
|
||||
NR_gNB_PUSCH *pusch_vars;
|
||||
NR_gNB_PUCCH_t *pucch;
|
||||
|
||||
@@ -52,10 +52,6 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac
|
||||
uint16_t max_preamble[4]={0},max_preamble_energy[4]={0},max_preamble_delay[4]={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);
|
||||
rach_ind->sfn = frame;
|
||||
rach_ind->slot = slot;
|
||||
@@ -63,7 +59,7 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac
|
||||
|
||||
ru=gNB->RU_list[0];
|
||||
|
||||
prach_item_t *prach_id = find_nr_prach(&gNB->prach_vars.list, frame, slot, SEARCH_EXIST);
|
||||
prach_item_t *prach_id = find_nr_prach(&gNB->prach_list, frame, slot, SEARCH_EXIST);
|
||||
if (!prach_id) {
|
||||
return;
|
||||
}
|
||||
@@ -75,16 +71,15 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac
|
||||
int N_dur = get_nr_prach_duration(prach_pdu->prach_format);
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
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]);
|
||||
c16_t *rxsigF[ru->nb_rx];
|
||||
for (int i = 0; i < ru->nb_rx; ++i)
|
||||
rxsigF[i] = (c16_t *)ru->prach_rxsigF[prach_oc][i];
|
||||
rx_nr_prach(gNB, prach_pdu, prach_oc, frame, slot, &max_preamble[0], &max_preamble_energy[0], &max_preamble_delay[0], rxsigF);
|
||||
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",
|
||||
@@ -145,6 +140,6 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac
|
||||
} // if prach_id>0
|
||||
rach_ind->slot = prach_start_slot;
|
||||
LOG_D(NR_PHY, "Freeing PRACH entry\n");
|
||||
free_nr_prach_entry(&gNB->prach_vars.list, prach_id);
|
||||
free_nr_prach_entry(&gNB->prach_list, prach_id);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0);
|
||||
}
|
||||
|
||||
@@ -567,7 +567,7 @@ int main(int argc, char **argv){
|
||||
|
||||
phy_init_nr_gNB(gNB);
|
||||
nr_phy_init_RU(ru);
|
||||
nfapi_nr_prach_pdu_t *prach_pdu = &gNB->prach_vars.list.list[0].pdu;
|
||||
nfapi_nr_prach_pdu_t *prach_pdu = &gNB->prach_list.list[0].pdu;
|
||||
prach_pdu->num_cs = get_NCS(NCS_config, format0, restrictedSetConfig);
|
||||
prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value = 1+(64/(N_ZC/prach_pdu->num_cs));
|
||||
prach_pdu->prach_format = prach_format;
|
||||
@@ -769,25 +769,27 @@ int main(int argc, char **argv){
|
||||
nr_slot_fep_ul(frame_parms, ru->common.rxdata[aa], ru->common.rxdataF[aa], l, slot, ru->N_TA_offset);
|
||||
}
|
||||
}
|
||||
rx_nr_prach_ru(ru, prach_format, numRA, 0, prachStartSymbol, slot, prachOccasion, frame, slot);
|
||||
c16_t *rxsigF[ru->nb_rx];
|
||||
for (int i = 0; i < ru->nb_rx; ++i)
|
||||
rxsigF[i] = (c16_t *)ru->prach_rxsigF[prachOccasion][i];
|
||||
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, prachOccasion, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay, rxsigF);
|
||||
|
||||
rx_nr_prach_ru(ru, prach_format, numRA, 0, prachStartSymbol, slot, prachOccasion, frame, slot);
|
||||
// printf(" preamble_energy %d preamble_rx %d preamble_tx %d \n", preamble_energy, preamble_rx, preamble_tx);
|
||||
|
||||
for (int i = 0; i < ru->nb_rx; ++i)
|
||||
gNB->prach_vars.rxsigF[i] = ru->prach_rxsigF[prachOccasion][i];
|
||||
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, prachOccasion, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay);
|
||||
if (preamble_rx != preamble_tx)
|
||||
prach_errors++;
|
||||
else
|
||||
delay_avg += (double)preamble_delay;
|
||||
|
||||
// printf(" preamble_energy %d preamble_rx %d preamble_tx %d \n", preamble_energy, preamble_rx, preamble_tx);
|
||||
N_ZC = (prach_sequence_length) ? 139 : 839;
|
||||
|
||||
if (preamble_rx != preamble_tx)
|
||||
prach_errors++;
|
||||
else
|
||||
delay_avg += (double)preamble_delay;
|
||||
|
||||
N_ZC = (prach_sequence_length) ? 139 : 839;
|
||||
|
||||
if (n_frames==1) {
|
||||
printf("preamble %d (tx %d) : energy %d, delay %d\n",preamble_rx,preamble_tx,preamble_energy,preamble_delay);
|
||||
if (n_frames == 1) {
|
||||
printf("preamble %d (tx %d) : energy %d, delay %d\n", preamble_rx, preamble_tx, preamble_energy, preamble_delay);
|
||||
#ifdef NR_PRACH_DEBUG
|
||||
LOG_M("prach0.m","prach0", &txdata[0][prach_start], frame_parms->samples_per_subframe, 1, 1);
|
||||
LOG_M("rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1);
|
||||
@@ -797,7 +799,7 @@ int main(int argc, char **argv){
|
||||
LOG_M("prach_preamble.m","prachp", &gNB->X_u[0], N_ZC, 1, 1);
|
||||
LOG_M("ue_prach_preamble.m","prachp", &UE->X_u[0], N_ZC, 1, 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("SNR %f dB, UE Speed %f km/h: errors %u/%d (delay %f)\n", SNR, ue_speed, prach_errors, n_frames, delay_avg/(double)(n_frames-prach_errors));
|
||||
|
||||
Reference in New Issue
Block a user