From 01ae8fbb3863cfe7651fac295f2c9adb8e701520 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 16 Aug 2024 15:35:49 +0200 Subject: [PATCH] prach code cleanup --- openair1/PHY/INIT/nr_init.c | 2 - openair1/PHY/NR_TRANSPORT/nr_prach.c | 203 +++++++++++++------------- openair1/PHY/defs_gNB.h | 3 - openair1/SIMULATION/NR_PHY/prachsim.c | 21 ++- 4 files changed, 112 insertions(+), 117 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 531d648463..d47eec2278 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -190,7 +190,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) common_vars->debugBuff_sample_offset = 0; // PRACH - prach_vars->prachF = (int16_t *)malloc16_clear( 1024*2*sizeof(int16_t) ); prach_vars->rxsigF = (int16_t **)malloc16_clear(Prx*sizeof(int16_t*)); prach_vars->prach_ifft = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t)); @@ -273,7 +272,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(common_vars->debugBuff); NR_gNB_PRACH* prach_vars = &gNB->prach_vars; - free_and_zero(prach_vars->prachF); free_and_zero(prach_vars->rxsigF); free_and_zero(prach_vars->prach_ifft); diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index c9f645333b..40c358477f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -432,21 +432,17 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, uint16_t *max_preamble_energy, uint16_t *max_preamble_delay) { - AssertFatal(gNB!=NULL,"Can only be called from gNB\n"); - - int i; - - nfapi_nr_prach_config_t *cfg=&gNB->gNB_config.prach_config; + AssertFatal(gNB != NULL, "Can only be called from gNB\n"); + nfapi_nr_prach_config_t *cfg = &gNB->gNB_config.prach_config; NR_DL_FRAME_PARMS *fp; - uint16_t rootSequenceIndex; - int numrootSequenceIndex; - uint8_t restricted_set; - uint8_t n_ra_prb=0xFF; - int16_t *prachF=NULL; - int nb_rx; + uint16_t rootSequenceIndex; + int numrootSequenceIndex; + uint8_t restricted_set; + uint8_t n_ra_prb=0xFF; + int nb_rx; - int16_t **rxsigF = gNB->prach_vars.rxsigF; + int16_t **rxsigF = gNB->prach_vars.rxsigF; uint8_t preamble_index; uint16_t NCS=99,NCS2; @@ -460,10 +456,8 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, uint8_t not_found; uint16_t u; int16_t *Xu=0; - uint16_t offset; uint16_t first_nonzero_root_idx=0; uint8_t new_dft=0; - uint8_t aa; int32_t lev; int16_t levdB; int log2_ifft_size=10; @@ -473,23 +467,22 @@ 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[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; + 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[prach_pdu->num_ra].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 - restricted_set = cfg->restricted_set_config.value; + restricted_set = cfg->restricted_set_config.value; 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, format %d \n",rootSequenceIndex,numrootSequenceIndex,NCS,N_ZC,prach_fmt); - prach_ifft = gNB->prach_vars.prach_ifft; - prachF = gNB->prach_vars.prachF; + prach_ifft = gNB->prach_vars.prach_ifft; if (LOG_DEBUGFLAG(PRACH)){ if ((frame&1023) < 20) LOG_D(PHY,"PRACH (gNB) : running rx_prach for slot %d, msg1_frequencystart %d, rootSequenceIndex %d\n", slot, msg1_frequencystart, rootSequenceIndex); } @@ -508,10 +501,10 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, preamble_offset_old = 99; - *max_preamble_energy=0; - *max_preamble_delay=0; - *max_preamble=0; - + *max_preamble_energy = 0; + *max_preamble_delay = 0; + *max_preamble = 0; + int16_t prachF[2 * 1024]; for (preamble_index=0 ; preamble_index<64 ; preamble_index++) { if (LOG_DEBUGFLAG(PRACH)){ @@ -521,14 +514,14 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, if (restricted_set == 0) { // This is the relative offset in the root sequence table (5.7.2-4 from 36.211) for the given preamble index preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS))); - + if (preamble_offset != preamble_offset_old) { preamble_offset_old = preamble_offset; new_dft = 1; // This is the \nu corresponding to the preamble index preamble_shift = 0; } - + else { preamble_shift -= NCS; @@ -551,33 +544,32 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, // current root depending on rootSequenceIndex int index = (rootSequenceIndex + preamble_offset) % N_ZC; - u = prach_root_sequence_map[index]; + u = prach_root_sequence_map[index]; - uint16_t n_group_ra = 0; + uint16_t n_group_ra = 0; - if ( (nr_du[u]<(N_ZC/3)) && (nr_du[u]>=NCS) ) { - n_shift_ra = nr_du[u]/NCS; - d_start = (nr_du[u]<<1) + (n_shift_ra * NCS); - n_group_ra = N_ZC/d_start; - n_shift_ra_bar = max(0,(N_ZC-(nr_du[u]<<1)-(n_group_ra*d_start))/N_ZC); - } else if ( (nr_du[u]>=(N_ZC/3)) && (nr_du[u]<=((N_ZC - NCS)>>1)) ) { - n_shift_ra = (N_ZC - (nr_du[u]<<1))/NCS; - d_start = N_ZC - (nr_du[u]<<1) + (n_shift_ra * NCS); - n_group_ra = nr_du[u]/d_start; - n_shift_ra_bar = min(n_shift_ra,max(0,(nr_du[u]- (n_group_ra*d_start))/NCS)); - } else { - n_shift_ra = 0; - n_shift_ra_bar = 0; - } - - // This is the number of cyclic shifts for the current root u - numshift = (n_shift_ra*n_group_ra) + n_shift_ra_bar; - // skip to next root and recompute parameters if numshift==0 - (numshift>0) ? (not_found = 0) : (preamble_offset++); - } - } - - + if ((nr_du[u] < (N_ZC / 3)) && (nr_du[u] >= NCS) ) { + n_shift_ra = nr_du[u] / NCS; + d_start = (nr_du[u] << 1) + (n_shift_ra * NCS); + n_group_ra = N_ZC / d_start; + n_shift_ra_bar = max(0, (N_ZC-(nr_du[u] << 1) - (n_group_ra * d_start)) / N_ZC); + } else if ((nr_du[u] >= (N_ZC / 3)) && (nr_du[u] <= ((N_ZC - NCS) >> 1))) { + n_shift_ra = (N_ZC - (nr_du[u] << 1)) / NCS; + d_start = N_ZC - (nr_du[u] << 1) + (n_shift_ra * NCS); + n_group_ra = nr_du[u] / d_start; + n_shift_ra_bar = min(n_shift_ra, max(0, (nr_du[u]- (n_group_ra * d_start)) / NCS)); + } else { + n_shift_ra = 0; + n_shift_ra_bar = 0; + } + + // This is the number of cyclic shifts for the current root u + numshift = (n_shift_ra * n_group_ra) + n_shift_ra_bar; + // skip to next root and recompute parameters if numshift==0 + (numshift>0) ? (not_found = 0) : (preamble_offset++); + } + } + if (n_shift_ra>0) preamble_shift = -((d_start * (preamble_index0/n_shift_ra)) + ((preamble_index0%n_shift_ra)*NCS)); // minus because the channel is h(t -\tau + Cv) else @@ -595,8 +587,17 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, // Compute DFT of RX signal (conjugate input, results in conjugate output) for each new rootSequenceIndex if (LOG_DEBUGFLAG(PRACH)) { int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); - if (en>60) LOG_D(PHY,"frame %d, slot %d : preamble index %d, NCS %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n", - frame,slot,preamble_index,NCS,N_ZC/NCS,preamble_offset,preamble_shift,en); + if (en>60) + LOG_D(PHY, + "frame %d, slot %d : preamble index %d, NCS %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n", + frame, + slot, + preamble_index, + NCS, + N_ZC / NCS, + preamble_offset, + preamble_shift, + en); } LOG_D(PHY,"PRACH RX preamble_index %d, preamble_offset %d\n",preamble_index,preamble_offset); @@ -605,57 +606,56 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, if (new_dft == 1) { new_dft = 0; - Xu=(int16_t*)gNB->X_u[preamble_offset-first_nonzero_root_idx]; + Xu = (int16_t*)gNB->X_u[preamble_offset-first_nonzero_root_idx]; LOG_D(PHY,"PRACH RX new dft preamble_offset-first_nonzero_root_idx %d\n",preamble_offset-first_nonzero_root_idx); - memset(prach_ifft,0,((N_ZC==839) ? 2048 : 256)*sizeof(int32_t)); - - - memset(prachF, 0, sizeof(int16_t)*2*1024 ); - if (LOG_DUMPFLAG(PRACH)) { + memset(prachF, 0, sizeof(int16_t) * 2 * 1024); + if (LOG_DUMPFLAG(PRACH)) { LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],N_ZC,1,1); LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],6144,1,1); } - for (aa=0;aa>15); - prachF[offset+1] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset+1] - (int32_t)Xu[offset+1]*rxsigF[aa][offset])>>15); - } + for (int offset = 0; offset < (N_ZC << 1); offset += 2) { + prachF[offset] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset] + (int32_t)Xu[offset+1]*rxsigF[aa][offset+1])>>15); + prachF[offset+1] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset+1] - (int32_t)Xu[offset+1]*rxsigF[aa][offset])>>15); + } - // Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139) - if (N_ZC == 839) { - idft(IDFT_1024,prachF,prach_ifft_tmp,1); - // compute energy and accumulate over receive antennas - for (i=0;i<1024;i++) - prach_ifft[i] += (int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[i<<1] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)]; - } else { - idft(IDFT_256,prachF,prach_ifft_tmp,1); - log2_ifft_size = 8; - // compute energy and accumulate over receive antennas and repetitions for BR - for (i=0;i<256;i++) - prach_ifft[i] += (int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[(i<<1)] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)]; - } - - if (LOG_DUMPFLAG(PRACH)) { - if (aa==0) LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1); - if (aa==1) LOG_M("prach_rxF_comp1.m","prach_rxF_comp1",prachF,1024,1,1); + // Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139) + if (N_ZC == 839) { + idft(IDFT_1024, prachF, prach_ifft_tmp, 1); + // compute energy and accumulate over receive antennas + for (int i = 0; i < 1024; i++) + prach_ifft[i] += (int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[i<<1] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)]; + } else { + idft(IDFT_256, prachF, prach_ifft_tmp, 1); + log2_ifft_size = 8; + // compute energy and accumulate over receive antennas and repetitions for BR + for (int i = 0; i < 256; i++) + prach_ifft[i] += (int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[(i<<1)] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)]; } - }// antennas_rx + if (LOG_DUMPFLAG(PRACH)) { + if (aa == 0) + LOG_M("prach_rxF_comp0.m","prach_rxF_comp0", prachF, 1024, 1, 1); + if (aa == 1) + LOG_M("prach_rxF_comp1.m","prach_rxF_comp1", prachF, 1024, 1, 1); + } + + } // antennas_rx // Normalization of energy over ifft and receive antennas if (N_ZC == 839) { log2_ifft_size = 10; - for (i=0;i<1024;i++) + for (int i = 0; i < 1024; i++) prach_ifft[i] = (prach_ifft[i]>>log2_ifft_size)/nb_rx; } else { log2_ifft_size = 8; - for (i=0;i<256;i++) + for (int i = 0; i < 256; i++) prach_ifft[i] = (prach_ifft[i]>>log2_ifft_size)/nb_rx; } @@ -665,14 +665,14 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, preamble_shift2 = ((preamble_shift==0) ? 0 : ((preamble_shift<*max_preamble_energy) { LOG_D(PHY,"preamble_index %d, delay %d en %d dB > %d dB\n",preamble_index,i,levdB,*max_preamble_energy); - *max_preamble_energy = levdB; - *max_preamble_delay = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate - *max_preamble = preamble_index; + *max_preamble_energy = levdB; + *max_preamble_delay = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate + *max_preamble = preamble_index; } } }// preamble_index @@ -695,9 +695,11 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, // max_preamble_delay * ( (2048/2^mu*(fs/30.72M)) / 256 ) / fs = TA * 16 * 64 / 2^mu * Tc uint16_t *TA = max_preamble_delay; int mu = fp->numerology_index; - if (cfg->prach_sequence_length.value==0) { - if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) *TA = *TA*3*(1<prach_sequence_length.value == 0) { + if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) + *TA = *TA * 3 * (1 << mu) / 2; + else if (prach_fmt == 3) + *TA = *TA * 3 * (1 << mu) / 8; } else *TA = *TA/2; @@ -705,19 +707,18 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, if (LOG_DUMPFLAG(PRACH)) { //int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); // if (en>60) { - int k = (12*n_ra_prb) - 6*fp->N_RB_UL; - - if (k<0) k+=fp->ofdm_symbol_size; - + int k = (12 * n_ra_prb) - 6 * fp->N_RB_UL; + if (k < 0) + k += fp->ofdm_symbol_size; + k*=12; k+=13; k*=2; - - LOG_M("rxsigF.m","prach_rxF",&rxsigF[0][0],12288,1,1); - LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1); - LOG_M("Xu.m","xu",Xu,N_ZC,1,1); - LOG_M("prach_ifft0.m","prach_t0",prach_ifft,1024,1,1); + LOG_M("rxsigF.m","prach_rxF", &rxsigF[0][0], 12288, 1, 1); + LOG_M("prach_rxF_comp0.m","prach_rxF_comp0", prachF, 1024, 1, 1); + LOG_M("Xu.m","xu", Xu, N_ZC, 1, 1); + LOG_M("prach_ifft0.m","prach_t0", prach_ifft, 1024, 1, 1); // } } /* LOG_DUMPFLAG(PRACH) */ stop_meas(&gNB->rx_prach); diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index fea27048de..3d84ada2dc 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -145,9 +145,6 @@ typedef struct { #define NUMBER_OF_NR_PRACH_MAX 8 typedef struct { - /// \brief ?. - /// first index: ? [0..1023] (hard coded) - int16_t *prachF; /// \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[ diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 94260334a1..d4b109a529 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -779,22 +779,21 @@ int main(int argc, char **argv){ 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("prachF0.m","prachF0", &gNB->prach_vars.prachF[0], N_ZC, 1, 1); - LOG_M("rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1); - LOG_M("ru_rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1); - LOG_M("ru_rxsigF0.m","rxsF0", ru->common.rxdataF[0], frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot, 1, 1); - LOG_M("ru_prach_rxsigF0.m","rxsF0", ru->prach_rxsigF[0][0], N_ZC, 1, 1); - 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 +#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); + LOG_M("ru_rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1); + LOG_M("ru_rxsigF0.m","rxsF0", ru->common.rxdataF[0], frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot, 1, 1); + LOG_M("ru_prach_rxsigF0.m","rxsF0", ru->prach_rxsigF[0][0], N_ZC, 1, 1); + 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)); if (input_fd) - break; + break; if (prach_errors) break;