From 70711633bcf574f5bfbd507ff337bb2d586c9960 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Sun, 26 Oct 2025 23:13:59 +0100 Subject: [PATCH] code cleaning pss and sss detection, no functional change --- openair1/PHY/NR_REFSIG/sss_nr.h | 3 - openair1/PHY/NR_TRANSPORT/nr_sss.c | 13 +- .../PHY/NR_TRANSPORT/nr_transport_proto.h | 6 +- .../PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/pss_nr.c | 188 +++------- openair1/PHY/NR_UE_TRANSPORT/sss_nr.c | 333 ++++-------------- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 2 +- 7 files changed, 113 insertions(+), 434 deletions(-) diff --git a/openair1/PHY/NR_REFSIG/sss_nr.h b/openair1/PHY/NR_REFSIG/sss_nr.h index 5bb55ebe2f..7bd37a7dc0 100644 --- a/openair1/PHY/NR_REFSIG/sss_nr.h +++ b/openair1/PHY/NR_REFSIG/sss_nr.h @@ -90,9 +90,6 @@ static const c16_t phase_nr[PHASE_HYPOTHESIS_NUMBER] = { void init_context_sss_nr(int amp); void free_context_sss_nr(void); -void insert_sss_nr(int16_t *sss_time, - NR_DL_FRAME_PARMS *frame_parms); - bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms, int nid2, int target_Nid_cell, diff --git a/openair1/PHY/NR_TRANSPORT/nr_sss.c b/openair1/PHY/NR_TRANSPORT/nr_sss.c index 71bae9a065..08f7f86cbf 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_sss.c +++ b/openair1/PHY/NR_TRANSPORT/nr_sss.c @@ -23,11 +23,7 @@ //#define NR_SSS_DEBUG -int nr_generate_sss( c16_t *txdataF, - int16_t amp, - uint8_t ssb_start_symbol, - nfapi_nr_config_request_scf_t* config, - NR_DL_FRAME_PARMS *frame_parms) +int nr_generate_sss(c16_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, int Nid, NR_DL_FRAME_PARMS *frame_parms) { int16_t x0[NR_SSS_LENGTH]; int16_t x1[NR_SSS_LENGTH]; @@ -35,7 +31,6 @@ int nr_generate_sss( c16_t *txdataF, const int x1_initial[7] = { 1, 0, 0, 0, 0, 0, 0 }; /// Sequence generation - int Nid = config->cell_config.phy_cell_id.value; int Nid2 = Nid % 3; int Nid1 = (Nid - Nid2)/3; @@ -59,13 +54,11 @@ int nr_generate_sss( c16_t *txdataF, /// Resource mapping // SSS occupies a predefined position (subcarriers 56-182, symbol 2) within the SSB block starting from - int k = frame_parms->ssb_start_subcarrier + 56; - int l = ssb_start_symbol + 2; + c16_t *tx = txdataF + (ssb_start_symbol + 2) * frame_parms->ofdm_symbol_size + frame_parms->ssb_start_subcarrier + 56; for (int i = 0; i < NR_SSS_LENGTH; i++) { int16_t d_sss = (1 - 2*x0[(i + m0) % NR_SSS_LENGTH] ) * (1 - 2*x1[(i + m1) % NR_SSS_LENGTH] ) * 23170; - ((int16_t*)txdataF)[2*(l*frame_parms->ofdm_symbol_size + k)] = (((int16_t)amp) * d_sss) >> 15; - k++; + *tx++ = (c16_t){.r = (amp * d_sss) >> 15}; } #ifdef NR_SSS_DEBUG // write_output("sss_0.m", "sss_0", (void*)txdataF[0][l*frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size, 1, 1); diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index a38bf9b6bb..68b3842594 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -60,11 +60,7 @@ int nr_generate_pss(c16_t *txdataF, @param @returns 0 on success */ -int nr_generate_sss(c16_t *txdataF, - int16_t amp, - uint8_t ssb_start_symbol, - nfapi_nr_config_request_scf_t *config, - NR_DL_FRAME_PARMS *frame_parms); +int nr_generate_sss(c16_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, int nid, NR_DL_FRAME_PARMS *frame_parms); /*! \fn void nr_generate_pbch_dmrs diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c index e407459bc8..0636c9d7d9 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c @@ -260,7 +260,7 @@ static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue, c16_t *sss = &sss_ext[0][0][0]; for (uint16_t id1 = 0; id1 < SL_NR_NUM_IDs_IN_SSS; id1++) { // all possible SSS Nid1 values - for (phase = 0; phase < PHASE_HYPOTHESIS_NUMBER; phase++) { // phase offset between PSS and SSS + for (phase = 0; phase < sizeofArray(phase_nr); phase++) { // phase offset between PSS and SSS int32_t metric = 0, metric_re = 0; diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index e4b68a4d66..2e142812e3 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -49,24 +49,12 @@ //#define DBG_PSS_NR static time_stats_t generic_time[TIME_LAST]; -int pss_search_time_nr(const c16_t **rxdata, - const NR_DL_FRAME_PARMS *frame_parms, - const c16_t pssTime[NUMBER_PSS_SEQUENCE][frame_parms->ofdm_symbol_size], - bool fo_flag, - int is, - int target_Nid_cell, - int *nid2, - int *f_off, - int *pssPeak, - int *pssAvg, - int search_start, - int search_length); -static int16_t primary_synchro_nr2[NUMBER_PSS_SEQUENCE][LENGTH_PSS_NR] = {0}; +static int16_t d_pss[NUMBER_PSS_SEQUENCE][LENGTH_PSS_NR] = {0}; static c16_t primary_synchro[NUMBER_PSS_SEQUENCE][LENGTH_PSS_NR] = {0}; int16_t *get_primary_synchro_nr2(const int nid2) { - return primary_synchro_nr2[nid2]; + return d_pss[nid2]; } /******************************************************************* @@ -86,12 +74,9 @@ int16_t *get_primary_synchro_nr2(const int nid2) void generate_pss_nr(NR_DL_FRAME_PARMS *fp, int N_ID_2) { AssertFatal(fp->ofdm_symbol_size > 127,"Illegal ofdm_symbol_size %d\n",fp->ofdm_symbol_size); - AssertFatal(N_ID_2>=0 && N_ID_2 <=2,"Illegal N_ID_2 %d\n",N_ID_2); - int16_t d_pss[LENGTH_PSS_NR]; + AssertFatal(N_ID_2 >= 0 && N_ID_2 <= 2, "Illegal N_ID_2 %d\n", N_ID_2); int16_t x[LENGTH_PSS_NR]; - int16_t *primary_synchro2 = primary_synchro_nr2[N_ID_2]; /* pss in complex with alternatively i then q */ - #define INITIAL_PSS_NR (7) const int16_t x_initial[INITIAL_PSS_NR] = {0, 1, 1, 0, 1, 1, 1}; assert(N_ID_2 < NUMBER_PSS_SEQUENCE); @@ -99,16 +84,15 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp, int N_ID_2) for (int i = 0; i < (LENGTH_PSS_NR - INITIAL_PSS_NR); i++) x[i + INITIAL_PSS_NR] = (x[i + 4] + x[i]) % (2); - + int16_t *pss = d_pss[N_ID_2]; for (int n=0; n < LENGTH_PSS_NR; n++) { const int m = (n + 43 * N_ID_2) % (LENGTH_PSS_NR); - d_pss[n] = 1 - 2*x[m]; + pss[n] = 1 - 2 * x[m]; } /* PSS is directly mapped to subcarrier without modulation 38.211 */ for (int i=0; i < LENGTH_PSS_NR; i++) { - primary_synchro[N_ID_2][i].r = (d_pss[i] * SHRT_MAX) >> SCALING_PSS_NR; /* Maximum value for type short int ie int16_t */ - primary_synchro2[i] = d_pss[i]; + primary_synchro[N_ID_2][i].r = (pss[i] * SHRT_MAX) >> SCALING_PSS_NR; /* Maximum value for type short int ie int16_t */ } #ifdef DBG_PSS_NR @@ -150,12 +134,13 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp, int N_ID_2) void generate_pss_nr_time(const NR_DL_FRAME_PARMS *fp, const int N_ID_2, int ssbFirstSCS, c16_t pssTime[fp->ofdm_symbol_size]) { unsigned int subcarrier_start = get_softmodem_params()->sl_mode == 0 ? PSS_SSS_SUB_CARRIER_START : PSS_SSS_SUB_CARRIER_START_SL; - unsigned int k = fp->first_carrier_offset + ssbFirstSCS + subcarrier_start; - if (k>= fp->ofdm_symbol_size) k-=fp->ofdm_symbol_size; c16_t synchroF_tmp[fp->ofdm_symbol_size] __attribute__((aligned(32))); memset(synchroF_tmp, 0, sizeof(synchroF_tmp)); + unsigned int k = fp->first_carrier_offset + ssbFirstSCS + subcarrier_start; for (int i=0; i < LENGTH_PSS_NR; i++) { - synchroF_tmp[k % fp->ofdm_symbol_size] = primary_synchro[N_ID_2][i]; + if (k >= fp->ofdm_symbol_size) + k -= fp->ofdm_symbol_size; + synchroF_tmp[k] = primary_synchro[N_ID_2][i]; k++; } @@ -182,54 +167,6 @@ void generate_pss_nr_time(const NR_DL_FRAME_PARMS *fp, const int N_ID_2, int ssb } #endif - - - -#if 0 - -/* it allows checking that process of idft on a signal and then dft gives same signal with limited errors */ - - if ((N_ID_2 == 0) && (length == 256)) { - - LOG_M("pss_f00.m","pss_f00",synchro_tmp,length,1,1); - - - bzero(synchroF_tmp, size); - - - - /* get pss in the time domain by applying an inverse FFT */ - dft((int16_t)get_dft(length), - synchro_tmp, /* complex input */ - synchroF_tmp, /* complex output */ - 1); /* scaling factor */ - - if ((N_ID_2 == 0) && (length == 256)) { - LOG_M("pss_f_0.m","pss_f_0",synchroF_tmp,length,1,1); - } - - /* check Pss */ - k = length - (LENGTH_PSS_NR/2); - -#define LIMIT_ERROR_FFT (10) - - for (int i=0; i < LENGTH_PSS_NR; i++) { - if (abs(synchroF_tmp[2*k] - primary_synchro[i].r) > LIMIT_ERROR_FFT) { - printf("Pss Error[%d] Compute %d Reference %d \n", k, synchroF_tmp[2*k], primary_synchro[i].r); - } - - if (abs(synchroF_tmp[2*k+1] - primary_synchro[i].i) > LIMIT_ERROR_FFT) { - printf("Pss Error[%d] Compute %d Reference %d\n", (2*k+1), synchroF_tmp[2*k+1], primary_synchro[i].i); - } - - k++; - - if (k >= length) { - k-=length; - } - } - } -#endif } /******************************************************************* @@ -391,50 +328,32 @@ int pss_synchro_nr(const c16_t **rxdata, int *pssAvg) { #ifdef DBG_PSS_NR - - LOG_M("rxdata0_rand.m","rxd0_rand", &PHY_vars_UE->common_vars.rxdata[0][0], frame_parms->samples_per_frame, 1, 1); - -#endif - -#ifdef DBG_PSS_NR - - LOG_M("rxdata0_des.m","rxd0_des", &rxdata[0][0], frame_parms->samples_per_frame,1,1); - + LOG_M("rxdata0_rand.m", "rxd0_rand", &PHY_vars_UE->common_vars.rxdata[0][0], frame_parms->samples_per_frame, 1, 1); + LOG_M("rxdata0_des.m", "rxd0_des", &rxdata[0][0], frame_parms->samples_per_frame, 1, 1); #endif start_meas(&generic_time[TIME_PSS]); - int synchro_position = pss_search_time_nr(rxdata, frame_parms, pssTime, fo_flag, is, target_Nid_cell, nid2, f_off, pssPeak, pssAvg, -1, -1); + stop_meas(&generic_time[TIME_PSS]); #if TEST_SYNCHRO_TIMING_PSS - stop_meas(&generic_time[TIME_PSS]); - - int duration_ms = generic_time[TIME_PSS].p_time/(cpuf*1000.0); - - #ifndef NR_UNIT_TEST - - LOG_D(PHY,"PSS execution duration %4d microseconds \n", duration_ms); - - #endif - + int duration_ms = generic_time[TIME_PSS].p_time / (cpuf * 1000.0); +#ifndef NR_UNIT_TEST + LOG_D(PHY, "PSS execution duration %4d microseconds \n", duration_ms); +#endif #endif #ifdef SYNCHRO_DECIMAT - if (rate_change != 1) { - if (rxdata[0] != NULL) { - for (int aa=0;aanb_antennas_rx;aa++) { free(rxdata[aa]); } - free(rxdata); } - - restore_frame_context_pss_nr(frame_parms, rate_change); + restore_frame_context_pss_nr(frame_parms, rate_change); } #endif @@ -504,11 +423,6 @@ int pss_search_time_nr(const c16_t **rxdata, int search_start, int search_length) { - unsigned int n, ar, peak_position, pss_source; - int64_t peak_value; - int64_t avg[NUMBER_PSS_SEQUENCE] = {0}; - double ffo_est = 0; - // Determine search window unsigned int start, length; if (search_start >= 0 && search_length > 0) { @@ -524,11 +438,7 @@ int pss_search_time_nr(const c16_t **rxdata, length = frame_parms->samples_per_frame; } - AssertFatal(length>0,"illegal length %d\n",length); - peak_value = 0; - peak_position = 0; - pss_source = 0; - + AssertFatal(length > 0, "illegal length %d\n", length); int maxval=0; int max_size = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL; for (int j = 0; j < max_size; j++) @@ -542,53 +452,55 @@ int pss_search_time_nr(const c16_t **rxdata, /* This is required by SIMD (single instruction Multiple Data) Extensions of Intel processors. */ /* Correlation computation is based on a a dot product which is realized thank to SIMS extensions */ - uint16_t pss_index_start = 0; - uint16_t pss_index_end = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL; + int pss_index_start; + int pss_index_end; if (target_Nid_cell != -1) { pss_index_start = GET_NID2(target_Nid_cell); pss_index_end = pss_index_start + 1; + } else { + pss_index_start = 0; + pss_index_end = max_size; } + int64_t avg[NUMBER_PSS_SEQUENCE] = {0}; + int64_t peak_value = 0; + unsigned int peak_position = 0; + unsigned int pss_source = 0; for (int pss_index = pss_index_start; pss_index < pss_index_end; pss_index++) { - for (n = start; n < start + length; n += 4) { // - - int64_t pss_corr_ue=0; + for (int n = start; n < start + length; n += 4) { // + int64_t pss_corr_ue = 0; /* calculate dot product of primary_synchro_time_nr and rxdata[ar][n] * (ar=0..nb_ant_rx) and store the sum in temp[n]; */ - for (ar=0; arnb_antennas_rx; ar++) { - + for (int ar = 0; ar < frame_parms->nb_antennas_rx; ar++) { /* perform correlation of rx data and pss sequence ie it is a dot product */ const c32_t result = dot_product(pssTime[pss_index], - &(rxdata[ar][n + is * frame_parms->samples_per_frame]), + &rxdata[ar][n + is * frame_parms->samples_per_frame], frame_parms->ofdm_symbol_size, shift); const c64_t r64 = {.r = result.r, .i = result.i}; pss_corr_ue += squaredMod(r64); - //((short*)pss_corr_ue[pss_index])[2*n] += ((short*) &result)[0]; /* real part */ - //((short*)pss_corr_ue[pss_index])[2*n+1] += ((short*) &result)[1]; /* imaginary part */ - //((short*)&synchro_out)[0] += ((int*) &result)[0]; /* real part */ - //((short*)&synchro_out)[1] += ((int*) &result)[1]; /* imaginary part */ - } - + /* calculate the absolute value of sync_corr[n] */ - avg[pss_index]+=pss_corr_ue; + avg[pss_index] += pss_corr_ue; if (pss_corr_ue > peak_value) { peak_value = pss_corr_ue; peak_position = n; pss_source = pss_index; - + #ifdef DEBUG_PSS_NR printf("pss_index %d: n %6u peak_value %15llu\n", pss_index, n, (unsigned long long)pss_corr_ue[n]); #endif } } + avg[pss_index] /= (length / 4); } - - if (fo_flag){ - // fractional frequency offset computation according to Cross-correlation Synchronization Algorithm Using PSS - // Shoujun Huang, Yongtao Su, Ying He and Shan Tang, "Joint time and frequency offset estimation in LTE downlink," 7th International Conference on Communications and Networking in China, 2012. + double ffo_est = 0; + if (fo_flag) { + // fractional frequency offset computation according to Cross-correlation Synchronization Algorithm Using PSS + // Shoujun Huang, Yongtao Su, Ying He and Shan Tang, "Joint time and frequency offset estimation in LTE downlink," 7th + // International Conference on Communications and Networking in China, 2012. // Computing cross-correlation at peak on half the symbol size for first half of data c32_t r1 = dot_product(pssTime[pss_source], @@ -606,15 +518,11 @@ int pss_search_time_nr(const c16_t **rxdata, ffo_est = atan2(r1d.r * r2d.i - r2d.r * r1d.i, r1d.r * r2d.r + r1d.i * r2d.i) / M_PI; #ifdef DBG_PSS_NR - printf("ffo %lf\n",ffo_est); + printf("ffo %lf\n", ffo_est); #endif } - // computing absolute value of frequency offset - *f_off = ffo_est*frame_parms->subcarrier_spacing; - - for (int pss_index = pss_index_start; pss_index < pss_index_end; pss_index++) - avg[pss_index] /= (length / 4); + *f_off = ffo_est * frame_parms->subcarrier_spacing; *nid2 = pss_source; *pssPeak = dB_fixed64(peak_value); @@ -631,22 +539,18 @@ int pss_search_time_nr(const c16_t **rxdata, ffo_est); if ((search_start < 0 || search_length == 0) && peak_value < 5 * avg[pss_source]) - return(-1); - + return (-1); #ifdef DBG_PSS_NR - static int debug_cnt = 0; - if (debug_cnt == 0) { if (is) - LOG_M("rxdata1.m","rxd0",rxdata[frame_parms->samples_per_frame],length,1,1); + LOG_M("rxdata1.m", "rxd0", rxdata[frame_parms->samples_per_frame], length, 1, 1); else - LOG_M("rxdata0.m","rxd0",rxdata[0],length,1,1); + LOG_M("rxdata0.m", "rxd0", rxdata[0], length, 1, 1); } else { debug_cnt++; } - #endif return peak_position; diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c index 34751c1742..8e9c3ad510 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c @@ -109,71 +109,8 @@ void init_context_sss_nr(int amp) #endif } -/******************************************************************* -* -* NAME : insert_sss_nr -* -* PARAMETERS : pointer to input buffer for which sss in inserted -* amp amplitude applied to input -* frame parameters for cell identity -* -* RETURN : none -* -* DESCRIPTION : Allow to generate a reference sss sequence according to cell identity -* -*********************************************************************/ - -//#define DEBUG_SSS_NR -//#define DEBUG_PLOT_SSS -void insert_sss_nr(int16_t *sss_time, - NR_DL_FRAME_PARMS *frame_parms) -{ - const unsigned int ofdm_symbol_size = frame_parms->ofdm_symbol_size; - int Nid2 = GET_NID2(frame_parms->Nid_cell); - int Nid1 = GET_NID1(frame_parms->Nid_cell); - - /* call of IDFT should be done with ordered input as below - * - * n input samples - * <------------------------------------------------> - * 0 n - * are written into input buffer for IFFT in this order - * ------------------------------------------------- - * |xxxxxxx N/2 xxxxxxxx| - * -------------------------------------------------- - * ^ ^ ^ ^ ^ - * | | | | | - * n/2 end of n=0 start of n/2-1 - * sss sss - * - * Frequencies - * positives negatives - * 0 (+N/2)(-N/2) - * |-----------------------><-------------------------| - * - * sample 0 is for continuous frequency which is not used here - */ - - unsigned int k = ofdm_symbol_size - ((LENGTH_SSS_NR/2)+1); - c16_t synchroF_tmp[2048] __attribute__((aligned(32))); - c16_t synchro_tmp[2048] __attribute__((aligned(32))); - bzero(synchroF_tmp, sizeof(synchroF_tmp)); - - /* SSS is directly mapped to subcarrier */ - for (int i=0; inb_antennas_rx][LENGTH_PSS_NR], c16_t sss_ext[frame_parms->nb_antennas_rx][LENGTH_SSS_NR]) @@ -199,148 +136,60 @@ static int pss_ch_est_nr(const NR_DL_FRAME_PARMS *frame_parms, c16_t *pss_ext2 = pss_ext[aarx]; for (int i = 0; i < LENGTH_PSS_NR; i++) { // This is H*(PSS) = R* \cdot PSS - const int tmp_re = pss_ext2[i].r * pss[i]; - const int tmp_im = -pss_ext2[i].i * pss[i]; - - const int32_t amp = tmp_re * tmp_re + tmp_im * tmp_im; + const c16_t tmp = (c16_t){pss_ext2[i].r * pss[i], -pss_ext2[i].i * pss[i]}; + const int32_t amp = squaredMod(tmp); const int shift = log2_approx(amp) / 2; // This is R(SSS) \cdot H*(PSS) - const c16_t tmp = {(tmp_re * sss_ext2[i].r - tmp_im * sss_ext2[i].i) >> shift, - (tmp_re * sss_ext2[i].i + tmp_im * sss_ext2[i].r) >> shift}; - // printf("SSSi(%d,%d) : (%d,%d)\n",aarx,i,sss_ext2[i<<1],sss_ext2[1+(i<<1)]); - // printf("SSSo(%d,%d) : (%d,%d)\n",aarx,i,tmp_re2,tmp_im2); - // MRC on RX antennas - if (aarx == 0) { - sss_ext2[i].r = tmp.r; - sss_ext2[i].i = tmp.i; - } else { - sss_ext2[i].r += tmp.r; - sss_ext2[i].i += tmp.i; - } + const c16_t new_sss = c16mulShift(tmp, sss_ext2[i], shift); + if (aarx == 0) + sss_ext2[i] = new_sss; + else + sss_ext2[i] = c16add(sss_ext2[i], new_sss); } } -#if 0 - LOG_M("pssrx.m","pssrx",pss,LENGTH_PSS_NR,1,1); - LOG_M("pss_ext.m","pssext",pss_ext2,LENGTH_PSS_NR,1,1); - LOG_M("psschest.m","pssch",chest,LENGTH_PSS_NR,1,1); -#endif -#if 0 - - for (int i = 0; i < LENGTH_PSS_NR; i++) { - printf(" sss ext 2 [%d] %d %d at address %p\n", i, sss_ext2[2*i], sss_ext2[2*i+1]); - printf(" sss ref [%d] %d %d at address %p\n", i, d_sss[0][0][i], d_sss[0][0][i]); - printf(" sss ext 3 [%d] %d %d at address %p\n", i, sss_ext3[2*i], sss_ext3[2*i+1]); - } - -#endif - - // sss_ext now contains the compensated SSS - return(0); + // sss_ext[0] now contains the compensated SSS } /******************************************************************* -* -* NAME : do_pss_sss_extract -* -* PARAMETERS : none -* -* RETURN : none -* -* DESCRIPTION : it allows extracting sss from samples buffer -* -*********************************************************************/ + * + * NAME : pss_sss_extract_nr + * + * PARAMETERS : none + * + * RETURN : none + * + * DESCRIPTION : it allows extracting sss from samples buffer + * + *********************************************************************/ -static int do_pss_sss_extract_nr(const NR_DL_FRAME_PARMS *frame_parms, +static void pss_sss_extract_nr(const NR_DL_FRAME_PARMS *frame_parms, c16_t pss_ext[frame_parms->nb_antennas_rx][LENGTH_PSS_NR], c16_t sss_ext[frame_parms->nb_antennas_rx][LENGTH_SSS_NR], - uint8_t doPss, - uint8_t doSss, int ssb_start_subcarrier, c16_t rxdataF[][frame_parms->samples_per_slot_wCP]) // add flag to indicate extracting only PSS, only SSS, or both { - AssertFatal(frame_parms->nb_antennas_rx > 0, "UB as sss_ext is not set to any value\n"); + AssertFatal(frame_parms->nb_antennas_rx > 0, "nb antennas as sss_ext is not set to any value\n"); + const unsigned int ofdm_symbol_size = frame_parms->ofdm_symbol_size; + const int pss_symbol = 0; + const int sss_symbol = + get_softmodem_params()->sl_mode == 0 ? (SSS_SYMBOL_NB - PSS_SYMBOL_NB) : (SSS0_SL_SYMBOL_NB - PSS0_SL_SYMBOL_NB); for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { - int pss_symbol = 0; - int sss_symbol = get_softmodem_params()->sl_mode == 0 ? - (SSS_SYMBOL_NB - PSS_SYMBOL_NB) : - (SSS0_SL_SYMBOL_NB - PSS0_SL_SYMBOL_NB) ; - unsigned int ofdm_symbol_size = frame_parms->ofdm_symbol_size; - c16_t *pss_rxF = rxdataF[aarx] + pss_symbol * ofdm_symbol_size; c16_t *sss_rxF = rxdataF[aarx] + sss_symbol * ofdm_symbol_size; - c16_t *pss_rxF_ext = pss_ext[aarx]; c16_t *sss_rxF_ext = sss_ext[aarx]; - unsigned int k = frame_parms->first_carrier_offset + ssb_start_subcarrier + ((get_softmodem_params()->sl_mode == 0) ? PSS_SSS_SUB_CARRIER_START : PSS_SSS_SUB_CARRIER_START_SL); - if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size; - for (int i=0; i < LENGTH_PSS_NR; i++) { - if (doPss) { - pss_rxF_ext[i] = pss_rxF[k]; - } - - if (doSss) { - sss_rxF_ext[i] = sss_rxF[k]; - } - + if (k >= frame_parms->ofdm_symbol_size) + k -= frame_parms->ofdm_symbol_size; + pss_rxF_ext[i] = pss_rxF[k]; + sss_rxF_ext[i] = sss_rxF[k]; k++; - if (k == frame_parms->ofdm_symbol_size) k = 0; } } - -#if 0 - - int16_t *p = (int16_t *)sss_rxF_ext; - - for (int i = 0; i < LENGTH_PSS_NR; i++) { - printf(" sss ext 2 [%d] %d %d at address %p\n", i, p[2*i], p[2*i+1], &p[2*i]); - printf(" sss ref [%d] %d %d at address %p\n", i, d_sss[0][0][i], d_sss[0][0][i], &d_sss[0][0][i]); - } - -#endif - -#if 0 - - int16_t *p2 = (int16_t *)pss_rxF_ext; - - for (int i = 0; i < LENGTH_PSS_NR; i++) { - printf(" pss_rxF_ext [%d] %d %d at address %p\n", i, p2[2*i], p2[2*i+1], &p2[2*i]); - } - -#endif - - return(0); -} - -/******************************************************************* -* -* NAME : pss_sss_extract_nr -* -* PARAMETERS : none -* -* RETURN : none -* -* DESCRIPTION : -* -*********************************************************************/ - -static int pss_sss_extract_nr(const NR_DL_FRAME_PARMS *frame_parms, - c16_t pss_ext[frame_parms->nb_antennas_rx][LENGTH_PSS_NR], - c16_t sss_ext[frame_parms->nb_antennas_rx][LENGTH_SSS_NR], - int ssb_start_subcarrier, - c16_t rxdataF[][frame_parms->samples_per_slot_wCP]) -{ - return do_pss_sss_extract_nr(frame_parms, - pss_ext, - sss_ext, - 1 /* doPss */, - 1 /* doSss */, - ssb_start_subcarrier, - rxdataF); } /******************************************************************* @@ -366,44 +215,22 @@ bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms, int *freq_offset_sss, c16_t rxdataF[][frame_parms->samples_per_slot_wCP]) { - uint8_t i; c16_t pss_ext[frame_parms->nb_antennas_rx][LENGTH_PSS_NR]; c16_t sss_ext[frame_parms->nb_antennas_rx][LENGTH_SSS_NR]; - uint8_t Nid2 = GET_NID2(nid2); - uint16_t Nid1; - uint8_t phase; - int32_t metric, metric_re; - int16_t *d; - + const int Nid2 = GET_NID2(nid2); // pss sss extraction pss_sss_extract_nr(frame_parms, pss_ext, sss_ext, ssb_start_subcarrier, rxdataF); /* subframe */ #ifdef DEBUG_PLOT_SSS - write_output("rxsig0.m","rxs0",&ue->common_vars.rxdata[0][0],ue->frame_parms.samples_per_subframe,1,1); write_output("rxdataF0_pss.m","rxF0_pss",&ue->common_vars.rxdataF[0][0],frame_parms->ofdm_symbol_size,1,1); write_output("rxdataF0_sss.m","rxF0_sss",&ue->common_vars.rxdataF[0][(SSS_SYMBOL_NB-PSS_SYMBOL_NB)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); - write_output("pss_ext.m","pss_ext",pss_ext,LENGTH_PSS_NR,1,1); - -#endif - -#if 0 - int16_t *p = (int16_t *)sss_ext[0]; - int16_t *p2 = (int16_t *)pss_ext[0]; - - for (int i = 0; i < LENGTH_SSS_NR; i++) { - printf("sss ref [%i] : %d %d \n", i, d_sss[0][0][i], d_sss[0][0][i]); - printf("sss ext [%i] : %d %d \n", i, p[2*i], p[2*i+1]); - - printf("pss ref [%i] : %d %d \n", i, primary_synchro_nr2[0][2*i], primary_synchro_nr2[0][2*i+1]); - printf("pss ext [%i] : %d %d \n", i, p2[2*i], p2[2*i+1]); - } + write_output("pss_ext.m", "pss_ext", pss_ext, LENGTH_PSS_NR, 1, 1); #endif // get conjugated channel estimate from PSS, H* = R* \cdot PSS // and do channel estimation and compensation based on PSS - pss_ch_est_nr(frame_parms, nid2, pss_ext, sss_ext); // now do the SSS detection based on the precomputed sequences in PHY/LTE_TRANSPORT/sss.h @@ -411,91 +238,49 @@ bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms, c16_t *sss = sss_ext[0]; -#ifdef DEBUG_PLOT_SSS - - write_output("sss_ext.m","sss_ext",sss_ext[0],LENGTH_SSS_NR,1,1); - write_output("sss_ref.m","sss_ref", d_sss,LENGTH_SSS_NR,1,1); - -#endif - - -#if 0 - - /* simulate of a phase shift on the signal */ - - int phase_shift_index = 0; - - phase_shift_samples(sss, LENGTH_SSS_NR, phase_re_nr[phase_shift_index], phase_im_nr[phase_shift_index]); - -#endif - -#if 0 - int16_t *ps = (int16_t *)pss_ext; - - for (int i = 0; i < LENGTH_SSS_NR; i++) { - printf("sss ref [%i] : %d \n", i, d_sss[0][0][i]); - printf("sss ext [%i] : %d %d \n", i, sss[i].r, sss[i].i); - - printf("pss ref [%i] : %d %d \n", i, primary_synchro_nr2[0][2*i], primary_synchro_nr2[0][2*i+1]); - printf("pss ext [%i] : %d %d \n", i, ps[2*i], ps[2*i+1]); - } -#endif - /* for phase evaluation, one uses an array of possible phase shifts */ /* then a correlation is done between received signal with a shift pĥase and the reference signal */ /* Computation of signal with shift phase is based on below formula */ /* cosinus cos(x + y) = cos(x)cos(y) - sin(x)sin(y) */ /* sinus sin(x + y) = sin(x)cos(y) + cos(x)sin(y) */ - uint16_t Nid1_start = 0; - uint16_t Nid1_end = N_ID_1_NUMBER; + int Nid1_start = 0; + int Nid1_end = N_ID_1_NUMBER; if (target_Nid_cell != -1) { Nid1_start = GET_NID1(target_Nid_cell); Nid1_end = Nid1_start + 1; } - for (Nid1 = Nid1_start; Nid1 < Nid1_end; Nid1++) { // all possible Nid1 values - for (phase = 0; phase < PHASE_HYPOTHESIS_NUMBER; phase++) { // phase offset between PSS and SSS - - metric = 0; - metric_re = 0; - - d = (int16_t *)&d_sss[Nid2][Nid1]; - + for (int n1 = Nid1_start; n1 < Nid1_end; n1++) { // all possible Nid1 values + for (int phase = 0; phase < sizeofArray(phase_nr); phase++) { // phase offset between PSS and SSS + int64_t metric = 0; + int16_t *d = d_sss[Nid2][n1]; // This is the inner product using one particular value of each unknown parameter - for (i=0; i < LENGTH_SSS_NR; i++) { - metric_re += d[i] * ((phase_nr[phase].r * sss[i].r - phase_nr[phase].i * sss[i].i) >> SCALING_METRIC_SSS_NR); + for (int i = 0; i < LENGTH_SSS_NR; i++) { + metric += d[i] * (phase_nr[phase].r * sss[i].r - phase_nr[phase].i * sss[i].i); } - - metric = metric_re; - + metric >>= SCALING_METRIC_SSS_NR; // if the current metric is better than the last save it if (metric > *tot_metric) { *tot_metric = metric; - *Nid_cell = Nid2 + (3 * Nid1); + *Nid_cell = Nid2 + (3 * n1); *phase_max = phase; #ifdef DEBUG_SSS_NR - - LOG_D(PHY,"(phase,Nid1) (%d,%d), metric_phase %d tot_metric %d, phase_max %d \n",phase, Nid1, metric, *tot_metric, *phase_max); - + LOG_D(PHY, + "(phase,Nid1) (%d,%d), metric_phase %d tot_metric %d, phase_max %d \n", + phase, + n1, + metric, + *tot_metric, + *phase_max); #endif } } } -//#ifdef DEBUG_SSS_NR #define SSS_METRIC_FLOOR_NR (30000) - if (*tot_metric > SSS_METRIC_FLOOR_NR) { - Nid2 = GET_NID2(*Nid_cell); - Nid1 = GET_NID1(*Nid_cell); - LOG_D(PHY,"Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max); - } -// #endif - - int re = 0; - int im = 0; - if (Nid1 == Nid1_end) { + if (*tot_metric < SSS_METRIC_FLOOR_NR) { LOG_D(PHY, "Failed to detect SSS after PSS, metric of SSS %d, threshold to consider SSS valid %d, detected PCI: %d\n", *tot_metric, @@ -503,15 +288,19 @@ bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms, *Nid_cell); return false; } - d = (int16_t *)&d_sss[Nid2][Nid1]; - for(i = 0; isubcarrier_spacing); - double ffo_pss = ((double)freq_offset_pss) / frame_parms->subcarrier_spacing; + double ffo_pss = (double)freq_offset_pss / frame_parms->subcarrier_spacing; LOG_D(NR_PHY, "SSS detected, PCI: %d, ffo_pss %f (%i Hz), ffo_sss %f (%i Hz), ffo_pss+ffo_sss %f (%i Hz), nid1: %d, nid2: %d\n", *Nid_cell, diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 97ad60cfff..46be5a18cc 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -156,7 +156,7 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n bitmap); nr_generate_pss(txdataF[beam_nb][0], gNB->TX_AMP, ssb_start_symbol, cfg, fp); - nr_generate_sss(txdataF[beam_nb][0], gNB->TX_AMP, ssb_start_symbol, cfg, fp); + nr_generate_sss(txdataF[beam_nb][0], gNB->TX_AMP, ssb_start_symbol, cfg->cell_config.phy_cell_id.value, fp); uint16_t slots_per_hf = (fp->slots_per_frame) >> 1; int n_hf = slot < slots_per_hf ? 0 : 1;