From 94b23d1eb034b01635cfd9c388bf4bf94a184c8f Mon Sep 17 00:00:00 2001 From: Raghavendra Dinavahi Date: Tue, 11 Jul 2023 18:46:39 +0200 Subject: [PATCH 1/6] PSBCH RX TX and SLSS search procedures - RX/TX Phy processing accg to 38.211, 38.212 Rel16 - PSBCH simulator used to validate TX/RX phy processing - PSBCH SLSS Search procedures - PSBCH SIM also tests SLSS SEARCH --- CMakeLists.txt | 20 + cmake_targets/autotests/test_case_list.xml | 12 + cmake_targets/build_oai | 2 +- .../nrPolar_tools/nr_polar_psbch_defs.h | 57 ++ openair1/PHY/CODING/nr_polar_init.c | 15 +- openair1/PHY/INIT/nr_init_ue.c | 46 +- openair1/PHY/INIT/nr_parms.c | 5 +- openair1/PHY/INIT/nr_phy_init.h | 1 + openair1/PHY/MODULATION/modulation_UE.h | 10 +- openair1/PHY/MODULATION/slot_fep_nr.c | 100 ++- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 36 +- openair1/PHY/NR_REFSIG/nr_gold_ue.c | 64 ++ openair1/PHY/NR_REFSIG/refsig_defs_ue.h | 13 +- openair1/PHY/NR_REFSIG/sss_nr.h | 9 + .../nr_dl_channel_estimation.c | 98 ++- openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h | 12 +- .../PHY/NR_UE_ESTIMATION/nr_ue_measurements.c | 54 ++ .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 5 +- .../PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c | 529 ++++++++++++++ openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c | 22 +- openair1/PHY/NR_UE_TRANSPORT/nr_psbch_rx.c | 235 +++++++ openair1/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c | 374 ++++++++++ .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 36 + openair1/PHY/NR_UE_TRANSPORT/pss_nr.c | 100 +++ openair1/PHY/NR_UE_TRANSPORT/sss_nr.c | 60 +- openair1/PHY/TOOLS/tools_defs.h | 7 + openair1/PHY/defs_nr_UE.h | 14 + openair1/PHY/defs_nr_common.h | 4 +- openair1/PHY/defs_nr_sl_UE.h | 166 +++++ openair1/SCHED_NR_UE/defs.h | 23 + openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 25 +- .../SCHED_NR_UE/phy_procedures_nr_ue_sl.c | 324 +++++++++ openair1/SIMULATION/NR_PHY/pbchsim.c | 44 +- openair1/SIMULATION/NR_PHY/psbchsim.c | 658 ++++++++++++++++++ openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h | 2 +- 35 files changed, 3069 insertions(+), 113 deletions(-) create mode 100644 openair1/PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h create mode 100644 openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c create mode 100644 openair1/PHY/NR_UE_TRANSPORT/nr_psbch_rx.c create mode 100644 openair1/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c create mode 100644 openair1/PHY/defs_nr_sl_UE.h create mode 100644 openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c create mode 100644 openair1/SIMULATION/NR_PHY/psbchsim.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 936938ed23..9111a3c026 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -718,6 +718,7 @@ target_link_libraries(SCHED_UE_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) set(SCHED_SRC_NR_UE ${OPENAIR1_DIR}/SCHED_NR_UE/phy_procedures_nr_ue.c + ${OPENAIR1_DIR}/SCHED_NR_UE/phy_procedures_nr_ue_sl.c ${OPENAIR1_DIR}/SCHED_NR_UE/fapi_nr_ue_l1.c ${OPENAIR1_DIR}/SCHED_NR_UE/phy_frame_config_nr_ue.c ${OPENAIR1_DIR}/SCHED_NR_UE/harq_nr.c @@ -1085,8 +1086,11 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/sss_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/cic_filter_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_initial_sync.c + ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pbch.c + ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_psbch_rx.c + ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -2238,6 +2242,22 @@ target_link_libraries(nr_pbchsim PRIVATE ) target_link_libraries(nr_pbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) +add_executable(nr_psbchsim + ${OPENAIR1_DIR}/SIMULATION/NR_PHY/psbchsim.c + ${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c + ${OPENAIR_DIR}/common/utils/nr/nr_common.c + ${OPENAIR_DIR}/executables/softmodem-common.c + ${OPENAIR2_DIR}/RRC/NAS/nas_config.c + ${NR_UE_RRC_DIR}/rrc_nsa.c + ${NFAPI_USER_DIR}/nfapi.c + ${NFAPI_USER_DIR}/gnb_ind_vars.c + ${PHY_INTERFACE_DIR}/queue_t.c + ) +target_link_libraries(nr_psbchsim PRIVATE + -Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON CONFIG_LIB L2_NR -lz -Wl,--end-group + m pthread ${T_LIB} ITTI dl shlib_loader + ) +target_link_libraries(nr_psbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) #PUCCH ---> Prashanth add_executable(nr_pucchsim diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 81b4f02465..797c1d50b9 100755 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -529,4 +529,16 @@ segmentation fault|assertion|exiting|fatal 3 + + + NR-Sidelink Test cases. (Test1: SLSS Search), + (Test2: PSBCH TxRx) + nr_psbchsim + -I + -n 10 + test1 test2 + PSBCH test OK + segmentation fault|assertion|exiting|fatal + 3 + diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index c7abef6604..bb61d356f4 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -324,7 +324,7 @@ function main() { -P | --phy_simulators) SIMUS_PHY=1 # TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim - TARGET_LIST="$TARGET_LIST dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim" + TARGET_LIST="$TARGET_LIST dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim nr_psbchsim" echo_info "Will compile dlsim, ulsim, ..." shift;; -s | --check) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h new file mode 100644 index 0000000000..6f0668ce5f --- /dev/null +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h @@ -0,0 +1,57 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file /PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h + \brief Polar definitions required for Sidelink PSBCH + \author + \date + \version + \company: Fraunhofer + \email: + \note + \warning +*/ + +#ifndef __NR_POLAR_PSBCH_DEFS__H__ +#define __NR_POLAR_PSBCH_DEFS__H__ + +//PSBCH related polar parameters. + +//PSBCH symbols sent in 11RBS, 9 symbols. 11*9*(12-3(for DMRS))*2bits = 1782 bits +#define SL_NR_POLAR_PSBCH_E_NORMAL_CP 1782 +//PSBCH symbols sent in 11RBS, 7 symbols. 11*7*(12-3(for DMRS))*2bits = 1386 bits +#define SL_NR_POLAR_PSBCH_E_EXT_CP 1386 +// SL_NR_POLAR_PSBCH_E_NORMAL_CP/32 +#define SL_NR_POLAR_PSBCH_E_DWORD 56 + +#define SL_NR_POLAR_PSBCH_MESSAGE_TYPE (NR_POLAR_UCI_PUCCH_MESSAGE_TYPE + 1) +#define SL_NR_POLAR_PSBCH_PAYLOAD_BITS 32 +#define SL_NR_POLAR_PSBCH_AGGREGATION_LEVEL 0 +#define SL_NR_POLAR_PSBCH_N_MAX 9 +#define SL_NR_POLAR_PSBCH_I_IL 1 +#define SL_NR_POLAR_PSBCH_I_SEG 0 +#define SL_NR_POLAR_PSBCH_N_PC 0 +#define SL_NR_POLAR_PSBCH_N_PC_WM 0 +#define SL_NR_POLAR_PSBCH_I_BIL 0 +#define SL_NR_POLAR_PSBCH_CRC_PARITY_BITS 24 +#define SL_NR_POLAR_PSBCH_CRC_ERROR_CORRECTION_BITS 3 + +#endif diff --git a/openair1/PHY/CODING/nr_polar_init.c b/openair1/PHY/CODING/nr_polar_init.c index 3d6d7848da..85424363c2 100644 --- a/openair1/PHY/CODING/nr_polar_init.c +++ b/openair1/PHY/CODING/nr_polar_init.c @@ -32,6 +32,7 @@ #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/NR_TRANSPORT/nr_dci.h" +#include "nrPolar_tools/nr_polar_psbch_defs.h" #define PolarKey ((messageType<<24)|(messageLength<<8)|aggregation_level) static t_nrPolar_params * PolarList=NULL; @@ -191,7 +192,19 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui newPolarInitNode->payloadBits = messageLength; newPolarInitNode->crcCorrectionBits = NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS; //LOG_D(PHY,"New polar node, encoderLength %d, aggregation_level %d\n",newPolarInitNode->encoderLength,aggregation_level); - + } else if (messageType == SL_NR_POLAR_PSBCH_MESSAGE_TYPE) { //PSBCH + newPolarInitNode->n_max = SL_NR_POLAR_PSBCH_N_MAX; + newPolarInitNode->i_il = SL_NR_POLAR_PSBCH_I_IL; + newPolarInitNode->i_seg = SL_NR_POLAR_PSBCH_I_SEG; + newPolarInitNode->n_pc = SL_NR_POLAR_PSBCH_N_PC; + newPolarInitNode->n_pc_wm = SL_NR_POLAR_PSBCH_N_PC_WM; + newPolarInitNode->i_bil = SL_NR_POLAR_PSBCH_I_BIL; + newPolarInitNode->crcParityBits = SL_NR_POLAR_PSBCH_CRC_PARITY_BITS; + newPolarInitNode->payloadBits = SL_NR_POLAR_PSBCH_PAYLOAD_BITS; + newPolarInitNode->encoderLength = SL_NR_POLAR_PSBCH_E_NORMAL_CP + 2; + newPolarInitNode->crcCorrectionBits = SL_NR_POLAR_PSBCH_CRC_ERROR_CORRECTION_BITS; + newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits);//G_P + LOG_D(PHY,"SIDELINK: Initializing polar parameters for PSBCH (K %d, E %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength); } else { AssertFatal(1 == 0, "[nr_polar_init] Incorrect Message Type(%d)", messageType); } diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 641c8a1f67..aade42fca7 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -32,7 +32,6 @@ #include "PHY/NR_REFSIG/ul_ref_seq_nr.h" #include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "PHY/NR_REFSIG/nr_refsig.h" -#include "PHY/MODULATION/nr_modulation.h" #include "openair2/COMMON/prs_nr_paramdef.h" #include "SCHED_NR_UE/harq_nr.h" @@ -384,6 +383,16 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) return 0; } +static void sl_ue_free(PHY_VARS_NR_UE *UE) +{ + + if (UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation) { + free_and_zero(UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[0]); + free_and_zero(UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[1]); + free_and_zero(UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation); + } +} + void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) { const NR_DL_FRAME_PARMS* fp = &ue->frame_parms; @@ -489,6 +498,8 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) free_and_zero(ue->prs_vars[idx]); } + + sl_ue_free(ue); } void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PROCESSES], int number_of_processes, int num_rb) { @@ -702,3 +713,36 @@ void phy_term_nr_top(void) free_ul_reference_signal_sequences(); free_context_synchro_nr(); } + +void sl_ue_phy_init(PHY_VARS_NR_UE *UE) +{ + + uint16_t scaling_value = ONE_OVER_SQRT2_Q15; + + NR_DL_FRAME_PARMS *sl_fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; + + if (!UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation) { + UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation = (int32_t **)malloc16_clear(SL_NR_NUM_IDs_IN_PSS *sizeof(int32_t *) ); + UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[0] = (int32_t *)malloc16_clear( sizeof(int32_t)*sl_fp->ofdm_symbol_size); + UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[1] = (int32_t *)malloc16_clear( sizeof(int32_t)*sl_fp->ofdm_symbol_size); + } + LOG_I(PHY, "SIDELINK INIT: GENERATE PSS, SSS, GOLD SEQUENCES AND PSBCH DMRS SEQUENCES FOR ALL possible SLSS IDs 0- 671\n"); + + // Generate PSS sequences for IDs 0,1 used in PSS + sl_generate_pss(&UE->SL_UE_PHY_PARAMS.init_params,0, scaling_value); + sl_generate_pss(&UE->SL_UE_PHY_PARAMS.init_params,1, scaling_value); + + // Generate psbch dmrs Gold Sequences and modulated dmrs symbols + sl_init_psbch_dmrs_gold_sequences(UE); + for (int slss_id = 0; slss_id < SL_NR_NUM_SLSS_IDs; slss_id++) { + sl_generate_psbch_dmrs_qpsk_sequences(UE, UE->SL_UE_PHY_PARAMS.init_params.psbch_dmrs_modsym[slss_id], slss_id); + sl_generate_sss(&UE->SL_UE_PHY_PARAMS.init_params, slss_id, scaling_value); + } + + // Generate PSS time domain samples used for correlation during SLSS reception. + sl_generate_pss_ifft_samples(&UE->SL_UE_PHY_PARAMS, &UE->SL_UE_PHY_PARAMS.init_params); + + init_symbol_rotation(sl_fp); + init_timeshift_rotation(sl_fp); +} + diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 5b45bbc8f9..00006697e8 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -425,7 +425,8 @@ void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp) LOG_I(PHY,"fp->samples_per_frame=%d\n",fp->samples_per_frame); LOG_I(PHY,"fp->dl_CarrierFreq=%lu\n",fp->dl_CarrierFreq); LOG_I(PHY,"fp->ul_CarrierFreq=%lu\n",fp->ul_CarrierFreq); + LOG_I(PHY,"fp->Nid_cell=%d\n",fp->Nid_cell); + LOG_I(PHY,"fp->first_carrier_offset=%d\n",fp->first_carrier_offset); + LOG_I(PHY,"fp->ssb_start_subcarrier=%d\n",fp->ssb_start_subcarrier); } - - diff --git a/openair1/PHY/INIT/nr_phy_init.h b/openair1/PHY/INIT/nr_phy_init.h index 5e36558e2b..a39f931de1 100644 --- a/openair1/PHY/INIT/nr_phy_init.h +++ b/openair1/PHY/INIT/nr_phy_init.h @@ -61,4 +61,5 @@ void init_delay_table(uint16_t ofdm_symbol_size, int max_ofdm_symbol_size, c16_t delay_table[][max_ofdm_symbol_size]); +void sl_ue_phy_init(PHY_VARS_NR_UE *UE); #endif diff --git a/openair1/PHY/MODULATION/modulation_UE.h b/openair1/PHY/MODULATION/modulation_UE.h index 07d7625770..1d7921d84c 100644 --- a/openair1/PHY/MODULATION/modulation_UE.h +++ b/openair1/PHY/MODULATION/modulation_UE.h @@ -49,9 +49,17 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue, int reset_freq_est); int nr_slot_fep(PHY_VARS_NR_UE *ue, + NR_DL_FRAME_PARMS *frame_parms, const UE_nr_rxtx_proc_t *proc, unsigned char symbol, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); + c16_t rxdataF[][frame_parms->samples_per_slot_wCP], + uint32_t linktype); +int sl_nr_slot_fep(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + unsigned char symbol, + unsigned char Ns, + uint32_t sample_offset, + c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]); int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index a645d9ded1..7eb31e44f4 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -34,12 +34,106 @@ #define LOG_I(A,B...) printf(A) #endif*/ +int sl_nr_slot_fep(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + unsigned char symbol, + unsigned char Ns, + uint32_t sample_offset, + c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]) +{ + NR_DL_FRAME_PARMS *frame_params = &ue->SL_UE_PHY_PARAMS.sl_frame_params; + NR_UE_COMMON *common_vars = &ue->common_vars; + + AssertFatal(symbol < frame_params->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_params->symbols_per_slot-1); + AssertFatal(Ns < frame_params->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_params->slots_per_frame-1); + + unsigned int nb_prefix_samples = frame_params->nb_prefix_samples; + unsigned int nb_prefix_samples0 = frame_params->nb_prefix_samples0; + + + dft_size_idx_t dftsize = get_dft(frame_params->ofdm_symbol_size); + // This is for misalignment issues + int32_t tmp_dft_in[8192] __attribute__ ((aligned (32))); + + unsigned int rx_offset = frame_params->get_samples_slot_timestamp(Ns,frame_params,0); + unsigned int abs_symbol = Ns * frame_params->symbols_per_slot + symbol; + + rx_offset += sample_offset; + + for (int idx_symb = Ns*frame_params->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++) + rx_offset += (idx_symb%(0x7<numerology_index)) ? nb_prefix_samples : nb_prefix_samples0; + rx_offset += frame_params->ofdm_symbol_size * symbol; + + // use OFDM symbol from within 1/8th of the CP to avoid ISI + rx_offset -= (nb_prefix_samples / frame_params->ofdm_offset_divisor); + +#ifdef SL_DEBUG_SLOT_FEP + // if (ue->frame <100) + LOG_I(PHY, "slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u\n", + Ns, symbol, nb_prefix_samples, nb_prefix_samples0, rx_offset); +#endif + + for (unsigned char aa=0; aanb_antennas_rx; aa++) { + memset(&rxdataF[aa][frame_params->ofdm_symbol_size*symbol],0,frame_params->ofdm_symbol_size*sizeof(int32_t)); + + int16_t *rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset]; + + // if input to dft is not 256-bit aligned + if ((rx_offset & 7) != 0) { + memcpy((void *)&tmp_dft_in[0], + (void *)&common_vars->rxdata[aa][rx_offset], + frame_params->ofdm_symbol_size * sizeof(int32_t)); + + rxdata_ptr = (int16_t *)tmp_dft_in; + } + + dft(dftsize, + rxdata_ptr, + (int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol], + 1); + + + int symb_offset = (Ns%frame_params->slots_per_subframe)*frame_params->symbols_per_slot; + int32_t rot2 = ((uint32_t*)frame_params->symbol_rotation[1])[symbol+symb_offset]; + ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; + +#ifdef SL_DEBUG_SLOT_FEP + // if (ue->frame <100) + LOG_I(PHY, "slot_fep: slot %d, symbol %d rx_offset %u, rotation symbol %d %d.%d\n", Ns,symbol, rx_offset, + symbol+symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]); +#endif + + rotate_cpx_vector((c16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol], + (c16_t *)&rot2, + (c16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol], + frame_params->ofdm_symbol_size, + 15); + + int16_t *shift_rot = (int16_t *)frame_params->timeshift_symbol_rotation; + + multadd_cpx_vector((int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol], + shift_rot, + (int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol], + 1, + frame_params->ofdm_symbol_size, + 15); + } + + + + LOG_D(PHY, "SIDELINK RX: Slot FEP: done for symbol:%d\n", symbol); + + return 0; +} + int nr_slot_fep(PHY_VARS_NR_UE *ue, + NR_DL_FRAME_PARMS *frame_parms, const UE_nr_rxtx_proc_t *proc, unsigned char symbol, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) + c16_t rxdataF[][frame_parms->samples_per_slot_wCP], + uint32_t linktype) { - NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + NR_UE_COMMON *common_vars = &ue->common_vars; int Ns = proc->nr_slot_rx; @@ -98,7 +192,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, apply_nr_rotation_RX(frame_parms, rxdataF[aa], - frame_parms->symbol_rotation[0], + frame_parms->symbol_rotation[linktype], Ns, frame_parms->N_RB_DL, 0, diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 82c55a1465..4789cdf232 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -202,22 +202,32 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, return(0); } -void nr_pbch_dmrs_rx(const int symbol, const unsigned int *nr_gold_pbch, c16_t *output) +void nr_pbch_dmrs_rx(int symbol, + unsigned int *nr_gold_pbch, + c16_t *output, + bool sidelink) { int m,m0,m1; uint8_t idx=0; - AssertFatal(symbol>=0 && symbol <3,"illegal symbol %d\n",symbol); - if (symbol == 0) { - m0=0; - m1=60; - } - else if (symbol == 1) { - m0=60; - m1=84; - } - else { - m0=84; - m1=144; + if (sidelink) { + AssertFatal(symbol== 0 || (symbol>=5 && symbol <=12),"illegal symbol %d\n",symbol); + m0 = (symbol) ? (symbol - 4) * 33 : 0; + m1 = (symbol) ? (symbol - 3) * 33 : 33; + + } else { + AssertFatal(symbol>=0 && symbol <3,"illegal symbol %d\n",symbol); + if (symbol == 0) { + m0=0; + m1=60; + } + else if (symbol == 1) { + m0=60; + m1=84; + } + else { + m0=84; + m1=144; + } } // printf("Generating pilots symbol %d, m0 %d, m1 %d\n",symbol,m0,m1); /// QPSK modulation diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c index 122cc11dd3..fbabd566e8 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold_ue.c +++ b/openair1/PHY/NR_REFSIG/nr_gold_ue.c @@ -20,6 +20,7 @@ */ #include "refsig_defs_ue.h" +#include "PHY/NR_REFSIG/nr_mod_table.h" void nr_gold_pbch(PHY_VARS_NR_UE* ue) { @@ -148,3 +149,66 @@ void init_nr_gold_prs(PHY_VARS_NR_UE* ue) } // for rsc } // for gnb } + +void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE) +{ + unsigned int x1, x2; + uint16_t slss_id; + uint8_t reset; + + for (slss_id = 0; slss_id < SL_NR_NUM_SLSS_IDs; slss_id++) { + + reset = 1; + x2 = slss_id; + +#ifdef SL_DEBUG_INIT + printf("\nPSBCH DMRS GOLD SEQ for SLSSID :%d :\n", slss_id); +#endif + + for (uint8_t n=0; nSL_UE_PHY_PARAMS.init_params.psbch_dmrs_gold_sequences[slss_id][n] = lte_gold_generic(&x1, &x2, reset); + reset = 0; + +#ifdef SL_DEBUG_INIT_DATA + printf("%x\n",SL_UE_INIT_PARAMS.sl_psbch_dmrs_gold_sequences[slss_id][n]); +#endif + + } + } +} + +void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, + struct complex16 *modulated_dmrs_sym, + uint16_t slss_id) +{ + + uint8_t idx = 0; + uint32_t *sl_dmrs_sequence = UE->SL_UE_PHY_PARAMS.init_params.psbch_dmrs_gold_sequences[slss_id]; + c16_t *mod_table = (c16_t *)nr_qpsk_mod_table; + +#ifdef SL_DEBUG_INIT + printf("SIDELINK INIT: PSBCH DMRS Generation with slss_id:%d\n", slss_id); +#endif + + /// QPSK modulation + for (int m=0; m>5])>>((m<<1)&0x1f))&3); + modulated_dmrs_sym[m].r = mod_table[idx].r; + modulated_dmrs_sym[m].i = mod_table[idx].i; + +#ifdef SL_DEBUG_INIT_DATA + printf("m:%d gold seq: %d b0-b1: %d-%d DMRS Symbols: %d %d\n", m, sl_dmrs_sequence[(m<<1)>>5], (((sl_dmrs_sequence[(m<<1)>>5])>>((m<<1)&0x1f))&1), + (((sl_dmrs_sequence[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1), modulated_dmrs_sym[m].r, modulated_dmrs_sym[m].i); + printf("idx:%d, qpsk_table.r:%d, qpsk_table.i:%d\n", idx, mod_table[idx].r, mod_table[idx].i); +#endif + } + +#ifdef SL_DUMP_INIT_SAMPLES + char filename[40], varname[25]; + sprintf(filename,"sl_psbch_dmrs_slssid_%d.m", slss_id); + sprintf(varname,"sl_dmrs_id_%d.m", slss_id); + LOG_M(filename, varname, (void*)modulated_dmrs_sym, SL_NR_NUM_PSBCH_DMRS_RE, 1, 1); +#endif + +} diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index 81c72f59ef..5f6366a067 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -30,7 +30,10 @@ /*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS. @param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables */ -void nr_pbch_dmrs_rx(const int dmrss, const unsigned int *nr_gold_pbch, c16_t *output); +void nr_pbch_dmrs_rx(int dmrss, + unsigned int *nr_gold_pbch, + c16_t *output, + bool sidelink); /*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS. @param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables @@ -66,5 +69,11 @@ void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue, void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid); void init_nr_gold_prs(PHY_VARS_NR_UE* ue); - +void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, uint16_t scaling); +void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params); +void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, uint16_t scaling); +void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE); +void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, + struct complex16 *modulated_dmrs_sym, + uint16_t slss_id); #endif diff --git a/openair1/PHY/NR_REFSIG/sss_nr.h b/openair1/PHY/NR_REFSIG/sss_nr.h index 129c5a5917..294fed3cb8 100644 --- a/openair1/PHY/NR_REFSIG/sss_nr.h +++ b/openair1/PHY/NR_REFSIG/sss_nr.h @@ -67,8 +67,17 @@ #define PHASE_HYPOTHESIS_NUMBER (16) #define INDEX_NO_PHASE_DIFFERENCE (3) /* this is for no phase shift case */ + /************** FUNCTION ******************************************/ +static const c16_t phase_nr[PHASE_HYPOTHESIS_NUMBER] = { + // {pi/3 ---- pi/3, -pi/3 ---- pi/3} + {16384, -28377}, {20173, -25821}, {23571, -22762}, {26509, -19260}, + {28932, -15383}, {30791, -11207}, {32051, -6813}, {32687, -2286}, + {32687, 2286}, {32051, 6813}, {30791, 11207}, {28932, 15383}, + {26509, 19260}, {23571, 22762}, {20173, 25821}, {16384, 28377} +}; + void init_context_sss_nr(int amp); void free_context_sss_nr(void); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 7b3f2f3f3d..7ae7d7b56b 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -657,7 +657,7 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue, // generate pilot // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS c16_t pilot[200] __attribute__((aligned(16))); - nr_pbch_dmrs_rx(dmrss, nr_gold_pbch, pilot); + nr_pbch_dmrs_rx(dmrss, (uint32_t *)nr_gold_pbch, pilot, false); c32_t computed_val = {0}; for (int aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { @@ -717,42 +717,70 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue, } int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, + NR_DL_FRAME_PARMS *fp, int estimateSz, struct complex16 dl_ch_estimates[][estimateSz], - struct complex16 dl_ch_estimates_time[][ue->frame_parms.ofdm_symbol_size], + struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size], const UE_nr_rxtx_proc_t *proc, unsigned char symbol, int dmrss, uint8_t ssb_index, uint8_t n_hf, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) + c16_t rxdataF[][fp->samples_per_slot_wCP], + bool sidelink, + uint16_t Nid) { int Ns = proc->nr_slot_rx; c16_t pilot[200] __attribute__((aligned(16))); //int slot_pbch; - const int nushift = ue->frame_parms.Nid_cell % 4; - unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier; - if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size; + uint8_t nushift = 0, lastsymbol = 0, num_rbs = 0; + uint32_t *gold_seq = NULL; - const int ch_offset = ue->frame_parms.ofdm_symbol_size * symbol; + if (sidelink) { - AssertFatal(dmrss >= 0 && dmrss < 3, + AssertFatal(dmrss == 0 || (dmrss >= 5 && dmrss <= 12), + "symbol %d is illegal for PSBCH DM-RS \n", + dmrss); + + sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS; + + LOG_D(PHY,"PSBCH Channel Estimation SLSSID:%d\n", Nid); + + gold_seq = sl_phy_params->init_params.psbch_dmrs_gold_sequences[Nid]; + lastsymbol = 12; + num_rbs = SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL; + + } else { + + nushift = fp->Nid_cell%4; + + AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss); - const int symbol_offset = ue->frame_parms.ofdm_symbol_size * symbol; + gold_seq = ue->nr_gold_pbch[n_hf][ssb_index]; + lastsymbol = 2; + num_rbs = 20; + } + unsigned int ssb_offset = fp->first_carrier_offset + fp->ssb_start_subcarrier; + if (ssb_offset>= fp->ofdm_symbol_size) ssb_offset-= fp->ofdm_symbol_size; + + const int ch_offset = fp->ofdm_symbol_size*symbol; + const int symbol_offset = fp->ofdm_symbol_size*symbol; const int k = nushift; - const c16_t *fl, *fm, *fr; + DEBUG_PBCH("PBCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", - proc->gNB_id, - ch_offset, - ue->frame_parms.ofdm_symbol_size, - ue->frame_parms.Ncp, - Ns, - k, - symbol); + proc->gNB_id, + ch_offset, + fp->ofdm_symbol_size, + fp->Ncp, + Ns, + k, + symbol); + + const c16_t *fl, *fm, *fr; switch (k) { case 0: @@ -787,7 +815,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, idft_size_idx_t idftsizeidx; - switch (ue->frame_parms.ofdm_symbol_size) { + switch (fp->ofdm_symbol_size) { case 128: idftsizeidx = IDFT_128; break; @@ -835,19 +863,19 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, // generate pilot // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS - nr_pbch_dmrs_rx(dmrss, ue->nr_gold_pbch[n_hf][ssb_index], pilot); + nr_pbch_dmrs_rx(dmrss,gold_seq, &pilot[0], sidelink); - for (int aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { + for (int aarx=0; aarxnb_antennas_rx; aarx++) { int re_offset = ssb_offset; c16_t *pil = pilot; c16_t *rxF = &rxdataF[aarx][symbol_offset + k]; c16_t *dl_ch = &dl_ch_estimates[aarx][ch_offset]; - memset(dl_ch, 0, sizeof(c16_t) * ue->frame_parms.ofdm_symbol_size); + memset(dl_ch, 0, sizeof(c16_t) * fp->ofdm_symbol_size); - DEBUG_PBCH("pbch ch est pilot RB_DL %d\n", ue->frame_parms.N_RB_DL); - DEBUG_PBCH("k %d, first_carrier %d\n", k, ue->frame_parms.first_carrier_offset); + DEBUG_PBCH("pbch ch est pilot RB_DL %d\n", fp->N_RB_DL); + DEBUG_PBCH("k %d, first_carrier %d\n", k, fp->first_carrier_offset); // Treat first 2 pilots specially (left edge) c16_t ch; @@ -855,31 +883,31 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, DEBUG_PBCH("pilot 0: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", rxF[re_offset].r, rxF[re_offset].i, ch.r, ch.i, pil->r, pil->i); multaddRealVectorComplexScalar(fl, ch, dl_ch, 16); pil++; - re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; + re_offset = (re_offset + 4) % fp->ofdm_symbol_size; ch = c16mulShift(*pil, rxF[re_offset], 15); DEBUG_PBCH("pilot 1: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", rxF[re_offset].r, rxF[re_offset].i, ch.r, ch.i, pil->r, pil->i); multaddRealVectorComplexScalar(fm, ch, dl_ch, 16); pil++; - re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; + re_offset = (re_offset + 4) % fp->ofdm_symbol_size; ch = c16mulShift(*pil, rxF[re_offset], 15); DEBUG_PBCH("pilot 2: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", rxF[re_offset].r, rxF[re_offset].i, ch.r, ch.i, pil->r, pil->i); multaddRealVectorComplexScalar(fr, ch, dl_ch, 16); pil++; - re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; + re_offset = (re_offset + 4) % fp->ofdm_symbol_size; dl_ch += 24; - for (int pilot_cnt = 3; pilot_cnt < (3 * 20); pilot_cnt += 3) { + for (int pilot_cnt = 3; pilot_cnt < (3 * num_rbs); pilot_cnt += 3) { // if (pilot_cnt == 30) // rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k)]; // in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS) if (dmrss == 1 && pilot_cnt == 12) { pilot_cnt=48; - re_offset = (re_offset + 144) % ue->frame_parms.ofdm_symbol_size; + re_offset = (re_offset + 144) % fp->ofdm_symbol_size; dl_ch += 288; } ch = c16mulShift(*pil, rxF[re_offset], 15); @@ -894,7 +922,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, multaddRealVectorComplexScalar(fl, ch, dl_ch, 16); pil++; - re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; + re_offset = (re_offset+4) % fp->ofdm_symbol_size; ch = c16mulShift(*pil, rxF[re_offset], 15); DEBUG_PBCH("pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", pilot_cnt + 1, @@ -906,7 +934,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, pil->i); multaddRealVectorComplexScalar(fm, ch, dl_ch, 16); pil++; - re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; + re_offset = (re_offset+4) % fp->ofdm_symbol_size; ch = c16mulShift(*pil, rxF[re_offset], 15); DEBUG_PBCH("pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", pilot_cnt + 2, @@ -918,11 +946,11 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, pil->i); multaddRealVectorComplexScalar(fr, ch, dl_ch, 16); pil++; - re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; + re_offset = (re_offset + 4) % fp->ofdm_symbol_size; dl_ch += 12; } - if( dmrss == 2) // update time statistics for last PBCH symbol + if( dmrss == lastsymbol) // update time statistics for last PBCH symbol { // do ifft of channel estimate LOG_D(PHY,"Channel Impulse Computation Slot %d Symbol %d ch_offset %d\n", Ns, symbol, ch_offset); @@ -933,13 +961,13 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, } } - if (dmrss == 2) + if (!sidelink && dmrss == lastsymbol) UEscopeCopy(ue, pbchDlChEstimateTime, (void *)dl_ch_estimates_time, sizeof(c16_t), - ue->frame_parms.nb_antennas_rx, - ue->frame_parms.ofdm_symbol_size, + fp->nb_antennas_rx, + fp->ofdm_symbol_size, 0); return(0); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 5b1e43f953..3dc603e44e 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -65,15 +65,18 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue, const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, + NR_DL_FRAME_PARMS *fp, int estimateSz, struct complex16 dl_ch_estimates[][estimateSz], - struct complex16 dl_ch_estimates_time[][ue->frame_parms.ofdm_symbol_size], + struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size], const UE_nr_rxtx_proc_t *proc, unsigned char symbol, int dmrss, uint8_t ssb_index, uint8_t n_hf, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); + c16_t rxdataF[][fp->samples_per_slot_wCP], + bool sidelink, + uint16_t Nid); int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, @@ -137,5 +140,10 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, NR_UE_DLSCH_t dlsch[2]); float_t get_nr_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t gNB_index); + +void nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params, + NR_DL_FRAME_PARMS *fp, + c16_t rxdataF[][fp->samples_per_slot_wCP], + bool use_SSS); /** @}*/ #endif diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index c21a6a709f..d58f9eaada 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -309,3 +309,57 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, ue->measurements.n0_power_tot_dB + 30 - 10 * log10(pow(2, 30)) - dB_fixed(ue->frame_parms.ofdm_symbol_size) - ((int)rx_gain - (int)rx_gain_offset)); } + +//PSBCH RSRP calculations according to 38.215 section 5.1.22 +void nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params, + NR_DL_FRAME_PARMS *fp, + c16_t rxdataF[][fp->samples_per_slot_wCP], + bool use_SSS) +{ + + SL_NR_UE_PSBCH_t *psbch_rx = &sl_phy_params->psbch; + uint8_t numsym = (fp->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP + : SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP; + uint32_t re_offset = fp->first_carrier_offset + fp->ssb_start_subcarrier; + uint32_t rsrp = 0, num_re = 0; + + LOG_D(PHY, "PSBCH RSRP MEAS: numsym:%d, re_offset:%d\n",numsym, re_offset); + + for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) { + + //Calculate PSBCH RSRP based from DMRS REs + for (uint8_t symbol=0; symbolofdm_symbol_size]; + + for (int re=0;reofdm_symbol_size; + + rsrp += c16amp2(rxF[offset]); + num_re++; + } + } + symbol = (symbol == 0) ? 5 : symbol+1; + } + } + + if (use_SSS) { + //TBD... + //UE can decide between using only PSBCH DMRS or PSBCH DMRS and SSS for PSBCH RSRP computation. + //If needed this can be implemented. Reference Spec 38.215 + } + + psbch_rx->rsrp_dB_per_RE = 10*log10(rsrp / num_re); + psbch_rx->rsrp_dBm_per_RE = psbch_rx->rsrp_dB_per_RE + + 30 - 10*log10(pow(2,30)) - + ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - + dB_fixed(fp->ofdm_symbol_size); + + + LOG_I(PHY, "PSBCH RSRP (DMRS REs): numREs:%d RSRP :%d dB/RE ,RSRP:%d dBm/RE\n", + num_re, psbch_rx->rsrp_dB_per_RE, psbch_rx->rsrp_dBm_per_RE); + +} + diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 97c3af3b1e..c8c7f6e73d 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -101,6 +101,7 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, for(int i=pbch_initial_symbol; iframe_parms, estimateSz, dl_ch_estimates, dl_ch_estimates_time, @@ -109,7 +110,9 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, i - pbch_initial_symbol, ssb->i_ssb, ssb->n_hf, - rxdataF); + rxdataF, + false, + frame_parms->Nid_cell); stop_meas(&ue->dlsch_channel_estimation_stats); fapiPbch_t result = {0}; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c new file mode 100644 index 0000000000..75df850b23 --- /dev/null +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c @@ -0,0 +1,529 @@ +#include "PHY/defs_nr_UE.h" +#include "PHY/TOOLS/tools_defs.h" +#include "PHY/NR_REFSIG/sss_nr.h" +#include "PHY/NR_UE_ESTIMATION/nr_estimation.h" +#include "PHY/MODULATION/modulation_UE.h" +#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" +#include "SCHED_NR_UE/defs.h" + +//Number of symbols carrying SLSS signal - PSS+SSS+PSBCH +#define SL_NR_NUMSYM_SLSS_NORMAL_CP 14 +#define SL_NR_MAX_RX_ANTENNA 1 +#define SL_NR_FIRST_PSS_SYMBOL 1 +#define SL_NR_FIRST_SSS_SYMBOL 3 +#define SL_NR_NUM_PSS_SSS_SYMBOLS 4 + +//#define SL_DEBUG + +static int sl_nr_pss_correlation(PHY_VARS_NR_UE *UE, int frame_index) +{ + + sl_nr_ue_phy_params_t *sl_ue = &UE->SL_UE_PHY_PARAMS; + SL_NR_SYNC_PARAMS_t *sync_params = &sl_ue->sync_params; + NR_DL_FRAME_PARMS *sl_fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; + int16_t **pss_for_correlation = (int16_t **)sl_ue->init_params.sl_pss_for_correlation; + + uint32_t length = (frame_index == 0) ? sl_fp->samples_per_frame + (2 * sl_fp->ofdm_symbol_size) : sl_fp->samples_per_frame; + int32_t **rxdata = (int32_t **)UE->common_vars.rxdata; + +#ifdef SL_DEBUG + char fname[50], sname[25]; + sprintf(fname,"rxdata_frame_%d.m",frame_index); + sprintf(sname,"rxd_frame%d",frame_index); + LOG_M(fname,sname, &rxdata[0][frame_index * sl_fp->samples_per_frame],sl_fp->samples_per_frame,1,1); + LOG_M("pss_for_correlation0.m","pss_id0", pss_for_correlation[0],2048,1,1); + LOG_M("pss_for_correlation1.m","pss_id1", pss_for_correlation[1],2048,1,1); + + int64_t *pss_corr_debug_values[SL_NR_NUM_IDs_IN_PSS]; +#endif + + int maxval=0; + for (int i=0;i<2*(sl_fp->ofdm_symbol_size);i++) { + maxval = max(maxval,pss_for_correlation[0][i]); + maxval = max(maxval,-pss_for_correlation[0][i]); + maxval = max(maxval,pss_for_correlation[1][i]); + maxval = max(maxval,-pss_for_correlation[1][i]); + } + + int shift = log2_approx(maxval);//*(sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)*2); + +#ifdef SL_DEBUG + LOG_I(PHY,"SIDELINK SLSS SEARCH: Function:%s\n", __func__); + LOG_I(PHY,"maxval:%d, shift:%d\n", maxval, shift); +#endif + + + int64_t avg[SL_NR_NUM_IDs_IN_PSS] = {0}; + int64_t peak_value = 0, psss_corr_value = 0; + unsigned int peak_position = 0, pss_source = 0; + for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) + avg[pss_index]=0; + +#ifdef SL_DEBUG + int64_t *pss_corr_debug_values[SL_NR_NUM_IDs_IN_PSS]; + for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) + pss_corr_debug_values[pss_index] = malloc16_clear(length*sizeof(int64_t)); +#endif + + for (int n=0; n < length - sl_fp->ofdm_symbol_size; n+=4) { // + + for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) { + psss_corr_value = 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 (int ar=0; arnb_antennas_rx; ar++) { + + /* perform correlation of rx data and pss sequence ie it is a dot product */ + const c32_t result = dot_product((c16_t *)pss_for_correlation[pss_index], + (c16_t *)&(rxdata[ar][n + frame_index * sl_fp->samples_per_frame]), + sl_fp->ofdm_symbol_size, + shift); + + const c64_t r64 = {.r = result.r, .i = result.i}; + psss_corr_value += squaredMod(r64); + +#ifdef SL_DEBUG + pss_corr_debug_values[pss_index][n] = psss_corr_value; + printf("frame:%d n:%d, pss_index:%d, pss_for_correlation[pss_index][0]:%x, rxdata[n]:%x\n", + frame_index, n, pss_index, pss_for_correlation[pss_index][0], rxdata[ar][n + frame_index * sl_fp->samples_per_frame]); + printf("result %lld, pss_corr_values[%d][%d]:%ld\n",result, pss_index, n, pss_corr_debug_values[pss_index][n]); + printf("pss_index %d: n %6u peak_value %15llu\n", pss_index, n, (unsigned long long)pss_corr_debug_values[pss_index][n]); + printf("peak_value:%ld, peak_position:%d, pss_source:%d\n", peak_value, peak_position, pss_source); +#endif + } + + // calculate the absolute value of sync_corr[n] + avg[pss_index] += psss_corr_value; + if (psss_corr_value > peak_value) { + peak_value = psss_corr_value; + peak_position = n; + pss_source = pss_index; + +#ifdef SL_DEBUG + printf("pss_index %d: n %6u peak_value %15llu\n", pss_index, n, (unsigned long long)psss_corr_value); +#endif + } + } + } + +#ifdef SL_DEBUG + LOG_M("pss_corr_debug_values_0.m","pss_corr0", &pss_corr_debug_values[0][0],length,1,6); + LOG_M("pss_corr_debug_values_1.m","pss_corr1", &pss_corr_debug_values[1][0],length,1,6); + + for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) { + free(pss_corr_debug_values[pss_index]); + } +#endif + + double ffo_est=0; + if (UE->UE_fo_compensation) { // Not tested + + // 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. + + c16_t *pss = (c16_t *)pss_for_correlation[pss_source]; + c16_t *rxd = (c16_t *)&(rxdata[0][peak_position + frame_index * sl_fp->samples_per_frame]); + int half_symbol = sl_fp->ofdm_symbol_size>>1; + + // Computing cross-correlation at peak on half the symbol size for first half of data + c32_t r1 = dot_product(pss, rxd, half_symbol, shift); + + // Computing cross-correlation at peak on half the symbol size for data shifted by half symbol size + // as it is real and complex it is necessary to shift by a value equal to symbol size to obtain such shift + c32_t r2 = dot_product(pss + half_symbol, rxd + half_symbol, half_symbol, shift); + + cd_t r1d = {r1.r, r1.i}, r2d = {r2.r, r2.i}; + // estimation of fractional frequency offset: angle[(result1)'*(result2)]/pi + ffo_est = atan2(r1d.r * r2d.i - r2d.r * r1d.i, r1d.r * r2d.r + r1d.i * r2d.i) / M_PI; + +#ifdef SL_DEBUG + printf("ffo %lf\n",ffo_est); +#endif + } + + + // computing absolute value of frequency offset + sync_params->freq_offset = ffo_est*sl_fp->subcarrier_spacing; + + for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) avg[pss_index]/=(length/4); + + sync_params->N_sl_id2 = pss_source; + + LOG_I(PHY,"PSS Source = %d, Peak found at pos %d, val = %llu (%d dB) avg %d dB, ffo %lf, freq offset:%d Hz\n", + pss_source, peak_position, (unsigned long long)peak_value, dB_fixed64(peak_value),dB_fixed64(avg[pss_source]),ffo_est, sync_params->freq_offset); + + if (peak_value < 5*avg[pss_source]) + return(-1); + + return peak_position; +} + +static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, + int32_t *tot_metric, uint8_t *phase_max, + c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]) +{ + + c16_t pss_ext[SL_NR_MAX_RX_ANTENNA][SL_NR_NUM_PSS_SYMBOLS][SL_NR_PSS_SEQUENCE_LENGTH]; + c16_t sss_ext[SL_NR_MAX_RX_ANTENNA][SL_NR_NUM_SSS_SYMBOLS][SL_NR_PSS_SEQUENCE_LENGTH]; + uint8_t Nid2 = ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id2; + NR_DL_FRAME_PARMS *sl_fp=&ue->SL_UE_PHY_PARAMS.sl_frame_params; + int16_t *d; + uint16_t Nid1 = 0; + uint8_t phase; + c16_t *rxF_ext; + + for (int aarx=0; aarx < sl_fp->nb_antennas_rx; aarx++) { + + unsigned int ofdm_symbol_size = sl_fp->ofdm_symbol_size; + + // pss, sss extraction + for (int sym = SL_NR_FIRST_PSS_SYMBOL; sym < SL_NR_FIRST_PSS_SYMBOL + SL_NR_NUM_PSS_SSS_SYMBOLS;sym ++) { + + if (sym < SL_NR_FIRST_PSS_SYMBOL + SL_NR_NUM_PSS_SYMBOLS) { + rxF_ext = &pss_ext[aarx][sym-SL_NR_FIRST_PSS_SYMBOL][0]; + } else { + rxF_ext = &sss_ext[aarx][sym-SL_NR_FIRST_SSS_SYMBOL][0]; + } + + unsigned int k = sl_fp->first_carrier_offset + sl_fp->ssb_start_subcarrier + 2; + if (k >= ofdm_symbol_size) k -= ofdm_symbol_size; + + LOG_D(PHY, "firstcarrieroffset:%d, ssb_sc:%d, k:%d, symbol:%d\n",sl_fp->first_carrier_offset, sl_fp->ssb_start_subcarrier, k, sym); + + for (int i=0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) { + rxF_ext[i] = rxdataF[aarx][sym*ofdm_symbol_size + k]; + k++; + if (k == ofdm_symbol_size) k=0; + } + + } + + LOG_D(PHY, "SIDELINK SLSS SEARCH: EXTRACTION OF PSS, SSS done\n"); + +#ifdef SL_DEBUG + LOG_M("pss_ext_sym1.m","pss_ext1",&pss_ext[aarx][0][0],SL_NR_PSS_SEQUENCE_LENGTH,1,1); + LOG_M("pss_ext_sym2.m","pss_ext2",&pss_ext[aarx][1][0],SL_NR_PSS_SEQUENCE_LENGTH,1,1); + LOG_M("sss_ext_sym3.m","sss_ext3",&sss_ext[aarx][0][0],SL_NR_PSS_SEQUENCE_LENGTH,1,1); + LOG_M("sss_ext_sym4.m","sss_ext4",&sss_ext[aarx][1][0],SL_NR_PSS_SEQUENCE_LENGTH,1,1); +#endif + + // get conjugated channel estimate from PSS, H* = R* \cdot PSS + // and do channel estimation and compensation based on PSS + int16_t *pss = ue->SL_UE_PHY_PARAMS.init_params.sl_pss_for_sync[Nid2]; + c16_t *pss_ext2,*sss_ext2; + + //2 Symbols each for PSS and SSS + for (int j=0; jcommon_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 +*/ + + /* 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) */ + + // now do the SSS detection based on the pre computed SSS sequences + *tot_metric = INT_MIN; + 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 + + int32_t metric = 0, metric_re = 0; + + d = (int16_t *)&ue->SL_UE_PHY_PARAMS.init_params.sl_sss_for_sync[Nid2 * SL_NR_NUM_IDs_IN_SSS + id1]; + + // This is the inner product using one particular value of each unknown parameter + for (int i=0; i < SL_NR_SSS_SEQUENCE_LENGTH; i++) { + metric_re += d[i] * (((int64_t) phase_nr[phase].r * sss[i].r - phase_nr[phase].i * sss[i].i) >> 15); + } + + metric = metric_re; + + // if the current metric is better than the last save it + if (metric > *tot_metric) { + *tot_metric = metric; + Nid1 = id1; + *phase_max = phase; + + LOG_D(PHY, "(phase,Nid1) (%d,%d), metric_phase %d tot_metric %d, phase_max %d \n", + phase, Nid1, metric, *tot_metric, *phase_max); + + } + } + } + + ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id1 = Nid1; + ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id = ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id1 + + SL_NR_NUM_IDs_IN_SSS * ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id2; + LOG_I(PHY, "UE[%d]NR-SL SLSS SEARCH: SSS Processing over. id2 from SSS:%d, id1 from PSS:%d, SLSS id:%d\n", + ue->Mod_id, ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id1, ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id2, + ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id); + + +#ifdef SL_DEBUG +#define SSS_METRIC_FLOOR_NR (30000) + if (*tot_metric > SSS_METRIC_FLOOR_NR) { + Nid2 = ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id2; + Nid1 = ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id1; + printf("Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max); + } +#endif + + return; +} + + +// Right now 2 frames worth of samples get processed for PSS in OAI. +// For PSS in Sidelink, worst case 1 SSB in 16 frames can be present +// Hence 16 frames worth of samples needs to be correlated to find the PSS. +nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, int num_frames) +{ + + sl_nr_ue_phy_params_t *sl_ue = &UE->SL_UE_PHY_PARAMS; + SL_NR_SYNC_PARAMS_t *sync_params = &sl_ue->sync_params; + NR_DL_FRAME_PARMS *sl_fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; + + int32_t sync_pos = -1;// sync_pos_frame = -1; + int32_t metric_tdd_ncp=0; + uint8_t phase_tdd_ncp; + double im, re; + int ret=-1; + uint16_t rx_slss_id = 65535; + + nr_initial_sync_t result = {true, 0}; + +#ifdef SL_DEBUG_SEARCH_SLSS + LOG_D(PHY, "SIDELINK SEARCH SLSS: Function:%s\n", __func__); +#endif + + /* Initial synchronisation + * + * 1 radio frame = 10 ms + * <---------------------------------------------------------------------------> + * | Received UE data buffer | + * ---------------------------------------------------------------------------- + * <-------------->|psbch|pss|pss|sss|sss|psbch sym5-sym 12|sym13 - guard| + * sync_pos SS/PSBCH block + */ + + // initial sync performed on 16 successive frames. Worst case - one PSBCH can be sent in 16 frames. + //If psbch passes on first frame, no need to process second frame + // Problem with the frame approach is that + // --------- SSB can be on the boundary between frames. In this case if only 1 SSB is sent we will miss it. + // rxdata will hold 16 frames + slot worth of samples. This needs to be processed to find the best SSB + for(int frame_index = 0; frame_index < num_frames; frame_index++) { + + /* process pss search on received buffer */ + sync_pos = sl_nr_pss_correlation(UE, frame_index); + + if (sync_pos == -1) { + LOG_I(PHY,"SIDELINK SEARCH SLSS: No PSSS found in this frame\n"); + continue; + } + + sync_pos += frame_index * sl_fp->samples_per_frame; // position in the num_frames frame samples + + for (int pss_sym = 1; pss_sym < 3;pss_sym++) { + // Now Sync pos can point to PSS 1st symbol or 2nd symbol. + // Right now implemented the strategy to try both locations for FFT + // Think about a better correlation strategy + if (pss_sym == 1) { // Check if sync pos points to SYMBOL1 - first symbol of PSS location + if (sync_pos > sl_fp->nb_prefix_samples0 + sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples) + sync_params->ssb_offset = sync_pos - (sl_fp->nb_prefix_samples0 + sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples); + else + sync_params->ssb_offset = sync_pos + sl_fp->samples_per_frame - (sl_fp->nb_prefix_samples0 + sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples); + } else { // Check if sync pos points to SYMBOL2 - second symbol of PSS location + if (sync_pos >= sl_fp->nb_prefix_samples0 + 2*(sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)) + sync_params->ssb_offset = sync_pos - (sl_fp->nb_prefix_samples0 + 2*(sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)); + else + sync_params->ssb_offset = sync_pos + sl_fp->samples_per_frame - (sl_fp->nb_prefix_samples0 + 2*(sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)); + } + + LOG_I(PHY,"UE[%d]SIDELINK SEARCH SLSS: PSS Peak at %d, PSS sym:%d, Estimated PSS position %d\n", + UE->Mod_id,sync_pos,pss_sym,sync_params->ssb_offset); + + int slss_block_samples = (SL_NR_NUMSYM_SLSS_NORMAL_CP * sl_fp->ofdm_symbol_size) + + (SL_NR_NUMSYM_SLSS_NORMAL_CP -1) * sl_fp->nb_prefix_samples + sl_fp->nb_prefix_samples0; + + int ssb_end_position = sync_params->ssb_offset + slss_block_samples; + + LOG_D(PHY, "ssb_end:%d ssb block samples:%d total samples: %d\n", ssb_end_position, slss_block_samples, num_frames * sl_fp->samples_per_frame); + + + /* check that SSS/PBCH block is continuous inside the received buffer */ + if (ssb_end_position < num_frames * sl_fp->samples_per_frame) { + + // digital compensation of FFO for SSB symbols + if (UE->UE_fo_compensation){ // This code to be checked. Why do we do this before PSS detection is successful? + double s_time = 1/(1.0e3 * sl_fp->samples_per_subframe); // sampling time + double off_angle = -2 * M_PI * s_time * (sync_params->freq_offset); // offset rotation angle compensation per sample + + int start = sync_params->ssb_offset; // start for offset correction is at ssb_offset (pss time position) + // Adapt this for other numerologies number of symbols with larger cp increases TBD + int end = ssb_end_position; // loop over samples in all symbols (ssb size), including prefix + + + LOG_I(PHY,"SLSS SEARCH: FREQ comp of SLSS samples. Freq_OFSET:%d, startpos:%d, end_pos:%d\n", + sync_params->freq_offset, start, end); + for(int n=start; nnb_antennas_rx; ar++) { + re = ((double)(((short *)UE->common_vars.rxdata[ar]))[2*n]); + im = ((double)(((short *)UE->common_vars.rxdata[ar]))[2*n+1]); + ((short *)UE->common_vars.rxdata[ar])[2*n] = (short)(round(re*cos(n*off_angle) - im*sin(n*off_angle))); + ((short *)UE->common_vars.rxdata[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle))); + } + } + } + + NR_DL_FRAME_PARMS *frame_parms = &UE->SL_UE_PHY_PARAMS.sl_frame_params; + const uint32_t rxdataF_sz = frame_parms->samples_per_slot_wCP; + __attribute__ ((aligned(32))) c16_t rxdataF[frame_parms->nb_antennas_rx][rxdataF_sz]; + + /* In order to achieve correct processing for NR prefix samples is forced to 0 and then restored after function call */ + for(int symbol=0; symbolssb_offset, + rxdataF); + } + + sl_nr_extract_sss(UE, NULL, &metric_tdd_ncp, &phase_tdd_ncp, rxdataF); + + // save detected cell id to psbch + rx_slss_id = UE->SL_UE_PHY_PARAMS.sync_params.N_sl_id; + + __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates[frame_parms->nb_antennas_rx][rxdataF_sz]; + __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size]; + + uint8_t decoded_output[4]; + + for (int symbol = 0; symbol < SL_NR_NUMSYM_SLSS_NORMAL_CP-1;) { + nr_pbch_channel_estimation(UE, + frame_parms, + rxdataF_sz, + dl_ch_estimates, + dl_ch_estimates_time, + proc, + symbol, + symbol, + 0, + 0, + rxdataF, + 1, + rx_slss_id); + + symbol = (symbol == 0) ? 5 : symbol+1; + } + + ret = nr_rx_psbch(UE,proc, + rxdataF_sz, + dl_ch_estimates, + frame_parms, + decoded_output, + rxdataF, + rx_slss_id); + + result.cell_detected = (ret == 0) ? true : false; + + if (result.cell_detected) { // Check this later TBD + // sync at symbol ue->symbol_offset + // computing the offset wrt the beginning of the frame + // SSB located at symbol 0 + sync_params->remaining_frames = (num_frames * sl_fp->samples_per_frame - sync_params->ssb_offset)/sl_fp->samples_per_frame; + //ssb_offset points to start of sl-ssb + //rx_offset points to remaining samples needed to fill a frame + sync_params->rx_offset = sync_params->ssb_offset % sl_fp->samples_per_frame; + + LOG_I(PHY,"UE[%d]SIDELINK SLSS SEARCH: PSBCH RX OK. Remainingframes:%d, rx_offset:%d\n", + UE->Mod_id,sync_params->remaining_frames, sync_params->rx_offset); + + uint32_t psbch_payload = (*(uint32_t *)decoded_output); + //retrieve DFN and slot number from SL-MIB + sync_params->DFN = (((psbch_payload & 0x0700) >> 1) | ((psbch_payload & 0xFE0000) >> 17)); + sync_params->slot_offset = (((psbch_payload & 0x010000) >> 10) | ((psbch_payload & 0xFC000000) >> 26)); + + LOG_I(PHY, "UE[%d]SIDELINK SLSS SEARCH: SL-MIB: DFN:%d, slot:%d.\n", + UE->Mod_id, sync_params->DFN, sync_params->slot_offset); + + nr_sl_psbch_rsrp_measurements(sl_ue,frame_parms,rxdataF, false); + + UE->init_sync_frame = sync_params->remaining_frames; + result.rx_offset = sync_params->rx_offset; + + nr_sidelink_indication_t sl_indication; + sl_nr_rx_indication_t rx_ind = {0}; + uint16_t number_pdus = 1; + nr_fill_sl_indication(&sl_indication, &rx_ind, NULL, proc, UE, NULL); + nr_fill_sl_rx_indication(&rx_ind, SL_NR_RX_PDU_TYPE_SSB, UE, number_pdus, proc, (void *)decoded_output, rx_slss_id); + + + LOG_D(PHY,"Sidelink SLSS SEARCH PSBCH RX OK. Send SL-SSB TO MAC\n"); + + if (UE->if_inst && UE->if_inst->sl_indication) + UE->if_inst->sl_indication(&sl_indication); + + + break; + } + + LOG_I(PHY,"SIDELINK SLSS SEARCH: SLSS ID: %d metric %d, phase %d, psbch CRC %s\n", + sl_ue->sync_params.N_sl_id,metric_tdd_ncp,phase_tdd_ncp,(ret == 0) ? "OK" : "NOT OK"); + + } else { + LOG_W(PHY,"SIDELINK SLSS SEARCH: Error: Not enough samples to process PSBCH. sync_pos %d\n", sync_pos); + } + } + if (result.cell_detected) break; + } + + if (!result.cell_detected) { // PSBCH not found so indicate sync to higher layers and configure frame parameters + LOG_E(PHY,"SIDELINK SLSS SEARCH: PSBCH not received. Estimated PSS position:%d\n", sync_pos); + } + + return result; +} diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 52c9ec5394..9669dcc6d0 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -45,7 +45,6 @@ //#include "PHY_INTERFACE/defs.h" #define PBCH_A 24 -#define PBCH_MAX_RE_PER_SYMBOL (20*12) #define PBCH_MAX_RE (PBCH_MAX_RE_PER_SYMBOL*4) #define print_shorts(s,x) printf("%s : %d,%d,%d,%d,%d,%d,%d,%d\n",s,((int16_t*)x)[0],((int16_t*)x)[1],((int16_t*)x)[2],((int16_t*)x)[3],((int16_t*)x)[4],((int16_t*)x)[5],((int16_t*)x)[6],((int16_t*)x)[7]) @@ -230,20 +229,19 @@ int nr_pbch_channel_level(struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER return(avg2); } -static void nr_pbch_channel_compensation(struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER_SYMBOL], - struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL], - int nb_re, - struct complex16 rxdataF_comp[][PBCH_MAX_RE_PER_SYMBOL], - NR_DL_FRAME_PARMS *frame_parms, - uint8_t output_shift) { +void nr_pbch_channel_compensation(struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER_SYMBOL], + struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL], + int nb_re, + struct complex16 rxdataF_comp[][PBCH_MAX_RE_PER_SYMBOL], + NR_DL_FRAME_PARMS *frame_parms, + uint8_t output_shift) +{ for (int aarx=0; aarxnb_antennas_rx; aarx++) { simde__m128i *dl_ch128 = (simde__m128i *)dl_ch_estimates_ext[aarx]; simde__m128i *rxdataF128 = (simde__m128i *)rxdataF_ext[aarx]; simde__m128i *rxdataF_comp128 = (simde__m128i *)rxdataF_comp[aarx]; - for (int re=0; re= 5), "SIDELINK: PSBCH DMRS not contained in symbol %d \n", symbol); + + for (aarx=0; aarxnb_antennas_rx; aarx++) { + unsigned int rx_offset = frame_params->first_carrier_offset + frame_params->ssb_start_subcarrier; + rx_offset = rx_offset % frame_params->ofdm_symbol_size; + + rxF = &rxdataF[aarx][symbol*frame_params->ofdm_symbol_size]; + rxF_ext = &rxdataF_ext[aarx][0]; + + dl_ch0 = &dl_ch_estimates[aarx][symbol*frame_params->ofdm_symbol_size]; + dl_ch0_ext = &dl_ch_estimates_ext[aarx][0]; + +#ifdef DEBUG_PSBCH + LOG_I(PHY, "extract_rbs: rx_offset=%d, symbol %u\n", (rx_offset + (symbol*frame_params->ofdm_symbol_size)),symbol); +#endif + + for (rb=0; rbofdm_symbol_size); + } + + rxF_ext += SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_RB; + dl_ch0_ext += SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_RB; + dl_ch0 += NR_NB_SC_PER_RB; + } + +#ifdef DEBUG_PSBCH + char filename[40], varname[25]; + sprintf(filename,"psbch_dlch_sym_%d.m", symbol); + sprintf(varname,"psbch_dlch%d.m", symbol); + LOG_M(filename, varname, (void*)dl_ch0, frame_params->ofdm_symbol_size, 1, 1); + sprintf(filename,"psbch_dlchext_sym_%d.m", symbol); + sprintf(varname,"psbch_dlchext%d.m", symbol); + LOG_M(filename, varname, (void*)&dl_ch_estimates_ext[0][0], SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL , 1, 1); +#endif + + } + + return; + +} + +int nr_rx_psbch(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + int estimateSz, + struct complex16 dl_ch_estimates[][estimateSz], + NR_DL_FRAME_PARMS *frame_parms, + uint8_t *decoded_output, + c16_t rxdataF[][frame_parms->samples_per_slot_wCP], + uint16_t slss_id) +{ + + uint32_t decoderState=0; + int psbch_e_rx_idx = 0; + //Extra 2 bits needed as polar decoder expects a multiple of 4 as encoder length + //If these 2 bits are not added, runs compiled with --sanitize will fail. + int16_t psbch_e_rx[SL_NR_POLAR_PSBCH_E_NORMAL_CP+2]= {0}; + +#ifdef DEBUG_PSBCH + write_output("psbch_rxdataF.m","psbchrxF", + &rxdataF[0][0],frame_parms->ofdm_symbol_size*SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP,1,1); +#endif + // symbol refers to symbol within SSB. symbol_offset is the offset of the SSB wrt start of slot + double log2_maxh = 0; + + // 0 for Normal Cyclic Prefix and 1 for EXT CyclicPrefix + const int numsym = (frame_parms->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP + : SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP; + + for (int symbol=0; symbolnb_antennas_rx][nb_re+1]; + __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_ext[frame_parms->nb_antennas_rx][nb_re+1]; + //memset(dl_ch_estimates_ext,0, sizeof dl_ch_estimates_ext); + nr_psbch_extract(frame_parms->samples_per_slot_wCP, + rxdataF, + estimateSz, + dl_ch_estimates, + rxdataF_ext, + dl_ch_estimates_ext, + symbol, + frame_parms); +#ifdef DEBUG_PSBCH + LOG_I(PHY,"PSBCH RX Symbol %d ofdm size %d\n",symbol, frame_parms->ofdm_symbol_size ); +#endif + + int max_h=0; + if (symbol == 0) { + max_h = nr_pbch_channel_level(dl_ch_estimates_ext, + frame_parms, + nb_re); + //log2_maxh = 3+(log2_approx(max_h)/2); + log2_maxh = 5 +(log2_approx(max_h)/2);// LLR32 crc error. LLR 16 CRC works + + } +#ifdef DEBUG_PSBCH + LOG_I(PHY,"PSBCH RX log2_maxh = %f (%d)\n", log2_maxh, max_h); +#endif + + __attribute__ ((aligned(32))) struct complex16 rxdataF_comp[frame_parms->nb_antennas_rx][nb_re+1]; + nr_pbch_channel_compensation(rxdataF_ext, + dl_ch_estimates_ext, + nb_re, + rxdataF_comp, + frame_parms, + log2_maxh); // log2_maxh+I0_shift + + nr_pbch_quantize(psbch_e_rx + psbch_e_rx_idx, + (short *)rxdataF_comp[0], + SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL); + + psbch_e_rx_idx += SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL; + + //SKIP 2 SL-PSS AND 2 SL-SSS symbols + //Symbols carrying PSBCH 0, 5-12 + symbol = (symbol == 0) ? 5 : symbol + 1; + } + + + +#if 0 //ENABLE SCOPE LATER + UEscopeCopy(ue, psbchRxdataF_comp, psbch_unClipped, sizeof(struct complex16), frame_parms->nb_antennas_rx, psbch_e_rx_idx/2); + UEscopeCopy(ue, psbchLlr, psbch_e_rx, sizeof(int16_t), frame_parms->nb_antennas_rx, psbch_e_rx_idx); +#endif + +#ifdef DEBUG_PSBCH + write_output("psbch_rxdataFcomp.m","psbch_rxFcomp",psbch_unClipped,SL_NR_NUM_PSBCH_DATA_RE_IN_ALL_SYMBOLS,1,1); +#endif + + //un-scrambling + LOG_D(PHY, "PSBCH RX POLAR DECODING: total PSBCH bits:%d, rx_slss_id:%d\n", psbch_e_rx_idx, slss_id); + + nr_pbch_unscrambling(psbch_e_rx, slss_id, 0, 0, psbch_e_rx_idx, + 0, 0, 0, NULL); + //polar decoding de-rate matching + uint64_t tmp=0; + decoderState = polar_decoder_int16(psbch_e_rx,(uint64_t *)&tmp,0, + SL_NR_POLAR_PSBCH_MESSAGE_TYPE, SL_NR_POLAR_PSBCH_PAYLOAD_BITS, SL_NR_POLAR_PSBCH_AGGREGATION_LEVEL); + + + uint32_t psbch_payload = tmp; + + if(decoderState) { + LOG_D(PHY,"%d:%d PSBCH RX: NOK \n",proc->frame_rx, proc->nr_slot_rx); + return(decoderState); + } + + // Decoder reversal + uint32_t a_reversed=0; + + for (int i=0; i>i)&1)<<(31-i); + + psbch_payload = a_reversed; + + *((uint32_t *)decoded_output) = psbch_payload; + +#ifdef DEBUG_PSBCH + for (int i=0; i<4; i++) { + LOG_I(PHY, "decoded_output[%d]:%x\n", i, decoded_output[i]); + } +#endif + + ue->symbol_offset = 0; + + //retrieve DFN and slot number from SL-MIB + uint32_t DFN = 0, slot_offset = 0; + DFN = (((psbch_payload & 0x0700) >> 1) | ((psbch_payload & 0xFE0000) >> 17)); + slot_offset = (((psbch_payload & 0x010000) >> 10) | ((psbch_payload & 0xFC000000) >> 26)); + + LOG_D(PHY, "PSBCH RX SL-MIB:%x, decoded DFN:slot %d:%d, %x\n",psbch_payload, DFN, slot_offset, *(uint32_t *)decoded_output); + + return 0; +} diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c b/openair1/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c new file mode 100644 index 0000000000..784be79d95 --- /dev/null +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c @@ -0,0 +1,374 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "PHY/defs_nr_UE.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" +#include "PHY/NR_REFSIG/nr_mod_table.h" +#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" +#include "PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h" +#include "PHY/MODULATION/nr_modulation.h" + +//#define SL_DEBUG + +/** +*This function performs PSBCH SCrambling as described in 38.211. +*Input parameter "output" is scrambled and the scrambled output is stored in this parameter. +*id - SLSS ID used for C_INIT +*length is the length of the buffer. +*/ +void sl_psbch_scrambling(uint32_t *output, uint32_t id, uint16_t length) +{ + uint32_t x1, x2, s=0; + // x1 is set in lte_gold_generic + x2 = id; // C_INIT + +#ifdef SL_DEBUG + printf("SIDELINK: Function %s\n", __func__); + printf("Scrambling params: length %d id %d \n", length, id); +#endif + +#ifdef SL_DEBUG + for (int i=0; i<56;i++) { + printf("\nBEFORE SCRAMBLING output[%d]:0x%x\n",i,output[i]); + } +#endif + + // get initial 32 scrambing bits + s = lte_gold_generic(&x1, &x2, 1); +#ifdef SL_DEBUG + printf("s: %04x\t", s); +#endif + + // scramble in 32bit chunks + int i = 0; + while(i+32 <= length) { + + output[i>>5] ^= s; + + i += 32; + s = lte_gold_generic(&x1, &x2, 0); +#ifdef SL_DEBUG + printf("s: %04x\t", s); +#endif + } + + // scramble remaining bits + for (; i < length; ++i) { + output[i>>5] ^= ((s>>(i&0x1f)&1)<<(i&0x1f)); + } + +#ifdef SL_DEBUG + for (int i=0; i<56;i++) { + printf("\nAFTER SCRAMBLING output[%d]:0x%x\n",i,output[i]); + } +#endif + +} + + +/** +*This function RE MAPS PSS, SSS sequences as described in 38.211. +*txF is the data in frequency domain, sync_seq = PSS or SSS seq +*startsym = 1 for PSS, 3 for SSS +*re_offset = sample which points to first RE + SSB start RE +*scaling factor = scaling factor used for PSS, SSS (determined according to PSBCH pwr) +*symbol size = OFDM symbol size used for RE Mapping +*/ +void sl_map_pss_or_sss(c16_t *txF, int16_t *sync_seq, uint16_t startsym, + uint16_t re_offset, uint16_t scaling_factor, + uint16_t symbol_size) +{ + + +#ifdef SL_DEBUG + printf("%s. DEBUG PSBCH TX: RE MAPPING of PSS/SSS \n", __func__); + printf("Input Params - StartSYM:%d, NUMSYM:%d, RE_OFFSET:%d, num_REs:%d, scaling_factor:%d, symbol_size:%d\n", + startsym, SL_NR_NUM_PSS_OR_SSS_SYMBOLS,re_offset, SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL, scaling_factor, symbol_size); +#endif + + // RE Mapping of SL-PSS, SL-SSS + for (int l = startsym;l < (startsym + SL_NR_NUM_PSS_OR_SSS_SYMBOLS);l++) { + + int k = re_offset % symbol_size; + int index = 0, offset = 0; + + for (int m = 0;m < SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL;m++) { + + offset = l*symbol_size + k; + if ((m < 2) || (m >= (SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL - 3))) { + txF[offset].r = 0; //Set REs 0,1,129,130,131 = 0 + +#ifdef SL_DEBUG + printf("sym:%d, RE:%d, txF[%d]:%d.%d \n", l, m, offset, txF[offset].r,txF[offset].i); +#endif + + } else { + txF[offset].r = (sync_seq[index] * scaling_factor) >> 15; + +#ifdef SL_DEBUG + printf("sym:%d, RE:%d, txF[%d]:%d.%d, syncseq[%d]:%d \n", l, m, offset, txF[offset].r,txF[offset].i, index, sync_seq[index]); +#endif + + index++; + } + txF[offset].i = 0; + k = (k + 1) % symbol_size; + } + } + +} + + +/** +* This function Generates the PSBCH DATA Modulation symbols and RE MAPS PSBCH Modulated symbols +* and PSBCH DMRS sequences as described in 38.211. +* txF is the data in frequency domain +* payload is the PSBCH payload (SL-MIB given by higher layers) +* id - SLSS ID used for knowing which DMRS sequence to be used. +* Cp - NORMAL of extended Cyclic prefix +* startsym = 0 and then PSBCH is mapped from symbols 5-13 if normal , 5-11 if extended +* re_offset = sample which points to first RE + SSB start RE +* scaling factor = scaling factor used for PSS, SSS (determined according to PSBCH pwr) +* symbol size = OFDM symbol size used for RE Mapping +*/ + +void sl_generate_and_map_psbch(c16_t *txF, uint32_t *payload, uint16_t id, + uint16_t cp, uint16_t re_offset, + uint16_t scaling_factor, uint16_t symbol_size, + c16_t *psbch_dmrs) +{ + + uint64_t psbch_a_reversed = 0; + uint16_t num_psbch_modsym = 0, numsym = 0; + const int mod_order = 2;//QPSK + uint32_t encoder_output[SL_NR_POLAR_PSBCH_E_DWORD]; + struct complex16 psbch_modsym[SL_NR_NUM_PSBCH_MODULATED_SYMBOLS]; + + LOG_D(PHY, "PSBCH TX: Generation accg to 38.212, 38.211. SLSS id:%d\n", id); + + // Encoder reversal + for (int i=0; i>i)&1)<<(31-i); + +#ifdef SL_DEBUG + printf("DEBUG PSBCH TX: 38.212 PSBCH CRC + Channel coding (POLAR) + Rate Matching:\n"); + printf("PSBCH payload:%x, Reversed Payload:%016lx\n",*payload, psbch_a_reversed); +#endif + + /// CRC, coding and rate matching + polar_encoder_fast(&psbch_a_reversed, (void*)encoder_output, 0, 0, + SL_NR_POLAR_PSBCH_MESSAGE_TYPE, + SL_NR_POLAR_PSBCH_PAYLOAD_BITS, + SL_NR_POLAR_PSBCH_AGGREGATION_LEVEL); + +#ifdef SL_DEBUG + for (int i=0; iSL_UE_PHY_PARAMS; + uint16_t slss_id = psbch_vars->tx_slss_id; + NR_DL_FRAME_PARMS *sl_fp = &sl_ue_phy_params->sl_frame_params; + uint32_t psbch_payload = *((uint32_t *)psbch_vars->psbch_payload); + + LOG_D(PHY,"PSBCH TX: slss-id %d, psbch payload %x \n", slss_id, psbch_payload); + + // Insert FN and Slot number into SL-MIB + uint32_t mask = ~(0x700 | 0xFE0000 | 0x10000 | 0xFC000000); + psbch_payload &= mask; + psbch_payload |= ((frame_tx%1024)<<1) & 0x700; + psbch_payload |= ((frame_tx%1024)<<17) & 0xFE0000; + psbch_payload |= (slot_tx<<10) & 0x10000; + psbch_payload |= (slot_tx<<26) & 0xFC000000; + +#ifdef SL_DEBUG + printf("DEBUG PSBCH TX: DFN, SLOT included. psbch_a :0x%08x, frame:%d, slot:%d\n", + psbch_payload, frame_tx, slot_tx); +#endif + + LOG_D(PHY,"PSBCH TX: Frame.Slot %d.%d. Payload::0x%08x, slssid:%d\n", + frame_tx, slot_tx, psbch_payload, slss_id); + + // GENERATE Sidelink PSS,SSS Sequences, PSBCH DMRS Symbols, PSBCH Symbols + int16_t *sl_pss = &sl_ue_phy_params->init_params.sl_pss[slss_id/336][0]; + int16_t *sl_sss = &sl_ue_phy_params->init_params.sl_sss[slss_id][0]; + + uint16_t re_offset = sl_fp->first_carrier_offset + sl_fp->ssb_start_subcarrier; + uint16_t symbol_size = sl_fp->ofdm_symbol_size; + // TBD: Need to be replaced by function which calculates scaling factor based on psbch tx power + uint16_t scaling_factor = AMP; + + struct complex16 *txF = &txdataF[0][0]; + uint16_t startsym = SL_NR_PSS_START_SYMBOL; + + +#ifdef SL_DEBUG + printf("DEBUG PSBCH TX: MAP PSS. startsym:%d, PSS RE START:%d, scaling factor:%d\n", + startsym, re_offset, scaling_factor); +#endif + sl_map_pss_or_sss(txF, sl_pss, startsym, re_offset, scaling_factor, symbol_size); // PSS + + + startsym += SL_NR_NUM_PSS_SYMBOLS; +#ifdef SL_DEBUG + printf("DEBUG PSBCH TX: MAP SSS. startsym:%d, SSS RE START:%d, scaling factor:%d\n", + startsym, re_offset, scaling_factor); +#endif + sl_map_pss_or_sss(txF, sl_sss, startsym, re_offset, scaling_factor, symbol_size); // SSS + +#ifdef SL_DEBUG + printf("DEBUG PSBCH TX: MAP PSBCH DATA AND DMRS. cyclicPrefix:%d, PSS RE START:%d, scaling factor:%d\n", + sl_fp->Ncp, re_offset, scaling_factor); +#endif + + struct complex16 *psbch_dmrs = &sl_ue_phy_params->init_params.psbch_dmrs_modsym[slss_id][0]; + + sl_generate_and_map_psbch(txF, &psbch_payload, slss_id, + sl_fp->Ncp, re_offset, scaling_factor, symbol_size, + psbch_dmrs); + + +#ifdef SL_DEBUG + printf("DEBUG PSBCH TX: txdataF Prepared\n"); +#endif + +#ifdef SL_DEBUG + LOG_M("sl_psbch_block.m", "sl_txF", (void*)txdataF[0], symbol_size*14, 1, 1); +#endif + +} + + + diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 5a4654f360..8a61895c29 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -418,6 +418,42 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t void dump_nrdlsch(PHY_VARS_NR_UE *ue,uint8_t gNB_id,uint8_t nr_slot_rx,unsigned int *coded_bits_per_codeword,int round, unsigned char harq_pid); void nr_a_sum_b(c16_t *input_x, c16_t *input_y, unsigned short nb_rb); + +int nr_rx_psbch(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + int estimateSz, + struct complex16 dl_ch_estimates[][estimateSz], + NR_DL_FRAME_PARMS *frame_parms, + uint8_t *decoded_output, + c16_t rxdataF[][frame_parms->samples_per_slot_wCP], + uint16_t slss_id); + +void nr_tx_psbch(PHY_VARS_NR_UE *UE, uint32_t frame_tx, uint32_t slot_tx, + sl_nr_tx_config_psbch_pdu_t *psbch_vars, + c16_t **txdataF); + +nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, int num_frames); + +//Reuse already existing PBCH functions +int nr_pbch_channel_level(struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL], + NR_DL_FRAME_PARMS *frame_parms, + int nb_re); +void nr_pbch_channel_compensation(struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER_SYMBOL], + struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL], + int nb_re, + struct complex16 rxdataF_comp[][PBCH_MAX_RE_PER_SYMBOL], + NR_DL_FRAME_PARMS *frame_parms, + uint8_t output_shift); +void nr_pbch_unscrambling(int16_t *demod_pbch_e, + uint16_t Nid, + uint8_t nushift, + uint16_t M, + uint16_t length, + uint8_t bitwise, + uint32_t unscrambling_mask, + uint32_t pbch_a_prime, + uint32_t *pbch_a_interleaved); +void nr_pbch_quantize(int16_t *pbch_llr8, int16_t *pbch_llr, uint16_t len); /**@}*/ #endif diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index b2c0a6242b..0881d76c2e 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -704,3 +704,103 @@ static int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, i return peak_position; } +void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, uint16_t scaling) +{ + + int i = 0, m = 0; + int16_t x[SL_NR_PSS_SEQUENCE_LENGTH]; + const int x_initial[7] = {0, 1, 1 , 0, 1, 1, 1}; + int16_t *sl_pss = sl_init_params->sl_pss[n_sl_id2]; + int16_t *sl_pss_for_sync = sl_init_params->sl_pss_for_sync[n_sl_id2]; + + LOG_D(PHY, "SIDELINK PSBCH INIT: PSS Generation with N_SL_id2:%d\n", n_sl_id2); + +#ifdef SL_DEBUG_INIT + printf("SIDELINK: PSS Generation with N_SL_id2:%d\n", n_sl_id2); +#endif + + /// Sequence generation + for (i=0; i < 7; i++) + x[i] = x_initial[i]; + + for (i=0; i < (SL_NR_PSS_SEQUENCE_LENGTH - 7); i++) { + x[i+7] = (x[i + 4] + x[i]) %2; + } + + for (i=0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) { + m = (i + 22 + 43*n_sl_id2) % SL_NR_PSS_SEQUENCE_LENGTH; + sl_pss_for_sync[i] = (1 - 2*x[m]); + sl_pss[i] = sl_pss_for_sync[i] * scaling; + +#ifdef SL_DEBUG_INIT_DATA + printf("m:%d, sl_pss[%d]:%d\n", m, i, sl_pss[i]); +#endif + + } + +#ifdef SL_DUMP_INIT_SAMPLES + LOG_M("sl_pss_seq.m", "sl_pss", (void*)sl_pss, SL_NR_PSS_SEQUENCE_LENGTH, 1, 0); +#endif + + + +} + +// This cannot be done at init time as ofdm symbol size, ssb start subcarrier depends on configuration +// done at SLSS read time. +void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params) +{ + + uint8_t id2 = 0; + int16_t *sl_pss = NULL; + NR_DL_FRAME_PARMS *sl_fp = &sl_ue_params->sl_frame_params; + int16_t scaling_factor = AMP; + + int32_t *pss_T = NULL; + + uint16_t k = 0; + + c16_t pss_F[sl_fp->ofdm_symbol_size]; // IQ samples in freq domain + + LOG_I(PHY, "SIDELINK INIT: Generation of PSS time domain samples. scaling_factor:%d\n", scaling_factor); + + for (id2 = 0; id2 < SL_NR_NUM_IDs_IN_PSS; id2++) { + + k = sl_fp->first_carrier_offset + sl_fp->ssb_start_subcarrier + 2; // PSS in from REs 2-129 + if (k >= sl_fp->ofdm_symbol_size) k -= sl_fp->ofdm_symbol_size; + + pss_T = &sl_init_params->sl_pss_for_correlation[id2][0]; + sl_pss = sl_init_params->sl_pss[id2]; + + memset(pss_T, 0, sl_fp->ofdm_symbol_size * sizeof(pss_T[0])); + memset(pss_F, 0, sl_fp->ofdm_symbol_size * sizeof(c16_t)); + + for (int i=0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) { + + pss_F[k].r = (sl_pss[i] * scaling_factor) >> 15; + //pss_F[2*k] = (sl_pss[i]/23170) * 4192; + //pss_F[2*k+1] = 0; + +#ifdef SL_DEBUG_INIT_DATA + printf("id:%d, k:%d, pss_F[%d]:%d, sl_pss[%d]:%d\n", id2, k, 2*k, pss_F[2*k], i, sl_pss[i]); +#endif + + k++; + if (k == sl_fp->ofdm_symbol_size) k=0; + + } + + idft((int16_t)get_idft(sl_fp->ofdm_symbol_size), + (int16_t *)&pss_F[0], /* complex input */ + (int16_t *)&pss_T[0], /* complex output */ + 1); /* scaling factor */ + + } + +#ifdef SL_DUMP_PSBCH_TX_SAMPLES + LOG_M("sl_pss_TD_id0.m", "pss_TD_0", (void*)sl_init_params->sl_pss_for_correlation[0], sl_fp->ofdm_symbol_size, 1, 1); + LOG_M("sl_pss_TD_id1.m", "pss_TD_1", (void*)sl_init_params->sl_pss_for_correlation[1], sl_fp->ofdm_symbol_size, 1, 1); +#endif + +} + diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c index 0ec5f23b40..9ab3b33e4f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c @@ -63,13 +63,6 @@ #define INITIAL_SSS_NR (7) -static const int16_t phase_re_nr[PHASE_HYPOTHESIS_NUMBER] - // -pi/3 ---- pi/3 - = {16384, 20173, 23571, 26509, 28932, 30791, 32051, 32687, 32687, 32051, 30791, 28932, 26509, 23571, 20173, 16384}; - -static const int16_t phase_im_nr[PHASE_HYPOTHESIS_NUMBER] // -pi/3 ---- pi/3 - = {-28377, -25821, -22762, -19260, -15383, -11207, -6813, -2286, 2286, 6813, 11207, 15383, 19260, 22762, 25821, 28377}; - static int16_t d_sss[N_ID_2_NUMBER][N_ID_1_NUMBER][LENGTH_SSS_NR]; void init_context_sss_nr(int amp) @@ -475,7 +468,7 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue, // 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_re_nr[phase] * sss[i].r - phase_im_nr[phase] * sss[i].i) >> SCALING_METRIC_SSS_NR); + metric_re += d[i] * ((phase_nr[phase].r * sss[i].r - phase_nr[phase].i * sss[i].i) >> SCALING_METRIC_SSS_NR); } metric = metric_re; @@ -537,3 +530,54 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue, return true; } + +void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, uint16_t scaling) +{ + + int i = 0; + int m0, m1; + int n_sl_id1, n_sl_id2; + int16_t *sl_sss = sl_init_params->sl_sss[slss_id]; + int16_t *sl_sss_for_sync = sl_init_params->sl_sss_for_sync[slss_id]; + + int16_t x0[SL_NR_SSS_SEQUENCE_LENGTH], x1[SL_NR_SSS_SEQUENCE_LENGTH]; + const int x_initial[7] = { 1, 0, 0, 0, 0, 0, 0 }; + + n_sl_id1 = slss_id % 336; + n_sl_id2 = slss_id / 336; + + LOG_D(PHY, "SIDELINK INIT: SSS Generation with N_SL_id1:%d N_SL_id2:%d\n", n_sl_id1, n_sl_id2); + +#ifdef SL_DEBUG_INIT + printf("SIDELINK: SSS Generation with slss_id:%d, N_SL_id1:%d, N_SL_id2:%d\n", slss_id, n_sl_id1, n_sl_id2); +#endif + + for ( i=0 ; i < 7 ; i++) { + x0[i] = x_initial[i]; + x1[i] = x_initial[i]; + } + + for ( i=0 ; i < SL_NR_SSS_SEQUENCE_LENGTH - 7 ; i++) { + x0[i+7] = (x0[i + 4] + x0[i]) % 2; + x1[i+7] = (x1[i + 1] + x1[i]) % 2; + } + + m0 = 15*(n_sl_id1/112) + (5*n_sl_id2); + m1 = n_sl_id1 % 112; + + for (i = 0; i < SL_NR_SSS_SEQUENCE_LENGTH ; i++) { + sl_sss_for_sync[i] = (1 - 2*x0[(i + m0) % SL_NR_SSS_SEQUENCE_LENGTH] ) * (1 - 2*x1[(i + m1) % SL_NR_SSS_SEQUENCE_LENGTH] ); + sl_sss[i] = sl_sss_for_sync[i] * scaling; + +#ifdef SL_DEBUG_INIT_DATA + printf("m0:%d, m1:%d, sl_sss_for_sync[%d]:%d, sl_sss[%d]:%d\n", m0, m1, i, sl_sss_for_sync[i], i, sl_sss[i]); +#endif + + } + +#ifdef SL_DUMP_PSBCH_TX_SAMPLES + LOG_M("sl_sss_seq.m", "sl_sss", (void*)sl_sss, SL_NR_SSS_SEQUENCE_LENGTH, 1, 0); + LOG_M("sl_sss_forsync_seq.m", "sl_sss_for_sync", (void*)sl_sss_for_sync, SL_NR_SSS_SEQUENCE_LENGTH, 1, 0); +#endif + +} diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index 06e31542d5..a2ffb834d5 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -242,6 +242,13 @@ extern "C" { }; } + __attribute__((always_inline)) inline c16_t c16xmulConstShift(const c16_t a, const int b, const int Shift) { + return (c16_t) { + .r = (int16_t)((a.r * b) >> Shift), + .i = (int16_t)((a.i * b) >> Shift) + }; + } + __attribute__((always_inline)) inline c32_t c32x16maddShift(const c16_t a, const c16_t b, const c32_t c, const int Shift) { return (c32_t) { .r = ((a.r * b.r - a.i * b.i) >> Shift) + c.r, diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 8bbb1f9d84..e50e890d29 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -39,6 +39,7 @@ #include "defs_nr_common.h" #include "CODING/nrPolar_tools/nr_polar_pbch_defs.h" +#include "PHY/defs_nr_sl_UE.h" #include #include @@ -591,6 +592,10 @@ typedef struct PHY_VARS_NR_UE_s { uint8_t *phy_sim_dlsch_b; notifiedFIFO_t tx_resume_ind_fifo[NR_MAX_SLOTS_PER_FRAME]; + + //Sidelink parameters + sl_nr_sidelink_mode_t sl_mode; + sl_nr_ue_phy_params_t SL_UE_PHY_PARAMS; } PHY_VARS_NR_UE; typedef struct { @@ -612,11 +617,20 @@ typedef struct { typedef struct nr_phy_data_tx_s { NR_UE_ULSCH_t ulsch; NR_UE_PUCCH pucch_vars; + + //Sidelink Rx action decided by MAC + sl_nr_tx_config_type_enum_t sl_tx_action; + sl_nr_tx_config_psbch_pdu_t psbch_vars; + } nr_phy_data_tx_t; typedef struct nr_phy_data_s { NR_UE_PDCCH_CONFIG phy_pdcch_config; NR_UE_DLSCH_t dlsch[2]; + + //Sidelink Rx action decided by MAC + sl_nr_rx_config_type_enum_t sl_rx_action; + } nr_phy_data_t; /* this structure is used to pass both UE phy vars and * proc to the function UE_thread_rxn_txnp4 diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 3a7e2032b9..f97a4c7eb0 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -96,6 +96,8 @@ #define MAX_DELAY_COMP 20 +#define PBCH_MAX_RE_PER_SYMBOL (20*12) + typedef enum { NR_MU_0=0, NR_MU_1, @@ -168,8 +170,6 @@ struct NR_DL_FRAME_PARMS { /// Frame type (0 FDD, 1 TDD) frame_type_t frame_type; uint8_t tdd_config; - /// Sidelink Cell ID - uint16_t Nid_SL; /// Cell ID uint16_t Nid_cell; /// subcarrier spacing (15,30,60,120) diff --git a/openair1/PHY/defs_nr_sl_UE.h b/openair1/PHY/defs_nr_sl_UE.h new file mode 100644 index 0000000000..6a703aee13 --- /dev/null +++ b/openair1/PHY/defs_nr_sl_UE.h @@ -0,0 +1,166 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/defs_nr_sl_UE.h + \brief Top-level defines and structure definitions + \author + \date + \version + \company Fraunhofer + \email: + \note + \warning +*/ + +#ifndef _DEFS_NR_SL_UE_H_ +#define _DEFS_NR_SL_UE_H_ + + + +#include "PHY/types.h" +#include "PHY/defs_nr_common.h" +#include "nfapi/open-nFAPI/nfapi/public_inc/sidelink_nr_ue_interface.h" +#include "common/utils/time_meas.h" + + +// (33*(13-4)) +// Normal CP - NUM_SSB_Symbols = 13. 4 symbols for PSS, SSS +#define SL_NR_NUM_PSBCH_DMRS_RE 297 +//ceil(2(QPSK)*SL_NR_NUM_PSBCH_DMRS_RE/32) +#define SL_NR_NUM_PSBCH_DMRS_RE_DWORD 20 +//11 RBs for PSBCH in one symbol * 12 REs +#define SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL 132 +//3 DMRS REs per RB * 11 RBS in one symbol +#define SL_NR_NUM_PSBCH_DMRS_RE_IN_ONE_SYMBOL 33 +//9 PSBCH DATA REs * 11 RBS in one symbol +#define SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL 99 +#define SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL 11 +// SL_NR_POLAR_PSBCH_E_NORMAL_CP/2 bits because QPSK used for PSBCH. +// 11 * (12-3 DMRS REs) * 9 symbols for PSBCH +#define SL_NR_NUM_PSBCH_MODULATED_SYMBOLS 891 +#define SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_RB 9 +#define SL_NR_NUM_PSBCH_DMRS_RE_IN_ONE_RB 3 +// 11 * (12-3 DMRS REs) * 9 symbols for PSBCH +#define SL_NR_NUM_PSBCH_DATA_RE_IN_ALL_SYMBOLS 891 + + + +#define SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP 13 +#define SL_NR_NUM_SYMBOLS_SSB_EXT_CP 11 +#define SL_NR_NUM_PSS_SYMBOLS 2 +#define SL_NR_NUM_SSS_SYMBOLS 2 +#define SL_NR_PSS_START_SYMBOL 1 +#define SL_NR_SSS_START_SYMBOL 3 +#define SL_NR_NUM_PSS_OR_SSS_SYMBOLS 2 +#define SL_NR_PSS_SEQUENCE_LENGTH 127 +#define SL_NR_SSS_SEQUENCE_LENGTH 127 +#define SL_NR_NUM_IDs_IN_PSS 2 +#define SL_NR_NUM_IDs_IN_SSS 336 +#define SL_NR_NUM_SLSS_IDs 672 + +typedef enum sl_nr_sidelink_mode { + SL_NOT_SUPPORTED = 0, + SL_MODE1_SUPPORTED, + SL_MODE2_SUPPORTED +} sl_nr_sidelink_mode_t; + +//(11*(12-3 DMRS REs) * 2 (QPSK used) +#define SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL 198 + +typedef struct SL_NR_UE_INIT_PARAMS { + + //gold sequences for PSBCH DMRS + uint32_t psbch_dmrs_gold_sequences[SL_NR_NUM_SLSS_IDs][SL_NR_NUM_PSBCH_DMRS_RE_DWORD]; // Gold sequences for PSBCH DMRS + + //PSBCH DMRS QPSK modulated symbols for all possible SLSS Ids + struct complex16 psbch_dmrs_modsym[SL_NR_NUM_SLSS_IDs][SL_NR_NUM_PSBCH_DMRS_RE]; + + // Scaled values + int16_t sl_pss[SL_NR_NUM_IDs_IN_PSS][SL_NR_PSS_SEQUENCE_LENGTH]; + int16_t sl_sss[SL_NR_NUM_SLSS_IDs][SL_NR_SSS_SEQUENCE_LENGTH]; + + // Contains Not scaled values just the simple generated sequence + int16_t sl_pss_for_sync[SL_NR_NUM_IDs_IN_PSS][SL_NR_PSS_SEQUENCE_LENGTH]; + int16_t sl_sss_for_sync[SL_NR_NUM_SLSS_IDs][SL_NR_SSS_SEQUENCE_LENGTH]; + + int32_t **sl_pss_for_correlation; // IFFT samples for correlation + +} SL_NR_UE_INIT_PARAMS_t; + +typedef struct SL_NR_SYNC_PARAMS { + + // Indicating start of SSB block in the initial set of samples + uint32_t ssb_offset; + // Freq Offset calculated + int32_t freq_offset; + + uint32_t remaining_frames; + uint32_t rx_offset; + uint32_t slot_offset; + uint16_t N_sl_id2; //id2 determined from PSS during sync ref UE selection + uint16_t N_sl_id1; //id2 determined from SSS during sync ref UE selection + uint16_t N_sl_id; //ID calculated from ID1 and ID2 + int32_t psbch_rsrp; //rsrp of the decoded psbch during sync ref ue selection + uint32_t DFN; // DFN calculated after sync ref UE search + +} SL_NR_SYNC_PARAMS_t; + +typedef struct SL_NR_UE_PSBCH { + + // AVG POWER OF PSBCH DMRS in dB/RE + int16_t rsrp_dB_per_RE; + // AVG POWER OF PSBCH DMRS in dBm/RE + int16_t rsrp_dBm_per_RE; + + // STATS - CRC Errors observed during PSBCH reception + uint16_t rx_errors; + + // STATS - Receptions with CRC OK + uint16_t rx_ok; + + // STATS - transmissions of PSBCH by the UE + uint16_t num_psbch_tx; + +} SL_NR_UE_PSBCH_t; + +typedef struct sl_nr_ue_phy_params { + + SL_NR_UE_INIT_PARAMS_t init_params; + + SL_NR_SYNC_PARAMS_t sync_params; + + // Sidelink PHY PARAMETERS USED FOR PSBCH reception/Txn + SL_NR_UE_PSBCH_t psbch; + + //Configuration parameters from MAC + sl_nr_phy_config_request_t sl_config; + + NR_DL_FRAME_PARMS sl_frame_params; + + time_stats_t phy_proc_sl_tx; + time_stats_t phy_proc_sl_rx; + time_stats_t channel_estimation_stats; + time_stats_t ue_sl_indication_stats; + +} sl_nr_ue_phy_params_t; + + +#endif \ No newline at end of file diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index f6b33359c8..2d434e0f83 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -165,5 +165,28 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); + +int psbch_pscch_processing(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + nr_phy_data_t *phy_data); +int phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + nr_phy_data_tx_t *phy_data); +/*! \brief This function prepares the sl indication to pass to the MAC + */ +void nr_fill_sl_indication(nr_sidelink_indication_t *sl_ind, + sl_nr_rx_indication_t *rx_ind, + sl_nr_sci_indication_t *sci_ind, + UE_nr_rxtx_proc_t *proc, + PHY_VARS_NR_UE *ue, + void *phy_data); +void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind, + uint8_t pdu_type, + PHY_VARS_NR_UE *ue, + uint16_t n_pdus, + UE_nr_rxtx_proc_t *proc, + void *typeSpecific, + uint16_t rx_slss_id); + #endif /** @}*/ diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index ee250f528e..c5afd8be46 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -866,12 +866,15 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ for (int i=1; i<4; i++) { nr_slot_fep(ue, + fp, proc, (ssb_start_symbol+i)%(fp->symbols_per_slot), - rxdataF); + rxdataF, + link_type_dl); start_meas(&ue->dlsch_channel_estimation_stats); nr_pbch_channel_estimation(ue, + &ue->frame_parms, estimateSz, dl_ch_estimates, dl_ch_estimates_time, @@ -880,7 +883,9 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ i-1, ssb_index&7, ssb_slot_2 == nr_slot_rx, - rxdataF); + rxdataF, + false, + fp->Nid_cell); stop_meas(&ue->dlsch_channel_estimation_stats); } @@ -922,9 +927,11 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ for(int j = prs_config->SymbolStart; j < (prs_config->SymbolStart+prs_config->NumPRSSymbols); j++) { nr_slot_fep(ue, + fp, proc, (j%fp->symbols_per_slot), - rxdataF); + rxdataF, + link_type_dl); } nr_prs_channel_estimation(gNB_id, rsc_id, i, ue, proc, fp, rxdataF); } @@ -956,9 +963,11 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ start_meas(&ue->ofdm_demod_stats); nr_slot_fep(ue, + fp, proc, l, - rxdataF); + rxdataF, + link_type_dl); } // Hold the channel estimates in frequency domain. @@ -1016,9 +1025,11 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_ for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){ nr_slot_fep(ue, + &ue->frame_parms, proc, m, //to be updated from higher layer - rxdataF); + rxdataF, + link_type_dl); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_OUT); @@ -1106,7 +1117,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_ } l_csiim[symb_idx] = ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx]; if(nr_slot_fep_done == false) { - nr_slot_fep(ue, proc, ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx], rxdataF); + nr_slot_fep(ue, &ue->frame_parms, proc, ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx], rxdataF, link_type_dl); } } nr_ue_csi_im_procedures(ue, proc, rxdataF); @@ -1117,7 +1128,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_ if ((ue->csirs_vars[gNB_id]) && (ue->csirs_vars[gNB_id]->active == 1)) { for(int symb = 0; symb < NR_SYMBOLS_PER_SLOT; symb++) { if(is_csi_rs_in_symbol(ue->csirs_vars[gNB_id]->csirs_config_pdu,symb)) { - nr_slot_fep(ue, proc, symb, rxdataF); + nr_slot_fep(ue, &ue->frame_parms, proc, symb, rxdataF, link_type_dl); } } nr_ue_csi_rs_procedures(ue, proc, rxdataF); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c new file mode 100644 index 0000000000..c8de521d67 --- /dev/null +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c @@ -0,0 +1,324 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#define _GNU_SOURCE + +#include "PHY/defs_nr_UE.h" +#include +#include "common/utils/LOG/log.h" +#include "common/utils/LOG/vcd_signal_dumper.h" +#include "UTIL/OPT/opt.h" +#include "intertask_interface.h" +#include "T.h" +#include "PHY/MODULATION/modulation_UE.h" +#include "PHY/NR_UE_ESTIMATION/nr_estimation.h" +#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" + +void nr_fill_sl_indication(nr_sidelink_indication_t *sl_ind, + sl_nr_rx_indication_t *rx_ind, + sl_nr_sci_indication_t *sci_ind, + UE_nr_rxtx_proc_t *proc, + PHY_VARS_NR_UE *ue, + void *phy_data) +{ + memset((void*)sl_ind, 0, sizeof(nr_sidelink_indication_t)); + + sl_ind->gNB_index = proc->gNB_id; + sl_ind->module_id = ue->Mod_id; + sl_ind->cc_id = ue->CC_id; + sl_ind->frame_rx = proc->frame_rx; + sl_ind->slot_rx = proc->nr_slot_rx; + sl_ind->frame_tx = proc->frame_tx; + sl_ind->slot_tx = proc->nr_slot_tx; + sl_ind->phy_data = phy_data; + + if (rx_ind) { + sl_ind->rx_ind = rx_ind; // hang on rx_ind instance + sl_ind->sci_ind = NULL; + } + if (sci_ind) { + sl_ind->rx_ind = NULL; + sl_ind->sci_ind = sci_ind; + } +} + +void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind, + uint8_t pdu_type, + PHY_VARS_NR_UE *ue, + uint16_t n_pdus, + UE_nr_rxtx_proc_t *proc, + void *typeSpecific, + uint16_t rx_slss_id) +{ + + if (n_pdus > 1){ + LOG_E(PHY, "In %s: multiple number of SL PDUs not supported yet...\n", __FUNCTION__); + } + + sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS; + + switch (pdu_type){ + case SL_NR_RX_PDU_TYPE_SLSCH: + break; + case FAPI_NR_RX_PDU_TYPE_SSB: { + sl_nr_ssb_pdu_t *ssb_pdu = &rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu; + if(typeSpecific) { + uint8_t *psbch_decoded_output = (uint8_t *)typeSpecific; + memcpy(ssb_pdu->psbch_payload, psbch_decoded_output, sizeof(4));//4 bytes of PSBCH payload bytes + ssb_pdu->rsrp_dbm = sl_phy_params->psbch.rsrp_dBm_per_RE; + ssb_pdu->rx_slss_id = rx_slss_id; + ssb_pdu->decode_status = true; + LOG_D(PHY, "SL-IND: SSB to MAC. rsrp:%d, slssid:%d, payload:%x\n", + ssb_pdu->rsrp_dbm,ssb_pdu->rx_slss_id, + *((uint32_t *)(ssb_pdu->psbch_payload)) ); + } + else + ssb_pdu->decode_status = false; + } + break; + default: + break; + } + + rx_ind->rx_indication_body[n_pdus -1].pdu_type = pdu_type; + rx_ind->number_pdus = n_pdus; + +} + +static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue, + NR_DL_FRAME_PARMS *fp, + UE_nr_rxtx_proc_t *proc, + int estimateSz, + struct complex16 dl_ch_estimates[][estimateSz], + nr_phy_data_t *phy_data, + c16_t rxdataF[][fp->samples_per_slot_wCP]) +{ + + int ret = 0; + DevAssert(ue); + + int frame_rx = proc->frame_rx; + int nr_slot_rx = proc->nr_slot_rx; + + sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS; + uint16_t rx_slss_id = sl_phy_params->sl_config.sl_sync_source.rx_slss_id; + + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PSBCH_PROCEDURES, VCD_FUNCTION_IN); + + LOG_D(PHY,"[UE %d] Frame %d Slot %d, Trying PSBCH (SLSS ID %d)\n", + ue->Mod_id,frame_rx,nr_slot_rx, + sl_phy_params->sl_config.sl_sync_source.rx_slss_id); + + uint8_t decoded_pdu[4] = {0}; + ret = nr_rx_psbch(ue, + proc, + estimateSz, + dl_ch_estimates, + fp, + decoded_pdu, + rxdataF, + sl_phy_params->sl_config.sl_sync_source.rx_slss_id); + + nr_sidelink_indication_t sl_indication; + sl_nr_rx_indication_t rx_ind = {0}; + uint16_t number_pdus = 1; + + uint8_t *result = NULL; + if (ret) { + sl_phy_params->psbch.rx_errors ++; + LOG_E(PHY,"%d:%d PSBCH RX: NOK \n",proc->frame_rx, proc->nr_slot_rx); + } else { + result = decoded_pdu; + sl_phy_params->psbch.rx_ok ++; + LOG_D(PHY,"%d:%d PSBCH RX: OK \n",proc->frame_rx, proc->nr_slot_rx); + } + + nr_fill_sl_indication(&sl_indication, &rx_ind, NULL, proc, ue, phy_data); + nr_fill_sl_rx_indication(&rx_ind, SL_NR_RX_PDU_TYPE_SSB, ue, number_pdus, proc, (void *)result, rx_slss_id); + + if (ue->if_inst && ue->if_inst->sl_indication) + ue->if_inst->sl_indication(&sl_indication); + + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PSBCH_PROCEDURES, VCD_FUNCTION_OUT); + return ret; +} + + + +int psbch_pscch_processing(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + nr_phy_data_t *phy_data) +{ + + int frame_rx = proc->frame_rx; + int nr_slot_rx = proc->nr_slot_rx; + sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS; + NR_DL_FRAME_PARMS *fp = &sl_phy_params->sl_frame_params; + int sampleShift = 0; + + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX_SL, VCD_FUNCTION_IN); + start_meas(&sl_phy_params->phy_proc_sl_rx); + + LOG_D(PHY," ****** Sidelink RX-Chain for Frame.Slot %d.%d ****** \n", + frame_rx%1024, nr_slot_rx); + + const uint32_t rxdataF_sz = fp->samples_per_slot_wCP; + __attribute__ ((aligned(32))) c16_t rxdataF[fp->nb_antennas_rx][rxdataF_sz]; + + if (phy_data->sl_rx_action == SL_NR_CONFIG_TYPE_RX_PSBCH){ + + const int estimateSz = fp->symbols_per_slot * fp->ofdm_symbol_size; + + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PSBCH, VCD_FUNCTION_IN); + LOG_D(PHY," ----- PSBCH RX TTI: frame.slot %d.%d ------ \n", + frame_rx%1024, nr_slot_rx); + + __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates[fp->nb_antennas_rx][estimateSz]; + __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[fp->nb_antennas_rx][fp->ofdm_symbol_size]; + + // 0 for Normal Cyclic Prefix and 1 for EXT CyclicPrefix + const int numsym = (fp->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP + : SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP; + + for (int sym=0; symchannel_estimation_stats); + nr_pbch_channel_estimation(ue, + fp, + estimateSz, + dl_ch_estimates, + dl_ch_estimates_time, + proc, + sym, + sym, + 0, + 0, + rxdataF, + true, + sl_phy_params->sl_config.sl_sync_source.rx_slss_id); + stop_meas(&sl_phy_params->channel_estimation_stats); + + //PSBCH present in symbols 0, 5-12 for normal cp + sym = (sym == 0) ? 5 : sym + 1; + } + + nr_sl_psbch_rsrp_measurements(sl_phy_params,fp, rxdataF,false); + + LOG_D(PHY," ------ Decode SL-MIB: frame.slot %d.%d ------ \n", + frame_rx%1024, nr_slot_rx); + + const int psbchSuccess = nr_ue_psbch_procedures(ue, fp, proc, estimateSz, + dl_ch_estimates, phy_data, rxdataF); + + if (ue->no_timing_correction==0 && psbchSuccess == 0) { + LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction); + sampleShift = nr_adjust_synch_ue(fp, ue, proc->gNB_id, fp->ofdm_symbol_size, + dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384); + } + + LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__); +// nr_ue_rrc_measurements(ue, proc, rxdataF); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PSBCH, VCD_FUNCTION_OUT); + + if (frame_rx%64 == 0) { + LOG_I(NR_PHY,"============================================\n"); + + LOG_I(NR_PHY,"[UE%d] %d:%d PSBCH Stats: TX %d, RX ok %d, RX not ok %d\n", + ue->Mod_id, frame_rx, nr_slot_rx, + sl_phy_params->psbch.num_psbch_tx, + sl_phy_params->psbch.rx_ok, + sl_phy_params->psbch.rx_errors); + + LOG_I(NR_PHY,"============================================\n"); + } + } + + return sampleShift; +} + +int phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + nr_phy_data_tx_t *phy_data) +{ + + int slot_tx = proc->nr_slot_tx; + int frame_tx = proc->frame_tx; + int tx_action = 0; + + sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS; + NR_DL_FRAME_PARMS *fp = &sl_phy_params->sl_frame_params; + + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_SL,VCD_FUNCTION_IN); + + const int samplesF_per_slot = NR_SYMBOLS_PER_SLOT * fp->ofdm_symbol_size; + c16_t txdataF_buf[fp->nb_antennas_tx * samplesF_per_slot] __attribute__((aligned(32))); + memset(txdataF_buf, 0, sizeof(txdataF_buf)); + c16_t *txdataF[fp->nb_antennas_tx]; /* workaround to be compatible with current txdataF usage in all tx procedures. */ + for(int i=0; i< fp->nb_antennas_tx; ++i) + txdataF[i] = &txdataF_buf[i * samplesF_per_slot]; + + LOG_D(PHY,"****** start Sidelink TX-Chain for AbsSubframe %d.%d ******\n", + frame_tx, slot_tx); + + start_meas(&sl_phy_params->phy_proc_sl_tx); + + if (phy_data->sl_tx_action == SL_NR_CONFIG_TYPE_TX_PSBCH) { + sl_nr_tx_config_psbch_pdu_t *psbch_vars = &phy_data->psbch_vars; + nr_tx_psbch(ue, frame_tx, slot_tx, psbch_vars, txdataF); + sl_phy_params->psbch.num_psbch_tx ++; + + if (frame_tx%64 == 0) { + LOG_I(NR_PHY,"============================================\n"); + + LOG_I(NR_PHY,"[UE%d] %d:%d PSBCH Stats: TX %d, RX ok %d, RX not ok %d\n", + ue->Mod_id, frame_tx, slot_tx, + sl_phy_params->psbch.num_psbch_tx, + sl_phy_params->psbch.rx_ok, + sl_phy_params->psbch.rx_errors); + + LOG_I(NR_PHY,"============================================\n"); + } + tx_action = 1; + } + + if (tx_action) { + LOG_D(PHY, "Sending Uplink data \n"); + nr_ue_pusch_common_procedures(ue, + proc->nr_slot_tx, + fp, + fp->nb_antennas_tx, + txdataF); + } + + LOG_D(PHY,"****** end Sidelink TX-Chain for AbsSubframe %d.%d ******\n", + frame_tx, slot_tx); + + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_SL, VCD_FUNCTION_OUT); + stop_meas(&sl_phy_params->phy_proc_sl_tx); + + return tx_action; +} diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 489931adcc..703c4bef20 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -786,36 +786,38 @@ int main(int argc, char **argv) int ssb_slot = (UE->symbol_offset/14)+(n_hf*(frame_parms->slots_per_frame>>1)); proc.nr_slot_rx = ssb_slot; proc.gNB_id = 0; - for (int i=UE->symbol_offset+1; isymbol_offset+4; i++) { + for (int i=UE->symbol_offset+1; isymbol_offset+4; i++) { nr_slot_fep(UE, + frame_parms, &proc, i%frame_parms->symbols_per_slot, - rxdataF); + rxdataF, link_type_dl); - nr_pbch_channel_estimation(UE,estimateSz, dl_ch_estimates, dl_ch_estimates_time, &proc, - i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf,rxdataF); + nr_pbch_channel_estimation(UE,&UE->frame_parms, estimateSz, dl_ch_estimates, dl_ch_estimates_time, &proc, + i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1), + ssb_index%8,n_hf,rxdataF,false,frame_parms->Nid_cell); } - fapiPbch_t result; + fapiPbch_t result; ret = nr_rx_pbch(UE, &proc, estimateSz, dl_ch_estimates, frame_parms, ssb_index % 8, &result, rxdataF); - if (ret==0) { - //UE->rx_ind.rx_indication_body->mib_pdu.ssb_index; //not yet detected automatically - //UE->rx_ind.rx_indication_body->mib_pdu.ssb_length; //Lmax, not yet detected automatically - uint8_t gNB_xtra_byte=0; - for (int i=0; i<8; i++) - gNB_xtra_byte |= ((gNB->pbch.pbch_a>>(31-i))&1)<<(7-i); - - payload_ret = (result.xtra_byte == gNB_xtra_byte); - for (i=0;i<3;i++){ - payload_ret += (result.decoded_output[i] == ((msgDataTx.ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff)); - } - //printf("ret %d\n", payload_ret); - if (payload_ret!=4) - n_errors_payload++; - } + if (ret==0) { + //UE->rx_ind.rx_indication_body->mib_pdu.ssb_index; //not yet detected automatically + //UE->rx_ind.rx_indication_body->mib_pdu.ssb_length; //Lmax, not yet detected automatically + uint8_t gNB_xtra_byte=0; + for (int i=0; i<8; i++) + gNB_xtra_byte |= ((gNB->pbch.pbch_a>>(31-i))&1)<<(7-i); + + payload_ret = (result.xtra_byte == gNB_xtra_byte); + for (i=0;i<3;i++){ + payload_ret += (result.decoded_output[i] == ((msgDataTx.ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff)); + } + //printf("ret %d\n", payload_ret); + if (payload_ret!=4) + n_errors_payload++; + } - if (ret!=0) n_errors++; + if (ret!=0) n_errors++; } } //noise trials printf("SNR %f: trials %d, n_errors_crc = %d, n_errors_payload %d\n", SNR,n_trials,n_errors,n_errors_payload); diff --git a/openair1/SIMULATION/NR_PHY/psbchsim.c b/openair1/SIMULATION/NR_PHY/psbchsim.c new file mode 100644 index 0000000000..73819b56b7 --- /dev/null +++ b/openair1/SIMULATION/NR_PHY/psbchsim.c @@ -0,0 +1,658 @@ + +#include +#include +#include +#include +#include +#include +#include "common/config/config_userapi.h" +#include "common/ran_context.h" +#include "PHY/types.h" +#include "PHY/defs_nr_common.h" +#include "PHY/defs_nr_UE.h" +#include "PHY/defs_gNB.h" +#include "PHY/phy_vars.h" +#include "NR_MasterInformationBlockSidelink.h" +#include "PHY/INIT/phy_init.h" +#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h" +#include "openair1/SIMULATION/TOOLS/sim.h" +#include "common/utils/nr/nr_common.h" +#include "openair2/RRC/NR/nr_rrc_extern.h" +#include "openair2/RRC/LTE/rrc_vars.h" +#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" +#include "PHY/INIT/nr_phy_init.h" +#include "SIMULATION/RF/rf.h" +#include "common/utils/load_module_shlib.h" +#include "PHY/MODULATION/nr_modulation.h" +#include "NR_SL-SSB-TimeAllocation-r16.h" + +void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) { abort(); } +void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req) { abort(); } +void e1_bearer_release_cmd(const e1ap_bearer_release_cmd_t *cmd) { abort(); } +void exit_function(const char* file, const char* function, const int line, const char* s, const int assert) { + const char * msg= s==NULL ? "no comment": s; + printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); + exit(-1); +} +int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { return 1; } +// to solve link errors +double cpuf; +//void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {} +void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu, + uint8_t *nb_dmrs_re_per_rb, + uint16_t *number_dmrs_symbols){} +uint64_t downlink_frequency[1][1]; +int32_t uplink_frequency_offset[1][1]; +THREAD_STRUCT thread_struct; +instance_t DUuniqInstance=0; +instance_t CUuniqInstance=0; +openair0_config_t openair0_cfg[1]; + +RAN_CONTEXT_t RC; +int oai_exit = 0; +char *uecap_file; + +void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) +{ + return; +} + +int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, + const int CC_id, + const uint8_t gNB_id, + const frame_t frameP, + const rb_id_t Srb_id, + uint8_t *buffer_pP) +{ + return 0; +} + +nr_bler_struct nr_bler_data[NR_NUM_MCS]; +void get_nrUE_params(void) { return;} +uint8_t check_if_ue_is_sl_syncsource() {return 0;} +////////////////////////////////////////////////////////////////////////// +static void prepare_mib_bits(uint8_t *buf, uint32_t frame_tx, uint32_t slot_tx) { + + NR_MasterInformationBlockSidelink_t *sl_mib; + asn_enc_rval_t enc_rval; + + void *buffer = (void *)buf; + + sl_mib = CALLOC(1, sizeof(NR_MasterInformationBlockSidelink_t)); + + sl_mib->inCoverage_r16 = 0;//TRUE; + + // allocate buffer for 7 bits slotnumber + sl_mib->slotIndex_r16.size = 1; + sl_mib->slotIndex_r16.buf = CALLOC(1, sl_mib->slotIndex_r16.size); + sl_mib->slotIndex_r16.bits_unused = sl_mib->slotIndex_r16.size*8 - 7; + sl_mib->slotIndex_r16.buf[0] = slot_tx << sl_mib->slotIndex_r16.bits_unused; + + sl_mib->directFrameNumber_r16.size = 2; + sl_mib->directFrameNumber_r16.buf = CALLOC(1, sl_mib->directFrameNumber_r16.size); + sl_mib->directFrameNumber_r16.bits_unused = sl_mib->directFrameNumber_r16.size*8 - 10; + sl_mib->directFrameNumber_r16.buf[0] = frame_tx >> (8 - sl_mib->directFrameNumber_r16.bits_unused); + sl_mib->directFrameNumber_r16.buf[1] = frame_tx << sl_mib->directFrameNumber_r16.bits_unused; + + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_MasterInformationBlockSidelink, + NULL, + (void *)sl_mib, + buffer, + 100); + + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + + asn_DEF_NR_MasterInformationBlockSidelink.op->free_struct(&asn_DEF_NR_MasterInformationBlockSidelink, sl_mib, ASFM_FREE_EVERYTHING); + +} + +static int test_rx_mib(uint8_t *decoded_output, uint16_t frame, uint16_t slot) { + + uint32_t sl_mib = *(uint32_t *)decoded_output; + + uint32_t fn = 0, sl = 0; + fn = (((sl_mib & 0x0700) >> 1) | ((sl_mib & 0xFE0000) >> 17)); + sl = (((sl_mib & 0x010000) >> 10) | ((sl_mib & 0xFC000000) >> 26)); + + printf("decoded output:%x, TX %d:%d, timing decoded from sl-MIB %d:%d\n", + *(uint32_t *)decoded_output, frame, slot, fn, sl); + + if (frame == fn && slot == sl) + return 0; + + return -1; +} + +////////////////////////////////////////////////////////////////////////// + +static void configure_NR_UE(PHY_VARS_NR_UE *UE, int mu, int N_RB) { + + fapi_nr_config_request_t config; + NR_DL_FRAME_PARMS *fp = &UE->frame_parms; + + config.ssb_config.scs_common = mu; + config.cell_config.frame_duplex_type = TDD; + config.carrier_config.dl_grid_size[mu] = N_RB; + config.carrier_config.ul_grid_size[mu] = N_RB; + config.carrier_config.dl_frequency = 0; + config.carrier_config.uplink_frequency = 0; + + int band; + if (mu == 1) band = 78; + if (mu == 0) band = 34; + nr_init_frame_parms_ue(fp, &config, band); + fp->ofdm_offset_divisor = 8; + nr_dump_frame_parms(fp); + + if (init_nr_ue_signal(UE, 1) != 0) { + printf("Error at UE NR initialisation\n"); + exit(-1); + } +} + +static void sl_init_frame_parameters(PHY_VARS_NR_UE *UE) { + + NR_DL_FRAME_PARMS *nr_fp = &UE->frame_parms; + NR_DL_FRAME_PARMS *sl_fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; + + memcpy(sl_fp, nr_fp, sizeof(NR_DL_FRAME_PARMS)); + sl_fp->ofdm_offset_divisor = 8; // What is this used for? + + sl_fp->att_tx = 1; + sl_fp->att_rx = 1; + // band47 //UL freq will be set to Sidelink freq + sl_fp->ul_CarrierFreq = 5880000000; + + sl_fp->ssb_start_subcarrier = UE->SL_UE_PHY_PARAMS.sl_config.sl_bwp_config.sl_ssb_offset_point_a; + sl_fp->Nid_cell = UE->SL_UE_PHY_PARAMS.sl_config.sl_sync_source.rx_slss_id; + +#ifdef DEBUG_INIT + LOG_I(PHY, "Dumping Sidelink Frame Parameters\n"); + nr_dump_frame_parms(sl_fp); +#endif + +} + +static void configure_SL_UE(PHY_VARS_NR_UE *UE, int mu, int N_RB, int ssb_offset, int slss_id) { + + sl_nr_phy_config_request_t *config = &UE->SL_UE_PHY_PARAMS.sl_config; + NR_DL_FRAME_PARMS *fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; + + config->sl_bwp_config.sl_scs = mu; + config->sl_bwp_config.sl_ssb_offset_point_a = ssb_offset; + config->sl_carrier_config.sl_bandwidth = N_RB; + config->sl_carrier_config.sl_grid_size = 106; + config->sl_sync_source.rx_slss_id = slss_id; + + sl_init_frame_parameters(UE); + sl_ue_phy_init(UE); + init_symbol_rotation(fp); + init_timeshift_rotation(fp); + LOG_I(PHY, "Dumping Sidelink Frame Parameters\n"); + nr_dump_frame_parms(fp); +} + +static int freq_domain_loopback(PHY_VARS_NR_UE *UE_tx, PHY_VARS_NR_UE *UE_rx, + int frame, int slot, + nr_phy_data_tx_t *phy_data) { + + sl_nr_ue_phy_params_t *sl_ue1 = &UE_tx->SL_UE_PHY_PARAMS; + sl_nr_ue_phy_params_t *sl_ue2 = &UE_rx->SL_UE_PHY_PARAMS; + + printf("\nPSBCH SIM -F: %d:%d slss id TX UE:%d, RX UE:%d\n", + frame, slot,phy_data->psbch_vars.tx_slss_id, + sl_ue2->sl_config.sl_sync_source.rx_slss_id); + + NR_DL_FRAME_PARMS *fp = &sl_ue1->sl_frame_params; + const int samplesF_per_slot = NR_SYMBOLS_PER_SLOT * fp->ofdm_symbol_size; + c16_t txdataF_buf[fp->nb_antennas_tx * samplesF_per_slot] __attribute__((aligned(32))); + memset(txdataF_buf, 0, sizeof(txdataF_buf)); + c16_t *txdataF[fp->nb_antennas_tx]; /* workaround to be compatible with current txdataF usage in all tx procedures. */ + for(int i=0; i< fp->nb_antennas_tx; ++i) + txdataF[i] = &txdataF_buf[i * samplesF_per_slot]; + + nr_tx_psbch(UE_tx,frame, slot, &phy_data->psbch_vars, txdataF); + + int estimateSz = sl_ue2->sl_frame_params.samples_per_slot_wCP; + __attribute__ ((aligned(32))) struct complex16 rxdataF[1][estimateSz]; + for (int i=0; isl_frame_params.samples_per_slot_wCP; i++) { + struct complex16 *txdataF_ptr = (struct complex16 *)&txdataF[0][i]; + struct complex16 *rxdataF_ptr = (struct complex16 *)&rxdataF[0][i]; + rxdataF_ptr->r = txdataF_ptr->r; + rxdataF_ptr->i = txdataF_ptr->i; + //printf("r,i TXDATAF[%d]- %d:%d, RXDATAF[%d]- %d:%d\n", + // i, txdataF_ptr->r, txdataF_ptr->i, i, txdataF_ptr->r, txdataF_ptr->i); + } + + uint8_t err_status = 0; + + UE_nr_rxtx_proc_t proc; + proc.frame_rx = frame; + proc.nr_slot_rx = slot; + + struct complex16 dl_ch_estimates[1][estimateSz]; + uint8_t decoded_output[4] = {0}; + + LOG_I(PHY,"DEBUG: HIJACKING DL CHANNEL ESTIMATES.\n"); + for (int s=0; s<14; s++) { + for (int j=0; jsl_frame_params.ofdm_symbol_size; j++) { + struct complex16 *dlch = (struct complex16 *)(&dl_ch_estimates[0][s*sl_ue2->sl_frame_params.ofdm_symbol_size]); + dlch[j].r = 128; + dlch[j].i = 0; + } + } + + err_status = nr_rx_psbch(UE_rx, + &proc, + estimateSz, + dl_ch_estimates, + &sl_ue2->sl_frame_params, + decoded_output, + rxdataF, + sl_ue2->sl_config.sl_sync_source.rx_slss_id); + + + int error_payload = 0; + error_payload = test_rx_mib(decoded_output, frame, slot); + + if (err_status == 0 || error_payload == 0) { + LOG_I(PHY,"---------PSBCH -F TEST OK.\n"); + return 0; + } + LOG_E(PHY, "--------PSBCH -F TEST NOK. FAIL.\n"); + return -1; +} + + +PHY_VARS_NR_UE *UE_TX; // for tx +PHY_VARS_NR_UE *UE_RX; // for rx +double cpuf; + +configmodule_interface_t *uniqCfg = NULL; +int main(int argc, char **argv) { + + char c; + int test_freqdomain_loopback = 0,test_slss_search = 0; + int frame = 5, slot = 10, frame_tx = 0, slot_tx = 0; + int loglvl = OAILOG_INFO; + uint16_t slss_id = 336, ssb_offset = 0; + double snr1 = 2.0, snr0 = 2.0, SNR; + double sigma2 = 0.0, sigma2_dB = 0.0; + double cfo=0, ip =0.0; + + SCM_t channel_model=AWGN;//Rayleigh1_anticorr; + int N_RB_DL=106,mu=1; + + uint16_t errors = 0, n_trials = 1; + + int frame_length_complex_samples; + //int frame_length_complex_samples_no_prefix; + NR_DL_FRAME_PARMS *frame_parms; + + int seed = 0; + + cpuf = get_cpu_freq_GHz(); + + if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == 0) { + exit_fun("[NR_PSBCHSIM] Error, configuration module init failed\n"); + } + + randominit(0); + + while ((c = getopt(argc, argv, "c:hn:o:s:FIL:N:R:S:T:")) != -1) { + + printf("SIDELINK PSBCH SIM: handling optarg %c\n",c); + switch (c) { + + case 'c': + cfo = atof(optarg); + printf("Setting CFO to %f Hz\n",cfo); + break; + + case 'g': + switch((char)*optarg) { + case 'A': + channel_model=SCM_A; + break; + + case 'B': + channel_model=SCM_B; + break; + + case 'C': + channel_model=SCM_C; + break; + + case 'D': + channel_model=SCM_D; + break; + + case 'E': + channel_model=EPA; + break; + + case 'F': + channel_model=EVA; + break; + + case 'G': + channel_model=ETU; + break; + + default: + printf("Unsupported channel model! Exiting.\n"); + exit(-1); + } + break; + + case 'n': + n_trials = atoi(optarg); + break; + + case 'o': + ssb_offset = atoi(optarg); + printf("SIDELINK PSBCH SIM: ssb offset from pointA:%d\n",ssb_offset); + break; + + case 's': + slss_id = atoi(optarg); + printf("SIDELINK PSBCH SIM: slss_id from arg:%d\n",slss_id); + AssertFatal(slss_id >= 0 && slss_id <= 671,"SLSS ID not within Range 0-671\n"); + break; + + case 'F': + test_freqdomain_loopback = 1; + break; + + case 'I': + test_slss_search = 1; + printf("SIDELINK PSBCH SIM: SLSS search will be tested\n"); + break; + + case 'L': + loglvl = atoi(optarg); + break; + + case 'N': + snr0 = atoi(optarg); + snr1 = snr0; + printf("Setting SNR0 to %f. Test uses this SNR as target SNR\n",snr0); + break; + + case 'R': + N_RB_DL = atoi(optarg); + printf("SIDELINK PSBCH SIM: N_RB_DL:%d\n",N_RB_DL); + break; + + case 'S': + snr1 = atof(optarg); + printf("Setting SNR1 to %f. Test will run until this SNR as target SNR\n",snr1); + AssertFatal(snr1 <= snr0, "Test runs SNR down, set snr1 to a lower value than %f\n", snr0); + break; + + case 'T': + frame = atoi(optarg); + slot = atoi(argv[optind]); + printf("PSBCH SIM: frame timing- %d:%d\n",frame, slot); + break; + + case 'h': + default : + printf("\n\nSIDELINK PSBCH SIM OPTIONS LIST - hus:FL:T:\n"); + printf("-h: HELP\n"); + printf("-c Carrier frequency offset in Hz\n"); + printf("-n Number of trials\n"); + printf("-o ssb offset from PointA - indicates ssb_start subcarrier\n"); + printf("-s: set Sidelink sync id slss_id. ex -s 100\n"); + printf("-F: Run PSBCH frequency domain loopback test of the samples\n"); + printf("-I: Sidelink SLSS search will be tested.\n"); + printf("-L: Set Log Level.\n"); + printf("-N: Test with Noise. target SNR0 eg -N 10\n"); + printf("-R N_RB_DL\n"); + printf("-S Ending SNR, runs from SNR0 to SNR1\n"); + printf("-T: Frame,Slot to be sent in sl-MIB eg -T 4 2\n"); + return 1; + + } + } + + randominit(seed); + + logInit(); + set_glog(loglvl); + + double fs=0, eps; + double scs = 30000; + double bw = 100e6; + + switch (mu) { + case 1: + scs = 30000; + if (N_RB_DL == 217) { + fs = 122.88e6; + bw = 80e6; + } + else if (N_RB_DL == 245) { + fs = 122.88e6; + bw = 90e6; + } + else if (N_RB_DL == 273) { + fs = 122.88e6; + bw = 100e6; + } + else if (N_RB_DL == 106) { + fs = 61.44e6; + bw = 40e6; + } + else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); + break; + case 3: + scs = 120000; + if (N_RB_DL == 66) { + fs = 122.88e6; + bw = 100e6; + } + else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); + break; + } + + // cfo with respect to sub-carrier spacing + eps = cfo/scs; + + // computation of integer and fractional FO to compare with estimation results + int IFO; + if(eps!=0.0){ + printf("Introducing a CFO of %lf relative to SCS of %d kHz\n",eps,(int)(scs/1000)); + if (eps>0) + IFO=(int)(eps+0.5); + else + IFO=(int)(eps-0.5); + printf("FFO = %lf; IFO = %d\n",eps-IFO,IFO); + } + + channel_desc_t *UE2UE; + int n_tx = 1, n_rx = 1; + UE2UE = new_channel_desc_scm(n_tx, + n_rx, + channel_model, + fs, + 0, + bw, + 300e-9, + 0.0, + CORR_LEVEL_LOW, + 0, + 0, + 0, + 0); + + if (UE2UE==NULL) { + printf("Problem generating channel model. Exiting.\n"); + exit(-1); + } + + /*****configure UE *************************/ + UE_TX = calloc(1, sizeof(PHY_VARS_NR_UE)); + UE_RX = calloc(1, sizeof(PHY_VARS_NR_UE)); + LOG_I(PHY, "Configure UE-TX and sidelink UE-TX.\n"); + configure_NR_UE(UE_TX, mu, N_RB_DL); + configure_SL_UE(UE_TX, mu, N_RB_DL,ssb_offset, 0xFFFF); + + LOG_I(PHY, "Configure UE-RX and sidelink UE-RX.\n"); + configure_NR_UE(UE_RX, mu, N_RB_DL); + UE_RX->is_synchronized = (test_slss_search) ? 0 : 1; + configure_SL_UE(UE_RX, mu, N_RB_DL,ssb_offset, slss_id); + /*****************************************/ + sl_nr_ue_phy_params_t *sl_uetx = &UE_TX->SL_UE_PHY_PARAMS; + sl_nr_ue_phy_params_t *sl_uerx = &UE_RX->SL_UE_PHY_PARAMS; + frame_parms = &sl_uetx->sl_frame_params; + frame_tx = frame % 1024; + slot_tx = slot % frame_parms->slots_per_frame; + + frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; + //frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; + + double **s_re,**s_im,**r_re,**r_im; + s_re = malloc(2*sizeof(double*)); + s_im = malloc(2*sizeof(double*)); + r_re = malloc(2*sizeof(double*)); + r_im = malloc(2*sizeof(double*)); + + s_re[0] = malloc16_clear(frame_length_complex_samples*sizeof(double)); + s_im[0] = malloc16_clear(frame_length_complex_samples*sizeof(double)); + r_re[0] = malloc16_clear(frame_length_complex_samples*sizeof(double)); + r_im[0] = malloc16_clear(frame_length_complex_samples*sizeof(double)); + + if(eps!=0.0) + UE_RX->UE_fo_compensation = 1; // if a frequency offset is set then perform fo estimation and compensation + + UE_nr_rxtx_proc_t proc; + proc.frame_tx = frame; + proc.nr_slot_tx = slot; + nr_phy_data_tx_t phy_data_tx; + phy_data_tx.psbch_vars.tx_slss_id = slss_id; + + uint8_t sl_mib[4] = {0}; + prepare_mib_bits(sl_mib,frame, slot); + memcpy(phy_data_tx.psbch_vars.psbch_payload,sl_mib, 4); + + phy_data_tx.sl_tx_action = SL_NR_CONFIG_TYPE_TX_PSBCH; + proc.frame_rx = frame; + proc.nr_slot_rx = slot; + nr_phy_data_t phy_data_rx; + phy_data_rx.sl_rx_action = SL_NR_CONFIG_TYPE_RX_PSBCH; + + if (test_freqdomain_loopback) { + errors += freq_domain_loopback(UE_TX, UE_RX, frame_tx, slot_tx, &phy_data_tx); + } + + printf("\nSidelink TX UE - Frame.Slot %d.%d SLSS id:%d\n", + frame, slot,phy_data_tx.psbch_vars.tx_slss_id); + printf("Sidelink RX UE - Frame.Slot %d.%d SLSS id:%d\n", + proc.frame_rx, proc.nr_slot_rx, + sl_uerx->sl_config.sl_sync_source.rx_slss_id); + + phy_procedures_nrUE_SL_TX(UE_TX, &proc, &phy_data_tx); + + for (SNR=snr0; SNR>=snr1; SNR-=1) { + + for (int trial=0; trialnb_antennas_tx; aa++) { + struct complex16 *txdata_ptr = (struct complex16 *)&UE_TX->common_vars.txData[aa][i]; + r_re[aa][i] = (double)txdata_ptr->r; + r_im[aa][i] = (double)txdata_ptr->i; + } + } + + LOG_M("txData0.m","txd0", UE_TX->common_vars.txData[0],frame_parms->samples_per_frame,1,1); + + //AWGN + sigma2_dB = 20*log10((double)AMP/4)-SNR; + sigma2 = pow(10,sigma2_dB/10); + //printf("sigma2 %f (%f dB), tx_lev %f (%f dB)\n",sigma2,sigma2_dB,txlev,10*log10((double)txlev)); + + if(eps!=0.0) { + rf_rx(r_re, // real part of txdata + r_im, // imag part of txdata + NULL, // interference real part + NULL, // interference imag part + 0, // interference power + frame_parms->nb_antennas_rx, // number of rx antennas + frame_length_complex_samples, // number of samples in frame + 1.0e9/fs, //sampling time (ns) + cfo, // frequency offset in Hz + 0.0, // drift (not implemented) + 0.0, // noise figure (not implemented) + 0.0, // rx gain in dB ? + 200, // 3rd order non-linearity in dB ? + &ip, // initial phase + 30.0e3, // phase noise cutoff in kHz + -500.0, // phase noise amplitude in dBc + 0.0, // IQ imbalance (dB), + 0.0); // IQ phase imbalance (rad) + } + + for (int i=0; inb_antennas_rx; aa++) { + UE_RX->common_vars.rxdata[aa][i].r = (short)(r_re[aa][i] + sqrt(sigma2 / 2) * gaussdouble(0.0, 1.0)); + UE_RX->common_vars.rxdata[aa][i].i = (short)(r_im[aa][i] + sqrt(sigma2 / 2) * gaussdouble(0.0, 1.0)); + } + } + + if (UE_RX->is_synchronized == 0) { + nr_initial_sync_t ret = {false, 0}; + UE_nr_rxtx_proc_t proc={0}; + //Should not have SLSS id configured. Search should find SLSS id from TX UE + UE_RX->SL_UE_PHY_PARAMS.sl_config.sl_sync_source.rx_slss_id = 0xFFFF; + ret = sl_nr_slss_search(UE_RX, &proc, 1); + printf("Sidelink SLSS search returns status:%d, rx_offset:%d\n",ret.cell_detected, ret.rx_offset); + if (!ret.cell_detected) sl_uerx->psbch.rx_errors = 1; + else { + AssertFatal(UE_RX->SL_UE_PHY_PARAMS.sync_params.N_sl_id == slss_id, + "DETECTED INCORRECT SLSS ID in SEARCH.CHECK id:%d\n", UE_RX->SL_UE_PHY_PARAMS.sync_params.N_sl_id); + sl_uerx->psbch.rx_ok = 1; + } + } else psbch_pscch_processing(UE_RX,&proc,&phy_data_rx); + + } //noise trials + + printf("Runs:%d SNR %f: SLSS Search:%d crc ERRORs = %d, OK = %d\n", + n_trials, SNR, !UE_RX->is_synchronized, + sl_uerx->psbch.rx_errors, sl_uerx->psbch.rx_ok); + errors += sl_uerx->psbch.rx_errors; + sl_uerx->psbch.rx_errors = 0; + sl_uerx->psbch.rx_ok = 0; + + } // NSR + + if (errors == 0) + LOG_I(PHY,"PSBCH test OK\n"); + else + LOG_E(PHY,"PSBCH test NOT OK\n"); + + free_channel_desc_scm(UE2UE); + + free(s_re[0]); + free(s_im[0]); + free(r_re[0]); + free(r_im[0]); + free(s_re); + free(s_im); + free(r_re); + free(r_im); + + term_nr_ue_signal(UE_TX, 1); + term_nr_ue_signal(UE_RX, 1); + + free(UE_TX); + free(UE_RX); + logTerm(); + loader_reset(); + + return errors; +} + + diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h index 9acb4785fd..5cca5b0f80 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h @@ -98,7 +98,7 @@ typedef struct { uint32_t gNB_index; /// component carrier id int cc_id; - /// frame + /// frame rx frame_t frame_rx; /// slot rx uint32_t slot_rx; From 9a2e080f7775a099f0e8cbbd4cff1fa12b973d19 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sat, 13 Apr 2024 08:54:15 +0200 Subject: [PATCH 2/6] Apply clang-format --- .../nrPolar_tools/nr_polar_psbch_defs.h | 6 +- openair1/PHY/CODING/nr_polar_init.c | 9 +- openair1/PHY/INIT/nr_init_ue.c | 13 +- openair1/PHY/INIT/nr_parms.c | 7 +- openair1/PHY/MODULATION/modulation_UE.h | 10 +- openair1/PHY/MODULATION/slot_fep_nr.c | 102 ++-- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 27 +- openair1/PHY/NR_REFSIG/nr_gold_ue.c | 34 +- openair1/PHY/NR_REFSIG/refsig_defs_ue.h | 9 +- openair1/PHY/NR_REFSIG/sss_nr.h | 21 +- .../nr_dl_channel_estimation.c | 148 +++--- openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h | 2 +- .../PHY/NR_UE_ESTIMATION/nr_ue_measurements.c | 48 +- .../PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c | 397 ++++++++-------- openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c | 23 +- openair1/PHY/NR_UE_TRANSPORT/nr_psbch_rx.c | 184 ++++---- openair1/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c | 276 +++++------ .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 18 +- openair1/PHY/NR_UE_TRANSPORT/pss_nr.c | 56 +-- openair1/PHY/NR_UE_TRANSPORT/sss_nr.c | 25 +- openair1/PHY/TOOLS/tools_defs.h | 8 +- openair1/PHY/defs_nr_UE.h | 6 +- openair1/PHY/defs_nr_common.h | 2 +- openair1/PHY/defs_nr_sl_UE.h | 44 +- openair1/SCHED_NR_UE/defs.h | 9 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 29 +- .../SCHED_NR_UE/phy_procedures_nr_ue_sl.c | 237 +++++----- openair1/SIMULATION/NR_PHY/pbchsim.c | 55 ++- openair1/SIMULATION/NR_PHY/psbchsim.c | 439 +++++++++--------- 29 files changed, 1095 insertions(+), 1149 deletions(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h index 6f0668ce5f..1398c64971 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h @@ -33,11 +33,11 @@ #ifndef __NR_POLAR_PSBCH_DEFS__H__ #define __NR_POLAR_PSBCH_DEFS__H__ -//PSBCH related polar parameters. +// PSBCH related polar parameters. -//PSBCH symbols sent in 11RBS, 9 symbols. 11*9*(12-3(for DMRS))*2bits = 1782 bits +// PSBCH symbols sent in 11RBS, 9 symbols. 11*9*(12-3(for DMRS))*2bits = 1782 bits #define SL_NR_POLAR_PSBCH_E_NORMAL_CP 1782 -//PSBCH symbols sent in 11RBS, 7 symbols. 11*7*(12-3(for DMRS))*2bits = 1386 bits +// PSBCH symbols sent in 11RBS, 7 symbols. 11*7*(12-3(for DMRS))*2bits = 1386 bits #define SL_NR_POLAR_PSBCH_E_EXT_CP 1386 // SL_NR_POLAR_PSBCH_E_NORMAL_CP/32 #define SL_NR_POLAR_PSBCH_E_DWORD 56 diff --git a/openair1/PHY/CODING/nr_polar_init.c b/openair1/PHY/CODING/nr_polar_init.c index 85424363c2..eb0817fd40 100644 --- a/openair1/PHY/CODING/nr_polar_init.c +++ b/openair1/PHY/CODING/nr_polar_init.c @@ -192,7 +192,7 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui newPolarInitNode->payloadBits = messageLength; newPolarInitNode->crcCorrectionBits = NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS; //LOG_D(PHY,"New polar node, encoderLength %d, aggregation_level %d\n",newPolarInitNode->encoderLength,aggregation_level); - } else if (messageType == SL_NR_POLAR_PSBCH_MESSAGE_TYPE) { //PSBCH + } else if (messageType == SL_NR_POLAR_PSBCH_MESSAGE_TYPE) { // PSBCH newPolarInitNode->n_max = SL_NR_POLAR_PSBCH_N_MAX; newPolarInitNode->i_il = SL_NR_POLAR_PSBCH_I_IL; newPolarInitNode->i_seg = SL_NR_POLAR_PSBCH_I_SEG; @@ -203,8 +203,11 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui newPolarInitNode->payloadBits = SL_NR_POLAR_PSBCH_PAYLOAD_BITS; newPolarInitNode->encoderLength = SL_NR_POLAR_PSBCH_E_NORMAL_CP + 2; newPolarInitNode->crcCorrectionBits = SL_NR_POLAR_PSBCH_CRC_ERROR_CORRECTION_BITS; - newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits);//G_P - LOG_D(PHY,"SIDELINK: Initializing polar parameters for PSBCH (K %d, E %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength); + newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits); // G_P + LOG_D(PHY, + "SIDELINK: Initializing polar parameters for PSBCH (K %d, E %d)\n", + newPolarInitNode->payloadBits, + newPolarInitNode->encoderLength); } else { AssertFatal(1 == 0, "[nr_polar_init] Incorrect Message Type(%d)", messageType); } diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index aade42fca7..ee90f0bccd 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -385,7 +385,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) static void sl_ue_free(PHY_VARS_NR_UE *UE) { - if (UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation) { free_and_zero(UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[0]); free_and_zero(UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[1]); @@ -716,21 +715,20 @@ void phy_term_nr_top(void) void sl_ue_phy_init(PHY_VARS_NR_UE *UE) { - uint16_t scaling_value = ONE_OVER_SQRT2_Q15; NR_DL_FRAME_PARMS *sl_fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; if (!UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation) { - UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation = (int32_t **)malloc16_clear(SL_NR_NUM_IDs_IN_PSS *sizeof(int32_t *) ); - UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[0] = (int32_t *)malloc16_clear( sizeof(int32_t)*sl_fp->ofdm_symbol_size); - UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[1] = (int32_t *)malloc16_clear( sizeof(int32_t)*sl_fp->ofdm_symbol_size); + UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation = malloc16_clear(SL_NR_NUM_IDs_IN_PSS * sizeof(int32_t *)); + UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[0] = malloc16_clear(sizeof(int32_t) * sl_fp->ofdm_symbol_size); + UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[1] = malloc16_clear(sizeof(int32_t) * sl_fp->ofdm_symbol_size); } LOG_I(PHY, "SIDELINK INIT: GENERATE PSS, SSS, GOLD SEQUENCES AND PSBCH DMRS SEQUENCES FOR ALL possible SLSS IDs 0- 671\n"); // Generate PSS sequences for IDs 0,1 used in PSS - sl_generate_pss(&UE->SL_UE_PHY_PARAMS.init_params,0, scaling_value); - sl_generate_pss(&UE->SL_UE_PHY_PARAMS.init_params,1, scaling_value); + sl_generate_pss(&UE->SL_UE_PHY_PARAMS.init_params, 0, scaling_value); + sl_generate_pss(&UE->SL_UE_PHY_PARAMS.init_params, 1, scaling_value); // Generate psbch dmrs Gold Sequences and modulated dmrs symbols sl_init_psbch_dmrs_gold_sequences(UE); @@ -745,4 +743,3 @@ void sl_ue_phy_init(PHY_VARS_NR_UE *UE) init_symbol_rotation(sl_fp); init_timeshift_rotation(sl_fp); } - diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 00006697e8..dc516d7f24 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -425,8 +425,7 @@ void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp) LOG_I(PHY,"fp->samples_per_frame=%d\n",fp->samples_per_frame); LOG_I(PHY,"fp->dl_CarrierFreq=%lu\n",fp->dl_CarrierFreq); LOG_I(PHY,"fp->ul_CarrierFreq=%lu\n",fp->ul_CarrierFreq); - LOG_I(PHY,"fp->Nid_cell=%d\n",fp->Nid_cell); - LOG_I(PHY,"fp->first_carrier_offset=%d\n",fp->first_carrier_offset); - LOG_I(PHY,"fp->ssb_start_subcarrier=%d\n",fp->ssb_start_subcarrier); + LOG_I(PHY, "fp->Nid_cell=%d\n", fp->Nid_cell); + LOG_I(PHY, "fp->first_carrier_offset=%d\n", fp->first_carrier_offset); + LOG_I(PHY, "fp->ssb_start_subcarrier=%d\n", fp->ssb_start_subcarrier); } - diff --git a/openair1/PHY/MODULATION/modulation_UE.h b/openair1/PHY/MODULATION/modulation_UE.h index 1d7921d84c..03c13db8ae 100644 --- a/openair1/PHY/MODULATION/modulation_UE.h +++ b/openair1/PHY/MODULATION/modulation_UE.h @@ -55,11 +55,11 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, c16_t rxdataF[][frame_parms->samples_per_slot_wCP], uint32_t linktype); int sl_nr_slot_fep(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - unsigned char symbol, - unsigned char Ns, - uint32_t sample_offset, - c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]); + UE_nr_rxtx_proc_t *proc, + unsigned char symbol, + unsigned char Ns, + uint32_t sample_offset, + c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]); int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 7eb31e44f4..4024796bb0 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -35,33 +35,34 @@ #endif*/ int sl_nr_slot_fep(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - unsigned char symbol, - unsigned char Ns, - uint32_t sample_offset, - c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]) + UE_nr_rxtx_proc_t *proc, + unsigned char symbol, + unsigned char Ns, + uint32_t sample_offset, + c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]) { NR_DL_FRAME_PARMS *frame_params = &ue->SL_UE_PHY_PARAMS.sl_frame_params; - NR_UE_COMMON *common_vars = &ue->common_vars; + NR_UE_COMMON *common_vars = &ue->common_vars; - AssertFatal(symbol < frame_params->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_params->symbols_per_slot-1); - AssertFatal(Ns < frame_params->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_params->slots_per_frame-1); + AssertFatal(symbol < frame_params->symbols_per_slot, + "slot_fep: symbol must be between 0 and %d\n", + frame_params->symbols_per_slot - 1); + AssertFatal(Ns < frame_params->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_params->slots_per_frame - 1); - unsigned int nb_prefix_samples = frame_params->nb_prefix_samples; + unsigned int nb_prefix_samples = frame_params->nb_prefix_samples; unsigned int nb_prefix_samples0 = frame_params->nb_prefix_samples0; - dft_size_idx_t dftsize = get_dft(frame_params->ofdm_symbol_size); // This is for misalignment issues - int32_t tmp_dft_in[8192] __attribute__ ((aligned (32))); + int32_t tmp_dft_in[8192] __attribute__((aligned(32))); - unsigned int rx_offset = frame_params->get_samples_slot_timestamp(Ns,frame_params,0); + unsigned int rx_offset = frame_params->get_samples_slot_timestamp(Ns, frame_params, 0); unsigned int abs_symbol = Ns * frame_params->symbols_per_slot + symbol; rx_offset += sample_offset; - for (int idx_symb = Ns*frame_params->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++) - rx_offset += (idx_symb%(0x7<numerology_index)) ? nb_prefix_samples : nb_prefix_samples0; + for (int idx_symb = Ns * frame_params->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++) + rx_offset += (idx_symb % (0x7 << frame_params->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0; rx_offset += frame_params->ofdm_symbol_size * symbol; // use OFDM symbol from within 1/8th of the CP to avoid ISI @@ -69,58 +70,61 @@ int sl_nr_slot_fep(PHY_VARS_NR_UE *ue, #ifdef SL_DEBUG_SLOT_FEP // if (ue->frame <100) - LOG_I(PHY, "slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u\n", - Ns, symbol, nb_prefix_samples, nb_prefix_samples0, rx_offset); + LOG_I(PHY, + "slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u\n", + Ns, + symbol, + nb_prefix_samples, + nb_prefix_samples0, + rx_offset); #endif - for (unsigned char aa=0; aanb_antennas_rx; aa++) { - memset(&rxdataF[aa][frame_params->ofdm_symbol_size*symbol],0,frame_params->ofdm_symbol_size*sizeof(int32_t)); + for (unsigned char aa = 0; aa < frame_params->nb_antennas_rx; aa++) { + memset(&rxdataF[aa][frame_params->ofdm_symbol_size * symbol], 0, frame_params->ofdm_symbol_size * sizeof(int32_t)); int16_t *rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset]; // if input to dft is not 256-bit aligned if ((rx_offset & 7) != 0) { - memcpy((void *)&tmp_dft_in[0], - (void *)&common_vars->rxdata[aa][rx_offset], - frame_params->ofdm_symbol_size * sizeof(int32_t)); + memcpy((void *)&tmp_dft_in[0], (void *)&common_vars->rxdata[aa][rx_offset], frame_params->ofdm_symbol_size * sizeof(int32_t)); rxdata_ptr = (int16_t *)tmp_dft_in; } - dft(dftsize, - rxdata_ptr, - (int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol], - 1); + dft(dftsize, rxdata_ptr, (int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size * symbol], 1); - - int symb_offset = (Ns%frame_params->slots_per_subframe)*frame_params->symbols_per_slot; - int32_t rot2 = ((uint32_t*)frame_params->symbol_rotation[1])[symbol+symb_offset]; - ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; + int symb_offset = (Ns % frame_params->slots_per_subframe) * frame_params->symbols_per_slot; + int32_t rot2 = ((uint32_t *)frame_params->symbol_rotation[1])[symbol + symb_offset]; + ((int16_t *)&rot2)[1] = -((int16_t *)&rot2)[1]; #ifdef SL_DEBUG_SLOT_FEP // if (ue->frame <100) - LOG_I(PHY, "slot_fep: slot %d, symbol %d rx_offset %u, rotation symbol %d %d.%d\n", Ns,symbol, rx_offset, - symbol+symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]); + LOG_I(PHY, + "slot_fep: slot %d, symbol %d rx_offset %u, rotation symbol %d %d.%d\n", + Ns, + symbol, + rx_offset, + symbol + symb_offset, + ((int16_t *)&rot2)[0], + ((int16_t *)&rot2)[1]); #endif - rotate_cpx_vector((c16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol], - (c16_t *)&rot2, - (c16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol], - frame_params->ofdm_symbol_size, - 15); + rotate_cpx_vector((c16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size * symbol], + (c16_t *)&rot2, + (c16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size * symbol], + frame_params->ofdm_symbol_size, + 15); int16_t *shift_rot = (int16_t *)frame_params->timeshift_symbol_rotation; - multadd_cpx_vector((int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol], - shift_rot, - (int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol], - 1, - frame_params->ofdm_symbol_size, - 15); + multadd_cpx_vector((int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size * symbol], + shift_rot, + (int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size * symbol], + 1, + frame_params->ofdm_symbol_size, + 15); } - - LOG_D(PHY, "SIDELINK RX: Slot FEP: done for symbol:%d\n", symbol); return 0; @@ -133,7 +137,6 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, c16_t rxdataF[][frame_parms->samples_per_slot_wCP], uint32_t linktype) { - NR_UE_COMMON *common_vars = &ue->common_vars; int Ns = proc->nr_slot_rx; @@ -190,14 +193,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, stop_meas(&ue->rx_dft_stats); - apply_nr_rotation_RX(frame_parms, - rxdataF[aa], - frame_parms->symbol_rotation[linktype], - Ns, - frame_parms->N_RB_DL, - 0, - symbol, - 1); + apply_nr_rotation_RX(frame_parms, rxdataF[aa], frame_parms->symbol_rotation[linktype], Ns, frame_parms->N_RB_DL, 0, symbol, 1); } #ifdef DEBUG_FEP diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 4789cdf232..6adcff9784 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -202,31 +202,26 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, return(0); } -void nr_pbch_dmrs_rx(int symbol, - unsigned int *nr_gold_pbch, - c16_t *output, - bool sidelink) +void nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, c16_t *output, bool sidelink) { int m,m0,m1; uint8_t idx=0; if (sidelink) { - AssertFatal(symbol== 0 || (symbol>=5 && symbol <=12),"illegal symbol %d\n",symbol); + AssertFatal(symbol == 0 || (symbol >= 5 && symbol <= 12), "illegal symbol %d\n", symbol); m0 = (symbol) ? (symbol - 4) * 33 : 0; m1 = (symbol) ? (symbol - 3) * 33 : 33; } else { - AssertFatal(symbol>=0 && symbol <3,"illegal symbol %d\n",symbol); + AssertFatal(symbol >= 0 && symbol < 3, "illegal symbol %d\n", symbol); if (symbol == 0) { - m0=0; - m1=60; - } - else if (symbol == 1) { - m0=60; - m1=84; - } - else { - m0=84; - m1=144; + m0 = 0; + m1 = 60; + } else if (symbol == 1) { + m0 = 60; + m1 = 84; + } else { + m0 = 84; + m1 = 144; } } // printf("Generating pilots symbol %d, m0 %d, m1 %d\n",symbol,m0,m1); diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c index fbabd566e8..926abfa49a 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold_ue.c +++ b/openair1/PHY/NR_REFSIG/nr_gold_ue.c @@ -157,31 +157,26 @@ void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE) uint8_t reset; for (slss_id = 0; slss_id < SL_NR_NUM_SLSS_IDs; slss_id++) { - reset = 1; x2 = slss_id; #ifdef SL_DEBUG_INIT - printf("\nPSBCH DMRS GOLD SEQ for SLSSID :%d :\n", slss_id); + printf("\nPSBCH DMRS GOLD SEQ for SLSSID :%d :\n", slss_id); #endif - for (uint8_t n=0; nSL_UE_PHY_PARAMS.init_params.psbch_dmrs_gold_sequences[slss_id][n] = lte_gold_generic(&x1, &x2, reset); reset = 0; #ifdef SL_DEBUG_INIT_DATA - printf("%x\n",SL_UE_INIT_PARAMS.sl_psbch_dmrs_gold_sequences[slss_id][n]); + printf("%x\n", SL_UE_INIT_PARAMS.sl_psbch_dmrs_gold_sequences[slss_id][n]); #endif - } } } -void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, - struct complex16 *modulated_dmrs_sym, - uint16_t slss_id) +void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, struct complex16 *modulated_dmrs_sym, uint16_t slss_id) { - uint8_t idx = 0; uint32_t *sl_dmrs_sequence = UE->SL_UE_PHY_PARAMS.init_params.psbch_dmrs_gold_sequences[slss_id]; c16_t *mod_table = (c16_t *)nr_qpsk_mod_table; @@ -191,24 +186,27 @@ void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, #endif /// QPSK modulation - for (int m=0; m>5])>>((m<<1)&0x1f))&3); + for (int m = 0; m < SL_NR_NUM_PSBCH_DMRS_RE; m++) { + idx = (((sl_dmrs_sequence[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 3); modulated_dmrs_sym[m].r = mod_table[idx].r; modulated_dmrs_sym[m].i = mod_table[idx].i; #ifdef SL_DEBUG_INIT_DATA - printf("m:%d gold seq: %d b0-b1: %d-%d DMRS Symbols: %d %d\n", m, sl_dmrs_sequence[(m<<1)>>5], (((sl_dmrs_sequence[(m<<1)>>5])>>((m<<1)&0x1f))&1), - (((sl_dmrs_sequence[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1), modulated_dmrs_sym[m].r, modulated_dmrs_sym[m].i); + printf("m:%d gold seq: %d b0-b1: %d-%d DMRS Symbols: %d %d\n", + m, + sl_dmrs_sequence[(m << 1) >> 5], + (((sl_dmrs_sequence[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 1), + (((sl_dmrs_sequence[((m << 1) + 1) >> 5]) >> (((m << 1) + 1) & 0x1f)) & 1), + modulated_dmrs_sym[m].r, + modulated_dmrs_sym[m].i); printf("idx:%d, qpsk_table.r:%d, qpsk_table.i:%d\n", idx, mod_table[idx].r, mod_table[idx].i); #endif } #ifdef SL_DUMP_INIT_SAMPLES char filename[40], varname[25]; - sprintf(filename,"sl_psbch_dmrs_slssid_%d.m", slss_id); - sprintf(varname,"sl_dmrs_id_%d.m", slss_id); - LOG_M(filename, varname, (void*)modulated_dmrs_sym, SL_NR_NUM_PSBCH_DMRS_RE, 1, 1); + sprintf(filename, "sl_psbch_dmrs_slssid_%d.m", slss_id); + sprintf(varname, "sl_dmrs_id_%d.m", slss_id); + LOG_M(filename, varname, (void *)modulated_dmrs_sym, SL_NR_NUM_PSBCH_DMRS_RE, 1, 1); #endif - } diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index 5f6366a067..23233c9119 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -30,10 +30,7 @@ /*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS. @param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables */ -void nr_pbch_dmrs_rx(int dmrss, - unsigned int *nr_gold_pbch, - c16_t *output, - bool sidelink); +void nr_pbch_dmrs_rx(int dmrss, unsigned int *nr_gold_pbch, c16_t *output, bool sidelink); /*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS. @param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables @@ -73,7 +70,5 @@ void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, u void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params); void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, uint16_t scaling); void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE); -void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, - struct complex16 *modulated_dmrs_sym, - uint16_t slss_id); +void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, struct complex16 *modulated_dmrs_sym, uint16_t slss_id); #endif diff --git a/openair1/PHY/NR_REFSIG/sss_nr.h b/openair1/PHY/NR_REFSIG/sss_nr.h index 294fed3cb8..1dff912889 100644 --- a/openair1/PHY/NR_REFSIG/sss_nr.h +++ b/openair1/PHY/NR_REFSIG/sss_nr.h @@ -72,11 +72,22 @@ static const c16_t phase_nr[PHASE_HYPOTHESIS_NUMBER] = { // {pi/3 ---- pi/3, -pi/3 ---- pi/3} - {16384, -28377}, {20173, -25821}, {23571, -22762}, {26509, -19260}, - {28932, -15383}, {30791, -11207}, {32051, -6813}, {32687, -2286}, - {32687, 2286}, {32051, 6813}, {30791, 11207}, {28932, 15383}, - {26509, 19260}, {23571, 22762}, {20173, 25821}, {16384, 28377} -}; + {16384, -28377}, + {20173, -25821}, + {23571, -22762}, + {26509, -19260}, + {28932, -15383}, + {30791, -11207}, + {32051, -6813}, + {32687, -2286}, + {32687, 2286}, + {32051, 6813}, + {30791, 11207}, + {28932, 15383}, + {26509, 19260}, + {23571, 22762}, + {20173, 25821}, + {16384, 28377}}; void init_context_sss_nr(int amp); void free_context_sss_nr(void); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 7ae7d7b56b..18d47d1ab4 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -717,7 +717,7 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue, } int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, - NR_DL_FRAME_PARMS *fp, + NR_DL_FRAME_PARMS *fp, int estimateSz, struct complex16 dl_ch_estimates[][estimateSz], struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size], @@ -738,47 +738,42 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, uint32_t *gold_seq = NULL; if (sidelink) { - - AssertFatal(dmrss == 0 || (dmrss >= 5 && dmrss <= 12), - "symbol %d is illegal for PSBCH DM-RS \n", - dmrss); + AssertFatal(dmrss == 0 || (dmrss >= 5 && dmrss <= 12), "symbol %d is illegal for PSBCH DM-RS \n", dmrss); sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS; - LOG_D(PHY,"PSBCH Channel Estimation SLSSID:%d\n", Nid); + LOG_D(PHY, "PSBCH Channel Estimation SLSSID:%d\n", Nid); gold_seq = sl_phy_params->init_params.psbch_dmrs_gold_sequences[Nid]; lastsymbol = 12; num_rbs = SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL; } else { + nushift = fp->Nid_cell % 4; - nushift = fp->Nid_cell%4; - - AssertFatal(dmrss >= 0 && dmrss < 3, - "symbol %d is illegal for PBCH DM-RS \n", - dmrss); + AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss); gold_seq = ue->nr_gold_pbch[n_hf][ssb_index]; lastsymbol = 2; num_rbs = 20; } - unsigned int ssb_offset = fp->first_carrier_offset + fp->ssb_start_subcarrier; - if (ssb_offset>= fp->ofdm_symbol_size) ssb_offset-= fp->ofdm_symbol_size; + unsigned int ssb_offset = fp->first_carrier_offset + fp->ssb_start_subcarrier; + if (ssb_offset >= fp->ofdm_symbol_size) + ssb_offset -= fp->ofdm_symbol_size; - const int ch_offset = fp->ofdm_symbol_size*symbol; - const int symbol_offset = fp->ofdm_symbol_size*symbol; + const int ch_offset = fp->ofdm_symbol_size * symbol; + const int symbol_offset = fp->ofdm_symbol_size * symbol; const int k = nushift; DEBUG_PBCH("PBCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", - proc->gNB_id, - ch_offset, - fp->ofdm_symbol_size, - fp->Ncp, - Ns, - k, - symbol); + proc->gNB_id, + ch_offset, + fp->ofdm_symbol_size, + fp->Ncp, + Ns, + k, + symbol); const c16_t *fl, *fm, *fr; @@ -814,59 +809,58 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, } idft_size_idx_t idftsizeidx; - - switch (fp->ofdm_symbol_size) { - case 128: - idftsizeidx = IDFT_128; - break; - - case 256: - idftsizeidx = IDFT_256; - break; - - case 512: - idftsizeidx = IDFT_512; - break; - - case 768: - idftsizeidx = IDFT_768; - break; - case 1024: - idftsizeidx = IDFT_1024; - break; - - case 1536: - idftsizeidx = IDFT_1536; - break; - - case 2048: - idftsizeidx = IDFT_2048; - break; - - case 3072: - idftsizeidx = IDFT_3072; - break; - - case 4096: - idftsizeidx = IDFT_4096; - break; - - case 6144: - idftsizeidx = IDFT_6144; - break; - - default: - printf("unsupported ofdm symbol size \n"); - assert(0); + switch (fp->ofdm_symbol_size) { + case 128: + idftsizeidx = IDFT_128; + break; + + case 256: + idftsizeidx = IDFT_256; + break; + + case 512: + idftsizeidx = IDFT_512; + break; + + case 768: + idftsizeidx = IDFT_768; + break; + + case 1024: + idftsizeidx = IDFT_1024; + break; + + case 1536: + idftsizeidx = IDFT_1536; + break; + + case 2048: + idftsizeidx = IDFT_2048; + break; + + case 3072: + idftsizeidx = IDFT_3072; + break; + + case 4096: + idftsizeidx = IDFT_4096; + break; + + case 6144: + idftsizeidx = IDFT_6144; + break; + + default: + printf("unsupported ofdm symbol size \n"); + assert(0); } - + // generate pilot // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS - nr_pbch_dmrs_rx(dmrss,gold_seq, &pilot[0], sidelink); - - for (int aarx=0; aarxnb_antennas_rx; aarx++) { + nr_pbch_dmrs_rx(dmrss, gold_seq, &pilot[0], sidelink); + for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) { int re_offset = ssb_offset; c16_t *pil = pilot; c16_t *rxF = &rxdataF[aarx][symbol_offset + k]; @@ -922,7 +916,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, multaddRealVectorComplexScalar(fl, ch, dl_ch, 16); pil++; - re_offset = (re_offset+4) % fp->ofdm_symbol_size; + re_offset = (re_offset + 4) % fp->ofdm_symbol_size; ch = c16mulShift(*pil, rxF[re_offset], 15); DEBUG_PBCH("pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", pilot_cnt + 1, @@ -934,7 +928,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, pil->i); multaddRealVectorComplexScalar(fm, ch, dl_ch, 16); pil++; - re_offset = (re_offset+4) % fp->ofdm_symbol_size; + re_offset = (re_offset + 4) % fp->ofdm_symbol_size; ch = c16mulShift(*pil, rxF[re_offset], 15); DEBUG_PBCH("pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", pilot_cnt + 2, @@ -950,7 +944,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch += 12; } - if( dmrss == lastsymbol) // update time statistics for last PBCH symbol + if (dmrss == lastsymbol) // update time statistics for last PBCH symbol { // do ifft of channel estimate LOG_D(PHY,"Channel Impulse Computation Slot %d Symbol %d ch_offset %d\n", Ns, symbol, ch_offset); @@ -962,13 +956,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, } if (!sidelink && dmrss == lastsymbol) - UEscopeCopy(ue, - pbchDlChEstimateTime, - (void *)dl_ch_estimates_time, - sizeof(c16_t), - fp->nb_antennas_rx, - fp->ofdm_symbol_size, - 0); + UEscopeCopy(ue, pbchDlChEstimateTime, (void *)dl_ch_estimates_time, sizeof(c16_t), fp->nb_antennas_rx, fp->ofdm_symbol_size, 0); return(0); } diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 3dc603e44e..157250a413 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -65,7 +65,7 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue, const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, - NR_DL_FRAME_PARMS *fp, + NR_DL_FRAME_PARMS *fp, int estimateSz, struct complex16 dl_ch_estimates[][estimateSz], struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size], diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index d58f9eaada..8cd33743dd 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -310,56 +310,50 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, - ((int)rx_gain - (int)rx_gain_offset)); } -//PSBCH RSRP calculations according to 38.215 section 5.1.22 +// PSBCH RSRP calculations according to 38.215 section 5.1.22 void nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params, NR_DL_FRAME_PARMS *fp, c16_t rxdataF[][fp->samples_per_slot_wCP], bool use_SSS) { - SL_NR_UE_PSBCH_t *psbch_rx = &sl_phy_params->psbch; - uint8_t numsym = (fp->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP - : SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP; + uint8_t numsym = (fp->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP : SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP; uint32_t re_offset = fp->first_carrier_offset + fp->ssb_start_subcarrier; uint32_t rsrp = 0, num_re = 0; - LOG_D(PHY, "PSBCH RSRP MEAS: numsym:%d, re_offset:%d\n",numsym, re_offset); + LOG_D(PHY, "PSBCH RSRP MEAS: numsym:%d, re_offset:%d\n", numsym, re_offset); for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) { + // Calculate PSBCH RSRP based from DMRS REs + for (uint8_t symbol = 0; symbol < numsym;) { + struct complex16 *rxF = &rxdataF[aarx][symbol * fp->ofdm_symbol_size]; - //Calculate PSBCH RSRP based from DMRS REs - for (uint8_t symbol=0; symbolofdm_symbol_size]; - - for (int re=0;reofdm_symbol_size; rsrp += c16amp2(rxF[offset]); num_re++; } } - symbol = (symbol == 0) ? 5 : symbol+1; + symbol = (symbol == 0) ? 5 : symbol + 1; } } if (use_SSS) { - //TBD... - //UE can decide between using only PSBCH DMRS or PSBCH DMRS and SSS for PSBCH RSRP computation. - //If needed this can be implemented. Reference Spec 38.215 + // TBD... + // UE can decide between using only PSBCH DMRS or PSBCH DMRS and SSS for PSBCH RSRP computation. + // If needed this can be implemented. Reference Spec 38.215 } - psbch_rx->rsrp_dB_per_RE = 10*log10(rsrp / num_re); - psbch_rx->rsrp_dBm_per_RE = psbch_rx->rsrp_dB_per_RE + - 30 - 10*log10(pow(2,30)) - - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - - dB_fixed(fp->ofdm_symbol_size); - - - LOG_I(PHY, "PSBCH RSRP (DMRS REs): numREs:%d RSRP :%d dB/RE ,RSRP:%d dBm/RE\n", - num_re, psbch_rx->rsrp_dB_per_RE, psbch_rx->rsrp_dBm_per_RE); + psbch_rx->rsrp_dB_per_RE = 10 * log10(rsrp / num_re); + psbch_rx->rsrp_dBm_per_RE = psbch_rx->rsrp_dB_per_RE + 30 - 10 * log10(pow(2, 30)) + - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) + - dB_fixed(fp->ofdm_symbol_size); + LOG_I(PHY, + "PSBCH RSRP (DMRS REs): numREs:%d RSRP :%d dB/RE ,RSRP:%d dBm/RE\n", + num_re, + psbch_rx->rsrp_dB_per_RE, + psbch_rx->rsrp_dBm_per_RE); } - 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 75df850b23..e18a6a1633 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c @@ -6,18 +6,17 @@ #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "SCHED_NR_UE/defs.h" -//Number of symbols carrying SLSS signal - PSS+SSS+PSBCH +// Number of symbols carrying SLSS signal - PSS+SSS+PSBCH #define SL_NR_NUMSYM_SLSS_NORMAL_CP 14 #define SL_NR_MAX_RX_ANTENNA 1 #define SL_NR_FIRST_PSS_SYMBOL 1 #define SL_NR_FIRST_SSS_SYMBOL 3 #define SL_NR_NUM_PSS_SSS_SYMBOLS 4 -//#define SL_DEBUG +// #define SL_DEBUG static int sl_nr_pss_correlation(PHY_VARS_NR_UE *UE, int frame_index) { - sl_nr_ue_phy_params_t *sl_ue = &UE->SL_UE_PHY_PARAMS; SL_NR_SYNC_PARAMS_t *sync_params = &sl_ue->sync_params; NR_DL_FRAME_PARMS *sl_fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; @@ -28,52 +27,49 @@ static int sl_nr_pss_correlation(PHY_VARS_NR_UE *UE, int frame_index) #ifdef SL_DEBUG char fname[50], sname[25]; - sprintf(fname,"rxdata_frame_%d.m",frame_index); - sprintf(sname,"rxd_frame%d",frame_index); - LOG_M(fname,sname, &rxdata[0][frame_index * sl_fp->samples_per_frame],sl_fp->samples_per_frame,1,1); - LOG_M("pss_for_correlation0.m","pss_id0", pss_for_correlation[0],2048,1,1); - LOG_M("pss_for_correlation1.m","pss_id1", pss_for_correlation[1],2048,1,1); + sprintf(fname, "rxdata_frame_%d.m", frame_index); + sprintf(sname, "rxd_frame%d", frame_index); + LOG_M(fname, sname, &rxdata[0][frame_index * sl_fp->samples_per_frame], sl_fp->samples_per_frame, 1, 1); + LOG_M("pss_for_correlation0.m", "pss_id0", pss_for_correlation[0], 2048, 1, 1); + LOG_M("pss_for_correlation1.m", "pss_id1", pss_for_correlation[1], 2048, 1, 1); int64_t *pss_corr_debug_values[SL_NR_NUM_IDs_IN_PSS]; #endif - int maxval=0; - for (int i=0;i<2*(sl_fp->ofdm_symbol_size);i++) { - maxval = max(maxval,pss_for_correlation[0][i]); - maxval = max(maxval,-pss_for_correlation[0][i]); - maxval = max(maxval,pss_for_correlation[1][i]); - maxval = max(maxval,-pss_for_correlation[1][i]); + int maxval = 0; + for (int i = 0; i < 2 * (sl_fp->ofdm_symbol_size); i++) { + maxval = max(maxval, pss_for_correlation[0][i]); + maxval = max(maxval, -pss_for_correlation[0][i]); + maxval = max(maxval, pss_for_correlation[1][i]); + maxval = max(maxval, -pss_for_correlation[1][i]); } - int shift = log2_approx(maxval);//*(sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)*2); + int shift = log2_approx(maxval); //*(sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)*2); #ifdef SL_DEBUG - LOG_I(PHY,"SIDELINK SLSS SEARCH: Function:%s\n", __func__); - LOG_I(PHY,"maxval:%d, shift:%d\n", maxval, shift); + LOG_I(PHY, "SIDELINK SLSS SEARCH: Function:%s\n", __func__); + LOG_I(PHY, "maxval:%d, shift:%d\n", maxval, shift); #endif - int64_t avg[SL_NR_NUM_IDs_IN_PSS] = {0}; int64_t peak_value = 0, psss_corr_value = 0; unsigned int peak_position = 0, pss_source = 0; for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) - avg[pss_index]=0; + avg[pss_index] = 0; #ifdef SL_DEBUG int64_t *pss_corr_debug_values[SL_NR_NUM_IDs_IN_PSS]; for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) - pss_corr_debug_values[pss_index] = malloc16_clear(length*sizeof(int64_t)); + pss_corr_debug_values[pss_index] = malloc16_clear(length * sizeof(int64_t)); #endif - for (int n=0; n < length - sl_fp->ofdm_symbol_size; n+=4) { // + for (int n = 0; n < length - sl_fp->ofdm_symbol_size; n += 4) { // for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) { psss_corr_value = 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 (int ar=0; arnb_antennas_rx; ar++) { - + for (int ar = 0; ar < sl_fp->nb_antennas_rx; ar++) { /* perform correlation of rx data and pss sequence ie it is a dot product */ const c32_t result = dot_product((c16_t *)pss_for_correlation[pss_index], (c16_t *)&(rxdata[ar][n + frame_index * sl_fp->samples_per_frame]), @@ -86,8 +82,12 @@ static int sl_nr_pss_correlation(PHY_VARS_NR_UE *UE, int frame_index) #ifdef SL_DEBUG pss_corr_debug_values[pss_index][n] = psss_corr_value; printf("frame:%d n:%d, pss_index:%d, pss_for_correlation[pss_index][0]:%x, rxdata[n]:%x\n", - frame_index, n, pss_index, pss_for_correlation[pss_index][0], rxdata[ar][n + frame_index * sl_fp->samples_per_frame]); - printf("result %lld, pss_corr_values[%d][%d]:%ld\n",result, pss_index, n, pss_corr_debug_values[pss_index][n]); + frame_index, + n, + pss_index, + pss_for_correlation[pss_index][0], + rxdata[ar][n + frame_index * sl_fp->samples_per_frame]); + printf("result %lld, pss_corr_values[%d][%d]:%ld\n", result, pss_index, n, pss_corr_debug_values[pss_index][n]); printf("pss_index %d: n %6u peak_value %15llu\n", pss_index, n, (unsigned long long)pss_corr_debug_values[pss_index][n]); printf("peak_value:%ld, peak_position:%d, pss_source:%d\n", peak_value, peak_position, pss_source); #endif @@ -108,23 +108,24 @@ static int sl_nr_pss_correlation(PHY_VARS_NR_UE *UE, int frame_index) } #ifdef SL_DEBUG - LOG_M("pss_corr_debug_values_0.m","pss_corr0", &pss_corr_debug_values[0][0],length,1,6); - LOG_M("pss_corr_debug_values_1.m","pss_corr1", &pss_corr_debug_values[1][0],length,1,6); + LOG_M("pss_corr_debug_values_0.m", "pss_corr0", &pss_corr_debug_values[0][0], length, 1, 6); + LOG_M("pss_corr_debug_values_1.m", "pss_corr1", &pss_corr_debug_values[1][0], length, 1, 6); - for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) { - free(pss_corr_debug_values[pss_index]); - } + for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) { + free(pss_corr_debug_values[pss_index]); + } #endif - double ffo_est=0; + double ffo_est = 0; if (UE->UE_fo_compensation) { // Not tested - // 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. + // 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. c16_t *pss = (c16_t *)pss_for_correlation[pss_source]; c16_t *rxd = (c16_t *)&(rxdata[0][peak_position + frame_index * sl_fp->samples_per_frame]); - int half_symbol = sl_fp->ofdm_symbol_size>>1; + int half_symbol = sl_fp->ofdm_symbol_size >> 1; // Computing cross-correlation at peak on half the symbol size for first half of data c32_t r1 = dot_product(pss, rxd, half_symbol, shift); @@ -138,125 +139,133 @@ static int sl_nr_pss_correlation(PHY_VARS_NR_UE *UE, int frame_index) ffo_est = atan2(r1d.r * r2d.i - r2d.r * r1d.i, r1d.r * r2d.r + r1d.i * r2d.i) / M_PI; #ifdef SL_DEBUG - printf("ffo %lf\n",ffo_est); + printf("ffo %lf\n", ffo_est); #endif } - // computing absolute value of frequency offset - sync_params->freq_offset = ffo_est*sl_fp->subcarrier_spacing; + sync_params->freq_offset = ffo_est * sl_fp->subcarrier_spacing; - for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) avg[pss_index]/=(length/4); + for (int pss_index = 0; pss_index < SL_NR_NUM_IDs_IN_PSS; pss_index++) + avg[pss_index] /= (length / 4); sync_params->N_sl_id2 = pss_source; - LOG_I(PHY,"PSS Source = %d, Peak found at pos %d, val = %llu (%d dB) avg %d dB, ffo %lf, freq offset:%d Hz\n", - pss_source, peak_position, (unsigned long long)peak_value, dB_fixed64(peak_value),dB_fixed64(avg[pss_source]),ffo_est, sync_params->freq_offset); + LOG_I(PHY, + "PSS Source = %d, Peak found at pos %d, val = %llu (%d dB) avg %d dB, ffo %lf, freq offset:%d Hz\n", + pss_source, + peak_position, + (unsigned long long)peak_value, + dB_fixed64(peak_value), + dB_fixed64(avg[pss_source]), + ffo_est, + sync_params->freq_offset); - if (peak_value < 5*avg[pss_source]) - return(-1); + if (peak_value < 5 * avg[pss_source]) + return (-1); return peak_position; } -static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - int32_t *tot_metric, uint8_t *phase_max, +static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + int32_t *tot_metric, + uint8_t *phase_max, c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]) { - c16_t pss_ext[SL_NR_MAX_RX_ANTENNA][SL_NR_NUM_PSS_SYMBOLS][SL_NR_PSS_SEQUENCE_LENGTH]; c16_t sss_ext[SL_NR_MAX_RX_ANTENNA][SL_NR_NUM_SSS_SYMBOLS][SL_NR_PSS_SEQUENCE_LENGTH]; uint8_t Nid2 = ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id2; - NR_DL_FRAME_PARMS *sl_fp=&ue->SL_UE_PHY_PARAMS.sl_frame_params; + NR_DL_FRAME_PARMS *sl_fp = &ue->SL_UE_PHY_PARAMS.sl_frame_params; int16_t *d; uint16_t Nid1 = 0; uint8_t phase; c16_t *rxF_ext; - for (int aarx=0; aarx < sl_fp->nb_antennas_rx; aarx++) { - + for (int aarx = 0; aarx < sl_fp->nb_antennas_rx; aarx++) { unsigned int ofdm_symbol_size = sl_fp->ofdm_symbol_size; // pss, sss extraction - for (int sym = SL_NR_FIRST_PSS_SYMBOL; sym < SL_NR_FIRST_PSS_SYMBOL + SL_NR_NUM_PSS_SSS_SYMBOLS;sym ++) { - + for (int sym = SL_NR_FIRST_PSS_SYMBOL; sym < SL_NR_FIRST_PSS_SYMBOL + SL_NR_NUM_PSS_SSS_SYMBOLS; sym++) { if (sym < SL_NR_FIRST_PSS_SYMBOL + SL_NR_NUM_PSS_SYMBOLS) { - rxF_ext = &pss_ext[aarx][sym-SL_NR_FIRST_PSS_SYMBOL][0]; + rxF_ext = &pss_ext[aarx][sym - SL_NR_FIRST_PSS_SYMBOL][0]; } else { - rxF_ext = &sss_ext[aarx][sym-SL_NR_FIRST_SSS_SYMBOL][0]; + rxF_ext = &sss_ext[aarx][sym - SL_NR_FIRST_SSS_SYMBOL][0]; } unsigned int k = sl_fp->first_carrier_offset + sl_fp->ssb_start_subcarrier + 2; - if (k >= ofdm_symbol_size) k -= ofdm_symbol_size; + if (k >= ofdm_symbol_size) + k -= ofdm_symbol_size; - LOG_D(PHY, "firstcarrieroffset:%d, ssb_sc:%d, k:%d, symbol:%d\n",sl_fp->first_carrier_offset, sl_fp->ssb_start_subcarrier, k, sym); + LOG_D(PHY, + "firstcarrieroffset:%d, ssb_sc:%d, k:%d, symbol:%d\n", + sl_fp->first_carrier_offset, + sl_fp->ssb_start_subcarrier, + k, + sym); - for (int i=0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) { - rxF_ext[i] = rxdataF[aarx][sym*ofdm_symbol_size + k]; + for (int i = 0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) { + rxF_ext[i] = rxdataF[aarx][sym * ofdm_symbol_size + k]; k++; - if (k == ofdm_symbol_size) k=0; + if (k == ofdm_symbol_size) + k = 0; } - } LOG_D(PHY, "SIDELINK SLSS SEARCH: EXTRACTION OF PSS, SSS done\n"); #ifdef SL_DEBUG - LOG_M("pss_ext_sym1.m","pss_ext1",&pss_ext[aarx][0][0],SL_NR_PSS_SEQUENCE_LENGTH,1,1); - LOG_M("pss_ext_sym2.m","pss_ext2",&pss_ext[aarx][1][0],SL_NR_PSS_SEQUENCE_LENGTH,1,1); - LOG_M("sss_ext_sym3.m","sss_ext3",&sss_ext[aarx][0][0],SL_NR_PSS_SEQUENCE_LENGTH,1,1); - LOG_M("sss_ext_sym4.m","sss_ext4",&sss_ext[aarx][1][0],SL_NR_PSS_SEQUENCE_LENGTH,1,1); + LOG_M("pss_ext_sym1.m", "pss_ext1", &pss_ext[aarx][0][0], SL_NR_PSS_SEQUENCE_LENGTH, 1, 1); + LOG_M("pss_ext_sym2.m", "pss_ext2", &pss_ext[aarx][1][0], SL_NR_PSS_SEQUENCE_LENGTH, 1, 1); + LOG_M("sss_ext_sym3.m", "sss_ext3", &sss_ext[aarx][0][0], SL_NR_PSS_SEQUENCE_LENGTH, 1, 1); + LOG_M("sss_ext_sym4.m", "sss_ext4", &sss_ext[aarx][1][0], SL_NR_PSS_SEQUENCE_LENGTH, 1, 1); #endif // get conjugated channel estimate from PSS, H* = R* \cdot PSS // and do channel estimation and compensation based on PSS int16_t *pss = ue->SL_UE_PHY_PARAMS.init_params.sl_pss_for_sync[Nid2]; - c16_t *pss_ext2,*sss_ext2; - - //2 Symbols each for PSS and SSS - for (int j=0; jcommon_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); - 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 -*/ + #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 */ @@ -268,16 +277,16 @@ static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, *tot_metric = INT_MIN; 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 (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 int32_t metric = 0, metric_re = 0; d = (int16_t *)&ue->SL_UE_PHY_PARAMS.init_params.sl_sss_for_sync[Nid2 * SL_NR_NUM_IDs_IN_SSS + id1]; // This is the inner product using one particular value of each unknown parameter - for (int i=0; i < SL_NR_SSS_SEQUENCE_LENGTH; i++) { - metric_re += d[i] * (((int64_t) phase_nr[phase].r * sss[i].r - phase_nr[phase].i * sss[i].i) >> 15); + for (int i = 0; i < SL_NR_SSS_SEQUENCE_LENGTH; i++) { + metric_re += d[i] * (((int64_t)phase_nr[phase].r * sss[i].r - phase_nr[phase].i * sss[i].i) >> 15); } metric = metric_re; @@ -288,23 +297,29 @@ static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, Nid1 = id1; *phase_max = phase; - 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, + Nid1, + metric, + *tot_metric, + *phase_max); } } } ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id1 = Nid1; - ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id = ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id1 + - SL_NR_NUM_IDs_IN_SSS * ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id2; - LOG_I(PHY, "UE[%d]NR-SL SLSS SEARCH: SSS Processing over. id2 from SSS:%d, id1 from PSS:%d, SLSS id:%d\n", - ue->Mod_id, ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id1, ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id2, - ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id); - + ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id = + ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id1 + SL_NR_NUM_IDs_IN_SSS * ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id2; + LOG_I(PHY, + "UE[%d]NR-SL SLSS SEARCH: SSS Processing over. id2 from SSS:%d, id1 from PSS:%d, SLSS id:%d\n", + ue->Mod_id, + ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id1, + ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id2, + ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id); #ifdef SL_DEBUG -#define SSS_METRIC_FLOOR_NR (30000) +#define SSS_METRIC_FLOOR_NR (30000) if (*tot_metric > SSS_METRIC_FLOOR_NR) { Nid2 = ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id2; Nid1 = ue->SL_UE_PHY_PARAMS.sync_params.N_sl_id1; @@ -315,22 +330,20 @@ static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, return; } - // Right now 2 frames worth of samples get processed for PSS in OAI. // For PSS in Sidelink, worst case 1 SSB in 16 frames can be present // Hence 16 frames worth of samples needs to be correlated to find the PSS. nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, int num_frames) { - sl_nr_ue_phy_params_t *sl_ue = &UE->SL_UE_PHY_PARAMS; SL_NR_SYNC_PARAMS_t *sync_params = &sl_ue->sync_params; NR_DL_FRAME_PARMS *sl_fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; - int32_t sync_pos = -1;// sync_pos_frame = -1; - int32_t metric_tdd_ncp=0; + int32_t sync_pos = -1; // sync_pos_frame = -1; + int32_t metric_tdd_ncp = 0; uint8_t phase_tdd_ncp; double im, re; - int ret=-1; + int ret = -1; uint16_t rx_slss_id = 65535; nr_initial_sync_t result = {true, 0}; @@ -341,32 +354,31 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, /* Initial synchronisation * - * 1 radio frame = 10 ms - * <---------------------------------------------------------------------------> - * | Received UE data buffer | - * ---------------------------------------------------------------------------- - * <-------------->|psbch|pss|pss|sss|sss|psbch sym5-sym 12|sym13 - guard| - * sync_pos SS/PSBCH block - */ + * 1 radio frame = 10 ms + * <---------------------------------------------------------------------------> + * | Received UE data buffer | + * ---------------------------------------------------------------------------- + * <-------------->|psbch|pss|pss|sss|sss|psbch sym5-sym 12|sym13 - guard| + * sync_pos SS/PSBCH block + */ - // initial sync performed on 16 successive frames. Worst case - one PSBCH can be sent in 16 frames. - //If psbch passes on first frame, no need to process second frame + // initial sync performed on 16 successive frames. Worst case - one PSBCH can be sent in 16 frames. + // If psbch passes on first frame, no need to process second frame // Problem with the frame approach is that // --------- SSB can be on the boundary between frames. In this case if only 1 SSB is sent we will miss it. // rxdata will hold 16 frames + slot worth of samples. This needs to be processed to find the best SSB - for(int frame_index = 0; frame_index < num_frames; frame_index++) { - + for (int frame_index = 0; frame_index < num_frames; frame_index++) { /* process pss search on received buffer */ sync_pos = sl_nr_pss_correlation(UE, frame_index); if (sync_pos == -1) { - LOG_I(PHY,"SIDELINK SEARCH SLSS: No PSSS found in this frame\n"); + LOG_I(PHY, "SIDELINK SEARCH SLSS: No PSSS found in this frame\n"); continue; } sync_pos += frame_index * sl_fp->samples_per_frame; // position in the num_frames frame samples - for (int pss_sym = 1; pss_sym < 3;pss_sym++) { + for (int pss_sym = 1; pss_sym < 3; pss_sym++) { // Now Sync pos can point to PSS 1st symbol or 2nd symbol. // Right now implemented the strategy to try both locations for FFT // Think about a better correlation strategy @@ -374,62 +386,68 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, if (sync_pos > sl_fp->nb_prefix_samples0 + sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples) sync_params->ssb_offset = sync_pos - (sl_fp->nb_prefix_samples0 + sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples); else - sync_params->ssb_offset = sync_pos + sl_fp->samples_per_frame - (sl_fp->nb_prefix_samples0 + sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples); + sync_params->ssb_offset = sync_pos + sl_fp->samples_per_frame + - (sl_fp->nb_prefix_samples0 + sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples); } else { // Check if sync pos points to SYMBOL2 - second symbol of PSS location - if (sync_pos >= sl_fp->nb_prefix_samples0 + 2*(sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)) - sync_params->ssb_offset = sync_pos - (sl_fp->nb_prefix_samples0 + 2*(sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)); + if (sync_pos >= sl_fp->nb_prefix_samples0 + 2 * (sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)) + sync_params->ssb_offset = + sync_pos - (sl_fp->nb_prefix_samples0 + 2 * (sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)); else - sync_params->ssb_offset = sync_pos + sl_fp->samples_per_frame - (sl_fp->nb_prefix_samples0 + 2*(sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)); + sync_params->ssb_offset = sync_pos + sl_fp->samples_per_frame + - (sl_fp->nb_prefix_samples0 + 2 * (sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)); } - LOG_I(PHY,"UE[%d]SIDELINK SEARCH SLSS: PSS Peak at %d, PSS sym:%d, Estimated PSS position %d\n", - UE->Mod_id,sync_pos,pss_sym,sync_params->ssb_offset); + LOG_I(PHY, + "UE[%d]SIDELINK SEARCH SLSS: PSS Peak at %d, PSS sym:%d, Estimated PSS position %d\n", + UE->Mod_id, + sync_pos, + pss_sym, + sync_params->ssb_offset); - int slss_block_samples = (SL_NR_NUMSYM_SLSS_NORMAL_CP * sl_fp->ofdm_symbol_size) + - (SL_NR_NUMSYM_SLSS_NORMAL_CP -1) * sl_fp->nb_prefix_samples + sl_fp->nb_prefix_samples0; + int slss_block_samples = (SL_NR_NUMSYM_SLSS_NORMAL_CP * sl_fp->ofdm_symbol_size) + + (SL_NR_NUMSYM_SLSS_NORMAL_CP - 1) * sl_fp->nb_prefix_samples + sl_fp->nb_prefix_samples0; int ssb_end_position = sync_params->ssb_offset + slss_block_samples; - LOG_D(PHY, "ssb_end:%d ssb block samples:%d total samples: %d\n", ssb_end_position, slss_block_samples, num_frames * sl_fp->samples_per_frame); - + LOG_D(PHY, + "ssb_end:%d ssb block samples:%d total samples: %d\n", + ssb_end_position, + slss_block_samples, + num_frames * sl_fp->samples_per_frame); /* check that SSS/PBCH block is continuous inside the received buffer */ if (ssb_end_position < num_frames * sl_fp->samples_per_frame) { - // digital compensation of FFO for SSB symbols - if (UE->UE_fo_compensation){ // This code to be checked. Why do we do this before PSS detection is successful? - double s_time = 1/(1.0e3 * sl_fp->samples_per_subframe); // sampling time - double off_angle = -2 * M_PI * s_time * (sync_params->freq_offset); // offset rotation angle compensation per sample + if (UE->UE_fo_compensation) { // This code to be checked. Why do we do this before PSS detection is successful? + double s_time = 1 / (1.0e3 * sl_fp->samples_per_subframe); // sampling time + double off_angle = -2 * M_PI * s_time * (sync_params->freq_offset); // offset rotation angle compensation per sample - int start = sync_params->ssb_offset; // start for offset correction is at ssb_offset (pss time position) + int start = sync_params->ssb_offset; // start for offset correction is at ssb_offset (pss time position) // Adapt this for other numerologies number of symbols with larger cp increases TBD int end = ssb_end_position; // loop over samples in all symbols (ssb size), including prefix - - LOG_I(PHY,"SLSS SEARCH: FREQ comp of SLSS samples. Freq_OFSET:%d, startpos:%d, end_pos:%d\n", - sync_params->freq_offset, start, end); - for(int n=start; nnb_antennas_rx; ar++) { - re = ((double)(((short *)UE->common_vars.rxdata[ar]))[2*n]); - im = ((double)(((short *)UE->common_vars.rxdata[ar]))[2*n+1]); - ((short *)UE->common_vars.rxdata[ar])[2*n] = (short)(round(re*cos(n*off_angle) - im*sin(n*off_angle))); - ((short *)UE->common_vars.rxdata[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle))); + LOG_I(PHY, + "SLSS SEARCH: FREQ comp of SLSS samples. Freq_OFSET:%d, startpos:%d, end_pos:%d\n", + sync_params->freq_offset, + start, + end); + for (int n = start; n < end; n++) { + for (int ar = 0; ar < sl_fp->nb_antennas_rx; ar++) { + re = ((double)(((short *)UE->common_vars.rxdata[ar]))[2 * n]); + im = ((double)(((short *)UE->common_vars.rxdata[ar]))[2 * n + 1]); + ((short *)UE->common_vars.rxdata[ar])[2 * n] = (short)(round(re * cos(n * off_angle) - im * sin(n * off_angle))); + ((short *)UE->common_vars.rxdata[ar])[2 * n + 1] = (short)(round(re * sin(n * off_angle) + im * cos(n * off_angle))); } } } NR_DL_FRAME_PARMS *frame_parms = &UE->SL_UE_PHY_PARAMS.sl_frame_params; const uint32_t rxdataF_sz = frame_parms->samples_per_slot_wCP; - __attribute__ ((aligned(32))) c16_t rxdataF[frame_parms->nb_antennas_rx][rxdataF_sz]; + __attribute__((aligned(32))) c16_t rxdataF[frame_parms->nb_antennas_rx][rxdataF_sz]; /* In order to achieve correct processing for NR prefix samples is forced to 0 and then restored after function call */ - for(int symbol=0; symbolssb_offset, - rxdataF); + for (int symbol = 0; symbol < SL_NR_NUMSYM_SLSS_NORMAL_CP; symbol++) { + sl_nr_slot_fep(UE, NULL, symbol, 0, sync_params->ssb_offset, rxdataF); } sl_nr_extract_sss(UE, NULL, &metric_tdd_ncp, &phase_tdd_ncp, rxdataF); @@ -437,36 +455,31 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, // save detected cell id to psbch rx_slss_id = UE->SL_UE_PHY_PARAMS.sync_params.N_sl_id; - __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates[frame_parms->nb_antennas_rx][rxdataF_sz]; - __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size]; + __attribute__((aligned(32))) struct complex16 dl_ch_estimates[frame_parms->nb_antennas_rx][rxdataF_sz]; + __attribute__(( + aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size]; uint8_t decoded_output[4]; - for (int symbol = 0; symbol < SL_NR_NUMSYM_SLSS_NORMAL_CP-1;) { + for (int symbol = 0; symbol < SL_NR_NUMSYM_SLSS_NORMAL_CP - 1;) { nr_pbch_channel_estimation(UE, - frame_parms, - rxdataF_sz, - dl_ch_estimates, - dl_ch_estimates_time, - proc, - symbol, - symbol, - 0, - 0, - rxdataF, - 1, - rx_slss_id); + frame_parms, + rxdataF_sz, + dl_ch_estimates, + dl_ch_estimates_time, + proc, + symbol, + symbol, + 0, + 0, + rxdataF, + 1, + rx_slss_id); - symbol = (symbol == 0) ? 5 : symbol+1; + symbol = (symbol == 0) ? 5 : symbol + 1; } - ret = nr_rx_psbch(UE,proc, - rxdataF_sz, - dl_ch_estimates, - frame_parms, - decoded_output, - rxdataF, - rx_slss_id); + ret = nr_rx_psbch(UE, proc, rxdataF_sz, dl_ch_estimates, frame_parms, decoded_output, rxdataF, rx_slss_id); result.cell_detected = (ret == 0) ? true : false; @@ -474,23 +487,30 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, // sync at symbol ue->symbol_offset // computing the offset wrt the beginning of the frame // SSB located at symbol 0 - sync_params->remaining_frames = (num_frames * sl_fp->samples_per_frame - sync_params->ssb_offset)/sl_fp->samples_per_frame; - //ssb_offset points to start of sl-ssb - //rx_offset points to remaining samples needed to fill a frame + sync_params->remaining_frames = + (num_frames * sl_fp->samples_per_frame - sync_params->ssb_offset) / sl_fp->samples_per_frame; + // ssb_offset points to start of sl-ssb + // rx_offset points to remaining samples needed to fill a frame sync_params->rx_offset = sync_params->ssb_offset % sl_fp->samples_per_frame; - LOG_I(PHY,"UE[%d]SIDELINK SLSS SEARCH: PSBCH RX OK. Remainingframes:%d, rx_offset:%d\n", - UE->Mod_id,sync_params->remaining_frames, sync_params->rx_offset); + LOG_I(PHY, + "UE[%d]SIDELINK SLSS SEARCH: PSBCH RX OK. Remainingframes:%d, rx_offset:%d\n", + UE->Mod_id, + sync_params->remaining_frames, + sync_params->rx_offset); uint32_t psbch_payload = (*(uint32_t *)decoded_output); - //retrieve DFN and slot number from SL-MIB + // retrieve DFN and slot number from SL-MIB sync_params->DFN = (((psbch_payload & 0x0700) >> 1) | ((psbch_payload & 0xFE0000) >> 17)); - sync_params->slot_offset = (((psbch_payload & 0x010000) >> 10) | ((psbch_payload & 0xFC000000) >> 26)); + sync_params->slot_offset = (((psbch_payload & 0x010000) >> 10) | ((psbch_payload & 0xFC000000) >> 26)); - LOG_I(PHY, "UE[%d]SIDELINK SLSS SEARCH: SL-MIB: DFN:%d, slot:%d.\n", - UE->Mod_id, sync_params->DFN, sync_params->slot_offset); + LOG_I(PHY, + "UE[%d]SIDELINK SLSS SEARCH: SL-MIB: DFN:%d, slot:%d.\n", + UE->Mod_id, + sync_params->DFN, + sync_params->slot_offset); - nr_sl_psbch_rsrp_measurements(sl_ue,frame_parms,rxdataF, false); + nr_sl_psbch_rsrp_measurements(sl_ue, frame_parms, rxdataF, false); UE->init_sync_frame = sync_params->remaining_frames; result.rx_offset = sync_params->rx_offset; @@ -501,28 +521,31 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, nr_fill_sl_indication(&sl_indication, &rx_ind, NULL, proc, UE, NULL); nr_fill_sl_rx_indication(&rx_ind, SL_NR_RX_PDU_TYPE_SSB, UE, number_pdus, proc, (void *)decoded_output, rx_slss_id); - - LOG_D(PHY,"Sidelink SLSS SEARCH PSBCH RX OK. Send SL-SSB TO MAC\n"); + LOG_D(PHY, "Sidelink SLSS SEARCH PSBCH RX OK. Send SL-SSB TO MAC\n"); if (UE->if_inst && UE->if_inst->sl_indication) UE->if_inst->sl_indication(&sl_indication); - break; } - LOG_I(PHY,"SIDELINK SLSS SEARCH: SLSS ID: %d metric %d, phase %d, psbch CRC %s\n", - sl_ue->sync_params.N_sl_id,metric_tdd_ncp,phase_tdd_ncp,(ret == 0) ? "OK" : "NOT OK"); + LOG_I(PHY, + "SIDELINK SLSS SEARCH: SLSS ID: %d metric %d, phase %d, psbch CRC %s\n", + sl_ue->sync_params.N_sl_id, + metric_tdd_ncp, + phase_tdd_ncp, + (ret == 0) ? "OK" : "NOT OK"); } else { - LOG_W(PHY,"SIDELINK SLSS SEARCH: Error: Not enough samples to process PSBCH. sync_pos %d\n", sync_pos); + LOG_W(PHY, "SIDELINK SLSS SEARCH: Error: Not enough samples to process PSBCH. sync_pos %d\n", sync_pos); } } - if (result.cell_detected) break; + if (result.cell_detected) + break; } - if (!result.cell_detected) { // PSBCH not found so indicate sync to higher layers and configure frame parameters - LOG_E(PHY,"SIDELINK SLSS SEARCH: PSBCH not received. Estimated PSS position:%d\n", sync_pos); + if (!result.cell_detected) { // PSBCH not found so indicate sync to higher layers and configure frame parameters + LOG_E(PHY, "SIDELINK SLSS SEARCH: PSBCH not received. Estimated PSS position:%d\n", sync_pos); } return result; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 9669dcc6d0..67403fe772 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -241,7 +241,7 @@ void nr_pbch_channel_compensation(struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER simde__m128i *rxdataF128 = (simde__m128i *)rxdataF_ext[aarx]; simde__m128i *rxdataF_comp128 = (simde__m128i *)rxdataF_comp[aarx]; - for (int re=0; re31) pbch_llr8[i]=32; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_psbch_rx.c b/openair1/PHY/NR_UE_TRANSPORT/nr_psbch_rx.c index ca4daab6d6..cf8ea994f1 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_psbch_rx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_psbch_rx.c @@ -25,59 +25,68 @@ #include "common/utils/LOG/log.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" - -//#define DEBUG_PSBCH +// #define DEBUG_PSBCH static void nr_psbch_extract(uint32_t rxdataF_sz, - c16_t rxdataF[][rxdataF_sz], - int estimateSz, - struct complex16 dl_ch_estimates[][estimateSz], - struct complex16 rxdataF_ext[][SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL], - struct complex16 dl_ch_estimates_ext[][SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL], - uint32_t symbol, - NR_DL_FRAME_PARMS *frame_params) + c16_t rxdataF[][rxdataF_sz], + int estimateSz, + struct complex16 dl_ch_estimates[][estimateSz], + struct complex16 rxdataF_ext[][SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL], + struct complex16 dl_ch_estimates_ext[][SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL], + uint32_t symbol, + NR_DL_FRAME_PARMS *frame_params) { uint16_t rb; - uint8_t i,j,aarx; - struct complex16 *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; - const uint8_t nb_rb = SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL; + uint8_t i, j, aarx; + struct complex16 *dl_ch0, *dl_ch0_ext, *rxF, *rxF_ext; + const uint8_t nb_rb = SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL; AssertFatal((symbol == 0 || symbol >= 5), "SIDELINK: PSBCH DMRS not contained in symbol %d \n", symbol); - for (aarx=0; aarxnb_antennas_rx; aarx++) { + for (aarx = 0; aarx < frame_params->nb_antennas_rx; aarx++) { unsigned int rx_offset = frame_params->first_carrier_offset + frame_params->ssb_start_subcarrier; rx_offset = rx_offset % frame_params->ofdm_symbol_size; - rxF = &rxdataF[aarx][symbol*frame_params->ofdm_symbol_size]; - rxF_ext = &rxdataF_ext[aarx][0]; + rxF = &rxdataF[aarx][symbol * frame_params->ofdm_symbol_size]; + rxF_ext = &rxdataF_ext[aarx][0]; - dl_ch0 = &dl_ch_estimates[aarx][symbol*frame_params->ofdm_symbol_size]; + dl_ch0 = &dl_ch_estimates[aarx][symbol * frame_params->ofdm_symbol_size]; dl_ch0_ext = &dl_ch_estimates_ext[aarx][0]; #ifdef DEBUG_PSBCH - LOG_I(PHY, "extract_rbs: rx_offset=%d, symbol %u\n", (rx_offset + (symbol*frame_params->ofdm_symbol_size)),symbol); + LOG_I(PHY, "extract_rbs: rx_offset=%d, symbol %u\n", (rx_offset + (symbol * frame_params->ofdm_symbol_size)), symbol); #endif - for (rb=0; rbofdm_symbol_size); + rx_offset = (rx_offset + 1) % (frame_params->ofdm_symbol_size); } rxF_ext += SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_RB; @@ -86,19 +95,17 @@ static void nr_psbch_extract(uint32_t rxdataF_sz, } #ifdef DEBUG_PSBCH - char filename[40], varname[25]; - sprintf(filename,"psbch_dlch_sym_%d.m", symbol); - sprintf(varname,"psbch_dlch%d.m", symbol); - LOG_M(filename, varname, (void*)dl_ch0, frame_params->ofdm_symbol_size, 1, 1); - sprintf(filename,"psbch_dlchext_sym_%d.m", symbol); - sprintf(varname,"psbch_dlchext%d.m", symbol); - LOG_M(filename, varname, (void*)&dl_ch_estimates_ext[0][0], SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL , 1, 1); + char filename[40], varname[25]; + sprintf(filename, "psbch_dlch_sym_%d.m", symbol); + sprintf(varname, "psbch_dlch%d.m", symbol); + LOG_M(filename, varname, (void *)dl_ch0, frame_params->ofdm_symbol_size, 1, 1); + sprintf(filename, "psbch_dlchext_sym_%d.m", symbol); + sprintf(varname, "psbch_dlchext%d.m", symbol); + LOG_M(filename, varname, (void *)&dl_ch_estimates_ext[0][0], SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL, 1, 1); #endif - } return; - } int nr_rx_psbch(PHY_VARS_NR_UE *ue, @@ -110,29 +117,31 @@ int nr_rx_psbch(PHY_VARS_NR_UE *ue, c16_t rxdataF[][frame_parms->samples_per_slot_wCP], uint16_t slss_id) { - - uint32_t decoderState=0; + uint32_t decoderState = 0; int psbch_e_rx_idx = 0; - //Extra 2 bits needed as polar decoder expects a multiple of 4 as encoder length - //If these 2 bits are not added, runs compiled with --sanitize will fail. - int16_t psbch_e_rx[SL_NR_POLAR_PSBCH_E_NORMAL_CP+2]= {0}; + // Extra 2 bits needed as polar decoder expects a multiple of 4 as encoder length + // If these 2 bits are not added, runs compiled with --sanitize will fail. + int16_t psbch_e_rx[SL_NR_POLAR_PSBCH_E_NORMAL_CP + 2] = {0}; #ifdef DEBUG_PSBCH - write_output("psbch_rxdataF.m","psbchrxF", - &rxdataF[0][0],frame_parms->ofdm_symbol_size*SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP,1,1); + write_output("psbch_rxdataF.m", + "psbchrxF", + &rxdataF[0][0], + frame_parms->ofdm_symbol_size * SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP, + 1, + 1); #endif // symbol refers to symbol within SSB. symbol_offset is the offset of the SSB wrt start of slot double log2_maxh = 0; // 0 for Normal Cyclic Prefix and 1 for EXT CyclicPrefix - const int numsym = (frame_parms->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP - : SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP; + const int numsym = (frame_parms->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP : SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP; - for (int symbol=0; symbolnb_antennas_rx][nb_re+1]; - __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_ext[frame_parms->nb_antennas_rx][nb_re+1]; - //memset(dl_ch_estimates_ext,0, sizeof dl_ch_estimates_ext); + __attribute__((aligned(32))) struct complex16 rxdataF_ext[frame_parms->nb_antennas_rx][nb_re + 1]; + __attribute__((aligned(32))) struct complex16 dl_ch_estimates_ext[frame_parms->nb_antennas_rx][nb_re + 1]; + // memset(dl_ch_estimates_ext,0, sizeof dl_ch_estimates_ext); nr_psbch_extract(frame_parms->samples_per_slot_wCP, rxdataF, estimateSz, @@ -142,23 +151,20 @@ int nr_rx_psbch(PHY_VARS_NR_UE *ue, symbol, frame_parms); #ifdef DEBUG_PSBCH - LOG_I(PHY,"PSBCH RX Symbol %d ofdm size %d\n",symbol, frame_parms->ofdm_symbol_size ); + LOG_I(PHY, "PSBCH RX Symbol %d ofdm size %d\n", symbol, frame_parms->ofdm_symbol_size); #endif - int max_h=0; + int max_h = 0; if (symbol == 0) { - max_h = nr_pbch_channel_level(dl_ch_estimates_ext, - frame_parms, - nb_re); - //log2_maxh = 3+(log2_approx(max_h)/2); - log2_maxh = 5 +(log2_approx(max_h)/2);// LLR32 crc error. LLR 16 CRC works - + max_h = nr_pbch_channel_level(dl_ch_estimates_ext, frame_parms, nb_re); + // log2_maxh = 3+(log2_approx(max_h)/2); + log2_maxh = 5 + (log2_approx(max_h) / 2); // LLR32 crc error. LLR 16 CRC works } #ifdef DEBUG_PSBCH - LOG_I(PHY,"PSBCH RX log2_maxh = %f (%d)\n", log2_maxh, max_h); + LOG_I(PHY, "PSBCH RX log2_maxh = %f (%d)\n", log2_maxh, max_h); #endif - __attribute__ ((aligned(32))) struct complex16 rxdataF_comp[frame_parms->nb_antennas_rx][nb_re+1]; + __attribute__((aligned(32))) struct complex16 rxdataF_comp[frame_parms->nb_antennas_rx][nb_re + 1]; nr_pbch_channel_compensation(rxdataF_ext, dl_ch_estimates_ext, nb_re, @@ -166,70 +172,68 @@ int nr_rx_psbch(PHY_VARS_NR_UE *ue, frame_parms, log2_maxh); // log2_maxh+I0_shift - nr_pbch_quantize(psbch_e_rx + psbch_e_rx_idx, - (short *)rxdataF_comp[0], - SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL); + nr_pbch_quantize(psbch_e_rx + psbch_e_rx_idx, (short *)rxdataF_comp[0], SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL); psbch_e_rx_idx += SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL; - //SKIP 2 SL-PSS AND 2 SL-SSS symbols - //Symbols carrying PSBCH 0, 5-12 + // SKIP 2 SL-PSS AND 2 SL-SSS symbols + // Symbols carrying PSBCH 0, 5-12 symbol = (symbol == 0) ? 5 : symbol + 1; } - - -#if 0 //ENABLE SCOPE LATER +#if 0 // ENABLE SCOPE LATER UEscopeCopy(ue, psbchRxdataF_comp, psbch_unClipped, sizeof(struct complex16), frame_parms->nb_antennas_rx, psbch_e_rx_idx/2); UEscopeCopy(ue, psbchLlr, psbch_e_rx, sizeof(int16_t), frame_parms->nb_antennas_rx, psbch_e_rx_idx); #endif #ifdef DEBUG_PSBCH - write_output("psbch_rxdataFcomp.m","psbch_rxFcomp",psbch_unClipped,SL_NR_NUM_PSBCH_DATA_RE_IN_ALL_SYMBOLS,1,1); + write_output("psbch_rxdataFcomp.m", "psbch_rxFcomp", psbch_unClipped, SL_NR_NUM_PSBCH_DATA_RE_IN_ALL_SYMBOLS, 1, 1); #endif - //un-scrambling + // un-scrambling LOG_D(PHY, "PSBCH RX POLAR DECODING: total PSBCH bits:%d, rx_slss_id:%d\n", psbch_e_rx_idx, slss_id); - nr_pbch_unscrambling(psbch_e_rx, slss_id, 0, 0, psbch_e_rx_idx, - 0, 0, 0, NULL); - //polar decoding de-rate matching - uint64_t tmp=0; - decoderState = polar_decoder_int16(psbch_e_rx,(uint64_t *)&tmp,0, - SL_NR_POLAR_PSBCH_MESSAGE_TYPE, SL_NR_POLAR_PSBCH_PAYLOAD_BITS, SL_NR_POLAR_PSBCH_AGGREGATION_LEVEL); - + nr_pbch_unscrambling(psbch_e_rx, slss_id, 0, 0, psbch_e_rx_idx, 0, 0, 0, NULL); + // polar decoding de-rate matching + uint64_t tmp = 0; + decoderState = polar_decoder_int16(psbch_e_rx, + (uint64_t *)&tmp, + 0, + SL_NR_POLAR_PSBCH_MESSAGE_TYPE, + SL_NR_POLAR_PSBCH_PAYLOAD_BITS, + SL_NR_POLAR_PSBCH_AGGREGATION_LEVEL); uint32_t psbch_payload = tmp; - if(decoderState) { - LOG_D(PHY,"%d:%d PSBCH RX: NOK \n",proc->frame_rx, proc->nr_slot_rx); - return(decoderState); + if (decoderState) { + LOG_D(PHY, "%d:%d PSBCH RX: NOK \n", proc->frame_rx, proc->nr_slot_rx); + return (decoderState); } // Decoder reversal - uint32_t a_reversed=0; + uint32_t a_reversed = 0; - for (int i=0; i>i)&1)<<(31-i); + for (int i = 0; i < SL_NR_POLAR_PSBCH_PAYLOAD_BITS; i++) + a_reversed |= (((uint64_t)psbch_payload >> i) & 1) << (31 - i); psbch_payload = a_reversed; *((uint32_t *)decoded_output) = psbch_payload; #ifdef DEBUG_PSBCH - for (int i=0; i<4; i++) { + for (int i = 0; i < 4; i++) { LOG_I(PHY, "decoded_output[%d]:%x\n", i, decoded_output[i]); } #endif ue->symbol_offset = 0; - //retrieve DFN and slot number from SL-MIB + // retrieve DFN and slot number from SL-MIB uint32_t DFN = 0, slot_offset = 0; DFN = (((psbch_payload & 0x0700) >> 1) | ((psbch_payload & 0xFE0000) >> 17)); - slot_offset = (((psbch_payload & 0x010000) >> 10) | ((psbch_payload & 0xFC000000) >> 26)); + slot_offset = (((psbch_payload & 0x010000) >> 10) | ((psbch_payload & 0xFC000000) >> 26)); - LOG_D(PHY, "PSBCH RX SL-MIB:%x, decoded DFN:slot %d:%d, %x\n",psbch_payload, DFN, slot_offset, *(uint32_t *)decoded_output); + LOG_D(PHY, "PSBCH RX SL-MIB:%x, decoded DFN:slot %d:%d, %x\n", psbch_payload, DFN, slot_offset, *(uint32_t *)decoded_output); return 0; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c b/openair1/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c index 784be79d95..cc8993bc6d 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c @@ -26,17 +26,17 @@ #include "PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h" #include "PHY/MODULATION/nr_modulation.h" -//#define SL_DEBUG +// #define SL_DEBUG /** -*This function performs PSBCH SCrambling as described in 38.211. -*Input parameter "output" is scrambled and the scrambled output is stored in this parameter. -*id - SLSS ID used for C_INIT -*length is the length of the buffer. -*/ + *This function performs PSBCH SCrambling as described in 38.211. + *Input parameter "output" is scrambled and the scrambled output is stored in this parameter. + *id - SLSS ID used for C_INIT + *length is the length of the buffer. + */ void sl_psbch_scrambling(uint32_t *output, uint32_t id, uint16_t length) { - uint32_t x1, x2, s=0; + uint32_t x1, x2, s = 0; // x1 is set in lte_gold_generic x2 = id; // C_INIT @@ -46,8 +46,8 @@ void sl_psbch_scrambling(uint32_t *output, uint32_t id, uint16_t length) #endif #ifdef SL_DEBUG - for (int i=0; i<56;i++) { - printf("\nBEFORE SCRAMBLING output[%d]:0x%x\n",i,output[i]); + for (int i = 0; i < 56; i++) { + printf("\nBEFORE SCRAMBLING output[%d]:0x%x\n", i, output[i]); } #endif @@ -59,9 +59,8 @@ void sl_psbch_scrambling(uint32_t *output, uint32_t id, uint16_t length) // scramble in 32bit chunks int i = 0; - while(i+32 <= length) { - - output[i>>5] ^= s; + while (i + 32 <= length) { + output[i >> 5] ^= s; i += 32; s = lte_gold_generic(&x1, &x2, 0); @@ -72,59 +71,68 @@ void sl_psbch_scrambling(uint32_t *output, uint32_t id, uint16_t length) // scramble remaining bits for (; i < length; ++i) { - output[i>>5] ^= ((s>>(i&0x1f)&1)<<(i&0x1f)); + output[i >> 5] ^= ((s >> (i & 0x1f) & 1) << (i & 0x1f)); } #ifdef SL_DEBUG - for (int i=0; i<56;i++) { - printf("\nAFTER SCRAMBLING output[%d]:0x%x\n",i,output[i]); + for (int i = 0; i < 56; i++) { + printf("\nAFTER SCRAMBLING output[%d]:0x%x\n", i, output[i]); } #endif - } - /** -*This function RE MAPS PSS, SSS sequences as described in 38.211. -*txF is the data in frequency domain, sync_seq = PSS or SSS seq -*startsym = 1 for PSS, 3 for SSS -*re_offset = sample which points to first RE + SSB start RE -*scaling factor = scaling factor used for PSS, SSS (determined according to PSBCH pwr) -*symbol size = OFDM symbol size used for RE Mapping -*/ -void sl_map_pss_or_sss(c16_t *txF, int16_t *sync_seq, uint16_t startsym, - uint16_t re_offset, uint16_t scaling_factor, + *This function RE MAPS PSS, SSS sequences as described in 38.211. + *txF is the data in frequency domain, sync_seq = PSS or SSS seq + *startsym = 1 for PSS, 3 for SSS + *re_offset = sample which points to first RE + SSB start RE + *scaling factor = scaling factor used for PSS, SSS (determined according to PSBCH pwr) + *symbol size = OFDM symbol size used for RE Mapping + */ +void sl_map_pss_or_sss(c16_t *txF, + int16_t *sync_seq, + uint16_t startsym, + uint16_t re_offset, + uint16_t scaling_factor, uint16_t symbol_size) { - - #ifdef SL_DEBUG - printf("%s. DEBUG PSBCH TX: RE MAPPING of PSS/SSS \n", __func__); - printf("Input Params - StartSYM:%d, NUMSYM:%d, RE_OFFSET:%d, num_REs:%d, scaling_factor:%d, symbol_size:%d\n", - startsym, SL_NR_NUM_PSS_OR_SSS_SYMBOLS,re_offset, SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL, scaling_factor, symbol_size); + printf("%s. DEBUG PSBCH TX: RE MAPPING of PSS/SSS \n", __func__); + printf("Input Params - StartSYM:%d, NUMSYM:%d, RE_OFFSET:%d, num_REs:%d, scaling_factor:%d, symbol_size:%d\n", + startsym, + SL_NR_NUM_PSS_OR_SSS_SYMBOLS, + re_offset, + SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL, + scaling_factor, + symbol_size); #endif // RE Mapping of SL-PSS, SL-SSS - for (int l = startsym;l < (startsym + SL_NR_NUM_PSS_OR_SSS_SYMBOLS);l++) { - + for (int l = startsym; l < (startsym + SL_NR_NUM_PSS_OR_SSS_SYMBOLS); l++) { int k = re_offset % symbol_size; int index = 0, offset = 0; - for (int m = 0;m < SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL;m++) { - - offset = l*symbol_size + k; + for (int m = 0; m < SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL; m++) { + offset = l * symbol_size + k; if ((m < 2) || (m >= (SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL - 3))) { - txF[offset].r = 0; //Set REs 0,1,129,130,131 = 0 + txF[offset].r = 0; // Set REs 0,1,129,130,131 = 0 #ifdef SL_DEBUG - printf("sym:%d, RE:%d, txF[%d]:%d.%d \n", l, m, offset, txF[offset].r,txF[offset].i); + printf("sym:%d, RE:%d, txF[%d]:%d.%d \n", l, m, offset, txF[offset].r, txF[offset].i); #endif } else { txF[offset].r = (sync_seq[index] * scaling_factor) >> 15; #ifdef SL_DEBUG - printf("sym:%d, RE:%d, txF[%d]:%d.%d, syncseq[%d]:%d \n", l, m, offset, txF[offset].r,txF[offset].i, index, sync_seq[index]); + printf("sym:%d, RE:%d, txF[%d]:%d.%d, syncseq[%d]:%d \n", + l, + m, + offset, + txF[offset].r, + txF[offset].i, + index, + sync_seq[index]); #endif index++; @@ -133,95 +141,97 @@ void sl_map_pss_or_sss(c16_t *txF, int16_t *sync_seq, uint16_t startsym, k = (k + 1) % symbol_size; } } - } - /** -* This function Generates the PSBCH DATA Modulation symbols and RE MAPS PSBCH Modulated symbols -* and PSBCH DMRS sequences as described in 38.211. -* txF is the data in frequency domain -* payload is the PSBCH payload (SL-MIB given by higher layers) -* id - SLSS ID used for knowing which DMRS sequence to be used. -* Cp - NORMAL of extended Cyclic prefix -* startsym = 0 and then PSBCH is mapped from symbols 5-13 if normal , 5-11 if extended -* re_offset = sample which points to first RE + SSB start RE -* scaling factor = scaling factor used for PSS, SSS (determined according to PSBCH pwr) -* symbol size = OFDM symbol size used for RE Mapping -*/ + * This function Generates the PSBCH DATA Modulation symbols and RE MAPS PSBCH Modulated symbols + * and PSBCH DMRS sequences as described in 38.211. + * txF is the data in frequency domain + * payload is the PSBCH payload (SL-MIB given by higher layers) + * id - SLSS ID used for knowing which DMRS sequence to be used. + * Cp - NORMAL of extended Cyclic prefix + * startsym = 0 and then PSBCH is mapped from symbols 5-13 if normal , 5-11 if extended + * re_offset = sample which points to first RE + SSB start RE + * scaling factor = scaling factor used for PSS, SSS (determined according to PSBCH pwr) + * symbol size = OFDM symbol size used for RE Mapping + */ -void sl_generate_and_map_psbch(c16_t *txF, uint32_t *payload, uint16_t id, - uint16_t cp, uint16_t re_offset, - uint16_t scaling_factor, uint16_t symbol_size, +void sl_generate_and_map_psbch(c16_t *txF, + uint32_t *payload, + uint16_t id, + uint16_t cp, + uint16_t re_offset, + uint16_t scaling_factor, + uint16_t symbol_size, c16_t *psbch_dmrs) { - uint64_t psbch_a_reversed = 0; uint16_t num_psbch_modsym = 0, numsym = 0; - const int mod_order = 2;//QPSK + const int mod_order = 2; // QPSK uint32_t encoder_output[SL_NR_POLAR_PSBCH_E_DWORD]; struct complex16 psbch_modsym[SL_NR_NUM_PSBCH_MODULATED_SYMBOLS]; LOG_D(PHY, "PSBCH TX: Generation accg to 38.212, 38.211. SLSS id:%d\n", id); // Encoder reversal - for (int i=0; i>i)&1)<<(31-i); + for (int i = 0; i < SL_NR_POLAR_PSBCH_PAYLOAD_BITS; i++) + psbch_a_reversed |= (((uint64_t)*payload >> i) & 1) << (31 - i); #ifdef SL_DEBUG printf("DEBUG PSBCH TX: 38.212 PSBCH CRC + Channel coding (POLAR) + Rate Matching:\n"); - printf("PSBCH payload:%x, Reversed Payload:%016lx\n",*payload, psbch_a_reversed); + printf("PSBCH payload:%x, Reversed Payload:%016lx\n", *payload, psbch_a_reversed); #endif /// CRC, coding and rate matching - polar_encoder_fast(&psbch_a_reversed, (void*)encoder_output, 0, 0, + polar_encoder_fast(&psbch_a_reversed, + (void *)encoder_output, + 0, + 0, SL_NR_POLAR_PSBCH_MESSAGE_TYPE, SL_NR_POLAR_PSBCH_PAYLOAD_BITS, SL_NR_POLAR_PSBCH_AGGREGATION_LEVEL); #ifdef SL_DEBUG - for (int i=0; iSL_UE_PHY_PARAMS; uint16_t slss_id = psbch_vars->tx_slss_id; NR_DL_FRAME_PARMS *sl_fp = &sl_ue_phy_params->sl_frame_params; uint32_t psbch_payload = *((uint32_t *)psbch_vars->psbch_payload); - LOG_D(PHY,"PSBCH TX: slss-id %d, psbch payload %x \n", slss_id, psbch_payload); + LOG_D(PHY, "PSBCH TX: slss-id %d, psbch payload %x \n", slss_id, psbch_payload); // Insert FN and Slot number into SL-MIB uint32_t mask = ~(0x700 | 0xFE0000 | 0x10000 | 0xFC000000); psbch_payload &= mask; - psbch_payload |= ((frame_tx%1024)<<1) & 0x700; - psbch_payload |= ((frame_tx%1024)<<17) & 0xFE0000; - psbch_payload |= (slot_tx<<10) & 0x10000; - psbch_payload |= (slot_tx<<26) & 0xFC000000; + psbch_payload |= ((frame_tx % 1024) << 1) & 0x700; + psbch_payload |= ((frame_tx % 1024) << 17) & 0xFE0000; + psbch_payload |= (slot_tx << 10) & 0x10000; + psbch_payload |= (slot_tx << 26) & 0xFC000000; #ifdef SL_DEBUG - printf("DEBUG PSBCH TX: DFN, SLOT included. psbch_a :0x%08x, frame:%d, slot:%d\n", - psbch_payload, frame_tx, slot_tx); + printf("DEBUG PSBCH TX: DFN, SLOT included. psbch_a :0x%08x, frame:%d, slot:%d\n", psbch_payload, frame_tx, slot_tx); #endif - LOG_D(PHY,"PSBCH TX: Frame.Slot %d.%d. Payload::0x%08x, slssid:%d\n", - frame_tx, slot_tx, psbch_payload, slss_id); + LOG_D(PHY, "PSBCH TX: Frame.Slot %d.%d. Payload::0x%08x, slssid:%d\n", frame_tx, slot_tx, psbch_payload, slss_id); // GENERATE Sidelink PSS,SSS Sequences, PSBCH DMRS Symbols, PSBCH Symbols - int16_t *sl_pss = &sl_ue_phy_params->init_params.sl_pss[slss_id/336][0]; + int16_t *sl_pss = &sl_ue_phy_params->init_params.sl_pss[slss_id / 336][0]; int16_t *sl_sss = &sl_ue_phy_params->init_params.sl_sss[slss_id][0]; uint16_t re_offset = sl_fp->first_carrier_offset + sl_fp->ssb_start_subcarrier; @@ -333,42 +352,33 @@ void nr_tx_psbch(PHY_VARS_NR_UE *UE, uint32_t frame_tx, struct complex16 *txF = &txdataF[0][0]; uint16_t startsym = SL_NR_PSS_START_SYMBOL; - #ifdef SL_DEBUG - printf("DEBUG PSBCH TX: MAP PSS. startsym:%d, PSS RE START:%d, scaling factor:%d\n", - startsym, re_offset, scaling_factor); + printf("DEBUG PSBCH TX: MAP PSS. startsym:%d, PSS RE START:%d, scaling factor:%d\n", startsym, re_offset, scaling_factor); #endif sl_map_pss_or_sss(txF, sl_pss, startsym, re_offset, scaling_factor, symbol_size); // PSS - startsym += SL_NR_NUM_PSS_SYMBOLS; #ifdef SL_DEBUG - printf("DEBUG PSBCH TX: MAP SSS. startsym:%d, SSS RE START:%d, scaling factor:%d\n", - startsym, re_offset, scaling_factor); + printf("DEBUG PSBCH TX: MAP SSS. startsym:%d, SSS RE START:%d, scaling factor:%d\n", startsym, re_offset, scaling_factor); #endif sl_map_pss_or_sss(txF, sl_sss, startsym, re_offset, scaling_factor, symbol_size); // SSS #ifdef SL_DEBUG printf("DEBUG PSBCH TX: MAP PSBCH DATA AND DMRS. cyclicPrefix:%d, PSS RE START:%d, scaling factor:%d\n", - sl_fp->Ncp, re_offset, scaling_factor); + sl_fp->Ncp, + re_offset, + scaling_factor); #endif struct complex16 *psbch_dmrs = &sl_ue_phy_params->init_params.psbch_dmrs_modsym[slss_id][0]; - sl_generate_and_map_psbch(txF, &psbch_payload, slss_id, - sl_fp->Ncp, re_offset, scaling_factor, symbol_size, - psbch_dmrs); - + sl_generate_and_map_psbch(txF, &psbch_payload, slss_id, sl_fp->Ncp, re_offset, scaling_factor, symbol_size, psbch_dmrs); #ifdef SL_DEBUG printf("DEBUG PSBCH TX: txdataF Prepared\n"); #endif #ifdef SL_DEBUG - LOG_M("sl_psbch_block.m", "sl_txF", (void*)txdataF[0], symbol_size*14, 1, 1); + LOG_M("sl_psbch_block.m", "sl_txF", (void *)txdataF[0], symbol_size * 14, 1, 1); #endif - } - - - diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 8a61895c29..deafd7a9ee 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -428,22 +428,20 @@ int nr_rx_psbch(PHY_VARS_NR_UE *ue, c16_t rxdataF[][frame_parms->samples_per_slot_wCP], uint16_t slss_id); -void nr_tx_psbch(PHY_VARS_NR_UE *UE, uint32_t frame_tx, uint32_t slot_tx, - sl_nr_tx_config_psbch_pdu_t *psbch_vars, - c16_t **txdataF); +void nr_tx_psbch(PHY_VARS_NR_UE *UE, uint32_t frame_tx, uint32_t slot_tx, sl_nr_tx_config_psbch_pdu_t *psbch_vars, c16_t **txdataF); nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, int num_frames); -//Reuse already existing PBCH functions +// Reuse already existing PBCH functions int nr_pbch_channel_level(struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL], NR_DL_FRAME_PARMS *frame_parms, - int nb_re); + int nb_re); void nr_pbch_channel_compensation(struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER_SYMBOL], - struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL], - int nb_re, - struct complex16 rxdataF_comp[][PBCH_MAX_RE_PER_SYMBOL], - NR_DL_FRAME_PARMS *frame_parms, - uint8_t output_shift); + struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL], + int nb_re, + struct complex16 rxdataF_comp[][PBCH_MAX_RE_PER_SYMBOL], + NR_DL_FRAME_PARMS *frame_parms, + uint8_t output_shift); void nr_pbch_unscrambling(int16_t *demod_pbch_e, uint16_t Nid, uint8_t nushift, diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index 0881d76c2e..721697e248 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -706,10 +706,9 @@ static int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, i void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, uint16_t scaling) { - int i = 0, m = 0; int16_t x[SL_NR_PSS_SEQUENCE_LENGTH]; - const int x_initial[7] = {0, 1, 1 , 0, 1, 1, 1}; + const int x_initial[7] = {0, 1, 1, 0, 1, 1, 1}; int16_t *sl_pss = sl_init_params->sl_pss[n_sl_id2]; int16_t *sl_pss_for_sync = sl_init_params->sl_pss_for_sync[n_sl_id2]; @@ -720,37 +719,32 @@ void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, u #endif /// Sequence generation - for (i=0; i < 7; i++) + for (i = 0; i < 7; i++) x[i] = x_initial[i]; - for (i=0; i < (SL_NR_PSS_SEQUENCE_LENGTH - 7); i++) { - x[i+7] = (x[i + 4] + x[i]) %2; + for (i = 0; i < (SL_NR_PSS_SEQUENCE_LENGTH - 7); i++) { + x[i + 7] = (x[i + 4] + x[i]) % 2; } - for (i=0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) { - m = (i + 22 + 43*n_sl_id2) % SL_NR_PSS_SEQUENCE_LENGTH; - sl_pss_for_sync[i] = (1 - 2*x[m]); + for (i = 0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) { + m = (i + 22 + 43 * n_sl_id2) % SL_NR_PSS_SEQUENCE_LENGTH; + sl_pss_for_sync[i] = (1 - 2 * x[m]); sl_pss[i] = sl_pss_for_sync[i] * scaling; #ifdef SL_DEBUG_INIT_DATA - printf("m:%d, sl_pss[%d]:%d\n", m, i, sl_pss[i]); + printf("m:%d, sl_pss[%d]:%d\n", m, i, sl_pss[i]); #endif - } #ifdef SL_DUMP_INIT_SAMPLES - LOG_M("sl_pss_seq.m", "sl_pss", (void*)sl_pss, SL_NR_PSS_SEQUENCE_LENGTH, 1, 0); + LOG_M("sl_pss_seq.m", "sl_pss", (void *)sl_pss, SL_NR_PSS_SEQUENCE_LENGTH, 1, 0); #endif - - - } // This cannot be done at init time as ofdm symbol size, ssb start subcarrier depends on configuration // done at SLSS read time. void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params) { - uint8_t id2 = 0; int16_t *sl_pss = NULL; NR_DL_FRAME_PARMS *sl_fp = &sl_ue_params->sl_frame_params; @@ -765,9 +759,9 @@ void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_ LOG_I(PHY, "SIDELINK INIT: Generation of PSS time domain samples. scaling_factor:%d\n", scaling_factor); for (id2 = 0; id2 < SL_NR_NUM_IDs_IN_PSS; id2++) { - k = sl_fp->first_carrier_offset + sl_fp->ssb_start_subcarrier + 2; // PSS in from REs 2-129 - if (k >= sl_fp->ofdm_symbol_size) k -= sl_fp->ofdm_symbol_size; + if (k >= sl_fp->ofdm_symbol_size) + k -= sl_fp->ofdm_symbol_size; pss_T = &sl_init_params->sl_pss_for_correlation[id2][0]; sl_pss = sl_init_params->sl_pss[id2]; @@ -775,32 +769,28 @@ void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_ memset(pss_T, 0, sl_fp->ofdm_symbol_size * sizeof(pss_T[0])); memset(pss_F, 0, sl_fp->ofdm_symbol_size * sizeof(c16_t)); - for (int i=0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) { - + for (int i = 0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) { pss_F[k].r = (sl_pss[i] * scaling_factor) >> 15; - //pss_F[2*k] = (sl_pss[i]/23170) * 4192; - //pss_F[2*k+1] = 0; + // pss_F[2*k] = (sl_pss[i]/23170) * 4192; + // pss_F[2*k+1] = 0; #ifdef SL_DEBUG_INIT_DATA - printf("id:%d, k:%d, pss_F[%d]:%d, sl_pss[%d]:%d\n", id2, k, 2*k, pss_F[2*k], i, sl_pss[i]); + printf("id:%d, k:%d, pss_F[%d]:%d, sl_pss[%d]:%d\n", id2, k, 2 * k, pss_F[2 * k], i, sl_pss[i]); #endif k++; - if (k == sl_fp->ofdm_symbol_size) k=0; - + if (k == sl_fp->ofdm_symbol_size) + k = 0; } - idft((int16_t)get_idft(sl_fp->ofdm_symbol_size), - (int16_t *)&pss_F[0], /* complex input */ - (int16_t *)&pss_T[0], /* complex output */ - 1); /* scaling factor */ - + idft((int16_t)get_idft(sl_fp->ofdm_symbol_size), + (int16_t *)&pss_F[0], /* complex input */ + (int16_t *)&pss_T[0], /* complex output */ + 1); /* scaling factor */ } #ifdef SL_DUMP_PSBCH_TX_SAMPLES - LOG_M("sl_pss_TD_id0.m", "pss_TD_0", (void*)sl_init_params->sl_pss_for_correlation[0], sl_fp->ofdm_symbol_size, 1, 1); - LOG_M("sl_pss_TD_id1.m", "pss_TD_1", (void*)sl_init_params->sl_pss_for_correlation[1], sl_fp->ofdm_symbol_size, 1, 1); + LOG_M("sl_pss_TD_id0.m", "pss_TD_0", (void *)sl_init_params->sl_pss_for_correlation[0], sl_fp->ofdm_symbol_size, 1, 1); + LOG_M("sl_pss_TD_id1.m", "pss_TD_1", (void *)sl_init_params->sl_pss_for_correlation[1], sl_fp->ofdm_symbol_size, 1, 1); #endif - } - diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c index 9ab3b33e4f..0fe7608271 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c @@ -533,7 +533,6 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue, void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, uint16_t scaling) { - int i = 0; int m0, m1; int n_sl_id1, n_sl_id2; @@ -541,7 +540,7 @@ void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, u int16_t *sl_sss_for_sync = sl_init_params->sl_sss_for_sync[slss_id]; int16_t x0[SL_NR_SSS_SEQUENCE_LENGTH], x1[SL_NR_SSS_SEQUENCE_LENGTH]; - const int x_initial[7] = { 1, 0, 0, 0, 0, 0, 0 }; + const int x_initial[7] = {1, 0, 0, 0, 0, 0, 0}; n_sl_id1 = slss_id % 336; n_sl_id2 = slss_id / 336; @@ -552,32 +551,30 @@ void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, u printf("SIDELINK: SSS Generation with slss_id:%d, N_SL_id1:%d, N_SL_id2:%d\n", slss_id, n_sl_id1, n_sl_id2); #endif - for ( i=0 ; i < 7 ; i++) { + for (i = 0; i < 7; i++) { x0[i] = x_initial[i]; x1[i] = x_initial[i]; } - for ( i=0 ; i < SL_NR_SSS_SEQUENCE_LENGTH - 7 ; i++) { - x0[i+7] = (x0[i + 4] + x0[i]) % 2; - x1[i+7] = (x1[i + 1] + x1[i]) % 2; + for (i = 0; i < SL_NR_SSS_SEQUENCE_LENGTH - 7; i++) { + x0[i + 7] = (x0[i + 4] + x0[i]) % 2; + x1[i + 7] = (x1[i + 1] + x1[i]) % 2; } - m0 = 15*(n_sl_id1/112) + (5*n_sl_id2); + m0 = 15 * (n_sl_id1 / 112) + (5 * n_sl_id2); m1 = n_sl_id1 % 112; - for (i = 0; i < SL_NR_SSS_SEQUENCE_LENGTH ; i++) { - sl_sss_for_sync[i] = (1 - 2*x0[(i + m0) % SL_NR_SSS_SEQUENCE_LENGTH] ) * (1 - 2*x1[(i + m1) % SL_NR_SSS_SEQUENCE_LENGTH] ); + for (i = 0; i < SL_NR_SSS_SEQUENCE_LENGTH; i++) { + sl_sss_for_sync[i] = (1 - 2 * x0[(i + m0) % SL_NR_SSS_SEQUENCE_LENGTH]) * (1 - 2 * x1[(i + m1) % SL_NR_SSS_SEQUENCE_LENGTH]); sl_sss[i] = sl_sss_for_sync[i] * scaling; #ifdef SL_DEBUG_INIT_DATA - printf("m0:%d, m1:%d, sl_sss_for_sync[%d]:%d, sl_sss[%d]:%d\n", m0, m1, i, sl_sss_for_sync[i], i, sl_sss[i]); + printf("m0:%d, m1:%d, sl_sss_for_sync[%d]:%d, sl_sss[%d]:%d\n", m0, m1, i, sl_sss_for_sync[i], i, sl_sss[i]); #endif - } #ifdef SL_DUMP_PSBCH_TX_SAMPLES - LOG_M("sl_sss_seq.m", "sl_sss", (void*)sl_sss, SL_NR_SSS_SEQUENCE_LENGTH, 1, 0); - LOG_M("sl_sss_forsync_seq.m", "sl_sss_for_sync", (void*)sl_sss_for_sync, SL_NR_SSS_SEQUENCE_LENGTH, 1, 0); + LOG_M("sl_sss_seq.m", "sl_sss", (void *)sl_sss, SL_NR_SSS_SEQUENCE_LENGTH, 1, 0); + LOG_M("sl_sss_forsync_seq.m", "sl_sss_for_sync", (void *)sl_sss_for_sync, SL_NR_SSS_SEQUENCE_LENGTH, 1, 0); #endif - } diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index a2ffb834d5..a268c01d00 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -242,11 +242,9 @@ extern "C" { }; } - __attribute__((always_inline)) inline c16_t c16xmulConstShift(const c16_t a, const int b, const int Shift) { - return (c16_t) { - .r = (int16_t)((a.r * b) >> Shift), - .i = (int16_t)((a.i * b) >> Shift) - }; + __attribute__((always_inline)) inline c16_t c16xmulConstShift(const c16_t a, const int b, const int Shift) + { + return (c16_t){.r = (int16_t)((a.r * b) >> Shift), .i = (int16_t)((a.i * b) >> Shift)}; } __attribute__((always_inline)) inline c32_t c32x16maddShift(const c16_t a, const c16_t b, const c32_t c, const int Shift) { diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index e50e890d29..c746bd69b8 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -593,7 +593,7 @@ typedef struct PHY_VARS_NR_UE_s { notifiedFIFO_t tx_resume_ind_fifo[NR_MAX_SLOTS_PER_FRAME]; - //Sidelink parameters + // Sidelink parameters sl_nr_sidelink_mode_t sl_mode; sl_nr_ue_phy_params_t SL_UE_PHY_PARAMS; } PHY_VARS_NR_UE; @@ -618,7 +618,7 @@ typedef struct nr_phy_data_tx_s { NR_UE_ULSCH_t ulsch; NR_UE_PUCCH pucch_vars; - //Sidelink Rx action decided by MAC + // Sidelink Rx action decided by MAC sl_nr_tx_config_type_enum_t sl_tx_action; sl_nr_tx_config_psbch_pdu_t psbch_vars; @@ -628,7 +628,7 @@ typedef struct nr_phy_data_s { NR_UE_PDCCH_CONFIG phy_pdcch_config; NR_UE_DLSCH_t dlsch[2]; - //Sidelink Rx action decided by MAC + // Sidelink Rx action decided by MAC sl_nr_rx_config_type_enum_t sl_rx_action; } nr_phy_data_t; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index f97a4c7eb0..121ef0d3c1 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -96,7 +96,7 @@ #define MAX_DELAY_COMP 20 -#define PBCH_MAX_RE_PER_SYMBOL (20*12) +#define PBCH_MAX_RE_PER_SYMBOL (20 * 12) typedef enum { NR_MU_0=0, diff --git a/openair1/PHY/defs_nr_sl_UE.h b/openair1/PHY/defs_nr_sl_UE.h index 6a703aee13..29958ac75a 100644 --- a/openair1/PHY/defs_nr_sl_UE.h +++ b/openair1/PHY/defs_nr_sl_UE.h @@ -30,27 +30,24 @@ \warning */ -#ifndef _DEFS_NR_SL_UE_H_ -#define _DEFS_NR_SL_UE_H_ - - +#ifndef _DEFS_NR_SL_UE_H_ +#define _DEFS_NR_SL_UE_H_ #include "PHY/types.h" #include "PHY/defs_nr_common.h" #include "nfapi/open-nFAPI/nfapi/public_inc/sidelink_nr_ue_interface.h" #include "common/utils/time_meas.h" - // (33*(13-4)) // Normal CP - NUM_SSB_Symbols = 13. 4 symbols for PSS, SSS -#define SL_NR_NUM_PSBCH_DMRS_RE 297 -//ceil(2(QPSK)*SL_NR_NUM_PSBCH_DMRS_RE/32) +#define SL_NR_NUM_PSBCH_DMRS_RE 297 +// ceil(2(QPSK)*SL_NR_NUM_PSBCH_DMRS_RE/32) #define SL_NR_NUM_PSBCH_DMRS_RE_DWORD 20 -//11 RBs for PSBCH in one symbol * 12 REs +// 11 RBs for PSBCH in one symbol * 12 REs #define SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL 132 -//3 DMRS REs per RB * 11 RBS in one symbol +// 3 DMRS REs per RB * 11 RBS in one symbol #define SL_NR_NUM_PSBCH_DMRS_RE_IN_ONE_SYMBOL 33 -//9 PSBCH DATA REs * 11 RBS in one symbol +// 9 PSBCH DATA REs * 11 RBS in one symbol #define SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL 99 #define SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL 11 // SL_NR_POLAR_PSBCH_E_NORMAL_CP/2 bits because QPSK used for PSBCH. @@ -61,8 +58,6 @@ // 11 * (12-3 DMRS REs) * 9 symbols for PSBCH #define SL_NR_NUM_PSBCH_DATA_RE_IN_ALL_SYMBOLS 891 - - #define SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP 13 #define SL_NR_NUM_SYMBOLS_SSB_EXT_CP 11 #define SL_NR_NUM_PSS_SYMBOLS 2 @@ -76,21 +71,16 @@ #define SL_NR_NUM_IDs_IN_SSS 336 #define SL_NR_NUM_SLSS_IDs 672 -typedef enum sl_nr_sidelink_mode { - SL_NOT_SUPPORTED = 0, - SL_MODE1_SUPPORTED, - SL_MODE2_SUPPORTED -} sl_nr_sidelink_mode_t; +typedef enum sl_nr_sidelink_mode { SL_NOT_SUPPORTED = 0, SL_MODE1_SUPPORTED, SL_MODE2_SUPPORTED } sl_nr_sidelink_mode_t; //(11*(12-3 DMRS REs) * 2 (QPSK used) #define SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL 198 typedef struct SL_NR_UE_INIT_PARAMS { - - //gold sequences for PSBCH DMRS + // gold sequences for PSBCH DMRS uint32_t psbch_dmrs_gold_sequences[SL_NR_NUM_SLSS_IDs][SL_NR_NUM_PSBCH_DMRS_RE_DWORD]; // Gold sequences for PSBCH DMRS - //PSBCH DMRS QPSK modulated symbols for all possible SLSS Ids + // PSBCH DMRS QPSK modulated symbols for all possible SLSS Ids struct complex16 psbch_dmrs_modsym[SL_NR_NUM_SLSS_IDs][SL_NR_NUM_PSBCH_DMRS_RE]; // Scaled values @@ -106,7 +96,6 @@ typedef struct SL_NR_UE_INIT_PARAMS { } SL_NR_UE_INIT_PARAMS_t; typedef struct SL_NR_SYNC_PARAMS { - // Indicating start of SSB block in the initial set of samples uint32_t ssb_offset; // Freq Offset calculated @@ -115,16 +104,15 @@ typedef struct SL_NR_SYNC_PARAMS { uint32_t remaining_frames; uint32_t rx_offset; uint32_t slot_offset; - uint16_t N_sl_id2; //id2 determined from PSS during sync ref UE selection - uint16_t N_sl_id1; //id2 determined from SSS during sync ref UE selection - uint16_t N_sl_id; //ID calculated from ID1 and ID2 - int32_t psbch_rsrp; //rsrp of the decoded psbch during sync ref ue selection + uint16_t N_sl_id2; // id2 determined from PSS during sync ref UE selection + uint16_t N_sl_id1; // id2 determined from SSS during sync ref UE selection + uint16_t N_sl_id; // ID calculated from ID1 and ID2 + int32_t psbch_rsrp; // rsrp of the decoded psbch during sync ref ue selection uint32_t DFN; // DFN calculated after sync ref UE search } SL_NR_SYNC_PARAMS_t; typedef struct SL_NR_UE_PSBCH { - // AVG POWER OF PSBCH DMRS in dB/RE int16_t rsrp_dB_per_RE; // AVG POWER OF PSBCH DMRS in dBm/RE @@ -142,7 +130,6 @@ typedef struct SL_NR_UE_PSBCH { } SL_NR_UE_PSBCH_t; typedef struct sl_nr_ue_phy_params { - SL_NR_UE_INIT_PARAMS_t init_params; SL_NR_SYNC_PARAMS_t sync_params; @@ -150,7 +137,7 @@ typedef struct sl_nr_ue_phy_params { // Sidelink PHY PARAMETERS USED FOR PSBCH reception/Txn SL_NR_UE_PSBCH_t psbch; - //Configuration parameters from MAC + // Configuration parameters from MAC sl_nr_phy_config_request_t sl_config; NR_DL_FRAME_PARMS sl_frame_params; @@ -162,5 +149,4 @@ typedef struct sl_nr_ue_phy_params { } sl_nr_ue_phy_params_t; - #endif \ No newline at end of file diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 2d434e0f83..b34d021390 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -165,13 +165,8 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); - -int psbch_pscch_processing(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - nr_phy_data_t *phy_data); -int phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - nr_phy_data_tx_t *phy_data); +int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data); +int phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data); /*! \brief This function prepares the sl indication to pass to the MAC */ void nr_fill_sl_indication(nr_sidelink_indication_t *sl_ind, diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index c5afd8be46..da734cc84d 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -865,12 +865,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[fp->nb_antennas_rx][fp->ofdm_symbol_size]; for (int i=1; i<4; i++) { - nr_slot_fep(ue, - fp, - proc, - (ssb_start_symbol+i)%(fp->symbols_per_slot), - rxdataF, - link_type_dl); + nr_slot_fep(ue, fp, proc, (ssb_start_symbol + i) % (fp->symbols_per_slot), rxdataF, link_type_dl); start_meas(&ue->dlsch_channel_estimation_stats); nr_pbch_channel_estimation(ue, @@ -879,9 +874,9 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ dl_ch_estimates, dl_ch_estimates_time, proc, - (ssb_start_symbol+i)%(fp->symbols_per_slot), - i-1, - ssb_index&7, + (ssb_start_symbol + i) % (fp->symbols_per_slot), + i - 1, + ssb_index & 7, ssb_slot_2 == nr_slot_rx, rxdataF, false, @@ -926,12 +921,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ { for(int j = prs_config->SymbolStart; j < (prs_config->SymbolStart+prs_config->NumPRSSymbols); j++) { - nr_slot_fep(ue, - fp, - proc, - (j%fp->symbols_per_slot), - rxdataF, - link_type_dl); + nr_slot_fep(ue, fp, proc, (j % fp->symbols_per_slot), rxdataF, link_type_dl); } nr_prs_channel_estimation(gNB_id, rsc_id, i, ue, proc, fp, rxdataF); } @@ -962,12 +952,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ for (uint16_t l=0; lofdm_demod_stats); - nr_slot_fep(ue, - fp, - proc, - l, - rxdataF, - link_type_dl); + nr_slot_fep(ue, fp, proc, l, rxdataF, link_type_dl); } // Hold the channel estimates in frequency domain. @@ -1027,7 +1012,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_ nr_slot_fep(ue, &ue->frame_parms, proc, - m, //to be updated from higher layer + m, // to be updated from higher layer rxdataF, link_type_dl); } diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c index c8de521d67..2bf8ee6cb9 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c @@ -39,21 +39,21 @@ void nr_fill_sl_indication(nr_sidelink_indication_t *sl_ind, PHY_VARS_NR_UE *ue, void *phy_data) { - memset((void*)sl_ind, 0, sizeof(nr_sidelink_indication_t)); + memset((void *)sl_ind, 0, sizeof(nr_sidelink_indication_t)); sl_ind->gNB_index = proc->gNB_id; sl_ind->module_id = ue->Mod_id; - sl_ind->cc_id = ue->CC_id; - sl_ind->frame_rx = proc->frame_rx; - sl_ind->slot_rx = proc->nr_slot_rx; - sl_ind->frame_tx = proc->frame_tx; - sl_ind->slot_tx = proc->nr_slot_tx; - sl_ind->phy_data = phy_data; + sl_ind->cc_id = ue->CC_id; + sl_ind->frame_rx = proc->frame_rx; + sl_ind->slot_rx = proc->nr_slot_rx; + sl_ind->frame_tx = proc->frame_tx; + sl_ind->slot_tx = proc->nr_slot_tx; + sl_ind->phy_data = phy_data; if (rx_ind) { sl_ind->rx_ind = rx_ind; // hang on rx_ind instance sl_ind->sci_ind = NULL; - } + } if (sci_ind) { sl_ind->rx_ind = NULL; sl_ind->sci_ind = sci_ind; @@ -68,39 +68,37 @@ void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind, void *typeSpecific, uint16_t rx_slss_id) { - - if (n_pdus > 1){ + if (n_pdus > 1) { LOG_E(PHY, "In %s: multiple number of SL PDUs not supported yet...\n", __FUNCTION__); } sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS; - switch (pdu_type){ + switch (pdu_type) { case SL_NR_RX_PDU_TYPE_SLSCH: break; case FAPI_NR_RX_PDU_TYPE_SSB: { - sl_nr_ssb_pdu_t *ssb_pdu = &rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu; - if(typeSpecific) { - uint8_t *psbch_decoded_output = (uint8_t *)typeSpecific; - memcpy(ssb_pdu->psbch_payload, psbch_decoded_output, sizeof(4));//4 bytes of PSBCH payload bytes - ssb_pdu->rsrp_dbm = sl_phy_params->psbch.rsrp_dBm_per_RE; - ssb_pdu->rx_slss_id = rx_slss_id; - ssb_pdu->decode_status = true; - LOG_D(PHY, "SL-IND: SSB to MAC. rsrp:%d, slssid:%d, payload:%x\n", - ssb_pdu->rsrp_dbm,ssb_pdu->rx_slss_id, - *((uint32_t *)(ssb_pdu->psbch_payload)) ); - } - else - ssb_pdu->decode_status = false; - } - break; + sl_nr_ssb_pdu_t *ssb_pdu = &rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu; + if (typeSpecific) { + uint8_t *psbch_decoded_output = (uint8_t *)typeSpecific; + memcpy(ssb_pdu->psbch_payload, psbch_decoded_output, sizeof(4)); // 4 bytes of PSBCH payload bytes + ssb_pdu->rsrp_dbm = sl_phy_params->psbch.rsrp_dBm_per_RE; + ssb_pdu->rx_slss_id = rx_slss_id; + ssb_pdu->decode_status = true; + LOG_D(PHY, + "SL-IND: SSB to MAC. rsrp:%d, slssid:%d, payload:%x\n", + ssb_pdu->rsrp_dbm, + ssb_pdu->rx_slss_id, + *((uint32_t *)(ssb_pdu->psbch_payload))); + } else + ssb_pdu->decode_status = false; + } break; default: break; } - rx_ind->rx_indication_body[n_pdus -1].pdu_type = pdu_type; + rx_ind->rx_indication_body[n_pdus - 1].pdu_type = pdu_type; rx_ind->number_pdus = n_pdus; - } static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue, @@ -111,7 +109,6 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue, nr_phy_data_t *phy_data, c16_t rxdataF[][fp->samples_per_slot_wCP]) { - int ret = 0; DevAssert(ue); @@ -121,21 +118,24 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue, sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS; uint16_t rx_slss_id = sl_phy_params->sl_config.sl_sync_source.rx_slss_id; - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PSBCH_PROCEDURES, VCD_FUNCTION_IN); + // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PSBCH_PROCEDURES, VCD_FUNCTION_IN); - LOG_D(PHY,"[UE %d] Frame %d Slot %d, Trying PSBCH (SLSS ID %d)\n", - ue->Mod_id,frame_rx,nr_slot_rx, - sl_phy_params->sl_config.sl_sync_source.rx_slss_id); + LOG_D(PHY, + "[UE %d] Frame %d Slot %d, Trying PSBCH (SLSS ID %d)\n", + ue->Mod_id, + frame_rx, + nr_slot_rx, + sl_phy_params->sl_config.sl_sync_source.rx_slss_id); uint8_t decoded_pdu[4] = {0}; ret = nr_rx_psbch(ue, - proc, - estimateSz, - dl_ch_estimates, - fp, - decoded_pdu, - rxdataF, - sl_phy_params->sl_config.sl_sync_source.rx_slss_id); + proc, + estimateSz, + dl_ch_estimates, + fp, + decoded_pdu, + rxdataF, + sl_phy_params->sl_config.sl_sync_source.rx_slss_id); nr_sidelink_indication_t sl_indication; sl_nr_rx_indication_t rx_ind = {0}; @@ -143,12 +143,12 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue, uint8_t *result = NULL; if (ret) { - sl_phy_params->psbch.rx_errors ++; - LOG_E(PHY,"%d:%d PSBCH RX: NOK \n",proc->frame_rx, proc->nr_slot_rx); + sl_phy_params->psbch.rx_errors++; + LOG_E(PHY, "%d:%d PSBCH RX: NOK \n", proc->frame_rx, proc->nr_slot_rx); } else { result = decoded_pdu; - sl_phy_params->psbch.rx_ok ++; - LOG_D(PHY,"%d:%d PSBCH RX: OK \n",proc->frame_rx, proc->nr_slot_rx); + sl_phy_params->psbch.rx_ok++; + LOG_D(PHY, "%d:%d PSBCH RX: OK \n", proc->frame_rx, proc->nr_slot_rx); } nr_fill_sl_indication(&sl_indication, &rx_ind, NULL, proc, ue, phy_data); @@ -157,114 +157,98 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue, if (ue->if_inst && ue->if_inst->sl_indication) ue->if_inst->sl_indication(&sl_indication); - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PSBCH_PROCEDURES, VCD_FUNCTION_OUT); + // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PSBCH_PROCEDURES, VCD_FUNCTION_OUT); return ret; } - - -int psbch_pscch_processing(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - nr_phy_data_t *phy_data) +int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data) { - int frame_rx = proc->frame_rx; int nr_slot_rx = proc->nr_slot_rx; sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS; NR_DL_FRAME_PARMS *fp = &sl_phy_params->sl_frame_params; int sampleShift = 0; - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX_SL, VCD_FUNCTION_IN); + // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX_SL, VCD_FUNCTION_IN); start_meas(&sl_phy_params->phy_proc_sl_rx); - LOG_D(PHY," ****** Sidelink RX-Chain for Frame.Slot %d.%d ****** \n", - frame_rx%1024, nr_slot_rx); + LOG_D(PHY, " ****** Sidelink RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx % 1024, nr_slot_rx); const uint32_t rxdataF_sz = fp->samples_per_slot_wCP; - __attribute__ ((aligned(32))) c16_t rxdataF[fp->nb_antennas_rx][rxdataF_sz]; - - if (phy_data->sl_rx_action == SL_NR_CONFIG_TYPE_RX_PSBCH){ + __attribute__((aligned(32))) c16_t rxdataF[fp->nb_antennas_rx][rxdataF_sz]; + if (phy_data->sl_rx_action == SL_NR_CONFIG_TYPE_RX_PSBCH) { const int estimateSz = fp->symbols_per_slot * fp->ofdm_symbol_size; - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PSBCH, VCD_FUNCTION_IN); - LOG_D(PHY," ----- PSBCH RX TTI: frame.slot %d.%d ------ \n", - frame_rx%1024, nr_slot_rx); + // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PSBCH, VCD_FUNCTION_IN); + LOG_D(PHY, " ----- PSBCH RX TTI: frame.slot %d.%d ------ \n", frame_rx % 1024, nr_slot_rx); - __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates[fp->nb_antennas_rx][estimateSz]; - __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[fp->nb_antennas_rx][fp->ofdm_symbol_size]; + __attribute__((aligned(32))) struct complex16 dl_ch_estimates[fp->nb_antennas_rx][estimateSz]; + __attribute__((aligned(32))) struct complex16 dl_ch_estimates_time[fp->nb_antennas_rx][fp->ofdm_symbol_size]; // 0 for Normal Cyclic Prefix and 1 for EXT CyclicPrefix - const int numsym = (fp->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP - : SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP; + const int numsym = (fp->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP : SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP; - for (int sym=0; symchannel_estimation_stats); nr_pbch_channel_estimation(ue, - fp, - estimateSz, - dl_ch_estimates, - dl_ch_estimates_time, - proc, - sym, - sym, - 0, - 0, - rxdataF, - true, - sl_phy_params->sl_config.sl_sync_source.rx_slss_id); + fp, + estimateSz, + dl_ch_estimates, + dl_ch_estimates_time, + proc, + sym, + sym, + 0, + 0, + rxdataF, + true, + sl_phy_params->sl_config.sl_sync_source.rx_slss_id); stop_meas(&sl_phy_params->channel_estimation_stats); - //PSBCH present in symbols 0, 5-12 for normal cp + // PSBCH present in symbols 0, 5-12 for normal cp sym = (sym == 0) ? 5 : sym + 1; } - nr_sl_psbch_rsrp_measurements(sl_phy_params,fp, rxdataF,false); + nr_sl_psbch_rsrp_measurements(sl_phy_params, fp, rxdataF, false); - LOG_D(PHY," ------ Decode SL-MIB: frame.slot %d.%d ------ \n", - frame_rx%1024, nr_slot_rx); + LOG_D(PHY, " ------ Decode SL-MIB: frame.slot %d.%d ------ \n", frame_rx % 1024, nr_slot_rx); - const int psbchSuccess = nr_ue_psbch_procedures(ue, fp, proc, estimateSz, - dl_ch_estimates, phy_data, rxdataF); + const int psbchSuccess = nr_ue_psbch_procedures(ue, fp, proc, estimateSz, dl_ch_estimates, phy_data, rxdataF); - if (ue->no_timing_correction==0 && psbchSuccess == 0) { - LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction); - sampleShift = nr_adjust_synch_ue(fp, ue, proc->gNB_id, fp->ofdm_symbol_size, - dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384); + if (ue->no_timing_correction == 0 && psbchSuccess == 0) { + LOG_D(PHY, "start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction); + sampleShift = + nr_adjust_synch_ue(fp, ue, proc->gNB_id, fp->ofdm_symbol_size, dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384); } LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__); -// nr_ue_rrc_measurements(ue, proc, rxdataF); - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PSBCH, VCD_FUNCTION_OUT); + // nr_ue_rrc_measurements(ue, proc, rxdataF); + // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PSBCH, VCD_FUNCTION_OUT); - if (frame_rx%64 == 0) { - LOG_I(NR_PHY,"============================================\n"); + if (frame_rx % 64 == 0) { + LOG_I(NR_PHY, "============================================\n"); - LOG_I(NR_PHY,"[UE%d] %d:%d PSBCH Stats: TX %d, RX ok %d, RX not ok %d\n", - ue->Mod_id, frame_rx, nr_slot_rx, - sl_phy_params->psbch.num_psbch_tx, - sl_phy_params->psbch.rx_ok, - sl_phy_params->psbch.rx_errors); + LOG_I(NR_PHY, + "[UE%d] %d:%d PSBCH Stats: TX %d, RX ok %d, RX not ok %d\n", + ue->Mod_id, + frame_rx, + nr_slot_rx, + sl_phy_params->psbch.num_psbch_tx, + sl_phy_params->psbch.rx_ok, + sl_phy_params->psbch.rx_errors); - LOG_I(NR_PHY,"============================================\n"); + LOG_I(NR_PHY, "============================================\n"); } } return sampleShift; } -int phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - nr_phy_data_tx_t *phy_data) +int phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data) { - int slot_tx = proc->nr_slot_tx; int frame_tx = proc->frame_tx; int tx_action = 0; @@ -272,52 +256,49 @@ int phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS; NR_DL_FRAME_PARMS *fp = &sl_phy_params->sl_frame_params; - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_SL,VCD_FUNCTION_IN); + // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_SL,VCD_FUNCTION_IN); const int samplesF_per_slot = NR_SYMBOLS_PER_SLOT * fp->ofdm_symbol_size; c16_t txdataF_buf[fp->nb_antennas_tx * samplesF_per_slot] __attribute__((aligned(32))); memset(txdataF_buf, 0, sizeof(txdataF_buf)); c16_t *txdataF[fp->nb_antennas_tx]; /* workaround to be compatible with current txdataF usage in all tx procedures. */ - for(int i=0; i< fp->nb_antennas_tx; ++i) + for (int i = 0; i < fp->nb_antennas_tx; ++i) txdataF[i] = &txdataF_buf[i * samplesF_per_slot]; - LOG_D(PHY,"****** start Sidelink TX-Chain for AbsSubframe %d.%d ******\n", - frame_tx, slot_tx); + LOG_D(PHY, "****** start Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx); start_meas(&sl_phy_params->phy_proc_sl_tx); if (phy_data->sl_tx_action == SL_NR_CONFIG_TYPE_TX_PSBCH) { sl_nr_tx_config_psbch_pdu_t *psbch_vars = &phy_data->psbch_vars; nr_tx_psbch(ue, frame_tx, slot_tx, psbch_vars, txdataF); - sl_phy_params->psbch.num_psbch_tx ++; + sl_phy_params->psbch.num_psbch_tx++; - if (frame_tx%64 == 0) { - LOG_I(NR_PHY,"============================================\n"); + if (frame_tx % 64 == 0) { + LOG_I(NR_PHY, "============================================\n"); - LOG_I(NR_PHY,"[UE%d] %d:%d PSBCH Stats: TX %d, RX ok %d, RX not ok %d\n", - ue->Mod_id, frame_tx, slot_tx, - sl_phy_params->psbch.num_psbch_tx, - sl_phy_params->psbch.rx_ok, - sl_phy_params->psbch.rx_errors); + LOG_I(NR_PHY, + "[UE%d] %d:%d PSBCH Stats: TX %d, RX ok %d, RX not ok %d\n", + ue->Mod_id, + frame_tx, + slot_tx, + sl_phy_params->psbch.num_psbch_tx, + sl_phy_params->psbch.rx_ok, + sl_phy_params->psbch.rx_errors); - LOG_I(NR_PHY,"============================================\n"); + LOG_I(NR_PHY, "============================================\n"); } tx_action = 1; } if (tx_action) { LOG_D(PHY, "Sending Uplink data \n"); - nr_ue_pusch_common_procedures(ue, - proc->nr_slot_tx, - fp, - fp->nb_antennas_tx, - txdataF); + nr_ue_pusch_common_procedures(ue, proc->nr_slot_tx, fp, fp->nb_antennas_tx, txdataF); } - LOG_D(PHY,"****** end Sidelink TX-Chain for AbsSubframe %d.%d ******\n", - frame_tx, slot_tx); + LOG_D(PHY, "****** end Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx); - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_SL, VCD_FUNCTION_OUT); + // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_SL, VCD_FUNCTION_OUT); stop_meas(&sl_phy_params->phy_proc_sl_tx); return tx_action; diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 703c4bef20..acfa696b24 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -786,38 +786,45 @@ int main(int argc, char **argv) int ssb_slot = (UE->symbol_offset/14)+(n_hf*(frame_parms->slots_per_frame>>1)); proc.nr_slot_rx = ssb_slot; proc.gNB_id = 0; - for (int i=UE->symbol_offset+1; isymbol_offset+4; i++) { - nr_slot_fep(UE, - frame_parms, - &proc, - i%frame_parms->symbols_per_slot, - rxdataF, link_type_dl); - - nr_pbch_channel_estimation(UE,&UE->frame_parms, estimateSz, dl_ch_estimates, dl_ch_estimates_time, &proc, - i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1), - ssb_index%8,n_hf,rxdataF,false,frame_parms->Nid_cell); + for (int i = UE->symbol_offset + 1; i < UE->symbol_offset + 4; i++) { + nr_slot_fep(UE, frame_parms, &proc, i % frame_parms->symbols_per_slot, rxdataF, link_type_dl); + nr_pbch_channel_estimation(UE, + &UE->frame_parms, + estimateSz, + dl_ch_estimates, + dl_ch_estimates_time, + &proc, + i % frame_parms->symbols_per_slot, + i - (UE->symbol_offset + 1), + ssb_index % 8, + n_hf, + rxdataF, + false, + frame_parms->Nid_cell); } - fapiPbch_t result; + fapiPbch_t result; ret = nr_rx_pbch(UE, &proc, estimateSz, dl_ch_estimates, frame_parms, ssb_index % 8, &result, rxdataF); - if (ret==0) { - //UE->rx_ind.rx_indication_body->mib_pdu.ssb_index; //not yet detected automatically - //UE->rx_ind.rx_indication_body->mib_pdu.ssb_length; //Lmax, not yet detected automatically - uint8_t gNB_xtra_byte=0; - for (int i=0; i<8; i++) - gNB_xtra_byte |= ((gNB->pbch.pbch_a>>(31-i))&1)<<(7-i); - + if (ret == 0) { + // UE->rx_ind.rx_indication_body->mib_pdu.ssb_index; //not yet detected automatically + // UE->rx_ind.rx_indication_body->mib_pdu.ssb_length; //Lmax, not yet detected automatically + uint8_t gNB_xtra_byte = 0; + for (int i = 0; i < 8; i++) + gNB_xtra_byte |= ((gNB->pbch.pbch_a >> (31 - i)) & 1) << (7 - i); + payload_ret = (result.xtra_byte == gNB_xtra_byte); - for (i=0;i<3;i++){ - payload_ret += (result.decoded_output[i] == ((msgDataTx.ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff)); - } - //printf("ret %d\n", payload_ret); - if (payload_ret!=4) + for (i = 0; i < 3; i++) { + payload_ret += + (result.decoded_output[i] == ((msgDataTx.ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload >> (8 * i)) & 0xff)); + } + // printf("ret %d\n", payload_ret); + if (payload_ret != 4) n_errors_payload++; } - if (ret!=0) n_errors++; + if (ret != 0) + n_errors++; } } //noise trials printf("SNR %f: trials %d, n_errors_crc = %d, n_errors_payload %d\n", SNR,n_trials,n_errors,n_errors_payload); diff --git a/openair1/SIMULATION/NR_PHY/psbchsim.c b/openair1/SIMULATION/NR_PHY/psbchsim.c index 73819b56b7..b30405bef9 100644 --- a/openair1/SIMULATION/NR_PHY/psbchsim.c +++ b/openair1/SIMULATION/NR_PHY/psbchsim.c @@ -6,7 +6,7 @@ #include #include #include "common/config/config_userapi.h" -#include "common/ran_context.h" +#include "common/ran_context.h" #include "PHY/types.h" #include "PHY/defs_nr_common.h" #include "PHY/defs_nr_UE.h" @@ -26,26 +26,39 @@ #include "PHY/MODULATION/nr_modulation.h" #include "NR_SL-SSB-TimeAllocation-r16.h" -void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) { abort(); } -void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req) { abort(); } -void e1_bearer_release_cmd(const e1ap_bearer_release_cmd_t *cmd) { abort(); } -void exit_function(const char* file, const char* function, const int line, const char* s, const int assert) { - const char * msg= s==NULL ? "no comment": s; +void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) +{ + abort(); +} +void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req) +{ + abort(); +} +void e1_bearer_release_cmd(const e1ap_bearer_release_cmd_t *cmd) +{ + abort(); +} +void exit_function(const char *file, const char *function, const int line, const char *s, const int assert) +{ + const char *msg = s == NULL ? "no comment" : s; printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); exit(-1); } -int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { return 1; } +int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) +{ + return 1; +} // to solve link errors double cpuf; -//void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {} -void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu, - uint8_t *nb_dmrs_re_per_rb, - uint16_t *number_dmrs_symbols){} +// void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {} +void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu, uint8_t *nb_dmrs_re_per_rb, uint16_t *number_dmrs_symbols) +{ +} uint64_t downlink_frequency[1][1]; int32_t uplink_frequency_offset[1][1]; THREAD_STRUCT thread_struct; -instance_t DUuniqInstance=0; -instance_t CUuniqInstance=0; +instance_t DUuniqInstance = 0; +instance_t CUuniqInstance = 0; openair0_config_t openair0_cfg[1]; RAN_CONTEXT_t RC; @@ -58,21 +71,27 @@ void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB } int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, - const int CC_id, - const uint8_t gNB_id, - const frame_t frameP, - const rb_id_t Srb_id, - uint8_t *buffer_pP) + const int CC_id, + const uint8_t gNB_id, + const frame_t frameP, + const rb_id_t Srb_id, + uint8_t *buffer_pP) { return 0; } nr_bler_struct nr_bler_data[NR_NUM_MCS]; -void get_nrUE_params(void) { return;} -uint8_t check_if_ue_is_sl_syncsource() {return 0;} +void get_nrUE_params(void) +{ + return; +} +uint8_t check_if_ue_is_sl_syncsource() +{ + return 0; +} ////////////////////////////////////////////////////////////////////////// -static void prepare_mib_bits(uint8_t *buf, uint32_t frame_tx, uint32_t slot_tx) { - +static void prepare_mib_bits(uint8_t *buf, uint32_t frame_tx, uint32_t slot_tx) +{ NR_MasterInformationBlockSidelink_t *sl_mib; asn_enc_rval_t enc_rval; @@ -80,67 +99,64 @@ static void prepare_mib_bits(uint8_t *buf, uint32_t frame_tx, uint32_t slot_tx) sl_mib = CALLOC(1, sizeof(NR_MasterInformationBlockSidelink_t)); - sl_mib->inCoverage_r16 = 0;//TRUE; + sl_mib->inCoverage_r16 = 0; // TRUE; // allocate buffer for 7 bits slotnumber sl_mib->slotIndex_r16.size = 1; sl_mib->slotIndex_r16.buf = CALLOC(1, sl_mib->slotIndex_r16.size); - sl_mib->slotIndex_r16.bits_unused = sl_mib->slotIndex_r16.size*8 - 7; + sl_mib->slotIndex_r16.bits_unused = sl_mib->slotIndex_r16.size * 8 - 7; sl_mib->slotIndex_r16.buf[0] = slot_tx << sl_mib->slotIndex_r16.bits_unused; sl_mib->directFrameNumber_r16.size = 2; sl_mib->directFrameNumber_r16.buf = CALLOC(1, sl_mib->directFrameNumber_r16.size); - sl_mib->directFrameNumber_r16.bits_unused = sl_mib->directFrameNumber_r16.size*8 - 10; + sl_mib->directFrameNumber_r16.bits_unused = sl_mib->directFrameNumber_r16.size * 8 - 10; sl_mib->directFrameNumber_r16.buf[0] = frame_tx >> (8 - sl_mib->directFrameNumber_r16.bits_unused); sl_mib->directFrameNumber_r16.buf[1] = frame_tx << sl_mib->directFrameNumber_r16.bits_unused; - enc_rval = uper_encode_to_buffer(&asn_DEF_NR_MasterInformationBlockSidelink, - NULL, - (void *)sl_mib, - buffer, - 100); + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_MasterInformationBlockSidelink, NULL, (void *)sl_mib, buffer, 100); - AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - - asn_DEF_NR_MasterInformationBlockSidelink.op->free_struct(&asn_DEF_NR_MasterInformationBlockSidelink, sl_mib, ASFM_FREE_EVERYTHING); + AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); + asn_DEF_NR_MasterInformationBlockSidelink.op->free_struct(&asn_DEF_NR_MasterInformationBlockSidelink, + sl_mib, + ASFM_FREE_EVERYTHING); } -static int test_rx_mib(uint8_t *decoded_output, uint16_t frame, uint16_t slot) { - +static int test_rx_mib(uint8_t *decoded_output, uint16_t frame, uint16_t slot) +{ uint32_t sl_mib = *(uint32_t *)decoded_output; uint32_t fn = 0, sl = 0; fn = (((sl_mib & 0x0700) >> 1) | ((sl_mib & 0xFE0000) >> 17)); - sl = (((sl_mib & 0x010000) >> 10) | ((sl_mib & 0xFC000000) >> 26)); + sl = (((sl_mib & 0x010000) >> 10) | ((sl_mib & 0xFC000000) >> 26)); - printf("decoded output:%x, TX %d:%d, timing decoded from sl-MIB %d:%d\n", - *(uint32_t *)decoded_output, frame, slot, fn, sl); + printf("decoded output:%x, TX %d:%d, timing decoded from sl-MIB %d:%d\n", *(uint32_t *)decoded_output, frame, slot, fn, sl); if (frame == fn && slot == sl) return 0; - + return -1; } ////////////////////////////////////////////////////////////////////////// -static void configure_NR_UE(PHY_VARS_NR_UE *UE, int mu, int N_RB) { - +static void configure_NR_UE(PHY_VARS_NR_UE *UE, int mu, int N_RB) +{ fapi_nr_config_request_t config; NR_DL_FRAME_PARMS *fp = &UE->frame_parms; - config.ssb_config.scs_common = mu; + config.ssb_config.scs_common = mu; config.cell_config.frame_duplex_type = TDD; - config.carrier_config.dl_grid_size[mu] = N_RB; - config.carrier_config.ul_grid_size[mu] = N_RB; + config.carrier_config.dl_grid_size[mu] = N_RB; + config.carrier_config.ul_grid_size[mu] = N_RB; config.carrier_config.dl_frequency = 0; config.carrier_config.uplink_frequency = 0; int band; - if (mu == 1) band = 78; - if (mu == 0) band = 34; + if (mu == 1) + band = 78; + if (mu == 0) + band = 34; nr_init_frame_parms_ue(fp, &config, band); fp->ofdm_offset_divisor = 8; nr_dump_frame_parms(fp); @@ -151,8 +167,8 @@ static void configure_NR_UE(PHY_VARS_NR_UE *UE, int mu, int N_RB) { } } -static void sl_init_frame_parameters(PHY_VARS_NR_UE *UE) { - +static void sl_init_frame_parameters(PHY_VARS_NR_UE *UE) +{ NR_DL_FRAME_PARMS *nr_fp = &UE->frame_parms; NR_DL_FRAME_PARMS *sl_fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; @@ -171,11 +187,10 @@ static void sl_init_frame_parameters(PHY_VARS_NR_UE *UE) { LOG_I(PHY, "Dumping Sidelink Frame Parameters\n"); nr_dump_frame_parms(sl_fp); #endif - } -static void configure_SL_UE(PHY_VARS_NR_UE *UE, int mu, int N_RB, int ssb_offset, int slss_id) { - +static void configure_SL_UE(PHY_VARS_NR_UE *UE, int mu, int N_RB, int ssb_offset, int slss_id) +{ sl_nr_phy_config_request_t *config = &UE->SL_UE_PHY_PARAMS.sl_config; NR_DL_FRAME_PARMS *fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; @@ -193,36 +208,36 @@ static void configure_SL_UE(PHY_VARS_NR_UE *UE, int mu, int N_RB, int ssb_offset nr_dump_frame_parms(fp); } -static int freq_domain_loopback(PHY_VARS_NR_UE *UE_tx, PHY_VARS_NR_UE *UE_rx, - int frame, int slot, - nr_phy_data_tx_t *phy_data) { - +static int freq_domain_loopback(PHY_VARS_NR_UE *UE_tx, PHY_VARS_NR_UE *UE_rx, int frame, int slot, nr_phy_data_tx_t *phy_data) +{ sl_nr_ue_phy_params_t *sl_ue1 = &UE_tx->SL_UE_PHY_PARAMS; sl_nr_ue_phy_params_t *sl_ue2 = &UE_rx->SL_UE_PHY_PARAMS; printf("\nPSBCH SIM -F: %d:%d slss id TX UE:%d, RX UE:%d\n", - frame, slot,phy_data->psbch_vars.tx_slss_id, - sl_ue2->sl_config.sl_sync_source.rx_slss_id); + frame, + slot, + phy_data->psbch_vars.tx_slss_id, + sl_ue2->sl_config.sl_sync_source.rx_slss_id); NR_DL_FRAME_PARMS *fp = &sl_ue1->sl_frame_params; const int samplesF_per_slot = NR_SYMBOLS_PER_SLOT * fp->ofdm_symbol_size; c16_t txdataF_buf[fp->nb_antennas_tx * samplesF_per_slot] __attribute__((aligned(32))); memset(txdataF_buf, 0, sizeof(txdataF_buf)); c16_t *txdataF[fp->nb_antennas_tx]; /* workaround to be compatible with current txdataF usage in all tx procedures. */ - for(int i=0; i< fp->nb_antennas_tx; ++i) + for (int i = 0; i < fp->nb_antennas_tx; ++i) txdataF[i] = &txdataF_buf[i * samplesF_per_slot]; - nr_tx_psbch(UE_tx,frame, slot, &phy_data->psbch_vars, txdataF); + nr_tx_psbch(UE_tx, frame, slot, &phy_data->psbch_vars, txdataF); int estimateSz = sl_ue2->sl_frame_params.samples_per_slot_wCP; - __attribute__ ((aligned(32))) struct complex16 rxdataF[1][estimateSz]; - for (int i=0; isl_frame_params.samples_per_slot_wCP; i++) { + __attribute__((aligned(32))) struct complex16 rxdataF[1][estimateSz]; + for (int i = 0; i < sl_ue1->sl_frame_params.samples_per_slot_wCP; i++) { struct complex16 *txdataF_ptr = (struct complex16 *)&txdataF[0][i]; struct complex16 *rxdataF_ptr = (struct complex16 *)&rxdataF[0][i]; rxdataF_ptr->r = txdataF_ptr->r; rxdataF_ptr->i = txdataF_ptr->i; - //printf("r,i TXDATAF[%d]- %d:%d, RXDATAF[%d]- %d:%d\n", - // i, txdataF_ptr->r, txdataF_ptr->i, i, txdataF_ptr->r, txdataF_ptr->i); + // printf("r,i TXDATAF[%d]- %d:%d, RXDATAF[%d]- %d:%d\n", + // i, txdataF_ptr->r, txdataF_ptr->i, i, txdataF_ptr->r, txdataF_ptr->i); } uint8_t err_status = 0; @@ -234,10 +249,10 @@ static int freq_domain_loopback(PHY_VARS_NR_UE *UE_tx, PHY_VARS_NR_UE *UE_rx, struct complex16 dl_ch_estimates[1][estimateSz]; uint8_t decoded_output[4] = {0}; - LOG_I(PHY,"DEBUG: HIJACKING DL CHANNEL ESTIMATES.\n"); - for (int s=0; s<14; s++) { - for (int j=0; jsl_frame_params.ofdm_symbol_size; j++) { - struct complex16 *dlch = (struct complex16 *)(&dl_ch_estimates[0][s*sl_ue2->sl_frame_params.ofdm_symbol_size]); + LOG_I(PHY, "DEBUG: HIJACKING DL CHANNEL ESTIMATES.\n"); + for (int s = 0; s < 14; s++) { + for (int j = 0; j < sl_ue2->sl_frame_params.ofdm_symbol_size; j++) { + struct complex16 *dlch = (struct complex16 *)(&dl_ch_estimates[0][s * sl_ue2->sl_frame_params.ofdm_symbol_size]); dlch[j].r = 128; dlch[j].i = 0; } @@ -249,45 +264,43 @@ static int freq_domain_loopback(PHY_VARS_NR_UE *UE_tx, PHY_VARS_NR_UE *UE_rx, dl_ch_estimates, &sl_ue2->sl_frame_params, decoded_output, - rxdataF, - sl_ue2->sl_config.sl_sync_source.rx_slss_id); - + rxdataF, + sl_ue2->sl_config.sl_sync_source.rx_slss_id); int error_payload = 0; error_payload = test_rx_mib(decoded_output, frame, slot); if (err_status == 0 || error_payload == 0) { - LOG_I(PHY,"---------PSBCH -F TEST OK.\n"); + LOG_I(PHY, "---------PSBCH -F TEST OK.\n"); return 0; } LOG_E(PHY, "--------PSBCH -F TEST NOK. FAIL.\n"); return -1; } - PHY_VARS_NR_UE *UE_TX; // for tx PHY_VARS_NR_UE *UE_RX; // for rx double cpuf; configmodule_interface_t *uniqCfg = NULL; -int main(int argc, char **argv) { - +int main(int argc, char **argv) +{ char c; - int test_freqdomain_loopback = 0,test_slss_search = 0; + int test_freqdomain_loopback = 0, test_slss_search = 0; int frame = 5, slot = 10, frame_tx = 0, slot_tx = 0; int loglvl = OAILOG_INFO; uint16_t slss_id = 336, ssb_offset = 0; double snr1 = 2.0, snr0 = 2.0, SNR; double sigma2 = 0.0, sigma2_dB = 0.0; - double cfo=0, ip =0.0; + double cfo = 0, ip = 0.0; - SCM_t channel_model=AWGN;//Rayleigh1_anticorr; - int N_RB_DL=106,mu=1; + SCM_t channel_model = AWGN; // Rayleigh1_anticorr; + int N_RB_DL = 106, mu = 1; uint16_t errors = 0, n_trials = 1; int frame_length_complex_samples; - //int frame_length_complex_samples_no_prefix; + // int frame_length_complex_samples_no_prefix; NR_DL_FRAME_PARMS *frame_parms; int seed = 0; @@ -301,48 +314,46 @@ int main(int argc, char **argv) { randominit(0); while ((c = getopt(argc, argv, "c:hn:o:s:FIL:N:R:S:T:")) != -1) { - - printf("SIDELINK PSBCH SIM: handling optarg %c\n",c); + printf("SIDELINK PSBCH SIM: handling optarg %c\n", c); switch (c) { - case 'c': cfo = atof(optarg); - printf("Setting CFO to %f Hz\n",cfo); + printf("Setting CFO to %f Hz\n", cfo); break; case 'g': - switch((char)*optarg) { - case 'A': - channel_model=SCM_A; - break; + switch ((char)*optarg) { + case 'A': + channel_model = SCM_A; + break; - case 'B': - channel_model=SCM_B; - break; + case 'B': + channel_model = SCM_B; + break; - case 'C': - channel_model=SCM_C; - break; + case 'C': + channel_model = SCM_C; + break; - case 'D': - channel_model=SCM_D; - break; + case 'D': + channel_model = SCM_D; + break; - case 'E': - channel_model=EPA; - break; + case 'E': + channel_model = EPA; + break; - case 'F': - channel_model=EVA; - break; + case 'F': + channel_model = EVA; + break; - case 'G': - channel_model=ETU; - break; + case 'G': + channel_model = ETU; + break; - default: - printf("Unsupported channel model! Exiting.\n"); - exit(-1); + default: + printf("Unsupported channel model! Exiting.\n"); + exit(-1); } break; @@ -352,14 +363,14 @@ int main(int argc, char **argv) { case 'o': ssb_offset = atoi(optarg); - printf("SIDELINK PSBCH SIM: ssb offset from pointA:%d\n",ssb_offset); + printf("SIDELINK PSBCH SIM: ssb offset from pointA:%d\n", ssb_offset); break; case 's': slss_id = atoi(optarg); - printf("SIDELINK PSBCH SIM: slss_id from arg:%d\n",slss_id); - AssertFatal(slss_id >= 0 && slss_id <= 671,"SLSS ID not within Range 0-671\n"); - break; + printf("SIDELINK PSBCH SIM: slss_id from arg:%d\n", slss_id); + AssertFatal(slss_id >= 0 && slss_id <= 671, "SLSS ID not within Range 0-671\n"); + break; case 'F': test_freqdomain_loopback = 1; @@ -377,28 +388,28 @@ int main(int argc, char **argv) { case 'N': snr0 = atoi(optarg); snr1 = snr0; - printf("Setting SNR0 to %f. Test uses this SNR as target SNR\n",snr0); + printf("Setting SNR0 to %f. Test uses this SNR as target SNR\n", snr0); break; case 'R': N_RB_DL = atoi(optarg); - printf("SIDELINK PSBCH SIM: N_RB_DL:%d\n",N_RB_DL); + printf("SIDELINK PSBCH SIM: N_RB_DL:%d\n", N_RB_DL); break; case 'S': snr1 = atof(optarg); - printf("Setting SNR1 to %f. Test will run until this SNR as target SNR\n",snr1); + printf("Setting SNR1 to %f. Test will run until this SNR as target SNR\n", snr1); AssertFatal(snr1 <= snr0, "Test runs SNR down, set snr1 to a lower value than %f\n", snr0); break; case 'T': frame = atoi(optarg); slot = atoi(argv[optind]); - printf("PSBCH SIM: frame timing- %d:%d\n",frame, slot); + printf("PSBCH SIM: frame timing- %d:%d\n", frame, slot); break; case 'h': - default : + default: printf("\n\nSIDELINK PSBCH SIM OPTIONS LIST - hus:FL:T:\n"); printf("-h: HELP\n"); printf("-c Carrier frequency offset in Hz\n"); @@ -413,7 +424,6 @@ int main(int argc, char **argv) { printf("-S Ending SNR, runs from SNR0 to SNR1\n"); printf("-T: Frame,Slot to be sent in sl-MIB eg -T 4 2\n"); return 1; - } } @@ -422,7 +432,7 @@ int main(int argc, char **argv) { logInit(); set_glog(loglvl); - double fs=0, eps; + double fs = 0, eps; double scs = 30000; double bw = 100e6; @@ -432,63 +442,48 @@ int main(int argc, char **argv) { if (N_RB_DL == 217) { fs = 122.88e6; bw = 80e6; - } - else if (N_RB_DL == 245) { + } else if (N_RB_DL == 245) { fs = 122.88e6; bw = 90e6; - } - else if (N_RB_DL == 273) { + } else if (N_RB_DL == 273) { fs = 122.88e6; bw = 100e6; - } - else if (N_RB_DL == 106) { + } else if (N_RB_DL == 106) { fs = 61.44e6; bw = 40e6; - } - else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); + } else + AssertFatal(1 == 0, "Unsupported numerology for mu %d, N_RB %d\n", mu, N_RB_DL); break; case 3: scs = 120000; if (N_RB_DL == 66) { fs = 122.88e6; bw = 100e6; - } - else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); + } else + AssertFatal(1 == 0, "Unsupported numerology for mu %d, N_RB %d\n", mu, N_RB_DL); break; } // cfo with respect to sub-carrier spacing - eps = cfo/scs; + eps = cfo / scs; // computation of integer and fractional FO to compare with estimation results int IFO; - if(eps!=0.0){ - printf("Introducing a CFO of %lf relative to SCS of %d kHz\n",eps,(int)(scs/1000)); - if (eps>0) - IFO=(int)(eps+0.5); + if (eps != 0.0) { + printf("Introducing a CFO of %lf relative to SCS of %d kHz\n", eps, (int)(scs / 1000)); + if (eps > 0) + IFO = (int)(eps + 0.5); else - IFO=(int)(eps-0.5); - printf("FFO = %lf; IFO = %d\n",eps-IFO,IFO); + IFO = (int)(eps - 0.5); + printf("FFO = %lf; IFO = %d\n", eps - IFO, IFO); } channel_desc_t *UE2UE; int n_tx = 1, n_rx = 1; - UE2UE = new_channel_desc_scm(n_tx, - n_rx, - channel_model, - fs, - 0, - bw, - 300e-9, - 0.0, - CORR_LEVEL_LOW, - 0, - 0, - 0, - 0); + UE2UE = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, 0, bw, 300e-9, 0.0, CORR_LEVEL_LOW, 0, 0, 0, 0); - if (UE2UE==NULL) { - printf("Problem generating channel model. Exiting.\n"); + if (UE2UE == NULL) { + printf("Problem generating channel model. Exiting.\n"); exit(-1); } @@ -497,12 +492,12 @@ int main(int argc, char **argv) { UE_RX = calloc(1, sizeof(PHY_VARS_NR_UE)); LOG_I(PHY, "Configure UE-TX and sidelink UE-TX.\n"); configure_NR_UE(UE_TX, mu, N_RB_DL); - configure_SL_UE(UE_TX, mu, N_RB_DL,ssb_offset, 0xFFFF); + configure_SL_UE(UE_TX, mu, N_RB_DL, ssb_offset, 0xFFFF); LOG_I(PHY, "Configure UE-RX and sidelink UE-RX.\n"); configure_NR_UE(UE_RX, mu, N_RB_DL); UE_RX->is_synchronized = (test_slss_search) ? 0 : 1; - configure_SL_UE(UE_RX, mu, N_RB_DL,ssb_offset, slss_id); + configure_SL_UE(UE_RX, mu, N_RB_DL, ssb_offset, slss_id); /*****************************************/ sl_nr_ue_phy_params_t *sl_uetx = &UE_TX->SL_UE_PHY_PARAMS; sl_nr_ue_phy_params_t *sl_uerx = &UE_RX->SL_UE_PHY_PARAMS; @@ -510,21 +505,21 @@ int main(int argc, char **argv) { frame_tx = frame % 1024; slot_tx = slot % frame_parms->slots_per_frame; - frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; - //frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; + frame_length_complex_samples = frame_parms->samples_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME; + // frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; - double **s_re,**s_im,**r_re,**r_im; - s_re = malloc(2*sizeof(double*)); - s_im = malloc(2*sizeof(double*)); - r_re = malloc(2*sizeof(double*)); - r_im = malloc(2*sizeof(double*)); + double **s_re, **s_im, **r_re, **r_im; + s_re = malloc(2 * sizeof(double *)); + s_im = malloc(2 * sizeof(double *)); + r_re = malloc(2 * sizeof(double *)); + r_im = malloc(2 * sizeof(double *)); - s_re[0] = malloc16_clear(frame_length_complex_samples*sizeof(double)); - s_im[0] = malloc16_clear(frame_length_complex_samples*sizeof(double)); - r_re[0] = malloc16_clear(frame_length_complex_samples*sizeof(double)); - r_im[0] = malloc16_clear(frame_length_complex_samples*sizeof(double)); + s_re[0] = malloc16_clear(frame_length_complex_samples * sizeof(double)); + s_im[0] = malloc16_clear(frame_length_complex_samples * sizeof(double)); + r_re[0] = malloc16_clear(frame_length_complex_samples * sizeof(double)); + r_im[0] = malloc16_clear(frame_length_complex_samples * sizeof(double)); - if(eps!=0.0) + if (eps != 0.0) UE_RX->UE_fo_compensation = 1; // if a frequency offset is set then perform fo estimation and compensation UE_nr_rxtx_proc_t proc; @@ -534,8 +529,8 @@ int main(int argc, char **argv) { phy_data_tx.psbch_vars.tx_slss_id = slss_id; uint8_t sl_mib[4] = {0}; - prepare_mib_bits(sl_mib,frame, slot); - memcpy(phy_data_tx.psbch_vars.psbch_payload,sl_mib, 4); + prepare_mib_bits(sl_mib, frame, slot); + memcpy(phy_data_tx.psbch_vars.psbch_payload, sl_mib, 4); phy_data_tx.sl_tx_action = SL_NR_CONFIG_TYPE_TX_PSBCH; proc.frame_rx = frame; @@ -547,81 +542,85 @@ int main(int argc, char **argv) { errors += freq_domain_loopback(UE_TX, UE_RX, frame_tx, slot_tx, &phy_data_tx); } - printf("\nSidelink TX UE - Frame.Slot %d.%d SLSS id:%d\n", - frame, slot,phy_data_tx.psbch_vars.tx_slss_id); + printf("\nSidelink TX UE - Frame.Slot %d.%d SLSS id:%d\n", frame, slot, phy_data_tx.psbch_vars.tx_slss_id); printf("Sidelink RX UE - Frame.Slot %d.%d SLSS id:%d\n", - proc.frame_rx, proc.nr_slot_rx, - sl_uerx->sl_config.sl_sync_source.rx_slss_id); + proc.frame_rx, + proc.nr_slot_rx, + sl_uerx->sl_config.sl_sync_source.rx_slss_id); phy_procedures_nrUE_SL_TX(UE_TX, &proc, &phy_data_tx); - for (SNR=snr0; SNR>=snr1; SNR-=1) { - - for (int trial=0; trialnb_antennas_tx; aa++) { + for (SNR = snr0; SNR >= snr1; SNR -= 1) { + for (int trial = 0; trial < n_trials; trial++) { + for (int i = 0; i < frame_length_complex_samples; i++) { + for (int aa = 0; aa < frame_parms->nb_antennas_tx; aa++) { struct complex16 *txdata_ptr = (struct complex16 *)&UE_TX->common_vars.txData[aa][i]; r_re[aa][i] = (double)txdata_ptr->r; r_im[aa][i] = (double)txdata_ptr->i; } } - LOG_M("txData0.m","txd0", UE_TX->common_vars.txData[0],frame_parms->samples_per_frame,1,1); + LOG_M("txData0.m", "txd0", UE_TX->common_vars.txData[0], frame_parms->samples_per_frame, 1, 1); - //AWGN - sigma2_dB = 20*log10((double)AMP/4)-SNR; - sigma2 = pow(10,sigma2_dB/10); - //printf("sigma2 %f (%f dB), tx_lev %f (%f dB)\n",sigma2,sigma2_dB,txlev,10*log10((double)txlev)); + // AWGN + sigma2_dB = 20 * log10((double)AMP / 4) - SNR; + sigma2 = pow(10, sigma2_dB / 10); + // printf("sigma2 %f (%f dB), tx_lev %f (%f dB)\n",sigma2,sigma2_dB,txlev,10*log10((double)txlev)); - if(eps!=0.0) { - rf_rx(r_re, // real part of txdata - r_im, // imag part of txdata - NULL, // interference real part - NULL, // interference imag part - 0, // interference power - frame_parms->nb_antennas_rx, // number of rx antennas - frame_length_complex_samples, // number of samples in frame - 1.0e9/fs, //sampling time (ns) - cfo, // frequency offset in Hz - 0.0, // drift (not implemented) - 0.0, // noise figure (not implemented) - 0.0, // rx gain in dB ? - 200, // 3rd order non-linearity in dB ? - &ip, // initial phase - 30.0e3, // phase noise cutoff in kHz - -500.0, // phase noise amplitude in dBc - 0.0, // IQ imbalance (dB), - 0.0); // IQ phase imbalance (rad) + if (eps != 0.0) { + rf_rx(r_re, // real part of txdata + r_im, // imag part of txdata + NULL, // interference real part + NULL, // interference imag part + 0, // interference power + frame_parms->nb_antennas_rx, // number of rx antennas + frame_length_complex_samples, // number of samples in frame + 1.0e9 / fs, // sampling time (ns) + cfo, // frequency offset in Hz + 0.0, // drift (not implemented) + 0.0, // noise figure (not implemented) + 0.0, // rx gain in dB ? + 200, // 3rd order non-linearity in dB ? + &ip, // initial phase + 30.0e3, // phase noise cutoff in kHz + -500.0, // phase noise amplitude in dBc + 0.0, // IQ imbalance (dB), + 0.0); // IQ phase imbalance (rad) } - for (int i=0; inb_antennas_rx; aa++) { - UE_RX->common_vars.rxdata[aa][i].r = (short)(r_re[aa][i] + sqrt(sigma2 / 2) * gaussdouble(0.0, 1.0)); - UE_RX->common_vars.rxdata[aa][i].i = (short)(r_im[aa][i] + sqrt(sigma2 / 2) * gaussdouble(0.0, 1.0)); - } + for (int i = 0; i < frame_length_complex_samples; i++) { + for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { + UE_RX->common_vars.rxdata[aa][i].r = (short)(r_re[aa][i] + sqrt(sigma2 / 2) * gaussdouble(0.0, 1.0)); + UE_RX->common_vars.rxdata[aa][i].i = (short)(r_im[aa][i] + sqrt(sigma2 / 2) * gaussdouble(0.0, 1.0)); } + } if (UE_RX->is_synchronized == 0) { nr_initial_sync_t ret = {false, 0}; - UE_nr_rxtx_proc_t proc={0}; - //Should not have SLSS id configured. Search should find SLSS id from TX UE + UE_nr_rxtx_proc_t proc = {0}; + // Should not have SLSS id configured. Search should find SLSS id from TX UE UE_RX->SL_UE_PHY_PARAMS.sl_config.sl_sync_source.rx_slss_id = 0xFFFF; - ret = sl_nr_slss_search(UE_RX, &proc, 1); - printf("Sidelink SLSS search returns status:%d, rx_offset:%d\n",ret.cell_detected, ret.rx_offset); - if (!ret.cell_detected) sl_uerx->psbch.rx_errors = 1; + ret = sl_nr_slss_search(UE_RX, &proc, 1); + printf("Sidelink SLSS search returns status:%d, rx_offset:%d\n", ret.cell_detected, ret.rx_offset); + if (!ret.cell_detected) + sl_uerx->psbch.rx_errors = 1; else { AssertFatal(UE_RX->SL_UE_PHY_PARAMS.sync_params.N_sl_id == slss_id, - "DETECTED INCORRECT SLSS ID in SEARCH.CHECK id:%d\n", UE_RX->SL_UE_PHY_PARAMS.sync_params.N_sl_id); + "DETECTED INCORRECT SLSS ID in SEARCH.CHECK id:%d\n", + UE_RX->SL_UE_PHY_PARAMS.sync_params.N_sl_id); sl_uerx->psbch.rx_ok = 1; } - } else psbch_pscch_processing(UE_RX,&proc,&phy_data_rx); + } else + psbch_pscch_processing(UE_RX, &proc, &phy_data_rx); - } //noise trials + } // noise trials printf("Runs:%d SNR %f: SLSS Search:%d crc ERRORs = %d, OK = %d\n", - n_trials, SNR, !UE_RX->is_synchronized, - sl_uerx->psbch.rx_errors, sl_uerx->psbch.rx_ok); + n_trials, + SNR, + !UE_RX->is_synchronized, + sl_uerx->psbch.rx_errors, + sl_uerx->psbch.rx_ok); errors += sl_uerx->psbch.rx_errors; sl_uerx->psbch.rx_errors = 0; sl_uerx->psbch.rx_ok = 0; @@ -629,9 +628,9 @@ int main(int argc, char **argv) { } // NSR if (errors == 0) - LOG_I(PHY,"PSBCH test OK\n"); + LOG_I(PHY, "PSBCH test OK\n"); else - LOG_E(PHY,"PSBCH test NOT OK\n"); + LOG_E(PHY, "PSBCH test NOT OK\n"); free_channel_desc_scm(UE2UE); @@ -654,5 +653,3 @@ int main(int argc, char **argv) { return errors; } - - From 21918ffd0a991f3e11f6d2a515474e9d860c018d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 11 Apr 2024 15:50:14 +0200 Subject: [PATCH 3/6] Include nr_psbchsim in image for physims --- docker/Dockerfile.phySim.rhel9 | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/Dockerfile.phySim.rhel9 b/docker/Dockerfile.phySim.rhel9 index 9935d61979..a5a4863a64 100644 --- a/docker/Dockerfile.phySim.rhel9 +++ b/docker/Dockerfile.phySim.rhel9 @@ -69,6 +69,7 @@ COPY --from=phy-sim-build \ /oai-ran/cmake_targets/ran_build/build/ldpctest \ /oai-ran/cmake_targets/ran_build/build/nr_dlschsim \ /oai-ran/cmake_targets/ran_build/build/nr_pbchsim \ + /oai-ran/cmake_targets/ran_build/build/nr_psbchsim \ /oai-ran/cmake_targets/ran_build/build/nr_pucchsim \ /oai-ran/cmake_targets/ran_build/build/nr_ulsim \ /oai-ran/cmake_targets/ran_build/build/smallblocktest \ From c547a4c1f8c6b8a6b12261a51f336508e3bc7e98 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 11 Apr 2024 16:03:57 +0200 Subject: [PATCH 4/6] Rename nr_psbchsim sidelink test case to harmonize with other tests --- cmake_targets/autotests/test_case_list.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 797c1d50b9..856b39c9fd 100755 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -530,9 +530,9 @@ 3 - - NR-Sidelink Test cases. (Test1: SLSS Search), - (Test2: PSBCH TxRx) + + NR-Sidelink PSBCH test cases. (Test1: SLSS Search), + (Test2: PSBCH TxRx) nr_psbchsim -I -n 10 From f042bd7a2de35ee0ef77bfaf63e8f4d4521eed27 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 11 Apr 2024 16:04:38 +0200 Subject: [PATCH 5/6] Add psbchsim charts to test in physim CI tests --- charts/physims/charts/nr-psbchsim/Chart.yaml | 36 +++++++++++ .../charts/nr-psbchsim/templates/_helpers.tpl | 63 +++++++++++++++++++ .../charts/nr-psbchsim/templates/job.yaml | 42 +++++++++++++ charts/physims/charts/nr-psbchsim/values.yaml | 48 ++++++++++++++ charts/physims/values.yaml | 1 + ci-scripts/cls_physim1.py | 2 +- 6 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 charts/physims/charts/nr-psbchsim/Chart.yaml create mode 100644 charts/physims/charts/nr-psbchsim/templates/_helpers.tpl create mode 100644 charts/physims/charts/nr-psbchsim/templates/job.yaml create mode 100644 charts/physims/charts/nr-psbchsim/values.yaml diff --git a/charts/physims/charts/nr-psbchsim/Chart.yaml b/charts/physims/charts/nr-psbchsim/Chart.yaml new file mode 100644 index 0000000000..8f1af6d648 --- /dev/null +++ b/charts/physims/charts/nr-psbchsim/Chart.yaml @@ -0,0 +1,36 @@ +apiVersion: v1 +name: oai-nr-psbchsim +description: A Helm subchart for nr-psbchsim network function + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +version: 0.1.1 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. +appVersion: v1 + +keywords: + - Physical Simulator + - nr-psbchsim + - RAN + - 5G + +sources: + - https://gitlab.eurecom.fr/oai/openairinterface5g + +maintainers: + - name: OPENAIRINTERFACE + email: contact@openairinterface.org diff --git a/charts/physims/charts/nr-psbchsim/templates/_helpers.tpl b/charts/physims/charts/nr-psbchsim/templates/_helpers.tpl new file mode 100644 index 0000000000..ef7fc150b5 --- /dev/null +++ b/charts/physims/charts/nr-psbchsim/templates/_helpers.tpl @@ -0,0 +1,63 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "oai-nr-psbchsim.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "oai-nr-psbchsim.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "oai-nr-psbchsim.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "oai-nr-psbchsim.labels" -}} +helm.sh/chart: {{ include "oai-nr-psbchsim.chart" . }} +{{ include "oai-nr-psbchsim.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "oai-nr-psbchsim.selectorLabels" -}} +app.kubernetes.io/name: {{ include "oai-nr-psbchsim.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "oai-nr-psbchsim.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "oai-nr-psbchsim.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} diff --git a/charts/physims/charts/nr-psbchsim/templates/job.yaml b/charts/physims/charts/nr-psbchsim/templates/job.yaml new file mode 100644 index 0000000000..a302630d3b --- /dev/null +++ b/charts/physims/charts/nr-psbchsim/templates/job.yaml @@ -0,0 +1,42 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ .Chart.Name }} +spec: + template: + metadata: + labels: + app: physim + spec: + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: physim + image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.version }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + env: + - name: OPENAIR_DIR + value: /opt/oai-physim + command: ["/bin/sh", "-c"] + args: + - > + cmake_targets/autotests/run_exec_autotests.bash -g "nr_psbchsim" -d bin/ && + echo "FINISHED" && sleep infinity + dnsPolicy: ClusterFirst + restartPolicy: Never + schedulerName: default-scheduler + serviceAccountName: {{ .Values.global.serviceAccountName }} + terminationGracePeriodSeconds: 30 + {{- if .Values.global.nodeSelector}} + nodeSelector: + {{- toYaml .Values.global.nodeSelector | nindent 12 }} + {{- end }} + {{- if .Values.global.nodeName.nrpsbchsim}} + nodeName: {{ .Values.global.nodeName.nrpsbchsim }} + {{- end }} diff --git a/charts/physims/charts/nr-psbchsim/values.yaml b/charts/physims/charts/nr-psbchsim/values.yaml new file mode 100644 index 0000000000..b6fa992ccf --- /dev/null +++ b/charts/physims/charts/nr-psbchsim/values.yaml @@ -0,0 +1,48 @@ +# Default values for oai-nr-psbchsim +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + # pullPolicy: IfNotPresent or Never or Always + pullPolicy: Always + +imagePullSecrets: [] + +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "oai-nr-psbchsim" + +podSecurityContext: + runAsUser: 0 + runAsGroup: 0 + +securityContext: + privileged: false + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/charts/physims/values.yaml b/charts/physims/values.yaml index bac4ed3eb5..82374001a2 100644 --- a/charts/physims/values.yaml +++ b/charts/physims/values.yaml @@ -27,6 +27,7 @@ global: nrpbschsim106rb: dedale nrpbchsim217rb: dedale nrpbchsim273rb: dedale + nrpsbchsim: dedale nrprachsim: dedale nrpucchsim: dedale nrulschsim: theseus diff --git a/ci-scripts/cls_physim1.py b/ci-scripts/cls_physim1.py index 70f8729764..85d8520a5f 100644 --- a/ci-scripts/cls_physim1.py +++ b/ci-scripts/cls_physim1.py @@ -166,7 +166,7 @@ class PhySim: mySSH.command('oc get pods -o wide -l app=physim | tee -a cmake_targets/log/physim_pods_summary.txt', '\$', 30, resync=True) running_count = mySSH.getBefore().count('Running') completed_count = mySSH.getBefore().count('Completed') - if (running_count + completed_count) == 21: + if (running_count + completed_count) == 22: logging.debug('\u001B[1m Running the physim test Scenarios\u001B[0m') isRunning = True podNames = re.findall('oai-[\S\d\w]+', mySSH.getBefore()) From d7a2795432414cabeca9e575ee4e9cd3c86024c3 Mon Sep 17 00:00:00 2001 From: francescomani Date: Sun, 14 Apr 2024 16:15:20 +0200 Subject: [PATCH 6/6] moving psbch DMRS modulation function away from gold sequence file --- openair1/PHY/INIT/nr_init_ue.c | 37 +++++++++++++++++++++++++ openair1/PHY/NR_REFSIG/nr_gold_ue.c | 37 ------------------------- openair1/PHY/NR_REFSIG/refsig_defs_ue.h | 1 - 3 files changed, 37 insertions(+), 38 deletions(-) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index ee90f0bccd..48152db15b 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -32,6 +32,7 @@ #include "PHY/NR_REFSIG/ul_ref_seq_nr.h" #include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "PHY/NR_REFSIG/nr_refsig.h" +#include "PHY/NR_REFSIG/nr_mod_table.h" #include "openair2/COMMON/prs_nr_paramdef.h" #include "SCHED_NR_UE/harq_nr.h" @@ -713,6 +714,42 @@ void phy_term_nr_top(void) free_context_synchro_nr(); } +static void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, struct complex16 *modulated_dmrs_sym, uint16_t slss_id) +{ + uint8_t idx = 0; + uint32_t *sl_dmrs_sequence = UE->SL_UE_PHY_PARAMS.init_params.psbch_dmrs_gold_sequences[slss_id]; + c16_t *mod_table = (c16_t *)nr_qpsk_mod_table; + +#ifdef SL_DEBUG_INIT + printf("SIDELINK INIT: PSBCH DMRS Generation with slss_id:%d\n", slss_id); +#endif + + /// QPSK modulation + for (int m = 0; m < SL_NR_NUM_PSBCH_DMRS_RE; m++) { + idx = (((sl_dmrs_sequence[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 3); + modulated_dmrs_sym[m].r = mod_table[idx].r; + modulated_dmrs_sym[m].i = mod_table[idx].i; + +#ifdef SL_DEBUG_INIT_DATA + printf("m:%d gold seq: %d b0-b1: %d-%d DMRS Symbols: %d %d\n", + m, + sl_dmrs_sequence[(m << 1) >> 5], + (((sl_dmrs_sequence[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 1), + (((sl_dmrs_sequence[((m << 1) + 1) >> 5]) >> (((m << 1) + 1) & 0x1f)) & 1), + modulated_dmrs_sym[m].r, + modulated_dmrs_sym[m].i); + printf("idx:%d, qpsk_table.r:%d, qpsk_table.i:%d\n", idx, mod_table[idx].r, mod_table[idx].i); +#endif + } + +#ifdef SL_DUMP_INIT_SAMPLES + char filename[40], varname[25]; + sprintf(filename, "sl_psbch_dmrs_slssid_%d.m", slss_id); + sprintf(varname, "sl_dmrs_id_%d.m", slss_id); + LOG_M(filename, varname, (void *)modulated_dmrs_sym, SL_NR_NUM_PSBCH_DMRS_RE, 1, 1); +#endif +} + void sl_ue_phy_init(PHY_VARS_NR_UE *UE) { uint16_t scaling_value = ONE_OVER_SQRT2_Q15; diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c index 926abfa49a..56dd09c0f0 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold_ue.c +++ b/openair1/PHY/NR_REFSIG/nr_gold_ue.c @@ -20,7 +20,6 @@ */ #include "refsig_defs_ue.h" -#include "PHY/NR_REFSIG/nr_mod_table.h" void nr_gold_pbch(PHY_VARS_NR_UE* ue) { @@ -174,39 +173,3 @@ void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE) } } } - -void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, struct complex16 *modulated_dmrs_sym, uint16_t slss_id) -{ - uint8_t idx = 0; - uint32_t *sl_dmrs_sequence = UE->SL_UE_PHY_PARAMS.init_params.psbch_dmrs_gold_sequences[slss_id]; - c16_t *mod_table = (c16_t *)nr_qpsk_mod_table; - -#ifdef SL_DEBUG_INIT - printf("SIDELINK INIT: PSBCH DMRS Generation with slss_id:%d\n", slss_id); -#endif - - /// QPSK modulation - for (int m = 0; m < SL_NR_NUM_PSBCH_DMRS_RE; m++) { - idx = (((sl_dmrs_sequence[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 3); - modulated_dmrs_sym[m].r = mod_table[idx].r; - modulated_dmrs_sym[m].i = mod_table[idx].i; - -#ifdef SL_DEBUG_INIT_DATA - printf("m:%d gold seq: %d b0-b1: %d-%d DMRS Symbols: %d %d\n", - m, - sl_dmrs_sequence[(m << 1) >> 5], - (((sl_dmrs_sequence[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 1), - (((sl_dmrs_sequence[((m << 1) + 1) >> 5]) >> (((m << 1) + 1) & 0x1f)) & 1), - modulated_dmrs_sym[m].r, - modulated_dmrs_sym[m].i); - printf("idx:%d, qpsk_table.r:%d, qpsk_table.i:%d\n", idx, mod_table[idx].r, mod_table[idx].i); -#endif - } - -#ifdef SL_DUMP_INIT_SAMPLES - char filename[40], varname[25]; - sprintf(filename, "sl_psbch_dmrs_slssid_%d.m", slss_id); - sprintf(varname, "sl_dmrs_id_%d.m", slss_id); - LOG_M(filename, varname, (void *)modulated_dmrs_sym, SL_NR_NUM_PSBCH_DMRS_RE, 1, 1); -#endif -} diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index 23233c9119..c7919130b5 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -70,5 +70,4 @@ void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, u void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params); void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, uint16_t scaling); void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE); -void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, struct complex16 *modulated_dmrs_sym, uint16_t slss_id); #endif