From a382a08bd33014ae52e15b5c25b32daa72498264 Mon Sep 17 00:00:00 2001 From: Patricio Latini Date: Sat, 20 Jul 2024 19:11:50 +0000 Subject: [PATCH 01/38] Fix support for USRP UHD Versions => 4.5.0.0 --- cmake_targets/tools/build_helper | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 9dffcd37a0..356229762f 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -269,6 +269,14 @@ install_usrp_uhd_driver_from_source(){ # - 3.15.0.0 git apply $OPENAIR_DIR/cmake_targets/tools/uhd-3.15-tdd-patch.diff ret=$?;[[ $ret -ne 0 ]] && echo_fatal "Could not apply the TDD patch" + elif [[ "$UHD_VERSION" == "4.7.0.0" || "$UHD_VERSION" == "4.6.0.0" || "$UHD_VERSION" == "4.5.0.0" ]]; then + # Tested that patch for the following versions: + # - 4.7.0.0 + cp $OPENAIR_DIR/cmake_targets/tools/uhd-4.x-tdd-patch.diff $OPENAIR_DIR/cmake_targets/tools/uhd-4.5plus-tdd-patch.diff + sed -i '9,13 s/STATE_OFF/STATE_RX1_OFF/' $OPENAIR_DIR/cmake_targets/tools/uhd-4.5plus-tdd-patch.diff + sed -i '24,28 s/STATE_OFF/STATE_RX2_OFF/' $OPENAIR_DIR/cmake_targets/tools/uhd-4.5plus-tdd-patch.diff + git apply $OPENAIR_DIR/cmake_targets/tools/uhd-4.5plus-tdd-patch.diff + ret=$?;[[ $ret -ne 0 ]] && echo_fatal "Could not apply the TDD patch" else # Tested that patch for the following versions: # - 4.0.0.0 From 3926e140e8856043ded1bfe4569b8951a3726c16 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 22 Jul 2024 12:09:54 +0200 Subject: [PATCH 02/38] fix(docker): base image for target oai-gnb-aw2s shall be jammy Signed-off-by: Raphael Defosseux --- docker/Dockerfile.gNB.aw2s.ubuntu22 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile.gNB.aw2s.ubuntu22 b/docker/Dockerfile.gNB.aw2s.ubuntu22 index e4645a71e0..1d81423c26 100644 --- a/docker/Dockerfile.gNB.aw2s.ubuntu22 +++ b/docker/Dockerfile.gNB.aw2s.ubuntu22 @@ -38,7 +38,7 @@ RUN /bin/sh oaienv && \ ./build_oai -w AW2SORI -t Ethernet #start from scratch for target executable -FROM ubuntu:bionic as oai-gnb-aw2s +FROM ubuntu:jammy as oai-gnb-aw2s ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe From 76aaf60dd1ec9f3102b15292ca3ecd40ee9719b5 Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 2 Jul 2024 09:41:36 +0200 Subject: [PATCH 03/38] UE feature set update --- doc/FEATURE_SET.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index ffacc9039b..7824759480 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -226,7 +226,8 @@ Furthermore, the gNB and UE support ## NR UE PHY Layer ## * Initial synchronization - - the UE needs to know the position in frequency of the SSBs (via command line parameter in SA) + - non-blind synchronization (information required: carrier frequency, bandwidth, numerology) + - option to search SSB inside the bandwidth available * Time tracking based on PBCH DMRS * Frequency offset estimation based on PSS and SSS * 15kHz and 30kHz SCS for FR1 and 120 kHz SCS for FR2 @@ -281,7 +282,7 @@ Furthermore, the gNB and UE support * MAC -> PHY configuration via UE FAPI P5 interface * Basic MAC to control PHY via UE FAPI P7 interface -* PHY -> MAC indication (needs some improvement) +* PHY -> MAC indication ## NR UE Higher Layers ## @@ -303,19 +304,21 @@ Furthermore, the gNB and UE support - format 01 (C-RNTI) * UCI processing - ACK/NACK processing - - Triggering periodic SR - - CSI measurement reporting + - Scheduling request procedures + - CSI measurement reporting (periodic and aperiodic) * DLSCH scheduler - Configuration of fapi PDU according to DCI - HARQ procedures * ULSCH scheduler - Configuration of fapi PDU according to DCI + - Buffer status reporting procedures - Logical channel prioritization of 'data from any logical channel' + - UCI on PUSCH * NR-CSIRS scheduler - Scheduling of NR-CSIRS reception - Fill UCI for CSI measurement reporting * Scheduler procedures for SRS transmission - - Periodic SRS transmission + - Periodic and aperiodic SRS transmission * Bandwidth part (BWP) operation - Operation in configured dedicated BWP through RRCSetup or RRCReconfiguration @@ -352,6 +355,7 @@ Furthermore, the gNB and UE support - RRCSetupRequest/RRCSetup/RRCSetupComplete - RRC Uplink/Downlink Information transfer carrying NAS messages transparently - RRC Reconfiguration/Reconfiguration complete + - RRCReestablishmentRequest/RRC Reestablishment/Reestablishment complete - Support for master cell group configuration - Reception of UECapabilityEnquiry, encoding and transmission of UECapability * Interface with PDCP: configuration, DCCH and CCCH message handling From 490620a0d82da529a8e272b95e6fc392fd27c537 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 4 Jul 2024 10:42:42 +0200 Subject: [PATCH 04/38] gNB supported number of antenna feature set update --- doc/FEATURE_SET.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index 7824759480..8ce1c3f8e9 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -59,7 +59,7 @@ Furthermore, the gNB and UE support - DMRS configuration type 1 and 2 - Single and multiple DMRS symbols - PTRS support - - Support for 1, 2 and 4 TX antennas + - Support for up to 4 TX antennas - Support for up to 2 layers - Support for 256 QAM * NR-CSIRS Generation of sequence at PHY @@ -68,7 +68,7 @@ Furthermore, the gNB and UE support - DMRS configuration type 1 and 2 - Single and multiple DMRS symbols - PTRS support - - Support for up to 2 RX antenna + - Support for up to 4 RX antennas - Support for up to 2 layers - Support for 256 QAM * NR-PUCCH From 032d4fc9ff544503adf37c389ce51dcf400104d6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 17 Jul 2024 16:40:46 +0200 Subject: [PATCH 05/38] RRC: reject PDU sessions if security is not active OAI 5GC seems to have a bug, and occasionally might send a PDU session setup request without having sent a UE context setup request, resulting in no security context activated for a UE. This lead to an assertion in rrc_gNB_process_e1_bearer_context_setup_resp(). To prevent the gNB from stopping, check if security is active before triggering PDU sessions. If not, the gNB will reject PDU sessions. --- openair2/RRC/NR/rrc_gNB.c | 2 -- openair2/RRC/NR/rrc_gNB_NGAP.c | 22 ++++++++++++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 420b31e662..db737823fe 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2200,8 +2200,6 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp } } - AssertFatal(UE->as_security_active, "logic bug: security should be active when activating DRBs\n"); - if (!UE->f1_ue_context_active) rrc_gNB_generate_UeContextSetupRequest(rrc, ue_context_p, nb_drb, drbs); else diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index e1395ce6cd..6f3341bc6b 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -342,6 +342,7 @@ static int decodePDUSessionResourceSetup(pdusession_t *session) void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession_t *sessions, uint64_t ueAggMaxBitRateDownlink) { + AssertFatal(UE->as_security_active, "logic bug: security should be active when activating DRBs\n"); e1ap_bearer_setup_req_t bearer_req = {0}; e1ap_nssai_t cuup_nssai = {0}; @@ -813,7 +814,6 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins gNB_RRC_UE_t *UE = &ue_context_p->ue_context; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0); gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; - LOG_I(NR_RRC, "[gNB %ld] gNB_ue_ngap_id %u \n", instance, msg->gNB_ue_ngap_id); if (ue_context_p == NULL) { MessageDef *msg_fail_p = NULL; @@ -825,7 +825,25 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins return ; } - AssertFatal(UE->rrc_ue_id == msg->gNB_ue_ngap_id, "logic bug\n"); + DevAssert(UE->rrc_ue_id == msg->gNB_ue_ngap_id); + LOG_I(NR_RRC, "UE %d: received PDU session setup request\n", UE->rrc_ue_id); + + if (!UE->as_security_active) { + LOG_E(NR_RRC, "UE %d: no security context active for UE, rejecting PDU session setup request\n", UE->rrc_ue_id); + MessageDef *msg_resp = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_RESP); + ngap_pdusession_setup_resp_t *resp = &NGAP_PDUSESSION_SETUP_RESP(msg_resp); + resp->gNB_ue_ngap_id = UE->rrc_ue_id; + resp->nb_of_pdusessions_failed = msg->nb_pdusessions_tosetup; + for (int i = 0; i < resp->nb_of_pdusessions_failed; ++i) { + pdusession_failed_t *f = &resp->pdusessions_failed[i]; + f->pdusession_id = msg->pdusession_setup_params[i].pdusession_id; + f->cause = NGAP_CAUSE_PROTOCOL; + f->cause_value = 3; // NGAP_CauseProtocol_message_not_compatible_with_receiver_state + } + itti_send_msg_to_task(TASK_NGAP, instance, msg_resp); + return; + } + UE->amf_ue_ngap_id = msg->amf_ue_ngap_id; trigger_bearer_setup(rrc, UE, msg->nb_pdusessions_tosetup, msg->pdusession_setup_params, msg->ueAggMaxBitRateDownlink); return; From d581c671e98d0cf0e8b09dfee85174b728cbc5d6 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Thu, 25 Jul 2024 13:48:03 +0200 Subject: [PATCH 06/38] Add enum for NGAP protocol cause IEs --- openair2/COMMON/ngap_messages_types.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index 29ea48294a..faeb11d377 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -409,6 +409,19 @@ typedef enum ngap_Cause_radio_network_e { NGAP_CAUSE_RADIO_NETWORK_MULTIPLE_LOCATION_REPORTING_REFERENCE_ID_INSTANCES } ngap_Cause_radio_network_t; +/** + * NGAP protocol cause values as per 9.3.1.2 `Cause` section in 3GPP TS 38.413. + */ +typedef enum ngap_cause_protocol_e { + NGAP_CAUSE_PROTOCOL_TRANSFER_SYNTAX_ERROR, + NGAP_CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_REJECT, + NGAP_CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_IGNORE, + NGAP_CAUSE_PROTOCOL_MSG_NOT_COMPATIBLE_WITH_RECEIVER_STATE, + NGAP_CAUSE_PROTOCOL_SEMANTIC_ERROR, + NGAP_CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_FCM, + NGAP_CAUSE_PROTOCOL_UNSPECIFIED +} ngap_cause_protocol_t; + typedef struct pdusession_failed_s { /* Unique pdusession_id for the UE. */ uint8_t pdusession_id; From 869b78efe2531a2e364a5ea14561ca4ed93477b5 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Thu, 25 Jul 2024 13:48:29 +0200 Subject: [PATCH 07/38] Use NGAP protocol cause IE in the stack --- openair2/RRC/NR/rrc_gNB_NGAP.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 6f3341bc6b..590cfcfecc 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -838,7 +838,7 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins pdusession_failed_t *f = &resp->pdusessions_failed[i]; f->pdusession_id = msg->pdusession_setup_params[i].pdusession_id; f->cause = NGAP_CAUSE_PROTOCOL; - f->cause_value = 3; // NGAP_CauseProtocol_message_not_compatible_with_receiver_state + f->cause_value = NGAP_CAUSE_PROTOCOL_MSG_NOT_COMPATIBLE_WITH_RECEIVER_STATE; } itti_send_msg_to_task(TASK_NGAP, instance, msg_resp); return; From 6fce49217798d25f635542d8cdc9e29b5df10f3d Mon Sep 17 00:00:00 2001 From: Raghavendra Dinavahi Date: Wed, 3 Jul 2024 20:42:20 +0200 Subject: [PATCH 08/38] Correction of variable initialisation --- openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 96c2638c9e..98433ea8b2 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c @@ -346,7 +346,7 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, int ret = -1; uint16_t rx_slss_id = 65535; - nr_initial_sync_t result = {true, 0}; + nr_initial_sync_t result = {false, 0}; #ifdef SL_DEBUG_SEARCH_SLSS LOG_D(PHY, "SIDELINK SEARCH SLSS: Function:%s\n", __func__); From 4c698bce2bf4b049836833e1cffdef3f99c02d55 Mon Sep 17 00:00:00 2001 From: Raghavendra Dinavahi Date: Wed, 3 Jul 2024 20:34:46 +0200 Subject: [PATCH 09/38] rewrite ssb meas function to call from initial sync --- .../PHY/NR_UE_ESTIMATION/nr_ue_measurements.c | 124 +++++++++++------- 1 file changed, 77 insertions(+), 47 deletions(-) diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index 30ff7a2f9b..3e42680dc8 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -170,6 +170,50 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, } } +// This function calculates: +// - SS reference signal received digital power in dB/RE +int nr_ue_calculate_ssb_rsrp(const NR_DL_FRAME_PARMS *fp, + const UE_nr_rxtx_proc_t *proc, + const c16_t rxdataF[][fp->samples_per_slot_wCP], + int symbol_offset, + int ssb_start_subcarrier) +{ + int k_start = 56; + int k_end = 183; + unsigned int ssb_offset = fp->first_carrier_offset + ssb_start_subcarrier; + + uint8_t l_sss = (symbol_offset + 2) % fp->symbols_per_slot; + + uint32_t rsrp = 0; + + LOG_D(PHY, "In %s: l_sss %d ssb_offset %d\n", __FUNCTION__, l_sss, ssb_offset); + int nb_re = 0; + + for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) { + int16_t *rxF_sss = (int16_t *)&rxdataF[aarx][l_sss * fp->ofdm_symbol_size]; + + for(int k = k_start; k < k_end; k++){ + int re = (ssb_offset + k) % fp->ofdm_symbol_size; + +#ifdef DEBUG_MEAS_UE + LOG_I(PHY, "In %s rxF_sss[%d] %d %d\n", __FUNCTION__, re, rxF_sss[re * 2], rxF_sss[re * 2 + 1]); +#endif + + rsrp += (((int32_t)rxF_sss[re*2]*rxF_sss[re*2]) + ((int32_t)rxF_sss[re*2 + 1]*rxF_sss[re*2 + 1])); + nb_re++; + + } + } + + rsrp /= nb_re; + + LOG_D(PHY, "In %s: RSRP/nb_re: %d nb_re :%d\n", __FUNCTION__, rsrp, nb_re); + + int rsrp_db_per_re = 10 * log10(rsrp); + + return rsrp_db_per_re; +} + // This function implements: // - SS reference signal received power (SS-RSRP) as per clause 5.1.1 of 3GPP TS 38.215 version 16.3.0 Release 16 // - no Layer 3 filtering implemented (no filterCoefficient provided from RRC) @@ -183,52 +227,27 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { - int k_start = 56; - int k_end = 183; - int slot = proc->nr_slot_rx; - unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier; - int symbol_offset = nr_get_ssb_start_symbol(&ue->frame_parms,ssb_index); + NR_DL_FRAME_PARMS *fp = &ue->frame_parms; - if (ue->frame_parms.half_frame_bit) - symbol_offset += (ue->frame_parms.slots_per_frame>>1)*ue->frame_parms.symbols_per_slot; + int symbol_offset = nr_get_ssb_start_symbol(fp, ssb_index); - uint8_t l_sss = (symbol_offset + 2) % ue->frame_parms.symbols_per_slot; + if (fp->half_frame_bit) + symbol_offset += (fp->slots_per_frame >> 1) * fp->symbols_per_slot; - uint32_t rsrp = 0; + int rsrp_db_per_re = nr_ue_calculate_ssb_rsrp(fp, proc, rxdataF, symbol_offset, fp->ssb_start_subcarrier); - LOG_D(PHY, "In %s: [UE %d] slot %d l_sss %d ssb_offset %d\n", __FUNCTION__, ue->Mod_id, slot, l_sss, ssb_offset); - int nb_re = 0; + openair0_config_t *cfg0 = &openair0_cfg[0]; - for (int aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) { + ue->measurements.ssb_rsrp_dBm[ssb_index] = rsrp_db_per_re + 30 - SQ15_SQUARED_NORM_FACTOR_DB + - ((int)cfg0->rx_gain[0] - (int)cfg0->rx_gain_offset[0]) + - dB_fixed(fp->ofdm_symbol_size); - int16_t *rxF_sss = (int16_t *)&rxdataF[aarx][l_sss*ue->frame_parms.ofdm_symbol_size]; - - for(int k = k_start; k < k_end; k++){ - - int re = (ssb_offset + k) % ue->frame_parms.ofdm_symbol_size; - -#ifdef DEBUG_MEAS_UE - LOG_I(PHY, "In %s rxF_sss %d %d\n", __FUNCTION__, rxF_sss[re*2], rxF_sss[re*2 + 1]); -#endif - - rsrp += (((int32_t)rxF_sss[re*2]*rxF_sss[re*2]) + ((int32_t)rxF_sss[re*2 + 1]*rxF_sss[re*2 + 1])); - nb_re++; - - } - } - - rsrp /= nb_re; - ue->measurements.ssb_rsrp_dBm[ssb_index] = 10*log10(rsrp) + - 30 - SQ15_SQUARED_NORM_FACTOR_DB - - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - - dB_fixed(ue->frame_parms.ofdm_symbol_size); - - LOG_D(PHY, "In %s: [UE %d] ssb %d SS-RSRP: %d dBm/RE (%d)\n", - __FUNCTION__, - ue->Mod_id, - ssb_index, - ue->measurements.ssb_rsrp_dBm[ssb_index], - rsrp); + LOG_D(PHY, + "[UE %d] ssb %d SS-RSRP: %d dBm/RE (%d dB/RE)\n", + ue->Mod_id, + ssb_index, + ue->measurements.ssb_rsrp_dBm[ssb_index], + rsrp_db_per_re); } // This function computes the received noise power @@ -310,11 +329,17 @@ 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 -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) +// This function implements: +// - PSBCH RSRP calculations according to 38.215 section 5.1.22 Release 16 +// - PSBCH DMRS used for calculations +// - TBD: SSS REs for calculation. +// Measurement units: +// - RSRP: W (dBW) +// returns RXgain to be adjusted based on target rx power (50db) - received digital power in db/RE +int 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; @@ -351,9 +376,14 @@ void nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params, - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(fp->ofdm_symbol_size); + int adjust_rxgain = TARGET_RX_POWER - psbch_rx->rsrp_dB_per_RE; + LOG_D(PHY, - "PSBCH RSRP (DMRS REs): numREs:%d RSRP :%d dB/RE ,RSRP:%d dBm/RE\n", + "PSBCH RSRP (DMRS REs): numREs:%d RSRP :%d dB/RE ,RSRP:%d dBm/RE, adjust_rxgain:%d dB\n", num_re, psbch_rx->rsrp_dB_per_RE, - psbch_rx->rsrp_dBm_per_RE); + psbch_rx->rsrp_dBm_per_RE, + adjust_rxgain); + + return adjust_rxgain; } From 95a876738382d0c03f062d995bc81603b17862e2 Mon Sep 17 00:00:00 2001 From: Raghavendra Dinavahi Date: Wed, 3 Jul 2024 20:40:28 +0200 Subject: [PATCH 10/38] Automatic update of USRP RX gain during initial search using --agc option - if search fails, keeps increasing the rx gain (set by --ue-rxgain) by 3 db until USRP max rx gain - if initial sync is success, sets the rxgain to the value of (TARGET_RX_POWER (50) - pbch digital power in dB/RE) --- executables/nr-softmodem-common.h | 2 +- executables/nr-ue.c | 43 ++++++++++++++++--- executables/nr-uesoftmodem.h | 2 + openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h | 14 ++++-- .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 6 +++ .../PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c | 2 +- openair1/PHY/defs_nr_UE.h | 4 ++ openair1/PHY/impl_defs_top.h | 3 ++ .../SCHED_NR_UE/phy_procedures_nr_ue_sl.c | 2 +- radio/USRP/usrp_lib.cpp | 31 +++++++------ 10 files changed, 83 insertions(+), 26 deletions(-) diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h index e84ca015cc..1d90b259df 100644 --- a/executables/nr-softmodem-common.h +++ b/executables/nr-softmodem-common.h @@ -106,7 +106,7 @@ #define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n" #define CONFIG_HLP_NOS1 "Disable s1 interface\n" #define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n" - +#define CONFIG_HLP_AGC "Rx Gain control used for UE" /*--------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters for LOG utility */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 447c99182b..26dbbb2d85 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -351,10 +351,31 @@ typedef struct { int rx_offset; } syncData_t; +static int nr_ue_adjust_rx_gain(PHY_VARS_NR_UE *UE, openair0_config_t *cfg0, int gain_change) +{ + // Increase the RX gain by the value determined by adjust_rxgain + cfg0->rx_gain[0] += gain_change; + + // Set new RX gain. + int ret_gain = UE->rfdevice.trx_set_gains_func(&UE->rfdevice, cfg0); + // APPLY RX gain again if crossed the MAX RX gain threshold + if (ret_gain < 0) { + gain_change += ret_gain; + cfg0->rx_gain[0] += ret_gain; + ret_gain = UE->rfdevice.trx_set_gains_func(&UE->rfdevice, cfg0); + } + + int applied_rxgain = cfg0->rx_gain[0] - cfg0->rx_gain_offset[0]; + LOG_I(PHY, "Rxgain adjusted by %d dB, RX gain: %d dB \n", gain_change, applied_rxgain); + + return gain_change; +} + static void UE_synch(void *arg) { syncData_t *syncD = (syncData_t *)arg; PHY_VARS_NR_UE *UE = syncD->UE; UE->is_synchronized = 0; + openair0_config_t *cfg0 = &openair0_cfg[UE->rf_map.card]; if (UE->target_Nid_cell != -1) { LOG_W(NR_PHY, "Starting re-sync detection for target Nid_cell %i\n", UE->target_Nid_cell); @@ -386,18 +407,30 @@ static void UE_synch(void *arg) { // rerun with new cell parameters and frequency-offset // todo: the freq_offset computed on DL shall be scaled before being applied to UL - nr_rf_card_config_freq(&openair0_cfg[UE->rf_map.card], ul_carrier, dl_carrier, freq_offset); + nr_rf_card_config_freq(cfg0, ul_carrier, dl_carrier, freq_offset); + + if (get_nrUE_params()->agc) { + nr_ue_adjust_rx_gain(UE, cfg0, UE->adjust_rxgain); + } LOG_I(PHY, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %f (DL %f Hz, UL %f Hz)\n", hw_slot_offset, freq_offset, - openair0_cfg[UE->rf_map.card].rx_gain[0], - openair0_cfg[UE->rf_map.card].rx_freq[0], - openair0_cfg[UE->rf_map.card].tx_freq[0]); + cfg0->rx_gain[0] - cfg0->rx_gain_offset[0], + cfg0->rx_freq[0], + cfg0->tx_freq[0]); - UE->rfdevice.trx_set_freq_func(&UE->rfdevice, &openair0_cfg[0]); + UE->rfdevice.trx_set_freq_func(&UE->rfdevice, cfg0); UE->is_synchronized = 1; + } else { + int gain_change = 0; + if (get_nrUE_params()->agc) + gain_change = nr_ue_adjust_rx_gain(UE, cfg0, INCREASE_IN_RXGAIN); + if (gain_change) + LOG_I(PHY, "synch retry: Rx gain increased \n"); + else + LOG_E(PHY, "synch Failed: \n"); } } diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 8e0650b4e4..3793e6b3a0 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -68,6 +68,7 @@ {"num-ues", NULL, 0, .iptr=&(NB_UE_INST), .defuintval=1, TYPE_INT, 0}, \ {"ntn-koffset", CONFIG_HLP_NTN_KOFFSET, 0, .uptr=&(nrUE_params.ntn_koffset), .defuintval=0, TYPE_UINT, 0}, \ {"ntn-ta-common", CONFIG_HLP_NTN_TA_COMMON, 0, .dblptr=&(nrUE_params.ntn_ta_common), .defdblval=0.0, TYPE_DOUBLE, 0}, \ + {"agc", CONFIG_HLP_AGC, PARAMFLAG_BOOL, .iptr=&(nrUE_params.agc), .defintval=0, TYPE_INT, 0}, \ } // clang-format on @@ -90,6 +91,7 @@ typedef struct { int ldpc_offload_flag; unsigned int ntn_koffset; double ntn_ta_common; + int agc; } nrUE_params_t; extern uint64_t get_nrUE_optmask(void); extern uint64_t set_nrUE_optmask(uint64_t bitmask); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index fc2e2bba62..390775fee7 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -115,6 +115,12 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, uint32_t pdsch_est_size, int32_t dl_ch_estimates[][pdsch_est_size]); +int nr_ue_calculate_ssb_rsrp(const NR_DL_FRAME_PARMS *fp, + const UE_nr_rxtx_proc_t *proc, + const c16_t rxdataF[][fp->samples_per_slot_wCP], + int symbol_offset, + int ssb_start_subcarrier); + void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue, uint8_t gNB_index, const UE_nr_rxtx_proc_t *proc, @@ -146,9 +152,9 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, 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); +int 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_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 4788c9ed9d..341459832f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -291,6 +291,11 @@ void nr_scan_ssb(void *arg) &ssbInfo->pbchResult, nr_gold_pbch_ref, rxdataF); // start pbch detection at first symbol after pss + if (ssbInfo->syncRes.cell_detected) { + int rsrp_db_per_re = nr_ue_calculate_ssb_rsrp(ssbInfo->fp, ssbInfo->proc, rxdataF, 0, ssbInfo->gscnInfo.ssbFirstSC); + ssbInfo->adjust_rxgain = TARGET_RX_POWER - rsrp_db_per_re; + LOG_I(PHY, "pbch rx ok. rsrp:%d dB/RE, adjust_rxgain:%d dB\n", rsrp_db_per_re, ssbInfo->adjust_rxgain); + } } } } @@ -370,6 +375,7 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, fp->ssb_index = res.ssbIndex; ue->symbol_offset = res.symbolOffset; ue->common_vars.freq_offset = res.freqOffset; + ue->adjust_rxgain = res.adjust_rxgain; } // In initial sync, we indicate PBCH to MAC after the scan is complete. 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 98433ea8b2..1d92bf99aa 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c @@ -512,7 +512,7 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, sync_params->DFN, sync_params->slot_offset); - nr_sl_psbch_rsrp_measurements(sl_ue, frame_parms, rxdataF, false); + UE->adjust_rxgain = 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; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 70b0dc041f..5178bc6320 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -600,6 +600,9 @@ typedef struct PHY_VARS_NR_UE_s { notifiedFIFO_t tx_resume_ind_fifo[NR_MAX_SLOTS_PER_FRAME]; + // Gain change required for automation RX gain change + int adjust_rxgain; + // Sidelink parameters sl_nr_sidelink_mode_t sl_mode; sl_nr_ue_phy_params_t SL_UE_PHY_PARAMS; @@ -645,6 +648,7 @@ typedef struct { fapiPbch_t pbchResult; int pssCorrPeakPower; int pssCorrAvgPower; + int adjust_rxgain; } nr_ue_ssb_scan_t; typedef struct nr_phy_data_tx_s { diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h index 618a7e6c58..24f1599873 100644 --- a/openair1/PHY/impl_defs_top.h +++ b/openair1/PHY/impl_defs_top.h @@ -181,6 +181,9 @@ #define TARGET_RX_POWER_MAX 65 // Maximum digital power, such that signal does not saturate (value found by simulation) #define TARGET_RX_POWER_MIN 35 // Minimum digital power, anything below will be discarded (value found by simulation) +// Increase USRP rx gain in steps of 3dB during Initial search +#define INCREASE_IN_RXGAIN 3 + //the min and max gains have to match the calibrated gain table //#define MAX_RF_GAIN 160 //#define MIN_RF_GAIN 96 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 b4335c7480..dac44e0f56 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c @@ -223,7 +223,7 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr sym = (sym == 0) ? 5 : sym + 1; } - nr_sl_psbch_rsrp_measurements(sl_phy_params, fp, rxdataF, false); + ue->adjust_rxgain = nr_sl_psbch_rsrp_measurements(sl_phy_params, fp, rxdataF, false); LOG_D(NR_PHY, " ------ Decode SL-MIB: frame.slot %d.%d ------ \n", frame_rx % 1024, nr_slot_rx); diff --git a/radio/USRP/usrp_lib.cpp b/radio/USRP/usrp_lib.cpp index 8cc4a5b2ee..71da4da167 100644 --- a/radio/USRP/usrp_lib.cpp +++ b/radio/USRP/usrp_lib.cpp @@ -869,7 +869,8 @@ int trx_usrp_set_gains(openair0_device *device, if (openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] > gain_range.stop()) { LOG_E(HW,"RX Gain 0 too high, reduce by %f dB\n", openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] - gain_range.stop()); - exit(-1); + int gain_diff = gain_range.stop() - (openair0_cfg[0].rx_gain[0] - openair0_cfg[0].rx_gain_offset[0]); + return gain_diff; } s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]); @@ -1424,25 +1425,27 @@ extern "C" { } for(int i=0; i<((int) s->usrp->get_rx_num_channels()); i++) { - if (iusrp->set_rx_rate(openair0_cfg[0].sample_rate,i+choffset); - uhd::tune_request_t rx_tune_req(openair0_cfg[0].rx_freq[i], - openair0_cfg[0].tune_offset); + openair0_config_t *cfg = &openair0_cfg[0]; + if (i < cfg->rx_num_channels) { + s->usrp->set_rx_rate(cfg->sample_rate, i + choffset); + uhd::tune_request_t rx_tune_req(cfg->rx_freq[i], cfg->tune_offset); s->usrp->set_rx_freq(rx_tune_req, i+choffset); - set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust); + set_rx_gain_offset(cfg, i, bw_gain_adjust); ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(i+choffset); // limit to maximum gain - double gain=openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i]; + double gain = cfg->rx_gain[i] - cfg->rx_gain_offset[i]; if ( gain > gain_range.stop()) { - LOG_E(HW,"RX Gain too high, lower by %f dB\n", - gain - gain_range.stop()); - gain=gain_range.stop(); + LOG_E(HW, "RX Gain too high, lower by %f dB\n", gain - gain_range.stop()); + gain = gain_range.stop(); } - s->usrp->set_rx_gain(gain,i+choffset); - LOG_I(HW,"RX Gain %d %f (%f) => %f (max %f)\n",i, - openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i], - openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],gain_range.stop()); + LOG_I(HW, + "RX Gain %d %f (%f) => %f (max %f)\n", + i, + cfg->rx_gain[i], + cfg->rx_gain_offset[i], + cfg->rx_gain[i] - cfg->rx_gain_offset[i], + gain_range.stop()); } } From c78b8dda5611cdb639c24a5f2ef13f71325a6ea6 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 24 Jul 2024 10:29:02 +0200 Subject: [PATCH 11/38] Fix memory leak in PDU Session Setup Request * fill_DRB_configList_e1 is filling `DRB_configList->list` then passing to PDCP * the contents of the struct are allocated but seem not to be freed * the following mem leak was detected by ASAN ``` Direct leak of 32 byte(s) in 1 object(s) allocated from: *0 0x7ffff74b4c38 in __interceptor_realloc /src/libsanitizer/asan/asan_malloc_linux.cpp:164 *1 0x55555caa6a3e in asn_set_add /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/asn_SET_OF.c:27 *2 0x55555c8b8bb6 in fill_DRB_configList_e1 /openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c:42 *3 0x55555c8be6eb in e1_bearer_context_setup /openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c:189 *4 0x55555d329668 in cucp_cuup_bearer_context_setup_direct /openair2/RRC/NR/cucp_cuup_direct.c:31 *5 0x55555b9a2c37 in trigger_bearer_setup /openair2/RRC/NR/rrc_gNB_NGAP.c:437 *6 0x55555b9b54bf in rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ /openair2/RRC/NR/rrc_gNB_NGAP.c:830 *7 0x55555b936871 in rrc_gnb_task /openair2/RRC/NR/rrc_gNB.c:2428 *8 0x7ffff5e94ac2 in start_thread nptl/pthread_create.c:442 ``` * using ASN_STRUCT_RESET to free the memory used by the members of the structure without freeing the structure pointer which is allocated on the stack --- openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c index 414edb052b..0cccdbcb6c 100644 --- a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c +++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c @@ -196,6 +196,7 @@ void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) cu_up_ue_id, &DRB_configList, &security_parameters); + ASN_STRUCT_RESET(asn_DEF_NR_DRB_ToAddModList, &DRB_configList.list); if (f1inst >= 0) { /* we have F1(-U) */ teid_t dummy_teid = 0xffff; // we will update later with answer from DU in_addr_t dummy_address = {0}; // IPv4, updated later with answer from DU From 2d6aef51837b183cb6f8bfe0d6de18047a06601a Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 24 Jul 2024 10:41:46 +0200 Subject: [PATCH 12/38] Fix memory leak in PDU Session Setup Request decoding * aper_decode allocates memory for for local pointer `pdusessionTransfer`, in `decodePDUSessionResourceSetup` * this memory seems not to be freed but its members are by: `ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer,pdusessionTransfer);` which btw in its header says: "AVOID using it in the application code; Use a safer ASN_STRUCT_RESET() instead" * the following mem leak was detected by ASAN: ``` Direct leak of 72 byte(s) in 1 object(s) allocated from: *0 0x7ffff74b4a57 in __interceptor_calloc /src/libsanitizer/asan/asan_malloc_linux.cpp:154 *1 0x55555cb306df in SEQUENCE_decode_aper /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_SEQUENCE_aper.c:36 *2 0x55555ca9fa28 in aper_decode /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/aper_decoder.c:78 *3 0x55555b99bae6 in decodePDUSessionResourceSetup /openair2/RRC/NR/rrc_gNB_NGAP.c:273 *4 0x55555b99fec2 in trigger_bearer_setup /openair2/RRC/NR/rrc_gNB_NGAP.c:357 *5 0x55555b9b54bf in rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ /openair2/RRC/NR/rrc_gNB_NGAP.c:830 *6 0x55555b936871 in rrc_gnb_task /openair2/RRC/NR/rrc_gNB.c:2428 *7 0x7ffff5e94ac2 in start_thread nptl/pthread_create.c:442 ``` * This commit replaces ASN_STRUCT_FREE_CONTENTS_ONLY with ASN_STRUCT_FREE, which will free the memory allocated for the entire struct and its members --- openair2/RRC/NR/rrc_gNB_NGAP.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index e1395ce6cd..dc69091383 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -335,7 +335,7 @@ static int decodePDUSessionResourceSetup(pdusession_t *session) return -1; } } - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer,pdusessionTransfer ); + ASN_STRUCT_FREE(asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer, pdusessionTransfer); return 0; } From 2cb6fd089041dfae6a36ad380e6ffab5cf044ca9 Mon Sep 17 00:00:00 2001 From: Xin Zhe Khooi Date: Sat, 18 May 2024 13:05:07 +0000 Subject: [PATCH 13/38] Stubs for F1 Reset --- openair2/COMMON/f1ap_messages_def.h | 4 +++ openair2/COMMON/f1ap_messages_types.h | 30 +++++++++++++++++++ openair2/F1AP/f1ap_cu_interface_management.c | 6 ++-- openair2/F1AP/f1ap_cu_interface_management.h | 6 ++-- openair2/F1AP/f1ap_cu_task.c | 4 +++ openair2/F1AP/f1ap_du_interface_management.c | 5 ++-- openair2/F1AP/f1ap_du_interface_management.h | 4 +-- openair2/F1AP/f1ap_du_task.c | 4 +++ openair2/F1AP/f1ap_handlers.c | 5 +++- .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 12 ++++++++ .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h | 2 ++ openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h | 3 ++ .../LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c | 14 +++++++++ openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c | 13 ++++++++ openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 ++ openair2/RRC/NR/mac_rrc_dl.h | 3 ++ openair2/RRC/NR/mac_rrc_dl_direct.c | 14 +++++++++ openair2/RRC/NR/mac_rrc_dl_f1ap.c | 14 +++++++++ openair2/RRC/NR/nr_rrc_defs.h | 2 ++ 19 files changed, 136 insertions(+), 11 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h index 9177ed9001..405ecae3d5 100644 --- a/openair2/COMMON/f1ap_messages_def.h +++ b/openair2/COMMON/f1ap_messages_def.h @@ -23,6 +23,10 @@ /* To setup F1 at DU */ MESSAGE_DEF(F1AP_DU_REGISTER_REQ, MESSAGE_PRIORITY_MED, f1ap_du_register_req_t, f1ap_du_register_req) +/* RESET */ +MESSAGE_DEF(F1AP_RESET, MESSAGE_PRIORITY_MED, f1ap_reset_t, f1ap_reset) +MESSAGE_DEF(F1AP_RESET_ACK, MESSAGE_PRIORITY_MED, f1ap_reset_ack_t, f1ap_reset_ack) + /* eNB_DU application layer -> F1AP messages or CU F1AP -> RRC*/ MESSAGE_DEF(F1AP_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_setup_req_t , f1ap_setup_req) MESSAGE_DEF(F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE , MESSAGE_PRIORITY_MED, f1ap_gnb_cu_configuration_update_acknowledge_t , f1ap_gnb_cu_configuration_update_acknowledge) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 8ec4613327..3b6082e221 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -34,6 +34,9 @@ #define F1AP_DU_REGISTER_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_du_register_req +#define F1AP_RESET(mSGpTR) (mSGpTR)->ittiMsg.f1ap_reset +#define F1AP_RESET_ACK(mSGpTR) (mSGpTR)->ittiMsg.f1ap_reset_ack + #define F1AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_setup_req #define F1AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_setup_resp #define F1AP_GNB_CU_CONFIGURATION_UPDATE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_cu_configuration_update @@ -78,6 +81,8 @@ #define F1AP_MAX_NO_OF_TNL_ASSOCIATIONS 32 #define F1AP_MAX_NO_UE_ID 1024 +#define F1AP_MAX_NO_OF_INDIVIDUAL_CONNECTIONS_TO_RESET 65536 + typedef net_ip_address_t f1ap_net_ip_address_t; typedef struct f1ap_net_config_t { @@ -534,4 +539,29 @@ typedef struct f1ap_lost_connection_t { int dummy; } f1ap_lost_connection_t; +typedef enum F1AP_ResetType_e { + F1AP_RESET_ALL, + F1AP_RESET_PART_OF_F1_INTERFACE +} f1ap_ResetType_t; + +typedef struct f1ap_reset_t { + uint64_t transaction_id; + f1ap_Cause_t cause; + long cause_value; + f1ap_ResetType_t reset_type; + struct { + uint32_t gNB_CU_ue_id; + uint32_t gNB_DU_ue_id; + } ue_to_reset[F1AP_MAX_NO_OF_INDIVIDUAL_CONNECTIONS_TO_RESET]; +} f1ap_reset_t; + +typedef struct f1ap_reset_ack_t { + uint64_t transaction_id; + struct { + uint32_t gNB_CU_ue_id; + uint32_t gNB_DU_ue_id; + } ue_to_reset[F1AP_MAX_NO_OF_INDIVIDUAL_CONNECTIONS_TO_RESET]; + uint16_t criticality_diagnostics; +} f1ap_reset_ack_t; + #endif /* F1AP_MESSAGES_TYPES_H_ */ diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index 360a2323aa..2e73172e2b 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -35,12 +35,12 @@ #include "f1ap_itti_messaging.h" #include "f1ap_cu_interface_management.h" -int CU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset) +int CU_send_RESET(sctp_assoc_t assoc_id, const f1ap_reset_t *reset) { AssertFatal(1==0,"Not implemented yet\n"); } -int CU_handle_RESET_ACKKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) +int CU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { AssertFatal(1==0,"Not implemented yet\n"); } @@ -50,7 +50,7 @@ int CU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, AssertFatal(1==0,"Not implemented yet\n"); } -int CU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge) +int CU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack) { AssertFatal(1==0,"Not implemented yet\n"); } diff --git a/openair2/F1AP/f1ap_cu_interface_management.h b/openair2/F1AP/f1ap_cu_interface_management.h index f506b83152..11a45868e1 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.h +++ b/openair2/F1AP/f1ap_cu_interface_management.h @@ -36,10 +36,10 @@ /* * Reset */ -int CU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset); -int CU_handle_RESET_ACKKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); +int CU_send_RESET(sctp_assoc_t assoc_id, const f1ap_reset_t *reset); +int CU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int CU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int CU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge); +int CU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack); /* * Error Indication diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index 3d8061b961..a320b92935 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -160,6 +160,10 @@ void *F1AP_CU_task(void *arg) { &received_msg->ittiMsg.sctp_data_ind); break; + case F1AP_RESET_ACK: + CU_send_RESET_ACKNOWLEDGE(assoc_id, &F1AP_RESET_ACK(received_msg)); + break; + case F1AP_SETUP_RESP: // from rrc CU_send_F1_SETUP_RESPONSE(assoc_id, &F1AP_SETUP_RESP(received_msg)); diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index 7ea710a0b4..caef18ed91 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -55,11 +55,12 @@ int DU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, AssertFatal(1==0,"Not implemented yet\n"); } -int DU_send_RESET_ACKKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge) { +int DU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack) +{ AssertFatal(1==0,"Not implemented yet\n"); } -int DU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset) +int DU_send_RESET(sctp_assoc_t assoc_id, const f1ap_reset_t *reset) { AssertFatal(1==0,"Not implemented yet\n"); } diff --git a/openair2/F1AP/f1ap_du_interface_management.h b/openair2/F1AP/f1ap_du_interface_management.h index c48754010f..f8d7eafb02 100644 --- a/openair2/F1AP/f1ap_du_interface_management.h +++ b/openair2/F1AP/f1ap_du_interface_management.h @@ -37,8 +37,8 @@ * Reset */ int DU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int DU_send_RESET_ACKKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge); -int DU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset); +int DU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack); +int DU_send_RESET(sctp_assoc_t assoc_id, const f1ap_reset_t *reset); int DU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); /* diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index 7959f734fe..ff188e52df 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -134,6 +134,10 @@ void *F1AP_DU_task(void *arg) { DUuniqInstance = gtpInst; } break; + case F1AP_RESET_ACK: + DU_send_RESET_ACKNOWLEDGE(assoc_id, &F1AP_RESET_ACK(msg)); + break; + case F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE: DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(assoc_id, &F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg)); diff --git a/openair2/F1AP/f1ap_handlers.c b/openair2/F1AP/f1ap_handlers.c index ecdda72000..bfaa9959dc 100644 --- a/openair2/F1AP/f1ap_handlers.c +++ b/openair2/F1AP/f1ap_handlers.c @@ -42,7 +42,10 @@ /* Handlers matrix. Only f1 related procedure present here */ static const f1ap_message_processing_t f1ap_messages_processing[][3] = { - {0, 0, 0}, /* Reset */ + // TODO: How to handle RESET if CU/DU has their respective handlers? + // We need to check node type and call the right handler. + {DU_handle_RESET, CU_handle_RESET_ACKNOWLEDGE, 0}, /* Reset */ + // {CU_handle_RESET, DU_handle_RESET_ACKNOWLEDGE, 0}, /* Reset */ {CU_handle_F1_SETUP_REQUEST, DU_handle_F1_SETUP_RESPONSE, DU_handle_F1_SETUP_FAILURE}, /* F1Setup */ {0, 0, 0}, /* ErrorIndication */ {CU_handle_gNB_DU_CONFIGURATION_UPDATE, 0, 0}, /* gNBDUConfigurationUpdate */ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 7353e61711..9596260163 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -95,6 +95,18 @@ static bool check_plmn_identity(const f1ap_plmn_t *check_plmn, const f1ap_plmn_t return plmn->mcc == check_plmn->mcc && plmn->mnc_digit_length == check_plmn->mnc_digit_length && plmn->mnc == check_plmn->mnc; } +void f1_reset_cu_initiated(const f1ap_reset_t *reset) +{ + (void) reset; + AssertFatal(false, "%s() not implemented yet\n", __func__); +} + +void f1_reset_acknowledge_du_initiated(const f1ap_reset_ack_t *ack) +{ + (void) ack; + AssertFatal(false, "%s() not implemented yet\n", __func__); +} + void f1_setup_response(const f1ap_setup_resp_t *resp) { LOG_I(MAC, "received F1 Setup Response from CU %s\n", resp->gNB_CU_name); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h index 7a284f2d8b..e9aceb1192 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h @@ -26,6 +26,8 @@ #include "f1ap_messages_types.h" #include "openair2/RRC/NR/MESSAGES/asn1_msg.h" +void f1_reset_cu_initiated(const f1ap_reset_t *reset); +void f1_reset_acknowledge_du_initiated(const f1ap_reset_ack_t *ack); void f1_setup_response(const f1ap_setup_resp_t *resp); void f1_setup_failure(const f1ap_setup_failure_t *failure); void gnb_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_update_acknowledge_t *ack); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h index 0d902a77c6..1e416f01f9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h @@ -25,6 +25,9 @@ #include "common/platform_types.h" #include "f1ap_messages_types.h" +typedef void (*f1_reset_du_initiated_func_t)(const f1ap_reset_t *reset); +typedef void (*f1_reset_acknowledge_cu_initiated_func_t)(const f1ap_reset_ack_t *ack); + typedef void (*f1_setup_request_func_t)(const f1ap_setup_req_t* req); typedef void (*gnb_du_configuration_update_t)(const f1ap_gnb_du_configuration_update_t *upd); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c index acef49ef5b..29a7bc8621 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -24,6 +24,18 @@ #include "mac_rrc_ul.h" +static void f1_reset_du_initiated_direct(const f1ap_reset_t *reset) +{ + (void) reset; + AssertFatal(false, "%s() not implemented yet\n", __func__); +} + +static void f1_reset_acknowledge_cu_initiated_direct(const f1ap_reset_ack_t *ack) +{ + (void) ack; + AssertFatal(false, "%s() not implemented yet\n", __func__); +} + static void f1_setup_request_direct(const f1ap_setup_req_t *req) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_SETUP_REQ); @@ -284,6 +296,8 @@ static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc) { + mac_rrc->f1_reset = f1_reset_du_initiated_direct; + mac_rrc->f1_reset_acknowledge = f1_reset_acknowledge_cu_initiated_direct; mac_rrc->f1_setup_request = f1_setup_request_direct; mac_rrc->gnb_du_configuration_update = gnb_du_configuration_update_direct; mac_rrc->ue_context_setup_response = ue_context_setup_response_direct; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index 19beddad7a..4d716e9fb7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -53,6 +53,17 @@ static f1ap_net_config_t read_DU_IP_config(const eth_params_t* f1_params, const return nc; } +static void f1_reset_du_initiated_f1ap(const f1ap_reset_t *reset) +{ + (void) reset; + AssertFatal(false, "%s() not implemented yet\n", __func__); +} + +static void f1_reset_acknowledge_cu_initiated_f1ap(const f1ap_reset_ack_t *ack) +{ + (void) ack; + AssertFatal(false, "%s() not implemented yet\n", __func__); +} static void f1_setup_request_f1ap(const f1ap_setup_req_t *req) { @@ -275,6 +286,8 @@ static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1 void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc) { + mac_rrc->f1_reset = f1_reset_du_initiated_f1ap; + mac_rrc->f1_reset_acknowledge = f1_reset_acknowledge_cu_initiated_f1ap; mac_rrc->f1_setup_request = f1_setup_request_f1ap; mac_rrc->gnb_du_configuration_update = gnb_du_configuration_update_f1ap; mac_rrc->ue_context_setup_response = ue_context_setup_response_f1ap; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 350a909088..8362a61205 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -690,6 +690,8 @@ typedef struct NR_bler_options { } NR_bler_options_t; typedef struct nr_mac_rrc_ul_if_s { + f1_reset_du_initiated_func_t f1_reset; + f1_reset_acknowledge_cu_initiated_func_t f1_reset_acknowledge; f1_setup_request_func_t f1_setup_request; gnb_du_configuration_update_t gnb_du_configuration_update; ue_context_setup_response_func_t ue_context_setup_response; diff --git a/openair2/RRC/NR/mac_rrc_dl.h b/openair2/RRC/NR/mac_rrc_dl.h index 49eb03512a..d6937591b5 100644 --- a/openair2/RRC/NR/mac_rrc_dl.h +++ b/openair2/RRC/NR/mac_rrc_dl.h @@ -25,6 +25,9 @@ #include "common/platform_types.h" #include "f1ap_messages_types.h" +typedef void (*f1_reset_cu_initiated_func_t)(sctp_assoc_t assoc_id, const f1ap_reset_t *reset); +typedef void (*f1_reset_acknowledge_du_initiated_func_t)(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack); + typedef void (*f1_setup_response_func_t)(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp); typedef void (*f1_setup_failure_func_t)(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail); typedef void (*gnb_du_configuration_update_ack_func_t)(sctp_assoc_t assoc_id, diff --git a/openair2/RRC/NR/mac_rrc_dl_direct.c b/openair2/RRC/NR/mac_rrc_dl_direct.c index 4b0afbc0e1..54ec7c8e4c 100644 --- a/openair2/RRC/NR/mac_rrc_dl_direct.c +++ b/openair2/RRC/NR/mac_rrc_dl_direct.c @@ -24,6 +24,18 @@ #include "mac_rrc_dl.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" +static void f1_reset_cu_initiated_direct(sctp_assoc_t assoc_id, const f1ap_reset_t *reset) +{ + (void)reset; + AssertFatal(false, "%s() not implemented yet\n", __func__); +} + +static void f1_reset_acknowledge_du_initiated_direct(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack) +{ + (void)ack; + AssertFatal(false, "%s() not implemented yet\n", __func__); +} + static void f1_setup_response_direct(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp) { AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); @@ -80,6 +92,8 @@ static void dl_rrc_message_transfer_direct(sctp_assoc_t assoc_id, const f1ap_dl_ void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc) { + mac_rrc->f1_reset = f1_reset_cu_initiated_direct; + mac_rrc->f1_reset_acknowledge = f1_reset_acknowledge_du_initiated_direct; mac_rrc->f1_setup_response = f1_setup_response_direct; mac_rrc->f1_setup_failure = f1_setup_failure_direct; mac_rrc->gnb_du_configuration_update_acknowledge = gnb_du_configuration_update_ack_direct; diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index 9a934cc675..439712ec7e 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -24,6 +24,18 @@ #include "mac_rrc_dl.h" #include "nr_rrc_defs.h" +static void f1_reset_cu_initiated_f1ap(sctp_assoc_t assoc_id, const f1ap_reset_t *reset) +{ + (void)reset; + AssertFatal(false, "%s() not implemented yet\n", __func__); +} + +static void f1_reset_acknowledge_du_initiated_f1ap(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack) +{ + (void)ack; + AssertFatal(false, "%s() not implemented yet\n", __func__); +} + static void f1_setup_response_f1ap(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp) { MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_SETUP_RESP); @@ -215,6 +227,8 @@ static void dl_rrc_message_transfer_f1ap(sctp_assoc_t assoc_id, const f1ap_dl_rr void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc) { + mac_rrc->f1_reset = f1_reset_cu_initiated_f1ap; + mac_rrc->f1_reset_acknowledge = f1_reset_acknowledge_du_initiated_f1ap; mac_rrc->f1_setup_response = f1_setup_response_f1ap; mac_rrc->f1_setup_failure = f1_setup_failure_f1ap; mac_rrc->gnb_du_configuration_update_acknowledge = gnb_du_configuration_update_ack_f1ap; diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 961406986a..a9234ed5bd 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -398,6 +398,8 @@ typedef struct neighbour_cell_configuration_s { } neighbour_cell_configuration_t; typedef struct nr_mac_rrc_dl_if_s { + f1_reset_cu_initiated_func_t f1_reset; + f1_reset_acknowledge_du_initiated_func_t f1_reset_acknowledge; f1_setup_response_func_t f1_setup_response; f1_setup_failure_func_t f1_setup_failure; gnb_du_configuration_update_ack_func_t gnb_du_configuration_update_acknowledge; From 03c2f6277dbc2fb569afc41d72347d2864887871 Mon Sep 17 00:00:00 2001 From: Xin Zhe Khooi Date: Tue, 21 May 2024 02:46:07 +0000 Subject: [PATCH 14/38] Implement encoder/decoder for F1 Reset at DU --- openair2/F1AP/f1ap_du_interface_management.c | 104 ++++++++++++++++++- 1 file changed, 102 insertions(+), 2 deletions(-) diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index caef18ed91..eec39ee7fc 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -52,12 +52,112 @@ int to_NRNRB(int nrb) { int DU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { - AssertFatal(1==0,"Not implemented yet\n"); + LOG_D(F1AP, "DU_handle_RESET\n");\ + F1AP_Reset_t *container; + F1AP_ResetIEs_t *ie; + DevAssert(pdu != NULL); + container = &pdu->choice.initiatingMessage->value.choice.Reset; + + /* Reset == Non UE-related procedure -> stream 0 */ + if (stream != 0) { + LOG_W(F1AP, "[SCTP %d] Received Reset on stream != 0 (%d)\n", + assoc_id, stream); + } + + MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_RESET); + msg_p->ittiMsgHeader.originInstance = assoc_id; + f1ap_reset_t *f1ap_reset = &F1AP_RESET(msg_p); + + /* Transaction ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ResetIEs_t, ie, container, F1AP_ProtocolIE_ID_id_TransactionID, true); + f1ap_reset->transaction_id = ie->value.choice.TransactionID; + LOG_D(F1AP, "req->transaction_id %lu \n", f1ap_reset->transaction_id); + + /* Cause */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ResetIEs_t, ie, container, F1AP_ProtocolIE_ID_id_Cause, true); + switch(ie->value.choice.Cause.present) + { + case F1AP_Cause_PR_radioNetwork: + LOG_D(F1AP, "Cause: Radio Network\n"); + f1ap_reset->cause = F1AP_CAUSE_RADIO_NETWORK; + f1ap_reset->cause_value = ie->value.choice.Cause.choice.radioNetwork; + break; + case F1AP_Cause_PR_transport: + LOG_D(F1AP, "Cause: Transport\n"); + f1ap_reset->cause = F1AP_CAUSE_TRANSPORT; + f1ap_reset->cause_value = ie->value.choice.Cause.choice.transport; + break; + case F1AP_Cause_PR_protocol: + LOG_D(F1AP, "Cause: Protocol\n"); + f1ap_reset->cause = F1AP_CAUSE_PROTOCOL; + f1ap_reset->cause_value = ie->value.choice.Cause.choice.protocol; + break; + case F1AP_Cause_PR_misc: + LOG_D(F1AP, "Cause: Misc\n"); + f1ap_reset->cause = F1AP_CAUSE_MISC; + f1ap_reset->cause_value = ie->value.choice.Cause.choice.misc; + break; + default: + AssertFatal(1==0,"Unknown cause\n"); + } + + /* ResetType */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ResetIEs_t, ie, container, F1AP_ProtocolIE_ID_id_ResetType, true); + switch(ie->value.choice.ResetType.present) { + case F1AP_ResetType_PR_f1_Interface: + LOG_D(F1AP, "ResetType: F1 Interface\n"); + f1ap_reset->reset_type = F1AP_RESET_ALL; + break; + case F1AP_ResetType_PR_partOfF1_Interface: + LOG_D(F1AP, "ResetType: Part of F1 Interface\n"); + f1ap_reset->reset_type = F1AP_RESET_PART_OF_F1_INTERFACE; + break; + default: + AssertFatal(1==0,"Unknown reset type\n"); + } + + /* Part of F1 Interface */ + if (f1ap_reset->reset_type == F1AP_RESET_PART_OF_F1_INTERFACE) { + AssertFatal(1==0, "Not implemented yet\n"); + } + + f1_reset_cu_initiated(f1ap_reset); + return 0; } int DU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack) { - AssertFatal(1==0,"Not implemented yet\n"); + F1AP_F1AP_PDU_t pdu= {0}; + uint8_t *buffer; + uint32_t len; + /* Create */ + /* 0. pdu Type */ + pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome; + asn1cCalloc(pdu.choice.successfulOutcome, successMsg); + successMsg->procedureCode = F1AP_ProcedureCode_id_Reset; + successMsg->criticality = F1AP_Criticality_reject; + successMsg->value.present = F1AP_SuccessfulOutcome__value_PR_ResetAcknowledge; + F1AP_ResetAcknowledge_t *f1ResetAcknowledge = &successMsg->value.choice.ResetAcknowledge; + /* mandatory */ + /* c1. Transaction ID (integer value) */ + asn1cSequenceAdd(f1ResetAcknowledge->protocolIEs.list, F1AP_ResetAcknowledgeIEs_t, ieC1); + ieC1->id = F1AP_ProtocolIE_ID_id_TransactionID; + ieC1->criticality = F1AP_Criticality_reject; + ieC1->value.present = F1AP_ResetAcknowledgeIEs__value_PR_TransactionID; + ieC1->value.choice.TransactionID = ack->transaction_id; + + /* TODO: (Optional) partialF1Interface, criticality diagnostics */ + + /* encode */ + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1ResetAcknowledge\n"); + return -1; + } + + /* send */ + ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); + return 0; } int DU_send_RESET(sctp_assoc_t assoc_id, const f1ap_reset_t *reset) From a92ab368f223699225ba675c21e6c6b485c25ee6 Mon Sep 17 00:00:00 2001 From: Xin Zhe Khooi Date: Thu, 25 Jul 2024 13:37:38 +0000 Subject: [PATCH 15/38] Decouple UEContextReleaseComplete message generation from MAC UE release The next commit implements the release of all UEs following the F1 Reset message. It uses nr_mac_release_ue(), which as of now, triggered a release complete message automatically, which we don't want in the case of F1 Reset. This commit refactors the code to split UE release at MAC/RLC and release complete message sending to allow to release UEs without sending the complete. Corresponding users are updated. --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 1 + .../NR_MAC_gNB/gNB_scheduler_primitives.c | 46 +++++++++++-------- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 1 + .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 1 + 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 200a21258e..495eb30eef 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -2190,6 +2190,7 @@ void nr_schedule_RA(module_id_t module_idP, if (ra->contention_resolution_timer < 0) { LOG_W(NR_MAC, "(%d.%d) RA Contention Resolution timer expired for UE 0x%04x, RA procedure failed...\n", frameP, slotP, ra->rnti); nr_mac_release_ue(mac, ra->rnti); + nr_mac_trigger_release_complete(mac, ra->rnti); nr_clear_ra_proc(ra); continue; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 4c67bfdf35..5728f6bb3f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -3013,32 +3013,36 @@ int nr_mac_enable_ue_rrc_processing_timer(gNB_MAC_INST *mac, NR_UE_info_t *UE, b return 0; } +void nr_mac_trigger_release_complete(gNB_MAC_INST *mac, int rnti) +{ + // the CU might not know such UE, e.g., because we never sent a message to + // it, so there might not be a corresponding entry for such UE in the look up + // table. This can happen, e.g., on Msg.3 with C-RNTI, where we create a UE + // MAC context, decode the PDU, find the C-RNTI MAC CE, and then throw the + // newly created context away. See also in _nr_rx_sdu() and commit 93f59a3c6e56f + if (!du_exists_f1_ue_data(rnti)) + return; + + // unlock the scheduler temporarily to prevent possible deadlocks with + // du_remove_f1_ue_data() (and also while sending the message to RRC) + NR_SCHED_UNLOCK(&mac->sched_lock); + f1_ue_data_t ue_data = du_get_f1_ue_data(rnti); + f1ap_ue_context_release_complete_t complete = { + .gNB_CU_ue_id = ue_data.secondary_ue, + .gNB_DU_ue_id = rnti, + }; + mac->mac_rrc.ue_context_release_complete(&complete); + + du_remove_f1_ue_data(rnti); + NR_SCHED_LOCK(&mac->sched_lock); +} + void nr_mac_release_ue(gNB_MAC_INST *mac, int rnti) { NR_SCHED_ENSURE_LOCKED(&mac->sched_lock); nr_rlc_remove_ue(rnti); mac_remove_nr_ue(mac, rnti); - - // the CU might not know such UE, e.g., because we never sent a message to - // it, so there might not be a corresponding entry for such UE in the look up - // table. This can happen, e.g., on Msg.3 with C-RNTI, where we create a UE - // MAC context, decode the PDU, find the C-RNTI MAC CE, and then throw the - // newly created context away. See also in _nr_rx_sdu() and commit 93f59a3c6e56f - if (du_exists_f1_ue_data(rnti)) { - // unlock the scheduler temporarily to prevent possible deadlocks with - // du_remove_f1_ue_data() (and also while sending the message to RRC) - NR_SCHED_UNLOCK(&mac->sched_lock); - f1_ue_data_t ue_data = du_get_f1_ue_data(rnti); - f1ap_ue_context_release_complete_t complete = { - .gNB_CU_ue_id = ue_data.secondary_ue, - .gNB_DU_ue_id = rnti, - }; - mac->mac_rrc.ue_context_release_complete(&complete); - - du_remove_f1_ue_data(rnti); - NR_SCHED_LOCK(&mac->sched_lock); - } } void nr_mac_update_timers(module_id_t module_id, @@ -3055,6 +3059,8 @@ void nr_mac_update_timers(module_id_t module_id, NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; if (nr_mac_check_release(sched_ctrl, UE->rnti)) { + // trigger release first as nr_mac_release_ue() invalidates UE ptr + nr_mac_trigger_release_complete(mac, UE->rnti); nr_mac_release_ue(mac, UE->rnti); // go back to examine the next UE, which is at the position the // current UE was diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 84f06c873c..938d5cf27b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -438,6 +438,7 @@ void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid); void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing); bool nr_mac_check_release(NR_UE_sched_ctrl_t *sched_ctrl, int rnti); +void nr_mac_trigger_release_complete(gNB_MAC_INST *mac, int rnti); void nr_mac_release_ue(gNB_MAC_INST *mac, int rnti); void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 9596260163..d47392491b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -627,6 +627,7 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) if (UE->UE_sched_ctrl.ul_failure || cmd->rrc_container_length == 0) { /* The UE is already not connected anymore or we have nothing to forward*/ nr_mac_release_ue(mac, cmd->gNB_DU_ue_id); + nr_mac_trigger_release_complete(mac, cmd->gNB_DU_ue_id); } else { /* UE is in sync: forward release message and mark to be deleted * after UL failure */ From 23a865db77d84121f055e21b8caf73b60f47b57b Mon Sep 17 00:00:00 2001 From: Xin Zhe Khooi Date: Tue, 21 May 2024 02:46:35 +0000 Subject: [PATCH 16/38] Implement DU F1 Reset handlers --- .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 38 ++++++++++++++++++- openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c | 6 ++- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index d47392491b..aac03be132 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -95,10 +95,44 @@ static bool check_plmn_identity(const f1ap_plmn_t *check_plmn, const f1ap_plmn_t return plmn->mcc == check_plmn->mcc && plmn->mnc_digit_length == check_plmn->mnc_digit_length && plmn->mnc == check_plmn->mnc; } +static void du_clear_all_ue_states() +{ + gNB_MAC_INST *mac = RC.nrmac[0]; + NR_SCHED_LOCK(&mac->sched_lock); + + NR_UE_info_t *UE = *mac->UE_info.list; + + instance_t f1inst = get_f1_gtp_instance(); + + while (UE != NULL) { + int rnti = UE->rnti; + nr_mac_release_ue(mac, rnti); + // free all F1 contexts + if (du_exists_f1_ue_data(rnti)) + du_remove_f1_ue_data(rnti); + newGtpuDeleteAllTunnels(f1inst, rnti); + UE = *mac->UE_info.list; + } + NR_SCHED_UNLOCK(&mac->sched_lock); +} + void f1_reset_cu_initiated(const f1ap_reset_t *reset) { - (void) reset; - AssertFatal(false, "%s() not implemented yet\n", __func__); + LOG_I(MAC, "F1 Reset initiated by CU\n"); + + f1ap_reset_ack_t ack = {0}; + if(reset->reset_type == F1AP_RESET_ALL) { + du_clear_all_ue_states(); + ack = (f1ap_reset_ack_t) { + .transaction_id = reset->transaction_id + }; + } else { + // reset->reset_type == F1AP_RESET_PART_OF_F1_INTERFACE + AssertFatal(1==0, "Not implemented yet\n"); + } + + gNB_MAC_INST *mac = RC.nrmac[0]; + mac->mac_rrc.f1_reset_acknowledge(&ack); } void f1_reset_acknowledge_du_initiated(const f1ap_reset_ack_t *ack) diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index 4d716e9fb7..742f85c390 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -61,8 +61,10 @@ static void f1_reset_du_initiated_f1ap(const f1ap_reset_t *reset) static void f1_reset_acknowledge_cu_initiated_f1ap(const f1ap_reset_ack_t *ack) { - (void) ack; - AssertFatal(false, "%s() not implemented yet\n", __func__); + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_RESET_ACK); + f1ap_reset_ack_t *f1ap_msg = &F1AP_RESET_ACK(msg); + *f1ap_msg = *ack; + itti_send_msg_to_task(TASK_DU_F1, 0, msg); } static void f1_setup_request_f1ap(const f1ap_setup_req_t *req) From 48d68f7d90da773aedc1a4bf1d892df073d915b0 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Wed, 17 Jul 2024 22:29:24 +0200 Subject: [PATCH 17/38] Fix a bug where if BWP size is not exactly maximum BWP size for a bandwidth power control code asserts. This assert and assumption is incorrect, according to 38.101-1 UE channel is defined only by the BWP size and BWP size can be any value supported by the RRC parameters defining the BWP. To determine the UE channel the smallest bandwidth supporting the BWP is selected. This is an assumption based on references in the same document to UE channel bandwidth being equal to one of the values in set {5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 90, 100}. Also: - calculated P_CMIN during BWP setup since the parameter doesn't depend on DCI. - initiialize uniqCfg structure in test_nr_ue_power_procedures main function which enables LOG prints during tests --- common/utils/nr/nr_common.c | 72 +++++++------------ common/utils/nr/nr_common.h | 5 +- openair1/PHY/INIT/nr_init.c | 4 +- openair1/SIMULATION/NR_PHY/pbchsim.c | 5 +- openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 4 ++ openair2/LAYER2/NR_MAC_UE/config_ue.c | 35 +++++---- openair2/LAYER2/NR_MAC_UE/config_ue_sl.c | 3 +- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 3 +- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 1 + .../LAYER2/NR_MAC_UE/nr_ue_power_procedures.c | 30 +++++--- .../tests/test_nr_ue_power_procedures.cpp | 46 +++++++++--- openair2/LAYER2/NR_MAC_gNB/config.c | 18 +++-- openair2/RRC/NR/nr_rrc_config.c | 2 +- 13 files changed, 133 insertions(+), 95 deletions(-) diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 2d7e4ce02f..c1ed6c7546 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -105,6 +105,16 @@ int get_supported_band_index(int scs, frequency_range_t freq_range, int n_rbs) return (-1); // not found } +int get_smallest_supported_bandwidth_index(int scs, frequency_range_t frequency_range, int n_rbs) +{ + int scs_index = scs + frequency_range; + for (int i = 0; i < 12; i++) { + if (n_rbs <= tables_5_3_2[scs_index][i]) + return i; + } + return -1; // not found +} + // Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101) // Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101) // Notes: @@ -299,64 +309,30 @@ void check_ssb_raster(uint64_t freq, int band, int scs) band); } -int get_supported_bw_mhz(frequency_range_t frequency_range, int scs, int nb_rb) +int get_supported_bw_mhz(frequency_range_t frequency_range, int bw_index) { - int bw_index = get_supported_band_index(scs, frequency_range, nb_rb); if (frequency_range == FR1) { - switch (bw_index) { - case 0 : - return 5; // 5MHz - case 1 : - return 10; - case 2 : - return 15; - case 3 : - return 20; - case 4 : - return 25; - case 5 : - return 30; - case 6 : - return 40; - case 7 : - return 50; - case 8 : - return 60; - case 9 : - return 80; - case 10 : - return 90; - case 11 : - return 100; - default : - AssertFatal(false, "Invalid band index for FR1 %d\n", bw_index); - } - } - else { - switch (bw_index) { - case 0 : - return 50; // 50MHz - case 1 : - return 100; - case 2 : - return 200; - case 3 : - return 400; - default : - AssertFatal(false, "Invalid band index for FR2 %d\n", bw_index); - } + int bandwidth_index_to_mhz[] = {5, 10, 15, 20, 25, 30, 40, 50, 60, 80, 90, 100}; + AssertFatal(bw_index >= 0 && bw_index <= sizeofArray(bandwidth_index_to_mhz), + "Bandwidth index %d is invalid\n", + bw_index); + return bandwidth_index_to_mhz[bw_index]; + } else { + int bandwidth_index_to_mhz[] = {50, 100, 200, 400}; + AssertFatal(bw_index >= 0 && bw_index <= sizeofArray(bandwidth_index_to_mhz), + "Bandwidth index %d is invalid\n", + bw_index); + return bandwidth_index_to_mhz[bw_index]; } } -bool compare_relative_ul_channel_bw(int nr_band, int scs, int nb_ul, frame_type_t frame_type) +bool compare_relative_ul_channel_bw(int nr_band, int scs, int channel_bandwidth, frame_type_t frame_type) { // 38.101-1 section 6.2.2 // Relative channel bandwidth <= 4% for TDD bands and <= 3% for FDD bands int index = get_nr_table_idx(nr_band, scs); - - int band_size_khz = get_supported_bw_mhz(nr_band > 256 ? FR2 : FR1, scs, nb_ul) * 1000; float limit = frame_type == TDD ? 0.04 : 0.03; - float rel_bw = (float) (band_size_khz) / (float) (nr_bandtable[index].ul_max - nr_bandtable[index].ul_min); + float rel_bw = (float) (2 * channel_bandwidth * 1000) / (float) (nr_bandtable[index].ul_max - nr_bandtable[index].ul_min); return rel_bw > limit; } diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 6ed86cb7bd..d65344b27d 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -224,8 +224,8 @@ int get_dmrs_port(int nl, uint16_t dmrs_ports); uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols); int get_nb_periods_per_frame(uint8_t tdd_period); long rrc_get_max_nr_csrs(const int max_rbs, long b_SRS); -bool compare_relative_ul_channel_bw(int nr_band, int scs, int nb_ul, frame_type_t frame_type); -int get_supported_bw_mhz(frequency_range_t frequency_range, int scs, int nb_rb); +bool compare_relative_ul_channel_bw(int nr_band, int scs, int channel_bandwidth, frame_type_t frame_type); +int get_supported_bw_mhz(frequency_range_t frequency_range, int bw_index); int get_supported_band_index(int scs, frequency_range_t freq_range, int n_rbs); void get_samplerate_and_bw(int mu, int n_rb, @@ -248,6 +248,7 @@ int get_scan_ssb_first_sc(const double fc, nr_gscn_info_t ssbStartSC[MAX_GSCN_BAND]); void check_ssb_raster(uint64_t freq, int band, int scs); +int get_smallest_supported_bandwidth_index(int scs, frequency_range_t frequency_range, int n_rbs); #define CEILIDIV(a,b) ((a+b-1)/b) #define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1)) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index e95451fcd8..a461d46142 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -518,7 +518,9 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, } fp->threequarter_fs = 0; - gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(fp->nr_band > 256 ? FR2 : FR1, mu, N_RB_DL); + frequency_range_t frequency_range = fp->nr_band > 256 ? FR2 : FR1; + int bw_index = get_supported_band_index(mu, frequency_range, N_RB_DL); + gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index); nr_init_frame_parms(gNB_config, fp); diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 63546246f0..f77d9e7e3e 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -161,8 +161,9 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB, if (mu>2) fp->nr_band = 257; else fp->nr_band = 78; fp->threequarter_fs= 0; - - gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(fp->nr_band > 256 ? FR2 : FR1, mu, N_RB_DL); + frequency_range_t frequency_range = fp->nr_band > 256 ? FR2 : FR1; + int bw_index = get_supported_band_index(mu, frequency_range, N_RB_DL); + gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index); fp->ofdm_offset_divisor = UINT_MAX; nr_init_frame_parms(gNB_config, fp); diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index d141215846..fa98a7ecac 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -573,6 +573,10 @@ typedef struct NR_UE_UL_BWP { nr_dci_format_t dci_format; int max_fb_time; long *p0_NominalWithGrant; + // UE Channel bandwidth according to 38.101 5.3.2 + int channel_bandwidth; + // Minimum transmission power according to 38.101 6.3.1 + float P_CMIN; } NR_UE_UL_BWP_t; // non-BWP serving cell configuration diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index c6c69311f7..e28f7dce93 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -118,9 +118,11 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, NR_FrequencyInfoDL_SIB_t *frequencyInfoDL = &scc->downlinkConfigCommon.frequencyInfoDL; AssertFatal(frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR, "Field mandatory present for DL in SIB1\n"); mac->nr_band = *frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR; - cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, - frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); + + int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, + mac->frequency_range, + frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); + cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index); uint64_t dl_bw_khz = (12 * frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth) * (15 << frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing); @@ -139,9 +141,11 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, NR_FrequencyInfoUL_SIB_t *frequencyInfoUL = &scc->uplinkConfigCommon->frequencyInfoUL; mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN; - cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, - frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); + + bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, + mac->frequency_range, + frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); + cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index); if (frequencyInfoUL->absoluteFrequencyPointA == NULL) cfg->carrier_config.uplink_frequency = cfg->carrier_config.dl_frequency; @@ -260,9 +264,10 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, mac->frame_type = get_frame_type(mac->nr_band, get_softmodem_params()->numerology); mac->frequency_range = mac->nr_band < 256 ? FR1 : FR2; - cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, - frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); + int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, + mac->frequency_range, + frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); + cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index); cfg->carrier_config.dl_frequency = from_nrarfcn(mac->nr_band, *scc->ssbSubcarrierSpacing, @@ -284,9 +289,10 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_FrequencyInfoUL_t *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL; mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN; - cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, - frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); + int bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, + mac->frequency_range, + frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); + cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index); long *UL_pointA = NULL; if (frequencyInfoUL->absoluteFrequencyPointA) @@ -1488,6 +1494,11 @@ static void configure_common_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Up bwp->cyclicprefix = ul_genericParameters->cyclicPrefix; bwp->BWPSize = NRRIV2BW(ul_genericParameters->locationAndBandwidth, MAX_BWP_SIZE); bwp->BWPStart = NRRIV2PRBOFFSET(ul_genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + // For power calculations assume the UE channel is the smallest channel that can support the BWP + int bw_index = get_smallest_supported_bandwidth_index(bwp->scs, mac->frequency_range, bwp->BWPSize); + bwp->channel_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index); + // Minumum transmission power depends on bandwidth, precalculate it here + bwp->P_CMIN = nr_get_Pcmin(bw_index); if (bwp_id == 0) { mac->sc_info.initial_ul_BWPSize = bwp->BWPSize; mac->sc_info.initial_ul_BWPStart = bwp->BWPStart; diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c b/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c index 04cf626a54..babdd96f10 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c @@ -138,7 +138,8 @@ static void sl_prepare_phy_config(int module_id, AssertFatal(carriercfg, "SCS_SpecificCarrier cannot be NULL"); - phycfg->sl_carrier_config.sl_bandwidth = get_supported_bw_mhz(FR1, carriercfg->subcarrierSpacing, carriercfg->carrierBandwidth); + int bw_index = get_supported_band_index(carriercfg->subcarrierSpacing, FR1, carriercfg->carrierBandwidth); + phycfg->sl_carrier_config.sl_bandwidth = get_supported_bw_mhz(FR1, bw_index); phycfg->sl_carrier_config.sl_frequency = from_nrarfcn(sl_band,carriercfg->subcarrierSpacing,pointA_ARFCN); // freq in kHz diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index d4a6bcfb7d..396294fc97 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -248,6 +248,7 @@ float nr_get_Pcmax(int p_Max, uint16_t nr_band, frame_type_t frame_type, frequency_range_t frequency_range, + int channel_bandwidth_index, int Qm, bool powerBoostPi2BPSK, int scs, @@ -256,7 +257,7 @@ float nr_get_Pcmax(int p_Max, int n_prbs, int start_prb); -float nr_get_Pcmin(int scs, int nr_band, int N_RB_UL); +float nr_get_Pcmin(int bandwidth_index); int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index dfe1c86e72..9264e4ad16 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -91,6 +91,7 @@ void init_RA(NR_UE_MAC_INST_t *mac, mac->nr_band, mac->frame_type, mac->frequency_range, + mac->current_UL_BWP->channel_bandwidth, 2, false, prach_scs, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c index 01bf59b56f..de16ba3d6a 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c @@ -66,16 +66,16 @@ static int get_deltatf(uint16_t nb_of_prbs, int O_UCI); // ∆MPR according to Table 6.2.2-3 38.101-1 -static float get_delta_mpr(uint16_t nr_band, frame_type_t frame_type, int scs, int N_RB_UL, int n_prbs, int start_prb, int power_class) +static float get_delta_mpr(uint16_t nr_band, frame_type_t frame_type, int scs, int channel_bandwidth, int n_prbs, int start_prb, int power_class) { - if (compare_relative_ul_channel_bw(nr_band, scs, N_RB_UL, frame_type)) { + if (compare_relative_ul_channel_bw(nr_band, scs, channel_bandwidth, frame_type)) { if (power_class == 3) { - if ((nr_band == 28 || nr_band == 83) && get_supported_bw_mhz(nr_band > 256 ? FR2 : FR1, scs, N_RB_UL) == 30) { + if ((nr_band == 28 || nr_band == 83) && channel_bandwidth == 30) { return 0.5f; } } if (power_class == 3 || power_class == 2) { - if ((nr_band == 40 || nr_band == 97) && get_supported_bw_mhz(nr_band > 256 ? FR2 : FR1, scs, N_RB_UL) == 100) { + if ((nr_band == 40 || nr_band == 97) && channel_bandwidth == 100) { return 1.0f; } } @@ -168,6 +168,7 @@ float nr_get_Pcmax(int p_Max, uint16_t nr_band, frame_type_t frame_type, frequency_range_t frequency_range, + int channel_bandwidth, int Qm, bool powerBoostPi2BPSK, int scs, @@ -197,7 +198,7 @@ float nr_get_Pcmax(int p_Max, int delta_TC = 0; float MPR = get_mpr(Qm, N_RB_UL, is_transform_precoding, n_prbs, start_prb, power_class); - float delta_MPR = get_delta_mpr(nr_band, frame_type, scs, N_RB_UL, n_prbs, start_prb, power_class); + float delta_MPR = get_delta_mpr(nr_band, frame_type, scs, channel_bandwidth, n_prbs, start_prb, power_class); int A_MPR = 0; // TODO too complicated to implement for now (see 6.2.3 in 38.101-1) int delta_rx_SRS = 0; // TODO for SRS int P_MPR = 0; // to ensure compliance with applicable electromagnetic energy absorption requirements @@ -216,7 +217,13 @@ float nr_get_Pcmax(int p_Max, } // TODO we need a strategy to select a value between minimum and maximum allowed PC_max float pcmax = (pcmax_low + pcmax_high) / 2; - LOG_D(MAC, "Configured maximum output power: %f dBm <= PCMAX %f dBm <= %f dBm \n", pcmax_low, pcmax, pcmax_high); + LOG_D(MAC, + "Configured maximum output power: %f dBm <= PCMAX %f dBm <= %f dBm MPR=%.2f deltaMPR=%.2f\n", + pcmax_low, + pcmax, + pcmax_high, + MPR, + delta_MPR); return pcmax; } else { // FR2 TODO it is even more complex because it is radiated power @@ -224,12 +231,11 @@ float nr_get_Pcmax(int p_Max, } } -float nr_get_Pcmin(int scs, int nr_band, int N_RB_UL) { - int band_index = get_supported_band_index(nr_band > 256 ? FR2 : FR1, scs, N_RB_UL); +float nr_get_Pcmin(int bandwidth_index) { const float table_38101_6_3_1_1[] = { -40, -40, -40, -40, -39, -38.2, -37.5, -37, -36.5, -35.2, -34.6, -34, -33.5, -33 }; - return table_38101_6_3_1_1[band_index]; + return table_38101_6_3_1_1[bandwidth_index]; } // This is not entirely correct. In certain k2/k1/k0 settings we might postpone accumulating delta_PUCCH until next HARQ feedback @@ -341,6 +347,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, mac->nr_band, mac->frame_type, mac->frequency_range, + current_UL_BWP->channel_bandwidth, 2, false, mac->current_UL_BWP->scs, @@ -348,7 +355,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, format_type == 2, 1, start_prb); - int P_CMIN = nr_get_Pcmin(mac->current_UL_BWP->scs, mac->nr_band, mac->current_UL_BWP->BWPSize); + float P_CMIN = current_UL_BWP->P_CMIN; int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); if (power_config->twoPUCCH_PC_AdjustmentStates && *power_config->twoPUCCH_PC_AdjustmentStates > 1) { @@ -522,6 +529,7 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac, mac->nr_band, mac->frame_type, mac->frequency_range, + mac->current_UL_BWP->channel_bandwidth, qm, false, mac->current_UL_BWP->scs, @@ -553,7 +561,7 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac, // TODO: compute pathoss using correct reference int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); - int P_CMIN = nr_get_Pcmin(mac->current_UL_BWP->scs, mac->nr_band, mac->current_UL_BWP->BWPSize); + int P_CMIN = mac->current_UL_BWP->P_CMIN; float pusch_power_without_f_b_f_c = P_O_PUSCH + M_pusch_component + alpha * pathloss + DELTA_TF; diff --git a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp index a315835df7..c8467241b8 100644 --- a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp +++ b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp @@ -44,24 +44,27 @@ TEST(test_pcmax, test_mpr) int nr_band = 20; float expected_power = 23 - (1.5 / 2); frame_type_t frame_type = TDD; - EXPECT_EQ(expected_power, nr_get_Pcmax(23, nr_band, frame_type, FR1, 2, false, 1, N_RB_UL, false, 6, prb_start)); + int channel_bandwidth = 20; + EXPECT_EQ(expected_power, + nr_get_Pcmax(23, nr_band, frame_type, FR1, channel_bandwidth, 2, false, 1, N_RB_UL, false, 6, prb_start)); // Outer PRB, MPR = 3, no delta MPR prb_start = 0; expected_power = 23 - (3.0 / 2); - EXPECT_EQ(expected_power, nr_get_Pcmax(23, nr_band, frame_type, FR1, 2, false, 1, N_RB_UL, false, 6, prb_start)); + EXPECT_EQ(expected_power, + nr_get_Pcmax(23, nr_band, frame_type, FR1, channel_bandwidth, 2, false, 1, N_RB_UL, false, 6, prb_start)); // Outer PRB on band 28, MPR = 3, delta MPR = 0.5 dB N_RB_UL = 78; nr_band = 28; expected_power = 23 - ((3.0 + 0.5) / 2); - EXPECT_EQ(expected_power, nr_get_Pcmax(23, nr_band, frame_type, FR1, 2, false, 1, N_RB_UL, false, 100, prb_start)); + EXPECT_EQ(expected_power, nr_get_Pcmax(23, nr_band, frame_type, FR1, 30, 2, false, 1, N_RB_UL, false, 100, prb_start)); } TEST(test_pcmax, test_not_implemented) { int N_RB_UL = 51; - EXPECT_DEATH(nr_get_Pcmax(23, 20, TDD, FR1, 1, false, 1, N_RB_UL, false, 6, 0), "MPR for Pi/2 BPSK not implemented yet"); + EXPECT_DEATH(nr_get_Pcmax(23, 20, TDD, FR1, 20, 1, false, 1, N_RB_UL, false, 6, 0), "MPR for Pi/2 BPSK not implemented yet"); } TEST(test_pcmax, test_pucch_max_power) @@ -70,11 +73,12 @@ TEST(test_pcmax, test_pucch_max_power) int prb_start = 0; int N_RB_UL = 51; // 10Mhz float expected_power = 23 - (1.0 / 2); - EXPECT_EQ(expected_power, nr_get_Pcmax(23, 20, TDD, FR1, 2, false, 1, N_RB_UL, true, 1, prb_start)); + int channel_bandwidth = 20; + EXPECT_EQ(expected_power, nr_get_Pcmax(23, 20, TDD, FR1, channel_bandwidth, 2, false, 1, N_RB_UL, true, 1, prb_start)); // Other fromats, no transform precoding, MPR = 3 expected_power = 23 - (3.0 / 2); - EXPECT_EQ(expected_power, nr_get_Pcmax(23, 20, TDD, FR1, 2, false, 1, N_RB_UL, false, 1, prb_start)); + EXPECT_EQ(expected_power, nr_get_Pcmax(23, 20, TDD, FR1, channel_bandwidth, 2, false, 1, N_RB_UL, false, 1, prb_start)); } TEST(test_pucch_power_state, test_accumulated_delta_pucch) @@ -108,6 +112,7 @@ TEST(test_pucch_power_state, test_accumulated_delta_pucch) mac.nr_band, mac.frame_type, FR1, + current_UL_BWP.channel_bandwidth, 2, false, current_UL_BWP.scs, @@ -177,9 +182,9 @@ TEST(test_pucch_power_state, test_accumulated_delta_pucch) TEST(pc_min, check_all_bw_indexes) { - const int NB_RB_UL[] = {11, 24, 38, 51, 65, 78, 106, 133, 162, 217, 245, 273}; - for (auto i = 0U; i < sizeof(NB_RB_UL) / sizeof(NB_RB_UL[0]); i++) { - (void)nr_get_Pcmin(1, 20, NB_RB_UL[i]); + const int bws[] = {5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 90, 100}; + for (auto i = 0U; i < sizeofArray(bws); i++) { + (void)nr_get_Pcmin(i); } } @@ -189,6 +194,7 @@ TEST(pusch_power_control, pusch_power_control_msg3) NR_UE_UL_BWP_t current_UL_BWP = {0}; current_UL_BWP.scs = 1; current_UL_BWP.BWPSize = 106; + current_UL_BWP.channel_bandwidth = 40; mac.current_UL_BWP = ¤t_UL_BWP; NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0}; current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon; @@ -218,6 +224,7 @@ TEST(pusch_power_control, pusch_power_control_msg3) mac.nr_band, mac.frame_type, FR1, + current_UL_BWP.channel_bandwidth, Qm, false, current_UL_BWP.scs, @@ -286,6 +293,7 @@ TEST(pusch_power_control, pusch_power_data) NR_UE_UL_BWP_t current_UL_BWP = {0}; current_UL_BWP.scs = 1; current_UL_BWP.BWPSize = 106; + current_UL_BWP.channel_bandwidth = 40; mac.current_UL_BWP = ¤t_UL_BWP; NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0}; current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon; @@ -317,6 +325,7 @@ TEST(pusch_power_control, pusch_power_data) mac.nr_band, mac.frame_type, FR1, + current_UL_BWP.channel_bandwidth, Qm, false, current_UL_BWP.scs, @@ -365,6 +374,7 @@ TEST(pusch_power_control, pusch_power_control_state_initialization) NR_UE_UL_BWP_t current_UL_BWP = {0}; current_UL_BWP.scs = 1; current_UL_BWP.BWPSize = 106; + current_UL_BWP.channel_bandwidth = 40; mac.current_UL_BWP = ¤t_UL_BWP; NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0}; current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon; @@ -412,6 +422,7 @@ TEST(pusch_power_control, pusch_power_control_state) NR_UE_UL_BWP_t current_UL_BWP = {0}; current_UL_BWP.scs = 1; current_UL_BWP.BWPSize = 106; + current_UL_BWP.channel_bandwidth = 40; mac.current_UL_BWP = ¤t_UL_BWP; NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0}; current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon; @@ -443,6 +454,7 @@ TEST(pusch_power_control, pusch_power_control_state) mac.nr_band, mac.frame_type, FR1, + current_UL_BWP.channel_bandwidth, Qm, false, current_UL_BWP.scs, @@ -569,9 +581,25 @@ TEST(pusch_power_control, pusch_power_100_rb) EXPECT_GT(power_100_prbs, power); } +TEST(test_pcmax, test_non_obvious_bwp_size) +{ + // Inner PRB, MPR = 1.5, no delta MPR + int prb_start = 4; + int N_RB_UL = 48; + int nr_band = 20; + frame_type_t frame_type = TDD; + int channel_bandwidth = 10; + float expected_power = 23 - 1.5 / 2; + EXPECT_EQ(expected_power, + nr_get_Pcmax(23, nr_band, frame_type, FR1, channel_bandwidth, 2, false, 1, N_RB_UL, false, 6, prb_start)); +} + int main(int argc, char** argv) { logInit(); + uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY); + g_log->log_component[MAC].level = OAILOG_DEBUG; + g_log->log_component[NR_MAC].level = OAILOG_DEBUG; testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 77f794332a..9c0ff76cec 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -280,9 +280,11 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant // Carrier configuration struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; - cfg->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(*frequencyInfoDL->frequencyBandList.list.array[0] > 256 ? FR2 : FR1, - frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); + frequency_range_t frequency_range = *frequencyInfoDL->frequencyBandList.list.array[0] > 256 ? FR2 : FR1; + int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, + frequency_range, + frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); + cfg->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index); cfg->carrier_config.dl_bandwidth.tl.tag = NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG; // temporary cfg->num_tlv++; LOG_I(NR_MAC, "DL_Bandwidth:%d\n", cfg->carrier_config.dl_bandwidth.value); @@ -308,9 +310,11 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant } } struct NR_FrequencyInfoUL *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL; - cfg->carrier_config.uplink_bandwidth.value = get_supported_bw_mhz(*frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1, - frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); + frequency_range = *frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1; + bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, + frequency_range, + frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); + cfg->carrier_config.uplink_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index); cfg->carrier_config.uplink_bandwidth.tl.tag = NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG; // temporary cfg->num_tlv++; LOG_I(NR_MAC, "DL_Bandwidth:%d\n", cfg->carrier_config.uplink_bandwidth.value); @@ -343,7 +347,7 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant } uint32_t band = *frequencyInfoDL->frequencyBandList.list.array[0]; - frequency_range_t frequency_range = band < 100 ? FR1 : FR2; + frequency_range = band < 100 ? FR1 : FR2; frame_type_t frame_type = get_frame_type(*frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing); nrmac->common_channels[0].frame_type = frame_type; diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index d0b692232f..dd3b3db216 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -529,7 +529,7 @@ void set_dl_maxmimolayers(NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig, NR_FeatureSets_t *fs = uecap ? uecap->featureSets : NULL; if (fs) { - const int bw_mhz = get_supported_bw_mhz(freq_range, scs, bw_size); + const int bw_mhz = get_supported_bw_mhz(freq_range, get_supported_band_index(scs, freq_range, bw_size)); // go through UL feature sets and look for one with current SCS for (int i = 0; i < fs->featureSetsDownlinkPerCC->list.count; i++) { NR_FeatureSetDownlinkPerCC_t *dl_fs = fs->featureSetsDownlinkPerCC->list.array[i]; From 9e0bcb7fe473708f7217c46fd3784077c494bc8d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 25 Jul 2024 15:51:14 +0200 Subject: [PATCH 18/38] nr_modulation(): make non-changing input parameter const ptr --- openair1/PHY/MODULATION/nr_modulation.c | 6 +++--- openair1/PHY/MODULATION/nr_modulation.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index 85490be63b..ad84245f86 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -112,7 +112,7 @@ const char nr_W_4l_4p[5][4][4] = { {{'1', '1', '1', '1'}, {'1', 'n', '1', 'n'}, {'j', 'j', 'o', 'o'}, {'j', 'o', 'o', 'j'}} // pmi 4 }; -void nr_modulation(uint32_t *in, +void nr_modulation(const uint32_t *in, uint32_t length, uint16_t mod_order, int16_t *out) @@ -120,8 +120,8 @@ void nr_modulation(uint32_t *in, uint16_t mask = ((1< Date: Thu, 25 Jul 2024 15:55:19 +0200 Subject: [PATCH 19/38] nr_pdc/sch_dmrs_rx(): make non-changing input parameter const ptr --- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 8 ++++---- openair1/PHY/NR_REFSIG/refsig_defs_ue.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 4f8d86762f..3352c5d3a6 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -120,9 +120,9 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, return(0); } -int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, +int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, unsigned int Ns, - unsigned int *nr_gold_pdsch, + const unsigned int *nr_gold_pdsch, c16_t *output, unsigned short p, unsigned char lp, @@ -170,9 +170,9 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, return(0); } -int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, +int nr_pdcch_dmrs_rx(const PHY_VARS_NR_UE *ue, unsigned int Ns, - unsigned int *nr_gold_pdcch, + const unsigned int *nr_gold_pdcch, c16_t *output, unsigned short p, unsigned short nb_rb_coreset) diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index 21d5a116d1..ffd16722cc 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -35,16 +35,16 @@ void nr_pbch_dmrs_rx(int dmrss, const unsigned int *nr_gold_pbch, c16_t *output, /*!\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 */ -int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, +int nr_pdcch_dmrs_rx(const PHY_VARS_NR_UE *ue, unsigned int Ns, - unsigned int *nr_gold_pdcch, + const unsigned int *nr_gold_pdcch, c16_t *output, unsigned short p, unsigned short nb_rb_corset); -int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, +int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, unsigned int Ns, - unsigned int *nr_gold_pdsch, + const unsigned int *nr_gold_pdsch, c16_t *output, unsigned short p, unsigned char lp, From fc5258962f9dd29247f1ec6dc980568d37942378 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 25 Jul 2024 17:12:08 +0200 Subject: [PATCH 20/38] nr_gen_ref_conj_symbols()/nr_ptrs_cpe_estimation(): const input --- openair1/PHY/NR_REFSIG/dmrs_nr.h | 2 +- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 2 +- openair1/PHY/NR_REFSIG/ptrs_nr.c | 2 +- openair1/PHY/NR_REFSIG/ptrs_nr.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.h b/openair1/PHY/NR_REFSIG/dmrs_nr.h index 2c1005a19b..5a3160857a 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.h +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.h @@ -61,7 +61,7 @@ uint8_t allowed_xlsch_re_in_dmrs_symbol(uint16_t k, uint8_t numDmrsCdmGrpsNoData, uint8_t dmrs_type); -void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order); +void nr_gen_ref_conj_symbols(const uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order); int8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol); uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb, uint8_t start); int8_t get_valid_dmrs_idx_for_channel_est(uint16_t dmrs_symb_pos, uint8_t counter); diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 3352c5d3a6..4647b6ea1a 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -245,7 +245,7 @@ void nr_pbch_dmrs_rx(int symbol, const unsigned int *nr_gold_pbch, c16_t *output \param length is number of RE in a OFDM symbol \param *output pointer to all ptrs RE in a OFDM symbol */ -void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, c16_t *output, uint16_t offset, int mod_order) +void nr_gen_ref_conj_symbols(const uint32_t *in, uint32_t length, c16_t *output, uint16_t offset, int mod_order) { uint8_t idx, b_idx; for (int i=0; i Date: Fri, 26 Jul 2024 12:02:20 +0200 Subject: [PATCH 21/38] nr_pusch_dmrs_rx(): const input --- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 2 +- openair1/PHY/NR_REFSIG/nr_refsig.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 4647b6ea1a..0debd23295 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -66,7 +66,7 @@ int nr_pusch_dmrs_delta(uint8_t dmrs_config_type, unsigned short p) { int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, unsigned int Ns, - unsigned int *nr_gold_pusch, + const uint32_t *nr_gold_pusch, c16_t *output, unsigned short p, unsigned char lp, diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index 47afec9ef1..ffdb347656 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -53,7 +53,7 @@ int nr_pusch_dmrs_delta(uint8_t dmrs_config_type, unsigned short p); int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, unsigned int Ns, - unsigned int *nr_gold_pusch, + const uint32_t *nr_gold_pusch, c16_t *output, unsigned short p, unsigned char lp, From 181ec25a23775791c07c2ce330a6d80d0aed2d26 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 26 Jul 2024 12:53:53 +0200 Subject: [PATCH 22/38] USRP: add a T trace to record the TX IQ data on antenna 0 --- common/utils/T/T_messages.txt | 5 +++++ radio/USRP/usrp_lib.cpp | 2 ++ 2 files changed, 7 insertions(+) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 1ca8c90e89..dc9080b158 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -9,6 +9,11 @@ ID = USRP_RX_ANT0 GROUP = ALL:HEAVY FORMAT = int,timestap : buffer,data +ID = USRP_TX_ANT0 + DESC = TX IQ data as sent by USRP driver on antenna 0 + GROUP = ALL:HEAVY + FORMAT = int,timestap : buffer,data + #PHY logs ID = ENB_PHY_UL_TICK DESC = eNodeB uplink tick - one tick per ms at start of uplink processing diff --git a/radio/USRP/usrp_lib.cpp b/radio/USRP/usrp_lib.cpp index 8cc4a5b2ee..617760b030 100644 --- a/radio/USRP/usrp_lib.cpp +++ b/radio/USRP/usrp_lib.cpp @@ -643,6 +643,8 @@ void *trx_usrp_write_thread(void * arg){ ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md); } + T(T_USRP_TX_ANT0, T_INT(timestamp), T_BUFFER(buff_tx[0], nsamps*4)); + if (ret != nsamps) LOG_E(HW,"[xmit] tx samples %d != %d\n",ret,nsamps); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_USRP_SEND_RETURN, ret ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_THREAD, 0 ); From 59086151e0bd1c7fbcd0103dbb982ee2fbe7433e Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 26 Jul 2024 12:19:35 +0200 Subject: [PATCH 23/38] Add generic usage-based gold cache Add gold sequence cache with dynamic size, private to each thread. It periodically reorders by call rate. To free the gold sequences after end of life time of a thread, use the pthread API. --- CMakeLists.txt | 1 + openair1/PHY/NR_REFSIG/nr_gold_ue.c | 1 + openair1/PHY/NR_REFSIG/nr_refsig.h | 1 + openair1/PHY/NR_REFSIG/nr_refsig_common.h | 32 +++++ openair1/PHY/NR_REFSIG/refsig.c | 166 ++++++++++++++++++++++ openair1/PHY/NR_REFSIG/refsig_defs_ue.h | 2 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 1 + 7 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 openair1/PHY/NR_REFSIG/nr_refsig_common.h create mode 100644 openair1/PHY/NR_REFSIG/refsig.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 94c49f8922..df3ad3d211 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1017,6 +1017,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_csi_rs.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_scrambling.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/scrambling_luts.c + ${OPENAIR1_DIR}/PHY/NR_REFSIG/refsig.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c ) diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c index 3259aa3173..424ee8e650 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 "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic() void nr_gold_pbch(uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD], int Nid, int Lmax) { diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index ffdb347656..ccae9cc629 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -25,6 +25,7 @@ #define __NR_REFSIG__H__ #include "PHY/defs_gNB.h" +#include "openair1/PHY/NR_REFSIG/nr_refsig_common.h" #include "PHY/LTE_REFSIG/lte_refsig.h" #include "PHY/sse_intrin.h" diff --git a/openair1/PHY/NR_REFSIG/nr_refsig_common.h b/openair1/PHY/NR_REFSIG/nr_refsig_common.h new file mode 100644 index 0000000000..303b1d7aa5 --- /dev/null +++ b/openair1/PHY/NR_REFSIG/nr_refsig_common.h @@ -0,0 +1,32 @@ +/* + * 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 + */ + +/* Definitions for NR Reference signals */ + +#ifndef __NR_REFSIG_COMMON_H__ +#define __NR_REFSIG_COMMON_H__ + +struct NR_DL_FRAME_PARMS; +typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS; + +uint32_t *gold_cache(uint32_t key, int length); + +#endif diff --git a/openair1/PHY/NR_REFSIG/refsig.c b/openair1/PHY/NR_REFSIG/refsig.c new file mode 100644 index 0000000000..80fe2a6dc3 --- /dev/null +++ b/openair1/PHY/NR_REFSIG/refsig.c @@ -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 + */ + +#include "nr_refsig.h" +#include "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic() + +#define REFRESH_RATE (1000 * 100) + +typedef struct { + int key; + int length; + int usage; +} gold_cache_t; + +typedef struct { + uint32_t *table; + uint32_t tblSz; + int calls; + int iterate; +} gold_cache_table_t; +static const int roundedHeaderSz = (((sizeof(gold_cache_t) + 63) / 64) * 64) / sizeof(uint32_t); +static const int grain = 64 / sizeof(uint32_t); + +// Allocate, also reorder to have the most frequent first, so the cache search is optimized +static void refresh_table(gold_cache_table_t *t, int sizeIncrease) +{ + uint32_t *old = t->table; + uint oldSz = t->tblSz; + if (t->tblSz == 0) + t->tblSz = PAGE_SIZE / sizeof(*t->table); + if (sizeIncrease) + t->tblSz += max(sizeIncrease, PAGE_SIZE / sizeof(*t->table)); + int ret = posix_memalign((void **)&t->table, 64, t->tblSz * sizeof(*t->table)); + AssertFatal(ret == 0, "No more memory"); + LOG_D(PHY, + "re-organize gold sequence table to %lu pages of memory calls since last reorder: %d, search rate: %f\n", + t->tblSz * sizeof(*t->table) / PAGE_SIZE, + t->calls, + t->calls ? t->iterate / (float)t->calls : 0.0); + int maxUsage; + uint32_t *currentTmp = t->table; + do { + maxUsage = 0; + gold_cache_t *entryToCopy = NULL; + for (uint32_t *searchmax = old; searchmax < old + oldSz; searchmax += roundedHeaderSz) { + gold_cache_t *tbl = (gold_cache_t *)searchmax; + if (!tbl->length) + break; + if (tbl->usage > maxUsage) { + maxUsage = tbl->usage; + entryToCopy = tbl; + } + searchmax += tbl->length; + } + if (maxUsage) { + memcpy(currentTmp, entryToCopy, (roundedHeaderSz + entryToCopy->length) * sizeof(*t->table)); + currentTmp += roundedHeaderSz + entryToCopy->length; + entryToCopy->usage = 0; + } + } while (maxUsage); + const uint usedSz = currentTmp - t->table; + memset(t->table + usedSz, 0, (t->tblSz - usedSz) * sizeof(*t->table)); + free(old); + t->calls = 0; + t->iterate = 0; + return; +} + +static pthread_key_t gold_table_key; +static pthread_once_t gold_key_once = PTHREAD_ONCE_INIT; + +static void delete_table(void *ptr) +{ + gold_cache_table_t *table = (gold_cache_table_t *)ptr; + if (table->table) + free(table->table); + free(ptr); +} + +static void make_table_key() +{ + (void)pthread_key_create(&gold_table_key, delete_table); +} + +uint32_t *gold_cache(uint32_t key, int length) +{ + (void)pthread_once(&gold_key_once, make_table_key); + gold_cache_table_t *tableCache; + if ((tableCache = pthread_getspecific(gold_table_key)) == NULL) { + tableCache = calloc(1, sizeof(gold_cache_table_t)); + (void)pthread_setspecific(gold_table_key, tableCache); + } + + // align for AVX512 + length = ((length + grain - 1) / grain) * grain; + tableCache->calls++; + + // periodic refresh + if (tableCache->calls > REFRESH_RATE) + refresh_table(tableCache, 0); + + uint32_t *ptr = tableCache->table; + // check if already cached + for (; ptr < tableCache->table + tableCache->tblSz; ptr += roundedHeaderSz) { + gold_cache_t *tbl = (gold_cache_t *)ptr; + tableCache->iterate++; + if (tbl->length >= length && tbl->key == key) { + tbl->usage++; + return ptr + roundedHeaderSz; + } + if (tbl->key == key) { + // We use a longer sequence, same key + // let's delete the shorter and force reorganize + tbl->usage = 0; + tableCache->calls += REFRESH_RATE; + } + if (!tbl->length) + break; + ptr += tbl->length; + } + + // not enough space in the table + if (!ptr || ptr > tableCache->table + tableCache->tblSz - (2 * roundedHeaderSz + length)) + refresh_table(tableCache, 2 * roundedHeaderSz + length); + + // We will add a new entry + uint32_t *firstFree; + int size = 0; + for (firstFree = tableCache->table; firstFree < tableCache->table + tableCache->tblSz; firstFree += roundedHeaderSz) { + gold_cache_t *tbl = (gold_cache_t *)firstFree; + if (!tbl->length) + break; + firstFree += tbl->length; + size++; + } + if (!tableCache->calls) + LOG_D(PHY, "Number of entries (after reorganization) in gold cache: %d\n", size); + + gold_cache_t *new = (gold_cache_t *)firstFree; + *new = (gold_cache_t){.key = key, .length = length, .usage = 1}; + unsigned int x1 = 0, x2 = key; + uint32_t *sequence = firstFree + roundedHeaderSz; + *sequence++ = lte_gold_generic(&x1, &x2, 1); + for (int n = 1; n < length; n++) + *sequence++ = lte_gold_generic(&x1, &x2, 0); + LOG_D(PHY, "created a gold sequence, start %d; len %d\n", key, length); + return firstFree + roundedHeaderSz; +} diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index ffd16722cc..b4395e07a9 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -25,7 +25,7 @@ #define __NR_REFSIG_DEFS__H__ #include "PHY/defs_nr_UE.h" -#include "PHY/LTE_REFSIG/lte_refsig.h" +#include "nr_refsig_common.h" /*!\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 diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index a12d203ae7..e7f40f0921 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -26,6 +26,7 @@ #include "PHY/NR_TRANSPORT/nr_ulsch.h" #include "PHY/NR_TRANSPORT/nr_dci.h" #include "PHY/NR_ESTIMATION/nr_ul_estimation.h" +#include "PHY/NR_REFSIG/nr_refsig_common.h" #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h" #include "fapi_nr_l1.h" #include "common/utils/LOG/log.h" From 52f077c478f2dfe76b79ac3543471371299ae046 Mon Sep 17 00:00:00 2001 From: Xin Zhe Khooi Date: Tue, 21 May 2024 03:33:41 +0000 Subject: [PATCH 24/38] Initialized DU UE states on F1SetupResponse 38.473 requires to reset UE-related contexts in F1 Setup Request, so do it. However, avoid resetting UE states in phy_test: it has preconfigured UE which we should not reset. Note that if NSA/phy-test used F1, we could likely reset the UE state here, as the F1 UE context setup would come afterwards. --- .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index aac03be132..2435ed629a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -29,6 +29,8 @@ #include "openair3/ocp-gtpu/gtp_itf.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h" +#include "executables/softmodem-common.h" + #include "uper_decoder.h" #include "uper_encoder.h" @@ -172,6 +174,24 @@ void f1_setup_response(const f1ap_setup_resp_t *resp) mac->f1_config.setup_resp->gNB_CU_name = strdup(resp->gNB_CU_name); NR_SCHED_UNLOCK(&mac->sched_lock); + + // NOTE: Before accepting any UEs, we should initialize the UE states. + // This is to handle cases when DU loses the existing SCTP connection, + // and reestablishes a new connection to either a new CU or the same CU. + // This triggers a new F1 Setup Request from DU to CU as per the specs. + // Reinitializing the UE states is necessary to avoid any inconsistent states + // between DU and CU. + // NOTE2: do not reset in phy_test, because there is a pre-configured UE in + // this case. Once NSA/phy-test use F1, this might be lifted, because + // creation of a UE will be requested from higher layers. + + // TS38.473 [Sec 8.2.3.1]: "This procedure also re-initialises the F1AP UE-related + // contexts (if any) and erases all related signalling connections + // in the two nodes like a Reset procedure would do." + if (!get_softmodem_params()->phy_test) { + LOG_I(MAC, "Clearing the DU's UE states before, if any.\n"); + du_clear_all_ue_states(); + } } void f1_setup_failure(const f1ap_setup_failure_t *failure) From 2b44e5252d045e95f4625f4a7e0cf9bbc2bfec97 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 26 Jul 2024 08:56:00 +0200 Subject: [PATCH 25/38] Add log statement that DU sends F1 Setup Request, as done in other functions --- openair2/F1AP/f1ap_du_interface_management.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index eec39ee7fc..f560754bf3 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -324,6 +324,8 @@ static F1AP_GNB_DU_System_Information_t *encode_system_info(const f1ap_gnb_du_sy // SETUP REQUEST int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, const f1ap_setup_req_t *setup_req) { + LOG_D(F1AP, "DU_send_F1_SETUP_REQUEST\n"); + F1AP_F1AP_PDU_t pdu= {0}; uint8_t *buffer; uint32_t len; From 52bd1ad7c6c5c670e5081fbee5845e0596541830 Mon Sep 17 00:00:00 2001 From: Xin Zhe Khooi Date: Fri, 26 Jul 2024 10:23:57 +0200 Subject: [PATCH 26/38] Update FEATURE_SET.md with F1 Reset (DU-only) --- doc/FEATURE_SET.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index b49c2e7a2f..a722b3a41d 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -205,6 +205,7 @@ These modes of operation are supported: - F1 UE Context modification required - F1 UE Context release req/cmd/complete - F1 gNB CU configuration update + - F1 Reset (handled at DU only, full reset only) - Interface with RRC - Interface with GTP-u (tunnel creation/handling for F1-U interface) - One CU(-CP) can handle multiple DUs From 9d81708b49ba8dd74068a5dd5433e72a07e002d2 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 30 Jul 2024 14:44:31 +0200 Subject: [PATCH 27/38] takeout --- openair1/PHY/NR_REFSIG/nr_refsig_common.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/openair1/PHY/NR_REFSIG/nr_refsig_common.h b/openair1/PHY/NR_REFSIG/nr_refsig_common.h index 303b1d7aa5..96f8affdcb 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig_common.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig_common.h @@ -24,9 +24,6 @@ #ifndef __NR_REFSIG_COMMON_H__ #define __NR_REFSIG_COMMON_H__ -struct NR_DL_FRAME_PARMS; -typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS; - uint32_t *gold_cache(uint32_t key, int length); #endif From 0316431e2702f69519feef5ac7bcb27c30dd26ac Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 26 Jul 2024 13:21:57 +0200 Subject: [PATCH 28/38] Use gold cache for PBCH encoding&decoding --- openair1/PHY/INIT/nr_init.c | 2 - openair1/PHY/NR_REFSIG/nr_gold.c | 32 ------------- openair1/PHY/NR_REFSIG/nr_gold_ue.c | 28 ----------- openair1/PHY/NR_REFSIG/nr_refsig.h | 5 -- openair1/PHY/NR_REFSIG/nr_refsig_common.h | 1 + openair1/PHY/NR_REFSIG/refsig.c | 8 ++++ openair1/PHY/NR_REFSIG/refsig_defs_ue.h | 2 - openair1/PHY/NR_TRANSPORT/nr_pbch.c | 48 +++++++------------ .../nr_dl_channel_estimation.c | 3 +- openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h | 1 - .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 8 +--- .../PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c | 1 - openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c | 45 ++++++----------- openair1/PHY/defs_gNB.h | 3 -- openair1/PHY/defs_nr_UE.h | 4 -- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 22 +++------ openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 1 - .../SCHED_NR_UE/phy_procedures_nr_ue_sl.c | 1 - openair1/SIMULATION/NR_PHY/dlsim.c | 2 - openair1/SIMULATION/NR_PHY/pbchsim.c | 3 -- 20 files changed, 50 insertions(+), 170 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index e95451fcd8..fe568720ae 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -143,8 +143,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) gNB->max_nb_pdsch = MAX_MOBILES_PER_GNB; init_delay_table(fp->ofdm_symbol_size, MAX_DELAY_COMP, NR_MAX_OFDM_SYMBOL_SIZE, fp->delay_table); - // PBCH DMRS gold sequences generation - nr_init_pbch_dmrs(gNB); //PDCCH DMRS init gNB->nr_gold_pdcch_dmrs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **)); uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs; diff --git a/openair1/PHY/NR_REFSIG/nr_gold.c b/openair1/PHY/NR_REFSIG/nr_gold.c index 1e7a4b8b8f..b7d5f246e4 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold.c +++ b/openair1/PHY/NR_REFSIG/nr_gold.c @@ -21,38 +21,6 @@ #include "nr_refsig.h" -void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB) -{ - unsigned int x1 = 0, x2 = 0; - uint16_t Nid, i_ssb, i_ssb2; - unsigned char Lmax, l, n_hf, N_hf; - nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; - NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - uint8_t reset; - - Nid = cfg->cell_config.phy_cell_id.value; - - Lmax = fp->Lmax; - N_hf = (Lmax == 4)? 2:1; - - for (n_hf = 0; n_hf < N_hf; n_hf++) { - for (l = 0; l < Lmax ; l++) { - i_ssb = l & (Lmax-1); - i_ssb2 = i_ssb + (n_hf<<2); - - reset = 1; - x2 = (1<<11) * (i_ssb2 + 1) * ((Nid>>2) + 1) + (1<<6) * (i_ssb2 + 1) + (Nid&3); - - for (uint8_t n=0; nnr_gold_pbch_dmrs[n_hf][l][n] = lte_gold_generic(&x1, &x2, reset); - reset = 0; - } - - } - } - -} - void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid) { NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c index 424ee8e650..cb854162fe 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold_ue.c +++ b/openair1/PHY/NR_REFSIG/nr_gold_ue.c @@ -22,34 +22,6 @@ #include "refsig_defs_ue.h" #include "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic() -void nr_gold_pbch(uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD], int Nid, int Lmax) -{ - unsigned int n = 0, x1 = 0, x2 = 0; - unsigned int i_ssb, i_ssb2; - unsigned char l, n_hf, N_hf; - uint8_t reset; - - N_hf = (Lmax == 4)? 2:1; - - for (n_hf = 0; n_hf < N_hf; n_hf++) { - - for (l = 0; l < Lmax ; l++) { - i_ssb = l & (Lmax-1); - i_ssb2 = i_ssb + (n_hf<<2); - - reset = 1; - x2 = (1<<11) * (i_ssb2 + 1) * ((Nid>>2) + 1) + (1<<6) * (i_ssb2 + 1) + (Nid&3); - - for (n=0; n> 2) + 1) + (1 << 6) * (i_ssb2 + 1) + (Nid & 3); + return gold_cache(x2, NR_PBCH_DMRS_LENGTH_DWORD); +} diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index b4395e07a9..b62f8ffdcc 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -51,8 +51,6 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, unsigned short nb_pdsch_rb, uint8_t config_type); -void nr_gold_pbch(uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD], int Nid, int Lmax); - void nr_gold_pdcch(PHY_VARS_NR_UE* ue, unsigned short n_idDMRS); diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c index 8c2ab883c2..cfbdc2ac95 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c @@ -33,9 +33,9 @@ #include "PHY/defs_gNB.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" -#include "PHY/LTE_REFSIG/lte_refsig.h" #include "PHY/sse_intrin.h" #include "executables/softmodem-common.h" +#include "openair1/PHY/NR_REFSIG/nr_refsig_common.h" //#define DEBUG_PBCH //#define DEBUG_PBCH_ENCODING @@ -143,27 +143,22 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, } static void nr_pbch_scrambling(NR_gNB_PBCH *pbch, - uint32_t Nid, - uint8_t nushift, - uint16_t M, - uint16_t length, - uint8_t encoded, - uint32_t unscrambling_mask) { - uint8_t reset, offset; - uint32_t x1 = 0, x2 = 0, s = 0; + uint32_t Nid, + uint8_t nushift, + uint16_t M, + uint16_t length, + uint8_t encoded, + uint32_t unscrambling_mask) +{ uint32_t *pbch_e = pbch->pbch_e; - reset = 1; // x1 is set in lte_gold_generic - x2 = Nid; + const int len = (nushift * M + 31) / 32 + (length + 31) / 32; + uint32_t *s = gold_cache(Nid, len); // The Gold sequence is shifted by nushift* M, so we skip (nushift*M /32) double words - for (int i=0; i<(uint16_t)ceil(((float)nushift*M)/32); i++) { - s = lte_gold_generic(&x1, &x2, reset); - reset = 0; - } - + int goldIdx = (nushift * M + 31) / 32 - 1; // Scrambling is now done with offset (nushift*M)%32 - offset = (nushift*M)&0x1f; + uint8_t offset = (nushift * M) & 0x1f; #ifdef DEBUG_PBCH_ENCODING printf("Scrambling params: nushift %d M %d length %d encoded %d offset %d\n", nushift, M, length, encoded, offset); #endif @@ -178,29 +173,22 @@ static void nr_pbch_scrambling(NR_gNB_PBCH *pbch, if ((unscrambling_mask>>i)&1) pbch->pbch_a_prime ^= ((pbch->pbch_a_interleaved>>i)&1)<pbch_a_prime ^= (((pbch->pbch_a_interleaved>>i)&1) ^ ((s>>((k+offset)&0x1f))&1))<pbch_a_prime ^= (((pbch->pbch_a_interleaved >> i) & 1) ^ ((s[goldIdx] >> ((k + offset) & 0x1f)) & 1)) << i; k++; /// k increase only when payload bit is not special bit } } } else { /// 2nd Scrambling for (int i = 0; i < length; ++i) { - if (((i+offset)&0x1f)==0) { - s = lte_gold_generic(&x1, &x2, reset); - reset = 0; - } - - pbch_e[i>>5] ^= (((s>>((i+offset)&0x1f))&1)<<(i&0x1f)); + if (((i + offset) & 0x1f) == 0) + goldIdx++; + pbch_e[i >> 5] ^= (((s[goldIdx] >> ((i + offset) & 0x1f)) & 1) << (i & 0x1f)); } } } - void nr_init_pbch_interleaver(uint8_t *interleaver) { uint8_t j_sfn=0, j_hrf=10, j_ssb=11, j_other=14; memset((void *)interleaver,0, NR_POLAR_PBCH_PAYLOAD_BITS); 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 89ad4bbc8f..cdec1be6bf 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -644,7 +644,6 @@ c32_t nr_pbch_dmrs_correlation(const NR_DL_FRAME_PARMS *fp, int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp, const sl_nr_ue_phy_params_t *sl_phy_params, - const uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD], int estimateSz, struct complex16 dl_ch_estimates[][estimateSz], struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size], @@ -679,7 +678,7 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp, AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss); - gold_seq = nr_gold_pbch[n_hf][ssb_index]; + gold_seq = nr_gold_pbch(fp->Lmax, Nid, n_hf, ssb_index); lastsymbol = 2; num_rbs = 20; } diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index fc2e2bba62..e36e1a655b 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -68,7 +68,6 @@ c32_t nr_pbch_dmrs_correlation(const NR_DL_FRAME_PARMS *fp, int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp, const sl_nr_ue_phy_params_t *sl_phy_params, - const uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD], 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_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 4788c9ed9d..5fa3d8c83b 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -71,7 +71,6 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, int *ssb_index, int *symbol_offset, fapiPbch_t *result, - const uint32_t nr_gold_pbch_ref[2][64][NR_PBCH_DMRS_LENGTH_DWORD], const c16_t rxdataF[][frame_parms->samples_per_slot_wCP]) { const int N_L = (frame_parms->Lmax == 4) ? 4 : 8; @@ -90,7 +89,7 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, i - pbch_initial_symbol, Nid_cell, ssb_start_subcarrier, - nr_gold_pbch_ref[hf][l], + nr_gold_pbch(frame_parms->Lmax, Nid_cell, hf, l), rxdataF); csum(cumul, cumul, meas); } @@ -110,7 +109,6 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, for(int i=pbch_initial_symbol; ifreqOffset = freq_offset_pss + freq_offset_sss; - uint32_t nr_gold_pbch_ref[2][64][NR_PBCH_DMRS_LENGTH_DWORD]; if (ssbInfo->syncRes.cell_detected) { // we got sss channel - nr_gold_pbch(nr_gold_pbch_ref, ssbInfo->nidCell, fp->Lmax); ssbInfo->syncRes.cell_detected = nr_pbch_detection(ssbInfo->proc, ssbInfo->fp, ssbInfo->nidCell, @@ -289,7 +285,6 @@ void nr_scan_ssb(void *arg) &ssbInfo->ssbIndex, &ssbInfo->symbolOffset, &ssbInfo->pbchResult, - nr_gold_pbch_ref, rxdataF); // start pbch detection at first symbol after pss } } @@ -400,7 +395,6 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, // and we do not know yet in which slot it goes. compensate_freq_offset(ue->common_vars.rxdata, fp, res.freqOffset, res.syncRes.frame_id); } - nr_gold_pbch(ue->nr_gold_pbch, fp->Nid_cell, fp->Lmax); // sync at symbol ue->symbol_offset // computing the offset wrt the beginning of the frame int mu = fp->numerology_index; 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 96c2638c9e..9b2094b983 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c @@ -464,7 +464,6 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, for (int symbol = 0; symbol < SL_NR_NUMSYM_SLSS_NORMAL_CP - 1;) { nr_pbch_channel_estimation(frame_parms, &UE->SL_UE_PHY_PARAMS, - UE->nr_gold_pbch, rxdataF_sz, dl_ch_estimates, dl_ch_estimates_time, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index a9b155a9bd..d09978728a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -33,12 +33,11 @@ #include "PHY/CODING/coding_extern.h" #include "PHY/phy_extern_nr_ue.h" #include "PHY/sse_intrin.h" -#include "PHY/LTE_REFSIG/lte_refsig.h" #include "PHY/INIT/nr_phy_init.h" #include "openair1/SCHED_NR_UE/defs.h" #include #include - +#include "openair1/PHY/NR_REFSIG/nr_refsig_common.h" //#define DEBUG_PBCH //#define DEBUG_PBCH_ENCODING @@ -294,46 +293,30 @@ void nr_pbch_unscrambling(int16_t *demod_pbch_e, uint32_t pbch_a_prime, uint32_t *pbch_a_interleaved) { - uint8_t reset, offset; - uint32_t x1 = 0, x2 = 0, s = 0; - uint8_t k=0; - reset = 1; - // x1 is set in first call to lte_gold_generic - x2 = Nid; //this is c_init - + uint32_t *seq = gold_cache(Nid, (nushift * M + length + 31) / 32); // this is c_init // The Gold sequence is shifted by nushift* M, so we skip (nushift*M /32) double words - for (int i=0; i<(uint16_t)ceil(((float)nushift*M)/32); i++) { - s = lte_gold_generic(&x1, &x2, reset); - reset = 0; - } + int idxGold = (nushift * M + 31) / 32 - 1; // Scrambling is now done with offset (nushift*M)%32 - offset = (nushift*M)&0x1f; - - for (int i=0; i>i)&1))) { - s = lte_gold_generic(&x1, &x2, reset); - reset = 0; - } - - *pbch_a_interleaved ^= ((unscrambling_mask>>i)&1)? ((pbch_a_prime>>i)&1)<>i)&1) ^ ((s>>((k+offset)&0x1f))&1))<> i) & 1))) + idxGold++; + *pbch_a_interleaved ^= ((unscrambling_mask >> i) & 1) + ? ((pbch_a_prime >> i) & 1) << i + : (((pbch_a_prime >> i) & 1) ^ ((seq[idxGold] >> ((k + offset) & 0x1f)) & 1)) << i; k += (!((unscrambling_mask>>i)&1)); #ifdef DEBUG_PBCH_ENCODING printf("i %d k %d offset %d (unscrambling_mask>>i)&1) %d s: %08x\t pbch_a_interleaved 0x%08x (!((unscrambling_mask>>i)&1)) %d\n", i, k, offset, (unscrambling_mask>>i)&1, s, *pbch_a_interleaved, (!((unscrambling_mask>>i)&1))); #endif } else { - if (((i+offset)&0x1f)==0) { - s = lte_gold_generic(&x1, &x2, reset); - reset = 0; - } + if (((i + offset) & 0x1f) == 0) + idxGold++; - if (((s>>((i+offset)&0x1f))&1)==1) + if (seq[idxGold] & (1UL << ((i + offset) % 32))) demod_pbch_e[i] = -demod_pbch_e[i]; #ifdef DEBUG_PBCH_ENCODING diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 5f76f90f8d..40bfd657a0 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -606,9 +606,6 @@ typedef struct PHY_VARS_gNB_s { // PUCCH0 Look-up table for cyclic-shifts NR_gNB_PUCCH0_LUT_t pucch0_lut; - /// PBCH DMRS sequence - uint32_t nr_gold_pbch_dmrs[2][64][NR_PBCH_DMRS_LENGTH_DWORD]; - /// PBCH interleaver uint8_t nr_pbch_interleaver[NR_POLAR_PBCH_PAYLOAD_BITS]; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 70b0dc041f..3282fbb2d2 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -408,10 +408,6 @@ typedef struct PHY_VARS_NR_UE_s { #endif - - /// PBCH DMRS sequence - uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD]; - /// PDSCH DMRS uint32_t ****nr_gold_pdsch[NUMBER_OF_CONNECTED_eNB_MAX]; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index e7f40f0921..8386752e81 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -26,7 +26,6 @@ #include "PHY/NR_TRANSPORT/nr_ulsch.h" #include "PHY/NR_TRANSPORT/nr_dci.h" #include "PHY/NR_ESTIMATION/nr_ul_estimation.h" -#include "PHY/NR_REFSIG/nr_refsig_common.h" #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h" #include "fapi_nr_l1.h" #include "common/utils/LOG/log.h" @@ -109,20 +108,13 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB,int frame,int slot, nfapi_nr_ nr_generate_pss(&txdataF[0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp); nr_generate_sss(&txdataF[0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp); - if (fp->Lmax == 4) - nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index & 7], - &txdataF[0][txdataF_offset], - gNB->TX_AMP, - ssb_start_symbol, - cfg, - fp); - else - nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index & 7], - &txdataF[0][txdataF_offset], - gNB->TX_AMP, - ssb_start_symbol, - cfg, - fp); + int hf = fp->Lmax == 4 ? n_hf : 0; + nr_generate_pbch_dmrs(nr_gold_pbch(fp->Lmax, gNB->gNB_config.cell_config.phy_cell_id.value, hf, ssb_index & 7), + &txdataF[0][txdataF_offset], + gNB->TX_AMP, + ssb_start_symbol, + cfg, + fp); #if T_TRACER if (T_ACTIVE(T_GNB_PHY_MIB)) { diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index cfb52f3266..6bea4b64c9 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -916,7 +916,6 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ start_meas(&ue->dlsch_channel_estimation_stats); nr_pbch_channel_estimation(&ue->frame_parms, NULL, - ue->nr_gold_pbch, estimateSz, dl_ch_estimates, dl_ch_estimates_time, 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 b4335c7480..8ca6cb022d 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c @@ -196,7 +196,6 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr start_meas(&sl_phy_params->channel_estimation_stats); nr_pbch_channel_estimation(fp, &ue->SL_UE_PHY_PARAMS, - ue->nr_gold_pbch, estimateSz, dl_ch_estimates, dl_ch_estimates_time, diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 27236d140e..a20b6cdfaf 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -840,8 +840,6 @@ int main(int argc, char **argv) init_nr_ue_transport(UE); - nr_gold_pbch(UE->nr_gold_pbch, frame_parms->Nid_cell, frame_parms->Lmax); - // compute the scramblingID_pdcch and the gold pdcch UE->scramblingID_pdcch = frame_parms->Nid_cell; nr_gold_pdcch(UE, frame_parms->Nid_cell); diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 63546246f0..064285c853 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -618,8 +618,6 @@ int main(int argc, char **argv) exit(-1); } - nr_gold_pbch(UE->nr_gold_pbch, Nid_cell, frame_parms->Lmax); - processingData_L1tx_t msgDataTx; // generate signal const uint32_t rxdataF_sz = UE->frame_parms.samples_per_slot_wCP; @@ -803,7 +801,6 @@ int main(int argc, char **argv) nr_pbch_channel_estimation(&UE->frame_parms, &UE->SL_UE_PHY_PARAMS, - UE->nr_gold_pbch, estimateSz, dl_ch_estimates, dl_ch_estimates_time, From 99c8dd420af3b37e09ab394b50437408cb610ac6 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 26 Jul 2024 13:50:37 +0200 Subject: [PATCH 29/38] Use gold cache for PDCCH decoding, scrambling, unscrambling --- openair1/PHY/INIT/nr_init.c | 28 ------------- openair1/PHY/INIT/nr_init_ue.c | 24 ----------- openair1/PHY/NR_REFSIG/nr_gold.c | 22 ---------- openair1/PHY/NR_REFSIG/nr_gold_ue.c | 21 ---------- openair1/PHY/NR_REFSIG/nr_refsig.h | 1 - openair1/PHY/NR_REFSIG/nr_refsig_common.h | 1 + openair1/PHY/NR_REFSIG/refsig.c | 11 +++++ openair1/PHY/NR_REFSIG/refsig_defs_ue.h | 3 -- openair1/PHY/NR_TRANSPORT/nr_dci.c | 42 +++++-------------- openair1/PHY/NR_TRANSPORT/nr_dci.h | 6 --- .../nr_dl_channel_estimation.c | 26 ++++++------ openair1/PHY/NR_UE_TRANSPORT/dci_nr.c | 23 +++------- .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 4 -- openair1/PHY/defs_gNB.h | 4 -- openair1/PHY/defs_nr_UE.h | 6 --- openair1/SIMULATION/NR_PHY/dlsim.c | 4 -- 16 files changed, 42 insertions(+), 184 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index fe568720ae..1899f28442 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -143,31 +143,11 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) gNB->max_nb_pdsch = MAX_MOBILES_PER_GNB; init_delay_table(fp->ofdm_symbol_size, MAX_DELAY_COMP, NR_MAX_OFDM_SYMBOL_SIZE, fp->delay_table); - //PDCCH DMRS init - gNB->nr_gold_pdcch_dmrs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **)); - uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs; - AssertFatal(pdcch_dmrs!=NULL, "NR init: pdcch_dmrs malloc failed\n"); - gNB->bad_pucch = 0; if (gNB->TX_AMP == 0) gNB->TX_AMP = AMP; // ceil(((NB_RB<<1)*3)/32) // 3 RE *2(QPSK) - int pdcch_dmrs_init_length = (((fp->N_RB_DL<<1)*3)>>5)+1; - - for (int slot=0; slotslots_per_frame; slot++) { - pdcch_dmrs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *)); - AssertFatal(pdcch_dmrs[slot]!=NULL, "NR init: pdcch_dmrs for slot %d - malloc failed\n", slot); - - for (int symb=0; symbsymbols_per_slot; symb++) { - pdcch_dmrs[slot][symb] = (uint32_t *)malloc16(pdcch_dmrs_init_length*sizeof(uint32_t)); - LOG_D(PHY,"pdcch_dmrs[%d][%d] %p\n",slot,symb,pdcch_dmrs[slot][symb]); - AssertFatal(pdcch_dmrs[slot][symb]!=NULL, "NR init: pdcch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb); - } - } - nr_generate_modulation_table(); - gNB->pdcch_gold_init = cfg->cell_config.phy_cell_id.value; - nr_init_pdcch_dmrs(gNB, cfg->cell_config.phy_cell_id.value); nr_init_pbch_interleaver(gNB->nr_pbch_interleaver); //PDSCH DMRS init @@ -340,14 +320,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(meas->n0_subband_power); free_and_zero(meas->n0_subband_power_dB); - uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs; - for (int slot = 0; slot < fp->slots_per_frame; slot++) { - for (int symb = 0; symb < fp->symbols_per_slot; symb++) - free_and_zero(pdcch_dmrs[slot][symb]); - free_and_zero(pdcch_dmrs[slot]); - } - free_and_zero(pdcch_dmrs); - uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs; for (int slot = 0; slot < fp->slots_per_frame; slot++) { for (int symb = 0; symb < fp->symbols_per_slot; symb++) { diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 3967090aeb..ecc14e71f8 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -304,23 +304,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) common_vars->rxdata[i] = malloc16_clear(num_samples * sizeof(c16_t)); } - // ceil(((NB_RB<<1)*3)/32) // 3 RE *2(QPSK) - int pdcch_dmrs_init_length = (((fp->N_RB_DL<<1)*3)>>5)+1; - //PDCCH DMRS init (gNB offset = 0) - ue->nr_gold_pdcch[0] = malloc16(fp->slots_per_frame * sizeof(uint32_t **)); - uint32_t ***pdcch_dmrs = ue->nr_gold_pdcch[0]; - AssertFatal(pdcch_dmrs!=NULL, "NR init: pdcch_dmrs malloc failed\n"); - - for (int slot=0; slotslots_per_frame; slot++) { - pdcch_dmrs[slot] = malloc16(fp->symbols_per_slot * sizeof(uint32_t *)); - AssertFatal(pdcch_dmrs[slot]!=NULL, "NR init: pdcch_dmrs for slot %d - malloc failed\n", slot); - - for (int symb=0; symbsymbols_per_slot; symb++) { - pdcch_dmrs[slot][symb] = malloc16(pdcch_dmrs_init_length * sizeof(uint32_t)); - AssertFatal(pdcch_dmrs[slot][symb]!=NULL, "NR init: pdcch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb); - } - } - // ceil(((NB_RB*6(k)*2(QPSK)/32) // 3 RE *2(QPSK) int pdsch_dmrs_init_length = ((fp->N_RB_DL*12)>>5)+1; @@ -425,13 +408,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) } free_and_zero(common_vars->rxdata); - for (int slot = 0; slot < fp->slots_per_frame; slot++) { - for (int symb = 0; symb < fp->symbols_per_slot; symb++) - free_and_zero(ue->nr_gold_pdcch[0][slot][symb]); - free_and_zero(ue->nr_gold_pdcch[0][slot]); - } - free_and_zero(ue->nr_gold_pdcch[0]); - for (int slot=0; slotslots_per_frame; slot++) { for (int symb=0; symbsymbols_per_slot; symb++) { for (int q=0; qframe_parms; - uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs; - int pdcch_dmrs_init_length = (((fp->N_RB_DL << 1) * 3) >> 5) + 1; - - for (int slot = 0; slot < fp->slots_per_frame; slot++) { - for (int symb = 0; symb < fp->symbols_per_slot; symb++) { - uint8_t reset = 1; - uint32_t x1 = 0; - uint64_t temp_x2 = ((1UL << 17) * (fp->symbols_per_slot * slot + symb + 1) * ((Nid << 1) + 1) + (Nid << 1)); - uint32_t x2 = temp_x2 % (1U << 31); - LOG_D(PHY,"PDCCH DMRS slot %d, symb %d, Nid %d, x2 %x\n", slot, symb, Nid, x2); - for (uint32_t n = 0; n < pdcch_dmrs_init_length; n++) { - pdcch_dmrs[slot][symb][n] = lte_gold_generic(&x1, &x2, reset); - reset = 0; - } - } - } -} - - void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint8_t nscid, uint32_t Nid) { NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c index cb854162fe..a6beb95ecd 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold_ue.c +++ b/openair1/PHY/NR_REFSIG/nr_gold_ue.c @@ -22,27 +22,6 @@ #include "refsig_defs_ue.h" #include "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic() -void nr_gold_pdcch(PHY_VARS_NR_UE* ue, - unsigned short nid) -{ - int pdcch_dmrs_init_length = (((ue->frame_parms.N_RB_DL << 1) * 3) >> 5) + 1; - for (int ns = 0; ns < ue->frame_parms.slots_per_frame; ns++) { - for (int l = 0; l < ue->frame_parms.symbols_per_slot; l++) { - uint8_t reset = 1; - uint64_t x2tmp0 = ((ue->frame_parms.symbols_per_slot * ns + l + 1) * ((nid << 1) + 1)); - x2tmp0 <<= 17; - x2tmp0 += (nid << 1); - uint32_t x1 = 0; - uint32_t x2 = x2tmp0 % (1U << 31); //cinit - LOG_D(PHY,"PDCCH DMRS slot %d, symb %d, Nid %d, x2 %x\n", ns, l, nid, x2); - for (int n = 0; n < pdcch_dmrs_init_length; n++) { - ue->nr_gold_pdcch[0][ns][l][n] = lte_gold_generic(&x1, &x2, reset); - reset = 0; - } - } - } -} - void nr_gold_pdsch(PHY_VARS_NR_UE* ue, int nscid, uint32_t nid) diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index de749728eb..da5f4e062b 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -39,7 +39,6 @@ void nr_init_prs(PHY_VARS_gNB* gNB); @param PHY_VARS_gNB* gNB structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables @param Nid is used for the initialization of x2, Physical cell Id by default or upper layer configured pdcch_scrambling_ID */ -void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid); void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint8_t nscid, uint32_t Nid); void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid); diff --git a/openair1/PHY/NR_REFSIG/nr_refsig_common.h b/openair1/PHY/NR_REFSIG/nr_refsig_common.h index 28726665a6..8e05fe3304 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig_common.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig_common.h @@ -26,5 +26,6 @@ uint32_t *gold_cache(uint32_t key, int length); uint32_t *nr_gold_pbch(int Lmax, int Nid, int n_hf, int ssb); +uint32_t *nr_gold_pdcch(int N_RB_DL, int symbols_per_slot, unsigned short n_idDMRS, int ns, int l); #endif diff --git a/openair1/PHY/NR_REFSIG/refsig.c b/openair1/PHY/NR_REFSIG/refsig.c index 205ef9fa78..5d377f316e 100644 --- a/openair1/PHY/NR_REFSIG/refsig.c +++ b/openair1/PHY/NR_REFSIG/refsig.c @@ -172,3 +172,14 @@ uint32_t *nr_gold_pbch(int Lmax, int Nid, int n_hf, int l) uint32_t x2 = (1 << 11) * (i_ssb2 + 1) * ((Nid >> 2) + 1) + (1 << 6) * (i_ssb2 + 1) + (Nid & 3); return gold_cache(x2, NR_PBCH_DMRS_LENGTH_DWORD); } + +uint32_t *nr_gold_pdcch(int N_RB_DL, int symbols_per_slot, unsigned short nid, int ns, int l) +{ + int pdcch_dmrs_init_length = (((N_RB_DL << 1) * 3) >> 5) + 1; + uint64_t x2tmp0 = (((uint64_t)symbols_per_slot * ns + l + 1) * ((nid << 1) + 1)); + x2tmp0 <<= 17; + x2tmp0 += (nid << 1); + uint32_t x2 = x2tmp0 % (1U << 31); // cinit + LOG_D(PHY, "PDCCH DMRS slot %d, symb %d, Nid %d, x2 %x\n", ns, l, nid, x2); + return gold_cache(x2, pdcch_dmrs_init_length); +} diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index b62f8ffdcc..12d043e4fd 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -51,9 +51,6 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, unsigned short nb_pdsch_rb, uint8_t config_type); -void nr_gold_pdcch(PHY_VARS_NR_UE* ue, - unsigned short n_idDMRS); - void nr_gold_pdsch(PHY_VARS_NR_UE* ue, int nscid, uint32_t nid); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index 678a407f9b..e3b3f3b42e 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -41,29 +41,13 @@ //#define DEBUG_DCI //#define DEBUG_CHANNEL_CODING -void nr_pdcch_scrambling(uint32_t *in, - uint32_t size, - uint32_t Nid, - uint32_t scrambling_RNTI, - uint32_t *out) { - uint8_t reset; - uint32_t x1 = 0, x2 = 0, s = 0; - reset = 1; - x2 = (scrambling_RNTI<<16) + Nid; - LOG_D(NR_PHY_DCI, "PDCCH Scrambling x2 %x : scrambling_RNTI %x \n", x2, scrambling_RNTI); - for (int i=0; i>(i&0x1f))&1) ^ ((s>>(i&0x1f))&1))<<(i&0x1f); - } +static void nr_pdcch_scrambling(uint32_t *in, uint32_t size, uint32_t Nid, uint32_t scrambling_RNTI, uint32_t *out) +{ + int roundedSz = ((size + 31) / 32); + uint32_t *seq = gold_cache((scrambling_RNTI << 16) + Nid, roundedSz); + LOG_D(NR_PHY_DCI, "PDCCH scrambling_RNTI %x \n", scrambling_RNTI); + for (int i = 0; i < roundedSz; i++) + out[i] = in[i] ^ seq[i]; } void nr_generate_dci(PHY_VARS_gNB *gNB, @@ -95,13 +79,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, * in time: by its first slot and its first symbol*/ const nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[d]; - if(dci_pdu->ScramblingId != gNB->pdcch_gold_init) { - gNB->pdcch_gold_init = dci_pdu->ScramblingId; - nr_init_pdcch_dmrs(gNB, dci_pdu->ScramblingId); - } - - uint32_t **gold_pdcch_dmrs = gNB->nr_gold_pdcch_dmrs[slot]; - cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex; cset_nsymb = pdcch_pdu_rel15->DurationSymbols; dci_idx = 0; @@ -131,9 +108,10 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, /// DMRS QPSK modulation for (int symb=cset_start_symb; symbDurationSymbols; symb++) { + const uint32_t *gold = nr_gold_pdcch(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, dci_pdu->ScramblingId, slot, symb); + nr_modulation(gold, dmrs_length, DMRS_MOD_ORDER, + mod_dmrs[symb]); // Qm = 2 as DMRS is QPSK modulated - nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated - #ifdef DEBUG_PDCCH_DMRS if(dci_pdu->RNTI!=0xFFFF) { for (int i=0; i>1; i++) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h index 578301a7a2..3a61d0b4a0 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h @@ -32,12 +32,6 @@ void nr_generate_dci_top(processingData_L1tx_t *msgTx, int16_t amp, NR_DL_FRAME_PARMS *frame_parms); -void nr_pdcch_scrambling(uint32_t *in, - uint32_t size, - uint32_t Nid, - uint32_t n_RNTI, - uint32_t *out); - int16_t find_nr_pdcch(int frame,int slot, PHY_VARS_gNB *gNB,find_type_t type); void nr_fill_dci(PHY_VARS_gNB *gNB, 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 cdec1be6bf..2709675213 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -842,9 +842,7 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, c16_t pdcch_dl_ch_estimates[][pdcch_est_size], c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { - - int Ns = proc->nr_slot_rx; - int gNB_id = proc->gNB_id; + int slot = proc->nr_slot_rx; unsigned char aarx; unsigned short k; unsigned int pilot_cnt; @@ -868,8 +866,13 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, unsigned short coreset_start_subcarrier = first_carrier_offset+(BWPStart + coreset_start_rb)*12; #ifdef DEBUG_PDCCH - printf("PDCCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, symbol %d\n", - gNB_id,ch_offset,ue->frame_parms.ofdm_symbol_size,ue->frame_parms.Ncp,Ns,symbol); + printf("PDCCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, slot=%d, symbol %d\n", + gNB_id, + ch_offset, + ue->frame_parms.ofdm_symbol_size, + ue->frame_parms.Ncp, + slot, + symbol); #endif #if CH_INTERP @@ -879,19 +882,18 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, #endif unsigned short scrambling_id = coreset->pdcch_dmrs_scrambling_id; - // checking if re-initialization of scrambling IDs is needed (should be done here but scrambling ID for PDCCH is not taken from RRC) - if (scrambling_id != ue->scramblingID_pdcch){ - ue->scramblingID_pdcch = scrambling_id; - nr_gold_pdcch(ue,ue->scramblingID_pdcch); - } - int dmrs_ref = 0; if (coreset->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) dmrs_ref = BWPStart; // generate pilot int pilot[(nb_rb_coreset + dmrs_ref) * 3] __attribute__((aligned(16))); // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS - nr_pdcch_dmrs_rx(ue, Ns, ue->nr_gold_pdcch[gNB_id][Ns][symbol], (c16_t *)pilot, 2000, (nb_rb_coreset + dmrs_ref)); + nr_pdcch_dmrs_rx(ue, + slot, + nr_gold_pdcch(ue->frame_parms.N_RB_DL, ue->frame_parms.symbols_per_slot, scrambling_id, slot, symbol), + (c16_t *)pilot, + 2000, + (nb_rb_coreset + dmrs_ref)); for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 47be51813f..15e02dcc5a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -39,6 +39,7 @@ #include "PHY/sse_intrin.h" #include "common/utils/nr/nr_common.h" #include +#include "openair1/PHY/NR_REFSIG/nr_refsig_common.h" #include "assertions.h" #include "T.h" @@ -655,25 +656,13 @@ static void nr_pdcch_unscrambling(c16_t *e_rx, uint16_t pdcch_DMRS_scrambling_id, int16_t *z2) { - int i; - uint8_t reset; - uint32_t x1 = 0, x2 = 0, s = 0; - uint16_t n_id; //{0,1,...,65535} uint32_t rnti = (uint32_t) scrambling_RNTI; - reset = 1; - // x1 is set in first call to lte_gold_generic - n_id = pdcch_DMRS_scrambling_id; - x2 = ((rnti << 16) + n_id) % (1U << 31); // this is c_init in 38.211 v15.1.0 Section 7.3.2.3 - - LOG_D(NR_PHY_DCI, "PDCCH Unscrambling x2 %x : scrambling_RNTI %x\n", x2, rnti); + uint16_t n_id = pdcch_DMRS_scrambling_id; + uint32_t *seq = gold_cache(((rnti << 16) + n_id) % (1U << 31), length / 32); // this is c_init in 38.211 v15.1.0 Section 7.3.2.3 + LOG_D(NR_PHY_DCI, "PDCCH Unscrambling: scrambling_RNTI %x\n", rnti); int16_t *ptr = &e_rx[0].r; - for (i = 0; i < length; i++) { - if ((i & 0x1f) == 0) { - s = lte_gold_generic(&x1, &x2, reset); - reset = 0; - } - - if (((s >> (i % 32)) & 1) == 1) + for (int i = 0; i < length; i++) { + if (seq[i / 32] & (1UL << (i % 32))) z2[i] = -ptr[i]; else z2[i] = ptr[i]; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 5fa3d8c83b..9b0f226321 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -407,10 +407,6 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, // the n_frames we got sync ue->init_sync_frame = n_frames - 1 - res.syncRes.frame_id; - // compute the scramblingID_pdcch and the gold pdcch - ue->scramblingID_pdcch = fp->Nid_cell; - nr_gold_pdcch(ue, fp->Nid_cell); - // compute the scrambling IDs for PDSCH DMRS for (int i = 0; i < NR_NB_NSCID; i++) { ue->scramblingID_dlsch[i] = fp->Nid_cell; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 40bfd657a0..9f8eef8fad 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -609,9 +609,6 @@ typedef struct PHY_VARS_gNB_s { /// PBCH interleaver uint8_t nr_pbch_interleaver[NR_POLAR_PBCH_PAYLOAD_BITS]; - /// PDCCH DMRS sequence - uint32_t ***nr_gold_pdcch_dmrs; - /// PDSCH DMRS sequence uint32_t ****nr_gold_pdsch_dmrs; @@ -638,7 +635,6 @@ typedef struct PHY_VARS_gNB_s { /// counter to average prach energh over first 100 prach opportunities int prach_energy_counter; - int pdcch_gold_init; int pdsch_gold_init[2]; int pusch_gold_init[2]; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 3282fbb2d2..22fadfd1e7 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -417,12 +417,6 @@ typedef struct PHY_VARS_NR_UE_s { // Scrambling IDs used in PUSCH DMRS uint16_t scramblingID_ulsch[2]; - /// PDCCH DMRS - uint32_t ***nr_gold_pdcch[NUMBER_OF_CONNECTED_eNB_MAX]; - - // Scrambling IDs used in PDCCH DMRS - uint16_t scramblingID_pdcch; - /// PUSCH DMRS sequence uint32_t ****nr_gold_pusch_dmrs; diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index a20b6cdfaf..b66b8357fa 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -840,10 +840,6 @@ int main(int argc, char **argv) init_nr_ue_transport(UE); - // compute the scramblingID_pdcch and the gold pdcch - UE->scramblingID_pdcch = frame_parms->Nid_cell; - nr_gold_pdcch(UE, frame_parms->Nid_cell); - // compute the scrambling IDs for PDSCH DMRS for (int i = 0; i < 2; i++) { UE->scramblingID_dlsch[i] = frame_parms->Nid_cell; From 745ea1c1dd3a46765358b78be0294e5a6b4272d1 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 26 Jul 2024 14:24:21 +0200 Subject: [PATCH 30/38] Use gold cache for PDSCH decoding --- openair1/PHY/INIT/nr_init.c | 39 -------------- openair1/PHY/INIT/nr_init_ue.c | 37 ------------- openair1/PHY/NR_REFSIG/nr_gold.c | 21 -------- openair1/PHY/NR_REFSIG/nr_gold_ue.c | 20 ------- openair1/PHY/NR_REFSIG/nr_refsig.h | 1 - openair1/PHY/NR_REFSIG/nr_refsig_common.h | 1 + openair1/PHY/NR_REFSIG/refsig.c | 9 ++++ openair1/PHY/NR_REFSIG/refsig_defs_ue.h | 4 -- openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 18 +++---- .../nr_dl_channel_estimation.c | 52 +++++++++---------- .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 6 --- openair1/PHY/defs_gNB.h | 4 -- openair1/PHY/defs_nr_UE.h | 7 --- openair1/SIMULATION/NR_PHY/dlsim.c | 6 --- 14 files changed, 42 insertions(+), 183 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 1899f28442..13de41c934 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -150,34 +150,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) nr_generate_modulation_table(); nr_init_pbch_interleaver(gNB->nr_pbch_interleaver); - //PDSCH DMRS init - gNB->nr_gold_pdsch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***)); - uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs; - - // ceil(((NB_RB*12(k)*2(QPSK)/32) // 3 RE *2(QPSK) - const int pdsch_dmrs_init_length = ((fp->N_RB_DL*24)>>5)+1; - for (int slot=0; slotslots_per_frame; slot++) { - pdsch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t **)); - AssertFatal(pdsch_dmrs[slot]!=NULL, "NR init: pdsch_dmrs for slot %d - malloc failed\n", slot); - - for (int symb=0; symbsymbols_per_slot; symb++) { - pdsch_dmrs[slot][symb] = (uint32_t **)malloc16(NR_NB_NSCID*sizeof(uint32_t *)); - AssertFatal(pdsch_dmrs[slot][symb]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb); - - for (int q=0; qpdsch_gold_init[nscid] = cfg->cell_config.phy_cell_id.value; - nr_init_pdsch_dmrs(gNB, nscid, cfg->cell_config.phy_cell_id.value); - } - //PUSCH DMRS init gNB->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(NR_NB_NSCID*sizeof(uint32_t ***)); @@ -320,17 +292,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(meas->n0_subband_power); free_and_zero(meas->n0_subband_power_dB); - uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs; - for (int slot = 0; slot < fp->slots_per_frame; slot++) { - for (int symb = 0; symb < fp->symbols_per_slot; symb++) { - for (int q = 0; q < NR_NB_NSCID; q++) - free_and_zero(pdsch_dmrs[slot][symb][q]); - free_and_zero(pdsch_dmrs[slot][symb]); - } - free_and_zero(pdsch_dmrs[slot]); - } - free_and_zero(gNB->nr_gold_pdsch_dmrs); - uint32_t ****pusch_dmrs = gNB->nr_gold_pusch_dmrs; for(int nscid = 0; nscid < 2; nscid++) { for (int slot = 0; slot < fp->slots_per_frame; slot++) { diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index ecc14e71f8..755ba9bbca 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -304,28 +304,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) common_vars->rxdata[i] = malloc16_clear(num_samples * sizeof(c16_t)); } - // ceil(((NB_RB*6(k)*2(QPSK)/32) // 3 RE *2(QPSK) - int pdsch_dmrs_init_length = ((fp->N_RB_DL*12)>>5)+1; - - //PDSCH DMRS init (eNB offset = 0) - ue->nr_gold_pdsch[0] = malloc16(fp->slots_per_frame * sizeof(uint32_t ***)); - uint32_t ****pdsch_dmrs = ue->nr_gold_pdsch[0]; - - for (int slot=0; slotslots_per_frame; slot++) { - pdsch_dmrs[slot] = malloc16(fp->symbols_per_slot * sizeof(uint32_t **)); - AssertFatal(pdsch_dmrs[slot]!=NULL, "NR init: pdsch_dmrs for slot %d - malloc failed\n", slot); - - for (int symb=0; symbsymbols_per_slot; symb++) { - pdsch_dmrs[slot][symb] = malloc16(NR_NB_NSCID * sizeof(uint32_t *)); - AssertFatal(pdsch_dmrs[slot][symb]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb); - - for (int q=0; qn_connected_gNB; gNB_id++) { prach_vars[gNB_id] = malloc16_clear(sizeof(NR_UE_PRACH)); @@ -408,21 +386,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) } free_and_zero(common_vars->rxdata); - for (int slot=0; slotslots_per_frame; slot++) { - for (int symb=0; symbsymbols_per_slot; symb++) { - for (int q=0; qnr_gold_pdsch[0][slot][symb][q]); - free_and_zero(ue->nr_gold_pdsch[0][slot][symb]); - } - free_and_zero(ue->nr_gold_pdsch[0][slot]); - } - free_and_zero(ue->nr_gold_pdsch[0]); - - for (int gNB_id = 0; gNB_id < ue->n_connected_gNB+1; gNB_id++) { - - // PDSCH - } - for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { for (int i=0; iframe_parms; - uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs; - int pdsch_dmrs_init_length = ((fp->N_RB_DL * 12) >> 5) + 1; - for (int slot = 0; slot < fp->slots_per_frame; slot++) { - for (int symb = 0; symb < fp->symbols_per_slot; symb++) { - uint8_t reset = 1; - uint32_t x1 = 0; - uint64_t temp_x2 = ((1UL << 17) * (fp->symbols_per_slot * slot + symb + 1) * ((Nid << 1) + 1) + ((Nid << 1) + nscid)); - uint32_t x2 = temp_x2 % (1U << 31); - LOG_D(PHY,"PDSCH DMRS slot %d, symb %d, Nid %d, nscid %d, x2 %x\n",slot, symb, Nid, nscid, x2); - for (uint32_t n = 0; n < pdsch_dmrs_init_length; n++) { - pdsch_dmrs[slot][symb][nscid][n] = lte_gold_generic(&x1, &x2, reset); - reset = 0; - } - } - } -} - - void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, uint32_t nid) { NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c index a6beb95ecd..be8a473d50 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold_ue.c +++ b/openair1/PHY/NR_REFSIG/nr_gold_ue.c @@ -22,26 +22,6 @@ #include "refsig_defs_ue.h" #include "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic() -void nr_gold_pdsch(PHY_VARS_NR_UE* ue, - int nscid, - uint32_t nid) -{ - int pdsch_dmrs_init_length = ((ue->frame_parms.N_RB_DL * 12) >> 5) + 1; - for (int ns=0; nsframe_parms.slots_per_frame; ns++) { - for (int l=0; lframe_parms.symbols_per_slot; l++) { - uint8_t reset = 1; - uint64_t x2tmp0 = ((ue->frame_parms.symbols_per_slot * ns + l + 1) * ((nid << 1) + 1)) << 17; - uint32_t x1 = 0; - uint32_t x2 = (x2tmp0 + (nid << 1) + nscid) % (1U << 31); //cinit - LOG_D(PHY,"UE DMRS slot %d, symb %d, nscid %d, x2 %x\n", ns, l, nscid, x2); - for (int n = 0; n < pdsch_dmrs_init_length; n++) { - ue->nr_gold_pdsch[0][ns][l][nscid][n] = lte_gold_generic(&x1, &x2, reset); - reset = 0; - } - } - } -} - void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue, uint16_t N_n_scid, uint8_t n_scid) { NR_DL_FRAME_PARMS *fp = &ue->frame_parms; diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index da5f4e062b..66a282760f 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -39,7 +39,6 @@ void nr_init_prs(PHY_VARS_gNB* gNB); @param PHY_VARS_gNB* gNB structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables @param Nid is used for the initialization of x2, Physical cell Id by default or upper layer configured pdcch_scrambling_ID */ -void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint8_t nscid, uint32_t Nid); void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid); void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, uint32_t nid); diff --git a/openair1/PHY/NR_REFSIG/nr_refsig_common.h b/openair1/PHY/NR_REFSIG/nr_refsig_common.h index 8e05fe3304..703ad5dac6 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig_common.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig_common.h @@ -27,5 +27,6 @@ uint32_t *gold_cache(uint32_t key, int length); uint32_t *nr_gold_pbch(int Lmax, int Nid, int n_hf, int ssb); uint32_t *nr_gold_pdcch(int N_RB_DL, int symbols_per_slot, unsigned short n_idDMRS, int ns, int l); +uint32_t *nr_gold_pdsch(int N_RB_DL, int symbols_per_slot, int nid, int nscid, int slot, int symbol); #endif diff --git a/openair1/PHY/NR_REFSIG/refsig.c b/openair1/PHY/NR_REFSIG/refsig.c index 5d377f316e..998f4e264c 100644 --- a/openair1/PHY/NR_REFSIG/refsig.c +++ b/openair1/PHY/NR_REFSIG/refsig.c @@ -183,3 +183,12 @@ uint32_t *nr_gold_pdcch(int N_RB_DL, int symbols_per_slot, unsigned short nid, i LOG_D(PHY, "PDCCH DMRS slot %d, symb %d, Nid %d, x2 %x\n", ns, l, nid, x2); return gold_cache(x2, pdcch_dmrs_init_length); } + +uint32_t *nr_gold_pdsch(int N_RB_DL, int symbols_per_slot, int nid, int nscid, int slot, int symbol) +{ + int pdsch_dmrs_init_length = ((N_RB_DL * 24) >> 5) + 1; + uint64_t x2tmp0 = (((uint64_t)symbols_per_slot * slot + symbol + 1) * (((uint64_t)nid << 1) + 1)) << 17; + uint32_t x2 = (x2tmp0 + (nid << 1) + nscid) % (1U << 31); // cinit + LOG_D(PHY, "UE DMRS slot %d, symb %d, nscid %d, x2 %x\n", slot, symbol, nscid, x2); + return gold_cache(x2, pdsch_dmrs_init_length); +} diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index 12d043e4fd..c9bdbdd2a8 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -51,10 +51,6 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, unsigned short nb_pdsch_rb, uint8_t config_type); -void nr_gold_pdsch(PHY_VARS_NR_UE* ue, - int nscid, - uint32_t nid); - void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue, uint16_t N_n_scid, uint8_t n_scid); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 63f1291fee..fa9a3859b1 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -76,12 +76,6 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) rel15->BWPStart,rel15->BWPSize,rel15->rbStart,rel15->rbSize); const int n_dmrs = (rel15->BWPStart + rel15->rbStart + rel15->rbSize) * nb_re_dmrs; - if(rel15->dlDmrsScramblingId != gNB->pdsch_gold_init[rel15->SCID]) { - gNB->pdsch_gold_init[rel15->SCID] = rel15->dlDmrsScramblingId; - nr_init_pdsch_dmrs(gNB, rel15->SCID, rel15->dlDmrsScramblingId); - } - - uint32_t ***pdsch_dmrs = gNB->nr_gold_pdsch_dmrs[slot]; const int dmrs_symbol_map = rel15->dlDmrsSymbPos; // single DMRS: 010000100 Double DMRS 110001100 const int xOverhead = 0; const int nb_re = @@ -251,9 +245,10 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) l_prime = 0; } /// DMRS QPSK modulation - nr_modulation(pdsch_dmrs[l_symbol][rel15->SCID], - n_dmrs * DMRS_MOD_ORDER, - DMRS_MOD_ORDER, + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; + const uint32_t *gold = + nr_gold_pdsch(fp->N_RB_DL, fp->symbols_per_slot, rel15->dlDmrsScramblingId, rel15->SCID, slot, l_symbol); + nr_modulation(gold, n_dmrs * DMRS_MOD_ORDER, DMRS_MOD_ORDER, (int16_t *)mod_dmrs); // Qm = 2 as DMRS is QPSK modulated #ifdef DEBUG_DLSCH @@ -276,7 +271,10 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) if(ptrs_symbol) { /* PTRS QPSK Modulation for each OFDM symbol in a slot */ LOG_D(PHY, "Doing ptrs modulation for symbol %d, n_ptrs %d\n", l_symbol, n_ptrs); - nr_modulation(pdsch_dmrs[l_symbol][rel15->SCID], n_ptrs * DMRS_MOD_ORDER, DMRS_MOD_ORDER, (int16_t *)mod_ptrs); + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; + const uint32_t *gold = + nr_gold_pdsch(fp->N_RB_DL, fp->symbols_per_slot, rel15->dlDmrsScramblingId, rel15->SCID, slot, l_symbol); + nr_modulation(gold, n_ptrs * DMRS_MOD_ORDER, DMRS_MOD_ORDER, (int16_t *)mod_ptrs); } } uint16_t k = start_sc; 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 2709675213..2e3059ee9c 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -888,12 +888,8 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, // generate pilot int pilot[(nb_rb_coreset + dmrs_ref) * 3] __attribute__((aligned(16))); // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS - nr_pdcch_dmrs_rx(ue, - slot, - nr_gold_pdcch(ue->frame_parms.N_RB_DL, ue->frame_parms.symbols_per_slot, scrambling_id, slot, symbol), - (c16_t *)pilot, - 2000, - (nb_rb_coreset + dmrs_ref)); + const uint32_t *gold = nr_gold_pdcch(ue->frame_parms.N_RB_DL, ue->frame_parms.symbols_per_slot, scrambling_id, slot, symbol); + nr_pdcch_dmrs_rx(ue, slot, gold, (c16_t *)pilot, 2000, (nb_rb_coreset + dmrs_ref)); for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { @@ -1423,35 +1419,33 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, c16_t rxdataF[][rxdataFsize], uint32_t *nvar) { - int gNB_id = proc->gNB_id; - int Ns = proc->nr_slot_rx; - const int ch_offset = ue->frame_parms.ofdm_symbol_size * symbol; - const int symbol_offset = ue->frame_parms.ofdm_symbol_size * symbol; + // int gNB_id = proc->gNB_id; + int slot = proc->nr_slot_rx; + NR_DL_FRAME_PARMS *fp = &ue->frame_parms; + const int ch_offset = fp->ofdm_symbol_size * symbol; + const int symbol_offset = fp->ofdm_symbol_size * symbol; #ifdef DEBUG_PDSCH - printf("PDSCH Channel Estimation : gNB_id %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, bwp_start_subcarrier=%d symbol %d\n", - gNB_id, - ch_offset, - symbol_offset, - ue->frame_parms.ofdm_symbol_size, - ue->frame_parms.Ncp, - Ns, - bwp_start_subcarrier, - symbol); + printf( + "PDSCH Channel Estimation : gNB_id %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, bwp_start_subcarrier=%d " + "symbol %d\n", + gNB_id, + ch_offset, + symbol_offset, + fp->ofdm_symbol_size, + fp->Ncp, + slot, + bwp_start_subcarrier, + symbol); #endif // generate pilot for gNB port number 1000+p int8_t delta = get_delta(p, config_type); - // checking if re-initialization of scrambling IDs is needed - if (scrambling_id != ue->scramblingID_dlsch[nscid]) { - ue->scramblingID_dlsch[nscid] = scrambling_id; - nr_gold_pdsch(ue, nscid, scrambling_id); - } - c16_t pilot[3280] __attribute__((aligned(16))); // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS - nr_pdsch_dmrs_rx(ue, Ns, ue->nr_gold_pdsch[gNB_id][Ns][symbol][nscid], pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type); + const uint32_t *gold = nr_gold_pdsch(fp->N_RB_DL, fp->symbols_per_slot, scrambling_id, nscid, slot, symbol); + nr_pdsch_dmrs_rx(ue, slot, gold, pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type); delay_t delay = {0}; @@ -1639,6 +1633,8 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, /*------------------------------------------------------------------------------------------------------- */ /* 1) Estimate common phase error per PTRS symbol */ /*------------------------------------------------------------------------------------------------------- */ + const uint32_t *gold = + nr_gold_pdsch(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, frame_parms->Nid_cell, nscid, nr_slot_rx, symbol); nr_ptrs_cpe_estimation(*K_ptrs, *ptrsReOffset, *nb_rb, @@ -1647,8 +1643,8 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, symbol, frame_parms->ofdm_symbol_size, (int16_t *)(rxdataF_comp[0][aarx] + symbol * nb_re_pdsch), - ue->nr_gold_pdsch[gNB_id][nr_slot_rx][symbol][nscid], - (int16_t*)&phase_per_symbol[symbol], + gold, + (int16_t *)&phase_per_symbol[symbol], &ptrs_re_symbol[symbol]); } }// HARQ 0 diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 9b0f226321..5df2ee5b10 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -407,12 +407,6 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, // the n_frames we got sync ue->init_sync_frame = n_frames - 1 - res.syncRes.frame_id; - // compute the scrambling IDs for PDSCH DMRS - for (int i = 0; i < NR_NB_NSCID; i++) { - ue->scramblingID_dlsch[i] = fp->Nid_cell; - nr_gold_pdsch(ue, i, ue->scramblingID_dlsch[i]); - } - nr_init_csi_rs(fp, ue->nr_csi_info->nr_gold_csi_rs, fp->Nid_cell); // initialize the pusch dmrs diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 9f8eef8fad..2d298b9103 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -609,9 +609,6 @@ typedef struct PHY_VARS_gNB_s { /// PBCH interleaver uint8_t nr_pbch_interleaver[NR_POLAR_PBCH_PAYLOAD_BITS]; - /// PDSCH DMRS sequence - uint32_t ****nr_gold_pdsch_dmrs; - /// PUSCH DMRS uint32_t ****nr_gold_pusch_dmrs; @@ -635,7 +632,6 @@ typedef struct PHY_VARS_gNB_s { /// counter to average prach energh over first 100 prach opportunities int prach_energy_counter; - int pdsch_gold_init[2]; int pusch_gold_init[2]; int ap_N1; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 22fadfd1e7..f29f083a3f 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -407,13 +407,6 @@ typedef struct PHY_VARS_NR_UE_s { uint32_t dmrs_pbch_bitmap_nr[DMRS_PBCH_I_SSB][DMRS_PBCH_N_HF][DMRS_BITMAP_SIZE]; #endif - - /// PDSCH DMRS - uint32_t ****nr_gold_pdsch[NUMBER_OF_CONNECTED_eNB_MAX]; - - // Scrambling IDs used in PDSCH DMRS - uint16_t scramblingID_dlsch[2]; - // Scrambling IDs used in PUSCH DMRS uint16_t scramblingID_ulsch[2]; diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index b66b8357fa..d7f390f315 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -840,12 +840,6 @@ int main(int argc, char **argv) init_nr_ue_transport(UE); - // compute the scrambling IDs for PDSCH DMRS - for (int i = 0; i < 2; i++) { - UE->scramblingID_dlsch[i] = frame_parms->Nid_cell; - nr_gold_pdsch(UE, i, UE->scramblingID_dlsch[i]); - } - nr_l2_init_ue(1); UE_mac = get_mac_inst(0); ue_init_config_request(UE_mac, mu); From e445ba2d1aec68e8d461c701d1dbb66e8e0e1d9f Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 26 Jul 2024 14:38:32 +0200 Subject: [PATCH 31/38] Use gold cache PUSCH decoding Harmonize nr_gold_pusch() and nr_gold_pdsch(), as the gold sequence calculation for PUSCH and PDSCH is the same. --- openair1/PHY/INIT/nr_init.c | 37 ------------------- openair1/PHY/INIT/nr_init_ue.c | 32 +--------------- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 22 +++++++---- openair1/PHY/NR_REFSIG/nr_gold.c | 20 ---------- openair1/PHY/NR_REFSIG/nr_gold_ue.c | 20 ---------- openair1/PHY/NR_REFSIG/nr_refsig.h | 2 - openair1/PHY/NR_REFSIG/nr_refsig_common.h | 1 + openair1/PHY/NR_REFSIG/refsig.c | 5 +++ openair1/PHY/NR_REFSIG/refsig_defs_ue.h | 4 -- .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 7 ---- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 22 +++++++---- openair1/PHY/defs_gNB.h | 5 --- openair1/PHY/defs_nr_UE.h | 5 --- openair1/SIMULATION/NR_PHY/ulsim.c | 5 --- 14 files changed, 36 insertions(+), 151 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 13de41c934..93f5de1a66 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -150,32 +150,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) nr_generate_modulation_table(); nr_init_pbch_interleaver(gNB->nr_pbch_interleaver); - //PUSCH DMRS init - gNB->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(NR_NB_NSCID*sizeof(uint32_t ***)); - - uint32_t ****pusch_dmrs = gNB->nr_gold_pusch_dmrs; - - int pusch_dmrs_init_length = ((fp->N_RB_UL*12)>>5)+1; - for(int nscid=0; nscidslots_per_frame*sizeof(uint32_t **)); - AssertFatal(pusch_dmrs[nscid]!=NULL, "NR init: pusch_dmrs for nscid %d - malloc failed\n", nscid); - - for (int slot=0; slotslots_per_frame; slot++) { - pusch_dmrs[nscid][slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *)); - AssertFatal(pusch_dmrs[nscid][slot]!=NULL, "NR init: pusch_dmrs for slot %d - malloc failed\n", slot); - - for (int symb=0; symbsymbols_per_slot; symb++) { - pusch_dmrs[nscid][slot][symb] = (uint32_t *)malloc16(pusch_dmrs_init_length*sizeof(uint32_t)); - AssertFatal(pusch_dmrs[nscid][slot][symb]!=NULL, "NR init: pusch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb); - } - } - } - - for (int nscid=0; nscidpusch_gold_init[nscid] = cfg->cell_config.phy_cell_id.value; - nr_gold_pusch(gNB, nscid, gNB->pusch_gold_init[nscid]); - } - // CSI RS init // ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32) int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1; @@ -292,17 +266,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(meas->n0_subband_power); free_and_zero(meas->n0_subband_power_dB); - uint32_t ****pusch_dmrs = gNB->nr_gold_pusch_dmrs; - for(int nscid = 0; nscid < 2; nscid++) { - for (int slot = 0; slot < fp->slots_per_frame; slot++) { - for (int symb = 0; symb < fp->symbols_per_slot; symb++) - free_and_zero(pusch_dmrs[nscid][slot][symb]); - free_and_zero(pusch_dmrs[nscid][slot]); - } - free_and_zero(pusch_dmrs[nscid]); - } - free_and_zero(pusch_dmrs); - uint32_t ***nr_gold_csi_rs = gNB->nr_csi_info->nr_gold_csi_rs; for (int slot = 0; slot < fp->slots_per_frame; slot++) { for (int symb = 0; symb < fp->symbols_per_slot; symb++) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 755ba9bbca..8220733402 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -200,7 +200,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) NR_UE_CSI_RS **const csirs_vars = ue->csirs_vars; NR_UE_SRS **const srs_vars = ue->srs_vars; - int i, slot, symb, gNB_id; + int i, gNB_id; LOG_I(PHY, "Initializing UE vars for gNB TXant %u, UE RXant %u\n", fp->nb_antennas_tx, fp->nb_antennas_rx); @@ -245,26 +245,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) /////////////////////////PUSCH DMRS init///////////////////////// /////////// - // ceil(((NB_RB*6(k)*2(QPSK)/32) // 3 RE *2(QPSK) - int pusch_dmrs_init_length = ((fp->N_RB_UL*12)>>5)+1; - ue->nr_gold_pusch_dmrs = malloc16(fp->slots_per_frame * sizeof(uint32_t ***)); - uint32_t ****pusch_dmrs = ue->nr_gold_pusch_dmrs; - - for (slot=0; slotslots_per_frame; slot++) { - pusch_dmrs[slot] = malloc16(fp->symbols_per_slot * sizeof(uint32_t **)); - AssertFatal(pusch_dmrs[slot]!=NULL, "init_nr_ue_signal: pusch_dmrs for slot %d - malloc failed\n", slot); - - for (symb=0; symbsymbols_per_slot; symb++) { - pusch_dmrs[slot][symb] = malloc16(NR_NB_NSCID * sizeof(uint32_t *)); - AssertFatal(pusch_dmrs[slot][symb]!=NULL, "init_nr_ue_signal: pusch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb); - - for (int q=0; qframe_parms; phy_term_nr_top(); - for (int slot = 0; slot < fp->slots_per_frame; slot++) { - for (int symb = 0; symb < fp->symbols_per_slot; symb++) { - for (int q=0; qnr_gold_pusch_dmrs[slot][symb][q]); - free_and_zero(ue->nr_gold_pusch_dmrs[slot][symb]); - } - free_and_zero(ue->nr_gold_pusch_dmrs[slot]); - } - free_and_zero(ue->nr_gold_pusch_dmrs); - NR_UE_COMMON* common_vars = &ue->common_vars; for (int i = 0; i < fp->nb_antennas_tx; i++) { diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 5f49549d21..d9f799ac37 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -103,16 +103,18 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, //------------------generate DMRS------------------// - if(pusch_pdu->ul_dmrs_scrambling_id != gNB->pusch_gold_init[pusch_pdu->scid]) { - gNB->pusch_gold_init[pusch_pdu->scid] = pusch_pdu->ul_dmrs_scrambling_id; - nr_gold_pusch(gNB, pusch_pdu->scid, pusch_pdu->ul_dmrs_scrambling_id); - } - if (pusch_pdu->transform_precoding == transformPrecoder_disabled) { // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; + const uint32_t *gold = nr_gold_pusch(fp->N_RB_UL, + fp->symbols_per_slot, + gNB->gNB_config.cell_config.phy_cell_id.value, + pusch_pdu->scid, + Ns, + symbol); nr_pusch_dmrs_rx(gNB, Ns, - gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], + gold, pilot, (1000 + p), 0, @@ -552,6 +554,12 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, /*------------------------------------------------------------------------------------------------------- */ /* 1) Estimate common phase error per PTRS symbol */ /*------------------------------------------------------------------------------------------------------- */ + const uint32_t *gold = nr_gold_pusch(frame_parms->N_RB_UL, + frame_parms->symbols_per_slot, + gNB->gNB_config.cell_config.phy_cell_id.value, + rel15_ul->scid, + nr_tti_rx, + symbol); nr_ptrs_cpe_estimation(*K_ptrs, *ptrsReOffset, *nb_rb, @@ -560,7 +568,7 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, symbol, frame_parms->ofdm_symbol_size, (int16_t *)&pusch_vars->rxdataF_comp[aarx][(symbol * nb_re_pusch)], - gNB->nr_gold_pusch_dmrs[rel15_ul->scid][nr_tti_rx][symbol], + gold, (int16_t *)&phase_per_symbol[symbol], ptrs_re_symbol); } diff --git a/openair1/PHY/NR_REFSIG/nr_gold.c b/openair1/PHY/NR_REFSIG/nr_gold.c index 00a7ba78b1..066707029b 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold.c +++ b/openair1/PHY/NR_REFSIG/nr_gold.c @@ -21,26 +21,6 @@ #include "nr_refsig.h" -void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, uint32_t nid) -{ - NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - int pusch_dmrs_init_length = ((fp->N_RB_UL * 12) >> 5) + 1; - for (int ns = 0; ns < fp->slots_per_frame; ns++) { - for (int l = 0; l < fp->symbols_per_slot; l++) { - int reset = 1; - uint32_t x1 = 0; - uint64_t temp_x2 = ((1UL << 17) * (fp->symbols_per_slot * ns + l + 1) * ((nid << 1) + 1) + ((nid << 1) + nscid)); - uint32_t x2 = temp_x2 % (1U << 31); - LOG_D(PHY,"DMRS slot %d, symb %d, nscid %d, nid %d, x2 %x\n", ns, l, nscid, nid, x2); - for (int n = 0; n < pusch_dmrs_init_length; n++) { - gNB->nr_gold_pusch_dmrs[nscid][ns][l][n] = lte_gold_generic(&x1, &x2, reset); - reset = 0; - } - } - } -} - - void nr_init_prs(PHY_VARS_gNB* gNB) { unsigned int x1 = 0, x2 = 0; diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c index be8a473d50..f9c23b33b8 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold_ue.c +++ b/openair1/PHY/NR_REFSIG/nr_gold_ue.c @@ -22,26 +22,6 @@ #include "refsig_defs_ue.h" #include "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic() -void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue, uint16_t N_n_scid, uint8_t n_scid) -{ - NR_DL_FRAME_PARMS *fp = &ue->frame_parms; - uint32_t ****pusch_dmrs = ue->nr_gold_pusch_dmrs; - int pusch_dmrs_init_length = ((fp->N_RB_UL * 12) >> 5) + 1; - for (int slot = 0; slot < fp->slots_per_frame; slot++) { - for (int symb = 0; symb < fp->symbols_per_slot; symb++) { - int reset = 1; - uint32_t x1 = 0; - uint64_t t_x2 = ((1UL << 17) * (fp->symbols_per_slot*slot + symb + 1) * ((N_n_scid << 1) + 1) + ((N_n_scid << 1) + n_scid)); - uint32_t x2 = t_x2 % (1U << 31); - LOG_D(PHY,"DMRS slot %d, symb %d, N_n_scid %d, n_scid %d, x2 %x\n", slot, symb, N_n_scid, n_scid, x2); - for (int n = 0; n < pusch_dmrs_init_length; n++) { - pusch_dmrs[slot][symb][n_scid][n] = lte_gold_generic(&x1, &x2, reset); - reset = 0; - } - } - } -} - void init_nr_gold_prs(PHY_VARS_NR_UE* ue) { unsigned int x1 = 0, x2 = 0; diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index 66a282760f..7aad67f7af 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -41,8 +41,6 @@ void nr_init_prs(PHY_VARS_gNB* gNB); */ void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid); -void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, uint32_t nid); - int nr_pusch_dmrs_delta(uint8_t dmrs_config_type, unsigned short p); int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, diff --git a/openair1/PHY/NR_REFSIG/nr_refsig_common.h b/openair1/PHY/NR_REFSIG/nr_refsig_common.h index 703ad5dac6..03f5153ca3 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig_common.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig_common.h @@ -28,5 +28,6 @@ uint32_t *gold_cache(uint32_t key, int length); uint32_t *nr_gold_pbch(int Lmax, int Nid, int n_hf, int ssb); uint32_t *nr_gold_pdcch(int N_RB_DL, int symbols_per_slot, unsigned short n_idDMRS, int ns, int l); uint32_t *nr_gold_pdsch(int N_RB_DL, int symbols_per_slot, int nid, int nscid, int slot, int symbol); +uint32_t *nr_gold_pusch(int N_RB_UL, int symbols_per_slot, int Nid, int nscid, int slot, int symbol); #endif diff --git a/openair1/PHY/NR_REFSIG/refsig.c b/openair1/PHY/NR_REFSIG/refsig.c index 998f4e264c..3e7e5549ea 100644 --- a/openair1/PHY/NR_REFSIG/refsig.c +++ b/openair1/PHY/NR_REFSIG/refsig.c @@ -192,3 +192,8 @@ uint32_t *nr_gold_pdsch(int N_RB_DL, int symbols_per_slot, int nid, int nscid, i LOG_D(PHY, "UE DMRS slot %d, symb %d, nscid %d, x2 %x\n", slot, symbol, nscid, x2); return gold_cache(x2, pdsch_dmrs_init_length); } + +uint32_t *nr_gold_pusch(int N_RB_UL, int symbols_per_slot, int Nid, int nscid, int slot, int symbol) +{ + return nr_gold_pdsch(N_RB_UL, symbols_per_slot, Nid, nscid, slot, symbol); +} diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index c9bdbdd2a8..a90383c254 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -51,10 +51,6 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, unsigned short nb_pdsch_rb, uint8_t config_type); -void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue, - uint16_t N_n_scid, - uint8_t n_scid); - 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); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 5df2ee5b10..5d15dc86a4 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -408,13 +408,6 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, ue->init_sync_frame = n_frames - 1 - res.syncRes.frame_id; nr_init_csi_rs(fp, ue->nr_csi_info->nr_gold_csi_rs, fp->Nid_cell); - - // initialize the pusch dmrs - for (int i = 0; i < NR_NB_NSCID; i++) { - ue->scramblingID_ulsch[i] = fp->Nid_cell; - nr_init_pusch_dmrs(ue, ue->scramblingID_ulsch[i], i); - } - // we also need to take into account the shift by samples_per_frame in case the if is true if (res.ssbOffset < sync_pos_frame) { res.syncRes.rx_offset = fp->samples_per_frame - sync_pos_frame + res.ssbOffset; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 3dec9e2c45..638d1e2e22 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -240,12 +240,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////////////////////DMRS Modulation///////////////////////// /////////// - if(pusch_pdu->ul_dmrs_scrambling_id != UE->scramblingID_ulsch[pusch_pdu->scid]) { - UE->scramblingID_ulsch[pusch_pdu->scid] = pusch_pdu->ul_dmrs_scrambling_id; - nr_init_pusch_dmrs(UE, pusch_pdu->scid, pusch_pdu->ul_dmrs_scrambling_id); - } - - uint32_t ***pusch_dmrs = UE->nr_gold_pusch_dmrs[slot]; uint16_t n_dmrs = (pusch_pdu->bwp_start + start_rb + nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4); c16_t mod_dmrs[n_dmrs] __attribute((aligned(16))); @@ -382,7 +376,13 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, // TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part // Perform this on gold sequence, not required when SC FDMA operation is done, LOG_D(PHY,"DMRS in symbol %d\n",l); - nr_modulation(pusch_dmrs[l][pusch_pdu->scid], + const uint32_t *gold = nr_gold_pusch(frame_parms->N_RB_UL, + frame_parms->symbols_per_slot, + pusch_pdu->ul_dmrs_scrambling_id, + pusch_pdu->scid, + slot, + l); + nr_modulation(gold, n_dmrs * 2, DMRS_MOD_ORDER, (int16_t *)mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated @@ -395,7 +395,13 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) { is_ptrs_sym = 1; - nr_modulation(pusch_dmrs[l][pusch_pdu->scid], nb_rb, DMRS_MOD_ORDER, (int16_t *)mod_ptrs); + const uint32_t *gold = nr_gold_pusch(frame_parms->N_RB_UL, + frame_parms->symbols_per_slot, + pusch_pdu->ul_dmrs_scrambling_id, + pusch_pdu->scid, + slot, + l); + nr_modulation(gold, nb_rb, DMRS_MOD_ORDER, (int16_t *)mod_ptrs); } } diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 2d298b9103..de83c257e5 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -609,9 +609,6 @@ typedef struct PHY_VARS_gNB_s { /// PBCH interleaver uint8_t nr_pbch_interleaver[NR_POLAR_PBCH_PAYLOAD_BITS]; - /// PUSCH DMRS - uint32_t ****nr_gold_pusch_dmrs; - /// PRS sequence uint32_t ****nr_gold_prs; @@ -632,8 +629,6 @@ typedef struct PHY_VARS_gNB_s { /// counter to average prach energh over first 100 prach opportunities int prach_energy_counter; - int pusch_gold_init[2]; - int ap_N1; int ap_N2; int ap_XP; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index f29f083a3f..0dafde1ec2 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -408,11 +408,6 @@ typedef struct PHY_VARS_NR_UE_s { #endif // Scrambling IDs used in PUSCH DMRS - uint16_t scramblingID_ulsch[2]; - - /// PUSCH DMRS sequence - uint32_t ****nr_gold_pusch_dmrs; - // PRS sequence per gNB, per resource uint32_t *****nr_gold_prs; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index c280bd64de..925202f4e6 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -703,11 +703,6 @@ int main(int argc, char *argv[]) init_nr_ue_transport(UE); - for(int n_scid = 0; n_scid<2; n_scid++) { - UE->scramblingID_ulsch[n_scid] = frame_parms->Nid_cell; - nr_init_pusch_dmrs(UE, frame_parms->Nid_cell, n_scid); - } - //Configure UE nr_l2_init_ue(1); NR_UE_MAC_INST_t* UE_mac = get_mac_inst(0); From 7563937af890054f34745a8041cd2edbd9abda11 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 26 Jul 2024 16:58:38 +0200 Subject: [PATCH 32/38] Use gold cache for CSI-RS decoding --- openair1/PHY/INIT/nr_init.c | 21 -------- openair1/PHY/INIT/nr_init_ue.c | 18 ------- openair1/PHY/NR_REFSIG/nr_refsig.h | 6 --- openair1/PHY/NR_REFSIG/nr_refsig_common.h | 1 + openair1/PHY/NR_REFSIG/refsig.c | 8 +++ openair1/PHY/NR_REFSIG/refsig_defs_ue.h | 1 - openair1/PHY/NR_TRANSPORT/nr_csi_rs.c | 53 +++++++------------ .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 1 - openair1/PHY/defs_nr_common.h | 2 - 9 files changed, 28 insertions(+), 83 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 93f5de1a66..61a517c962 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -152,21 +152,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) // CSI RS init // ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32) - int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1; gNB->nr_csi_info = (nr_csi_info_t *)malloc16_clear(sizeof(nr_csi_info_t)); - gNB->nr_csi_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame * sizeof(uint32_t **)); - AssertFatal(gNB->nr_csi_info->nr_gold_csi_rs != NULL, "NR init: csi reference signal malloc failed\n"); - for (int slot=0; slotslots_per_frame; slot++) { - gNB->nr_csi_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot * sizeof(uint32_t *)); - AssertFatal(gNB->nr_csi_info->nr_gold_csi_rs[slot] != NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot); - for (int symb=0; symbsymbols_per_slot; symb++) { - gNB->nr_csi_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length * sizeof(uint32_t)); - AssertFatal(gNB->nr_csi_info->nr_gold_csi_rs[slot][symb] != NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb); - } - } - - gNB->nr_csi_info->csi_gold_init = cfg->cell_config.phy_cell_id.value; - nr_init_csi_rs(&gNB->frame_parms, gNB->nr_csi_info->nr_gold_csi_rs, cfg->cell_config.phy_cell_id.value); //PRS init nr_init_prs(gNB); @@ -266,13 +252,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(meas->n0_subband_power); free_and_zero(meas->n0_subband_power_dB); - uint32_t ***nr_gold_csi_rs = gNB->nr_csi_info->nr_gold_csi_rs; - for (int slot = 0; slot < fp->slots_per_frame; slot++) { - for (int symb = 0; symb < fp->symbols_per_slot; symb++) - free_and_zero(nr_gold_csi_rs[slot][symb]); - free_and_zero(nr_gold_csi_rs[slot]); - } - free_and_zero(nr_gold_csi_rs); free_and_zero(gNB->nr_csi_info); for (int id = 0; id < gNB->max_nb_srs; id++) { diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 8220733402..13f4922440 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -296,18 +296,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) srs_vars[gNB_id]->active = false; // ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32) - int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1; ue->nr_csi_info = malloc16_clear(sizeof(nr_csi_info_t)); - ue->nr_csi_info->nr_gold_csi_rs = malloc16(fp->slots_per_frame * sizeof(uint32_t **)); - AssertFatal(ue->nr_csi_info->nr_gold_csi_rs != NULL, "NR init: csi reference signal malloc failed\n"); - for (int slot=0; slotslots_per_frame; slot++) { - ue->nr_csi_info->nr_gold_csi_rs[slot] = malloc16(fp->symbols_per_slot * sizeof(uint32_t *)); - AssertFatal(ue->nr_csi_info->nr_gold_csi_rs[slot] != NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot); - for (int symb=0; symbsymbols_per_slot; symb++) { - ue->nr_csi_info->nr_gold_csi_rs[slot][symb] = malloc16(csi_dmrs_init_length * sizeof(uint32_t)); - AssertFatal(ue->nr_csi_info->nr_gold_csi_rs[slot][symb] != NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb); - } - } ue->nr_csi_info->csi_rs_generated_signal = malloc16(NR_MAX_NB_PORTS * sizeof(int32_t *)); for (i=0; inr_csi_info->csi_rs_generated_signal[i] = malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t)); @@ -362,13 +351,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) free_and_zero(ue->nr_csi_info->csi_rs_generated_signal[i]); } free_and_zero(ue->nr_csi_info->csi_rs_generated_signal); - for (int slot=0; slotslots_per_frame; slot++) { - for (int symb=0; symbsymbols_per_slot; symb++) { - free_and_zero(ue->nr_csi_info->nr_gold_csi_rs[slot][symb]); - } - free_and_zero(ue->nr_csi_info->nr_gold_csi_rs[slot]); - } - free_and_zero(ue->nr_csi_info->nr_gold_csi_rs); free_and_zero(ue->nr_csi_info); free_and_zero(ue->nr_srs_info); diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index 7aad67f7af..97b2bb0d37 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -35,12 +35,6 @@ This function generates NR Gold Sequence(ts 138.211) for the PRS. */ void nr_init_prs(PHY_VARS_gNB* gNB); -/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS. -@param PHY_VARS_gNB* gNB structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables -@param Nid is used for the initialization of x2, Physical cell Id by default or upper layer configured pdcch_scrambling_ID - */ -void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid); - int nr_pusch_dmrs_delta(uint8_t dmrs_config_type, unsigned short p); int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, diff --git a/openair1/PHY/NR_REFSIG/nr_refsig_common.h b/openair1/PHY/NR_REFSIG/nr_refsig_common.h index 03f5153ca3..e43c9f10d1 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig_common.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig_common.h @@ -29,5 +29,6 @@ uint32_t *nr_gold_pbch(int Lmax, int Nid, int n_hf, int ssb); uint32_t *nr_gold_pdcch(int N_RB_DL, int symbols_per_slot, unsigned short n_idDMRS, int ns, int l); uint32_t *nr_gold_pdsch(int N_RB_DL, int symbols_per_slot, int nid, int nscid, int slot, int symbol); uint32_t *nr_gold_pusch(int N_RB_UL, int symbols_per_slot, int Nid, int nscid, int slot, int symbol); +uint32_t *nr_gold_csi_rs(int N_RB_DL, int symbols_per_slot, int slot, int symb, uint32_t Nid); #endif diff --git a/openair1/PHY/NR_REFSIG/refsig.c b/openair1/PHY/NR_REFSIG/refsig.c index 3e7e5549ea..5946227d85 100644 --- a/openair1/PHY/NR_REFSIG/refsig.c +++ b/openair1/PHY/NR_REFSIG/refsig.c @@ -197,3 +197,11 @@ uint32_t *nr_gold_pusch(int N_RB_UL, int symbols_per_slot, int Nid, int nscid, i { return nr_gold_pdsch(N_RB_UL, symbols_per_slot, Nid, nscid, slot, symbol); } + +uint32_t *nr_gold_csi_rs(int N_RB_DL, int symbols_per_slot, int slot, int symb, uint32_t Nid) +{ + int csi_dmrs_init_length = ((N_RB_DL << 4) >> 5) + 1; + uint64_t temp_x2 = (1ULL << 10) * ((uint64_t)symbols_per_slot * slot + symb + 1) * ((Nid << 1) + 1) + Nid; + uint32_t x2 = temp_x2 % (1U << 31); + return gold_cache(x2, csi_dmrs_init_length); +} diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index a90383c254..290ea89ffe 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -51,7 +51,6 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, unsigned short nb_pdsch_rb, uint8_t config_type); -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); diff --git a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c index 001ad8ad87..3c859a7e67 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c @@ -24,23 +24,6 @@ //#define NR_CSIRS_DEBUG - -void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid) -{ - uint32_t x1 = 0; - int csi_dmrs_init_length = ((fp->N_RB_DL << 4) >> 5) + 1; - for (int slot = 0; slot < fp->slots_per_frame; slot++) { - for (int symb = 0; symb < fp->symbols_per_slot; symb++) { - uint8_t reset = 1; - uint32_t x2 = ((1 << 10) * (fp->symbols_per_slot * slot + symb + 1) * ((Nid << 1) + 1) + Nid); - for (uint32_t n = 0; n < csi_dmrs_init_length; n++) { - csi_rs[slot][symb][n] = lte_gold_generic(&x1, &x2, reset); - reset = 0; - } - } - } -} - void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, int32_t **dataF, const int16_t amp, @@ -74,7 +57,6 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, #endif int dataF_offset = slot * frame_parms->samples_per_slot_wCP; - uint32_t **nr_gold_csi_rs = nr_csi_info->nr_gold_csi_rs[slot]; //*8(max allocation per RB)*2(QPSK)) int csi_rs_length = frame_parms->N_RB_DL << 4; int16_t mod_csi[frame_parms->symbols_per_slot][csi_rs_length>>1] __attribute__((aligned(16))); @@ -82,19 +64,11 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, uint32_t beta = amp; nr_csi_info->csi_rs_generated_signal_bits = log2_approx(amp); - AssertFatal(b!=0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n"); - - // if the scrambling id is not the one previously used to initialize we need to re-initialize the rs - if (csi_params->scramb_id != nr_csi_info->csi_gold_init) { - nr_csi_info->csi_gold_init = csi_params->scramb_id; - nr_init_csi_rs(frame_parms, nr_csi_info->nr_gold_csi_rs, csi_params->scramb_id); - } - + AssertFatal(b != 0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n"); int size, ports, kprime, lprime; int j[16], k_n[6], koverline[16], loverline[16]; int found = 0; int fi = 0; - // implementation of table 7.4.1.5.3-1 of 38.211 // lprime and kprime are the max value of l' and k' switch (csi_params->row) { @@ -581,14 +555,25 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, for (int lp = 0; lp <= lprime; lp++) { int symb = csi_params->symb_l0; - nr_modulation(nr_gold_csi_rs[symb + lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]); - if ((csi_params->row == 5) || (csi_params->row == 7) || (csi_params->row == 11) || (csi_params->row == 13) || (csi_params->row == 16)) - nr_modulation(nr_gold_csi_rs[symb + 1], csi_length, DMRS_MOD_ORDER, mod_csi[symb + 1]); - if ((csi_params->row == 14) || (csi_params->row == 13) || (csi_params->row == 16) || (csi_params->row == 17)) { + const uint32_t *gold = + nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + lp, csi_params->scramb_id); + nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]); + uint8_t row = csi_params->row; + if ((row == 5) || (row == 7) || (row == 11) || (row == 13) || (row == 16)) { + const uint32_t *gold = + nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + 1, csi_params->scramb_id); + nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + 1]); + } + if ((row == 14) || (row == 13) || (row == 16) || (row == 17)) { symb = csi_params->symb_l1; - nr_modulation(nr_gold_csi_rs[symb + lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]); - if ((csi_params->row == 13) || (csi_params->row == 16)) - nr_modulation(nr_gold_csi_rs[symb + 1], csi_length, DMRS_MOD_ORDER, mod_csi[symb + 1]); + const uint32_t *gold = + nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + lp, csi_params->scramb_id); + nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]); + if ((row == 13) || (row == 16)) { + const uint32_t *gold = + nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + 1, csi_params->scramb_id); + nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + 1]); + } } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 5d15dc86a4..8febf221d2 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -407,7 +407,6 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, // the n_frames we got sync ue->init_sync_frame = n_frames - 1 - res.syncRes.frame_id; - nr_init_csi_rs(fp, ue->nr_csi_info->nr_gold_csi_rs, fp->Nid_cell); // we also need to take into account the shift by samples_per_frame in case the if is true if (res.ssbOffset < sync_pos_frame) { res.syncRes.rx_offset = fp->samples_per_frame - sync_pos_frame + res.ssbOffset; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 9c2dff22b8..d3122eb78f 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -122,8 +122,6 @@ typedef struct { } nr_srs_info_t; typedef struct { - uint16_t csi_gold_init; - uint32_t ***nr_gold_csi_rs; uint8_t csi_rs_generated_signal_bits; int32_t **csi_rs_generated_signal; bool csi_im_meas_computed; From 00cb43bac399060b59f3416980a9e19a4e3ee1e8 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 26 Jul 2024 14:59:47 +0200 Subject: [PATCH 33/38] Use gold cache for PRS decoding --- openair1/PHY/INIT/nr_init.c | 15 ------ openair1/PHY/INIT/nr_init_ue.c | 44 ---------------- openair1/PHY/NR_REFSIG/nr_gold.c | 52 ------------------- openair1/PHY/NR_REFSIG/nr_gold_ue.c | 37 ------------- openair1/PHY/NR_REFSIG/nr_refsig.h | 8 --- openair1/PHY/NR_REFSIG/nr_refsig_common.h | 1 + openair1/PHY/NR_REFSIG/refsig.c | 13 +++++ openair1/PHY/NR_REFSIG/refsig_defs_ue.h | 1 - openair1/PHY/NR_TRANSPORT/nr_prs.c | 17 +++--- openair1/PHY/NR_TRANSPORT/nr_scrambling.c | 1 + .../PHY/NR_TRANSPORT/nr_transport_proto.h | 2 +- .../PHY/NR_TRANSPORT/nr_uci_tools_common.c | 2 + openair1/PHY/NR_TRANSPORT/pucch_rx.c | 1 + .../nr_dl_channel_estimation.c | 9 ++-- openair1/PHY/defs_gNB.h | 3 -- openair1/PHY/defs_nr_UE.h | 3 -- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 2 +- 17 files changed, 34 insertions(+), 177 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 61a517c962..8663fe37b9 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -154,9 +154,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) // ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32) gNB->nr_csi_info = (nr_csi_info_t *)malloc16_clear(sizeof(nr_csi_info_t)); - //PRS init - nr_init_prs(gNB); - generate_ul_reference_signal_sequences(SHRT_MAX); /* Generate low PAPR type 1 sequences for PUSCH DMRS, these are used if transform precoding is enabled. */ @@ -240,7 +237,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) void phy_free_nr_gNB(PHY_VARS_gNB *gNB) { - NR_DL_FRAME_PARMS* const fp = &gNB->frame_parms; const int Ptx = gNB->gNB_config.carrier_config.num_tx_ant.value; const int Prx = gNB->gNB_config.carrier_config.num_rx_ant.value; const int max_ul_mimo_layers = 4; // taken from phy_init_nr_gNB() @@ -274,17 +270,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(common_vars->beam_id[i]); } - for (int rsc=0; rsc < gNB->prs_vars.NumPRSResources; rsc++) { - for (int slot=0; slotslots_per_frame; slot++) { - for (int symb=0; symbsymbols_per_slot; symb++) { - free_and_zero(gNB->nr_gold_prs[rsc][slot][symb]); - } - free_and_zero(gNB->nr_gold_prs[rsc][slot]); - } - free_and_zero(gNB->nr_gold_prs[rsc]); - } - free_and_zero(gNB->nr_gold_prs); - /* Do NOT free per-antenna txdataF/rxdataF: the gNB gets a pointer to the * RU's txdataF/rxdataF, and the RU will free that */ free_and_zero(common_vars->txdataF); diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 13f4922440..d0191b0225 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -162,32 +162,6 @@ void init_nr_prs_ue_vars(PHY_VARS_NR_UE *ue) // load the config file params RCconfig_nrUE_prs(ue); - - //PRS sequence init - ue->nr_gold_prs = malloc16(ue->prs_active_gNBs * sizeof(uint32_t ****)); - uint32_t *****prs = ue->nr_gold_prs; - AssertFatal(prs!=NULL, "%s: positioning reference signal malloc failed\n", __FUNCTION__); - for (int gnb = 0; gnb < ue->prs_active_gNBs; gnb++) { - prs[gnb] = malloc16(ue->prs_vars[gnb]->NumPRSResources * sizeof(uint32_t ***)); - AssertFatal(prs[gnb]!=NULL, "%s: positioning reference signal for gnb %d - malloc failed\n", __FUNCTION__, gnb); - - for (int rsc = 0; rsc < ue->prs_vars[gnb]->NumPRSResources; rsc++) { - prs[gnb][rsc] = malloc16(fp->slots_per_frame * sizeof(uint32_t **)); - AssertFatal(prs[gnb][rsc]!=NULL, "%s: positioning reference signal for gnb %d rsc %d- malloc failed\n", __FUNCTION__, gnb, rsc); - - for (int slot=0; slotslots_per_frame; slot++) { - prs[gnb][rsc][slot] = malloc16(fp->symbols_per_slot * sizeof(uint32_t *)); - AssertFatal(prs[gnb][rsc][slot]!=NULL, "%s: positioning reference signal for gnb %d rsc %d slot %d - malloc failed\n", __FUNCTION__, gnb, rsc, slot); - - for (int symb=0; symbsymbols_per_slot; symb++) { - prs[gnb][rsc][slot][symb] = malloc16(NR_MAX_PRS_INIT_LENGTH_DWORD * sizeof(uint32_t)); - AssertFatal(prs[gnb][rsc][slot][symb]!=NULL, "%s: positioning reference signal for gnb %d rsc %d slot %d symbol %d - malloc failed\n", __FUNCTION__, gnb, rsc, slot, symb); - } // for symb - } // for slot - } // for rsc - } // for gnb - - init_nr_gold_prs(ue); } int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) @@ -362,24 +336,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) free_and_zero(ue->prach_vars[gNB_id]); } - for (int gnb = 0; gnb < ue->prs_active_gNBs; gnb++) - { - for (int rsc = 0; rsc < ue->prs_vars[gnb]->NumPRSResources; rsc++) - { - for (int slot=0; slotslots_per_frame; slot++) - { - for (int symb=0; symbsymbols_per_slot; symb++) - { - free_and_zero(ue->nr_gold_prs[gnb][rsc][slot][symb]); - } - free_and_zero(ue->nr_gold_prs[gnb][rsc][slot]); - } - free_and_zero(ue->nr_gold_prs[gnb][rsc]); - } - free_and_zero(ue->nr_gold_prs[gnb]); - } - free_and_zero(ue->nr_gold_prs); - for(int idx = 0; idx < NR_MAX_PRS_COMB_SIZE; idx++) { for(int k = 0; k < NR_MAX_PRS_RESOURCES_PER_SET; k++) diff --git a/openair1/PHY/NR_REFSIG/nr_gold.c b/openair1/PHY/NR_REFSIG/nr_gold.c index 066707029b..d50ecaa94b 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold.c +++ b/openair1/PHY/NR_REFSIG/nr_gold.c @@ -20,55 +20,3 @@ */ #include "nr_refsig.h" - -void nr_init_prs(PHY_VARS_gNB* gNB) -{ - unsigned int x1 = 0, x2 = 0; - uint16_t Nid; - - NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - gNB->nr_gold_prs = (uint32_t ****)malloc16(gNB->prs_vars.NumPRSResources*sizeof(uint32_t ***)); - uint32_t ****prs = gNB->nr_gold_prs; - AssertFatal(prs!=NULL, "NR init: positioning reference signal malloc failed\n"); - for (int rsc=0; rsc < gNB->prs_vars.NumPRSResources; rsc++) { - prs[rsc] = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **)); - AssertFatal(prs[rsc]!=NULL, "NR init: positioning reference signal for rsc %d - malloc failed\n", rsc); - - for (int slot=0; slotslots_per_frame; slot++) { - prs[rsc][slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *)); - AssertFatal(prs[rsc][slot]!=NULL, "NR init: positioning reference signal for slot %d - malloc failed\n", slot); - - for (int symb=0; symbsymbols_per_slot; symb++) { - prs[rsc][slot][symb] = (uint32_t *)malloc16(NR_MAX_PRS_INIT_LENGTH_DWORD*sizeof(uint32_t)); - AssertFatal(prs[rsc][slot][symb]!=NULL, "NR init: positioning reference signal for rsc %d slot %d symbol %d - malloc failed\n", rsc, slot, symb); - } - } - } - - uint8_t reset; - uint8_t slotNum, symNum, rsc_id; - - for (rsc_id = 0; rsc_id < gNB->prs_vars.NumPRSResources; rsc_id++) { - Nid = gNB->prs_vars.prs_cfg[rsc_id].NPRSID; // seed value - LOG_I(PHY, "Initiaized NR-PRS sequence with PRS_ID %3d for resource %d\n", Nid, rsc_id); - for (slotNum = 0; slotNum < fp->slots_per_frame; slotNum++) { - for (symNum = 0; symNum < fp->symbols_per_slot ; symNum++) { - reset = 1; - // initial x2 for prs as ts138.211 - uint32_t c_init1, c_init2, c_init3; - uint32_t pow22=1<<22; - uint32_t pow10=1<<10; - c_init1 = pow22*ceil(Nid/1024); - c_init2 = pow10*(slotNum+symNum+1)*(2*(Nid%1024)+1); - c_init3 = Nid%1024; - x2 = c_init1 + c_init2 + c_init3; - - for (uint8_t n=0; nnr_gold_prs[rsc_id][slotNum][symNum][n] = lte_gold_generic(&x1, &x2, reset); - reset = 0; - //printf("%d \n",gNB->nr_gold_prs[slotNum][symNum][n]); - } - } - } - } -} diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c index f9c23b33b8..4cb75e0f78 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold_ue.c +++ b/openair1/PHY/NR_REFSIG/nr_gold_ue.c @@ -22,43 +22,6 @@ #include "refsig_defs_ue.h" #include "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic() -void init_nr_gold_prs(PHY_VARS_NR_UE* ue) -{ - unsigned int x1 = 0, x2 = 0; - uint16_t Nid; - - NR_DL_FRAME_PARMS *fp = &ue->frame_parms; - uint8_t reset; - uint8_t slotNum, symNum, gnb, rsc; - - for(gnb = 0; gnb < ue->prs_active_gNBs; gnb++) { - for(rsc = 0; rsc < ue->prs_vars[gnb]->NumPRSResources; rsc++) { - Nid = ue->prs_vars[gnb]->prs_resource[rsc].prs_cfg.NPRSID; // seed value - LOG_I(PHY,"Initialised NR-PRS sequence with PRS_ID %3d for resource %d\n",Nid, rsc); - for (slotNum = 0; slotNum < fp->slots_per_frame; slotNum++) { - for (symNum = 0; symNum < fp->symbols_per_slot ; symNum++) { - reset = 1; - // initial x2 for prs as ts138.211 - uint32_t c_init1, c_init2, c_init3; - uint32_t pow22=1<<22; - uint32_t pow10=1<<10; - c_init1 = pow22*ceil(Nid/1024); - c_init2 = pow10*(slotNum+symNum+1)*(2*(Nid%1024)+1); - c_init3 = Nid%1024; - x2 = c_init1 + c_init2 + c_init3; - - for (uint8_t n=0; nnr_gold_prs[gnb][rsc][slotNum][symNum][n] = lte_gold_generic(&x1, &x2, reset); - reset = 0; - //printf("%d \n",gNB->nr_gold_prs[slotNum][symNum][n]); - - } - } - } - } // for rsc - } // for gnb -} - void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE) { unsigned int x1, x2; diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index 97b2bb0d37..8636c9972a 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -26,14 +26,6 @@ #include "PHY/defs_gNB.h" #include "openair1/PHY/NR_REFSIG/nr_refsig_common.h" -#include "PHY/LTE_REFSIG/lte_refsig.h" -#include "PHY/sse_intrin.h" - -/* -This function generates NR Gold Sequence(ts 138.211) for the PRS. -@param PHY_VARS_gNB* gNB structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables -*/ -void nr_init_prs(PHY_VARS_gNB* gNB); int nr_pusch_dmrs_delta(uint8_t dmrs_config_type, unsigned short p); diff --git a/openair1/PHY/NR_REFSIG/nr_refsig_common.h b/openair1/PHY/NR_REFSIG/nr_refsig_common.h index e43c9f10d1..46678424f6 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig_common.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig_common.h @@ -30,5 +30,6 @@ uint32_t *nr_gold_pdcch(int N_RB_DL, int symbols_per_slot, unsigned short n_idDM uint32_t *nr_gold_pdsch(int N_RB_DL, int symbols_per_slot, int nid, int nscid, int slot, int symbol); uint32_t *nr_gold_pusch(int N_RB_UL, int symbols_per_slot, int Nid, int nscid, int slot, int symbol); uint32_t *nr_gold_csi_rs(int N_RB_DL, int symbols_per_slot, int slot, int symb, uint32_t Nid); +uint32_t *nr_gold_prs(int nid, int slot, int symbol); #endif diff --git a/openair1/PHY/NR_REFSIG/refsig.c b/openair1/PHY/NR_REFSIG/refsig.c index 5946227d85..871e1aa805 100644 --- a/openair1/PHY/NR_REFSIG/refsig.c +++ b/openair1/PHY/NR_REFSIG/refsig.c @@ -205,3 +205,16 @@ uint32_t *nr_gold_csi_rs(int N_RB_DL, int symbols_per_slot, int slot, int symb, uint32_t x2 = temp_x2 % (1U << 31); return gold_cache(x2, csi_dmrs_init_length); } + +uint32_t *nr_gold_prs(int Nid, int slotNum, int symNum) +{ + LOG_D(PHY, "Initialised NR-PRS sequence for PCI %d\n", Nid); + // initial x2 for prs as ts138.211 + uint32_t pow22 = 1 << 22; + uint32_t pow10 = 1 << 10; + uint32_t c_init1 = pow22 * ceil(Nid / 1024); + uint32_t c_init2 = pow10 * (slotNum + symNum + 1) * (2 * (Nid % 1024) + 1); + uint32_t c_init3 = Nid % 1024; + uint32_t x2 = c_init1 + c_init2 + c_init3; + return gold_cache(x2, NR_MAX_PRS_INIT_LENGTH_DWORD); +} diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index 290ea89ffe..7df105d05c 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -51,7 +51,6 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, unsigned short nb_pdsch_rb, uint8_t config_type); -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); diff --git a/openair1/PHY/NR_TRANSPORT/nr_prs.c b/openair1/PHY/NR_TRANSPORT/nr_prs.c index 4a93e4d66a..382e995a65 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prs.c @@ -3,18 +3,18 @@ #include "PHY/LTE_REFSIG/lte_refsig.h" #include "PHY/NR_REFSIG/nr_refsig.h" #include "PHY/sse_intrin.h" - +#include "openair1/PHY/NR_REFSIG/refsig_defs_ue.h" //#define DEBUG_PRS_MOD //#define DEBUG_PRS_MAP extern short nr_qpsk_mod_table[8]; -int nr_generate_prs(uint32_t **nr_gold_prs, - c16_t *txdataF, - int16_t amp, - prs_config_t *prs_cfg, - nfapi_nr_config_request_scf_t *config, - NR_DL_FRAME_PARMS *frame_parms) +int nr_generate_prs(int slot, + c16_t *txdataF, + int16_t amp, + prs_config_t *prs_cfg, + nfapi_nr_config_request_scf_t *config, + NR_DL_FRAME_PARMS *frame_parms) { int k_prime = 0, k = 0, idx; @@ -42,8 +42,9 @@ int nr_generate_prs(uint32_t **nr_gold_prs, k = (prs_cfg->REOffset+k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset*12 + frame_parms->first_carrier_offset; // QPSK modulation + uint32_t *gold = nr_gold_prs(prs_cfg->NPRSID, slot, l); for (int m = 0; m < (12/prs_cfg->CombSize) * prs_cfg->NumRB; m++) { - idx = (((nr_gold_prs[l][(m<<1)>>5])>>((m<<1)&0x1f))&3); + idx = (((gold[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 3); mod_prs[m<<1] = nr_qpsk_mod_table[idx<<1]; mod_prs[(m<<1)+1] = nr_qpsk_mod_table[(idx<<1) + 1]; diff --git a/openair1/PHY/NR_TRANSPORT/nr_scrambling.c b/openair1/PHY/NR_TRANSPORT/nr_scrambling.c index 353db70454..23c5aa9d4e 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_scrambling.c +++ b/openair1/PHY/NR_TRANSPORT/nr_scrambling.c @@ -21,6 +21,7 @@ #include "nr_transport_common_proto.h" #include "PHY/NR_REFSIG/nr_refsig.h" +#include "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic() #include "common/utils/LOG/vcd_signal_dumper.h" #define DEBUG_SCRAMBLING(a) //#define DEBUG_SCRAMBLING(a) a diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 75d77f211a..a8b9e8ebf6 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -40,7 +40,7 @@ NR_gNB_PHY_STATS_t *get_phy_stats(PHY_VARS_gNB *gNB, uint16_t rnti); -int nr_generate_prs(uint32_t **nr_gold_prs, +int nr_generate_prs(int slot, c16_t *txdataF, int16_t amp, prs_config_t *prs_cfg, diff --git a/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c b/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c index 1c3d0f7008..da9f1acfe5 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c +++ b/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c @@ -31,6 +31,8 @@ */ #include "nr_dci.h" +#include "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic() + void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping, uint32_t n_id, diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 05d7f03832..eee3778c6a 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -43,6 +43,7 @@ #include "PHY/sse_intrin.h" #include "PHY/NR_UE_TRANSPORT/pucch_nr.h" #include +#include "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic() #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_REFSIG/nr_refsig.h" 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 2e3059ee9c..4eec02d240 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -89,9 +89,9 @@ int nr_prs_channel_estimation(uint8_t gNB_id, memset(ch_tmp_buf,0,sizeof(ch_tmp_buf)); memset(chF_interpol,0,sizeof(chF_interpol)); memset(chT_interpol,0,sizeof(chF_interpol)); - - int slot_prs = (proc->nr_slot_rx - rep_num*prs_cfg->PRSResourceTimeGap + frame_params->slots_per_frame)%frame_params->slots_per_frame; - uint32_t **nr_gold_prs = ue->nr_gold_prs[gNB_id][rsc_id][slot_prs]; + + int slot_prs = + (proc->nr_slot_rx - rep_num * prs_cfg->PRSResourceTimeGap + frame_params->slots_per_frame) % frame_params->slots_per_frame; int16_t *rxF, *pil, mod_prs[NR_MAX_PRS_LENGTH << 1]; const int16_t *fl, *fm, *fmm, *fml, *fmr, *fr; @@ -113,6 +113,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, int16_t k_prime_table[K_PRIME_TABLE_ROW_SIZE][K_PRIME_TABLE_COL_SIZE] = PRS_K_PRIME_TABLE; for(int l = prs_cfg->SymbolStart; l < prs_cfg->SymbolStart+prs_cfg->NumPRSSymbols; l++) { + uint32_t *gold_prs = nr_gold_prs(ue->prs_vars[gNB_id]->prs_resource[rsc_id].prs_cfg.NPRSID, slot_prs, l); int symInd = l-prs_cfg->SymbolStart; if (prs_cfg->CombSize == 2) { k_prime = k_prime_table[0][symInd]; @@ -135,7 +136,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, AssertFatal(num_pilots > 0, "num_pilots needs to be gt 0 or mod_prs[0] UB"); for (int m = 0; m < num_pilots; m++) { - idx = (((nr_gold_prs[l][(m<<1)>>5])>>((m<<1)&0x1f))&3); + idx = (((gold_prs[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 3); mod_prs[m<<1] = nr_qpsk_mod_table[idx<<1]; mod_prs[(m<<1)+1] = nr_qpsk_mod_table[(idx<<1) + 1]; } diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index de83c257e5..1cb7d256fd 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -609,9 +609,6 @@ typedef struct PHY_VARS_gNB_s { /// PBCH interleaver uint8_t nr_pbch_interleaver[NR_POLAR_PBCH_PAYLOAD_BITS]; - /// PRS sequence - uint32_t ****nr_gold_prs; - /// PRACH root sequence c16_t X_u[64][839]; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 0dafde1ec2..db3e47aa1d 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -408,9 +408,6 @@ typedef struct PHY_VARS_NR_UE_s { #endif // Scrambling IDs used in PUSCH DMRS - // PRS sequence per gNB, per resource - uint32_t *****nr_gold_prs; - c16_t X_u[64][839]; // flag to activate PRB based averaging of channel estimates diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 8386752e81..97205f28c7 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -179,7 +179,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, { slot_prs = (slot - i*prs_config->PRSResourceTimeGap + fp->slots_per_frame)%fp->slots_per_frame; LOG_D(PHY,"gNB_TX: frame %d, slot %d, slot_prs %d, PRS Resource ID %d\n",frame, slot, slot_prs, rsc_id); - nr_generate_prs(gNB->nr_gold_prs[rsc_id][slot_prs],&gNB->common_vars.txdataF[0][txdataF_offset], AMP, prs_config, cfg, fp); + nr_generate_prs(slot_prs, &gNB->common_vars.txdataF[0][txdataF_offset], AMP, prs_config, cfg, fp); } } } From f207ac12be62c13ac4c01648c6bf54d87bd6c198 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Sun, 16 Jun 2024 12:01:16 +0200 Subject: [PATCH 34/38] Use gold cache in UCI --- .../PHY/NR_TRANSPORT/nr_uci_tools_common.c | 61 ++++++++----------- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c b/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c index da9f1acfe5..b6b56ec79f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c +++ b/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c @@ -31,8 +31,6 @@ */ #include "nr_dci.h" -#include "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic() - void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping, uint32_t n_id, @@ -65,11 +63,7 @@ void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping, #endif uint8_t f_ss=0,f_gh=0; *u=0; - *v=0; - uint32_t c_init = 0; - uint32_t x1,s; // TS 38.211 Subclause 5.2.1 - int l = 32, minShift = ((2*nr_slot_tx+n_hop)<<3); - int tmpShift =0; + *v = 0; #ifdef DEBUG_NR_PUCCH_TX printf("\t\t [nr_group_sequence_hopping] calculating u,v -> "); #endif @@ -79,41 +73,39 @@ void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping, } if (PUCCH_GroupHopping == enable) { // PUCCH_GroupHopping 'enabled' - c_init = floor(n_id/30); // we initialize c_init to calculate u,v according to 6.3.2.2.1 of 38.211 - s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 + uint32_t c_init = floor(n_id / 30); // we initialize c_init to calculate u,v according to 6.3.2.2.1 of 38.211 + int l = 32, minShift = (2 * nr_slot_tx + n_hop) << 3; + uint32_t *seq = gold_cache(c_init, (minShift + 31) / 32 + 8); // TS 38.211 Subclause 5.2.1 + int goldIdx = 0; for (int m=0; m<8; m++) { while(minShift >= l) { - s = lte_gold_generic(&x1, &c_init, 0); + goldIdx++; l = l+32; } - - tmpShift = (minShift&((1<<5)-1)); //minShift%32; - f_gh = f_gh + ((1<>tmpShift)&1))); + AssertFatal(goldIdx < 8 + (minShift + 31) / 32, ""); + int tmpShift = (minShift & ((1 << 5) - 1)); // minShift%32; + f_gh = f_gh + ((1 << m) * ((uint8_t)((seq[goldIdx] >> tmpShift) & 1))); minShift ++; } f_gh = f_gh%30; - f_ss = n_id%30; - /* for (int m=0; m<8; m++){ - f_gh = f_gh + ((1<>(8*(2*nr_slot_tx+n_hop)+m))&1))); // Not sure we have to use nr_slot_tx FIXME!!! - } - f_gh = f_gh%30; - f_ss = n_id%30;*/ + f_ss = n_id % 30; } if (PUCCH_GroupHopping == disable) { // PUCCH_GroupHopping 'disabled' - c_init = (1<<5)*floor(n_id/30)+(n_id%30); // we initialize c_init to calculate u,v - s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 + uint32_t c_init = (1 << 5) * floor(n_id / 30) + (n_id % 30); // we initialize c_init to calculate u,v + int goldIdx = 0; f_ss = n_id%30; - l = 32, minShift = (2*nr_slot_tx+n_hop); + int l = 32, minShift = (2 * nr_slot_tx + n_hop); while(minShift >= l) { - s = lte_gold_generic(&x1, &c_init, 0); + goldIdx++; l = l+32; } - - tmpShift = (minShift&((1<<5)-1)); //minShift%32; - *v = (uint8_t)((s>>tmpShift)&1); + // TS 38.211 Subclause 5.2.1 + uint32_t *seq = gold_cache(c_init, goldIdx + 1); + int tmpShift = (minShift & ((1 << 5) - 1)); // minShift%32; + *v = (uint8_t)((seq[goldIdx] >> tmpShift) & 1); // *v = (uint8_t)((s>>(2*nr_slot_tx+n_hop))&1); // Not sure we have to use nr_slot_tx FIXME!!! } @@ -141,28 +133,27 @@ double nr_cyclic_shift_hopping(uint32_t n_id, double alpha = 0.5235987756; uint32_t c_init = n_id; // we initialize c_init again to calculate n_cs - uint32_t x1,s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 uint8_t n_cs=0; - int l = 32, minShift = (14*8*nr_slot_tx )+ 8*(lnormal+lprime); - int tmpShift =0; + int l = 32, minShift = (14 * 8 * nr_slot_tx) + 8 * (lnormal + lprime); #ifdef DEBUG_NR_PUCCH_TX printf("\t\t [nr_cyclic_shift_hopping] calculating alpha (cyclic shift) using c_init=%u -> \n",c_init); #endif - + uint32_t *seq = gold_cache(c_init, 8 + (minShift + 31) / 32); // TS 38.211 Subclause 5.2.1 + int goldIdx = 0; for (int m=0; m<8; m++) { while(minShift >= l) { - s = lte_gold_generic(&x1, &c_init, 0); + goldIdx++; l = l+32; } - - tmpShift = (minShift&((1<<5)-1)); //minShift%32; + AssertFatal(goldIdx < 8 + (minShift + 31) / 32, ""); + int tmpShift = (minShift & ((1 << 5) - 1)); // minShift%32; minShift ++; - n_cs = n_cs+((1<>tmpShift)&1))); + n_cs += (1 << m) * (uint8_t)((seq[goldIdx] >> tmpShift) & 1); // calculating n_cs (Not sure we have to use nr_slot_tx FIXME!!!) // n_cs = n_cs+((1<>((14*8*nr_slot_tx) + 8*(lnormal+lprime) + m))&1))); } - alpha = (alpha * (double)((m0+mcs+n_cs)%12)); + alpha = alpha * (double)((m0 + mcs + n_cs) % 12); #ifdef DEBUG_NR_PUCCH_TX printf("n_cs=%d -> %lf\n",n_cs,alpha); #endif From 803b0289a628ac94b15b9fa5b2dc5c9fb31e9339 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 26 Jul 2024 15:27:05 +0200 Subject: [PATCH 35/38] Use gold cache in code word (un)scrambling --- openair1/PHY/NR_TRANSPORT/nr_scrambling.c | 46 +++++++--------------- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 30 +++++--------- 2 files changed, 23 insertions(+), 53 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_scrambling.c b/openair1/PHY/NR_TRANSPORT/nr_scrambling.c index 23c5aa9d4e..b71ee0cce0 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_scrambling.c +++ b/openair1/PHY/NR_TRANSPORT/nr_scrambling.c @@ -21,7 +21,6 @@ #include "nr_transport_common_proto.h" #include "PHY/NR_REFSIG/nr_refsig.h" -#include "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic() #include "common/utils/LOG/vcd_signal_dumper.h" #define DEBUG_SCRAMBLING(a) //#define DEBUG_SCRAMBLING(a) a @@ -32,45 +31,32 @@ void nr_codeword_scrambling(uint8_t *in, uint32_t n_RNTI, uint32_t* out) { - uint32_t x1; - uint32_t x2 = (n_RNTI << 15) + (q << 14) + Nid; - uint32_t s = lte_gold_generic(&x1, &x2, 1); - for (int i = 0; i < ((size >> 5) + ((size & 0x1f) > 0 ? 1 : 0)); i++) { + const int roundedSz = (size + 31) / 32; + uint32_t *seq = gold_cache((n_RNTI << 15) + (q << 14) + Nid, roundedSz); + for (int i = 0; i < roundedSz; i++) { simde__m256i c = ((simde__m256i*)in)[i]; uint32_t in32 = simde_mm256_movemask_epi8(simde_mm256_slli_epi16(c, 7)); - out[i] = (in32 ^ s); + out[i] = in32 ^ seq[i]; DEBUG_SCRAMBLING(LOG_D(PHY, "in[%d] %x => %x\n", i, in32, out[i])); - s = lte_gold_generic(&x1, &x2, 0); } } void nr_codeword_unscrambling(int16_t* llr, uint32_t size, uint8_t q, uint32_t Nid, uint32_t n_RNTI) { - uint32_t x1; - uint32_t x2 = (n_RNTI << 15) + (q << 14) + Nid; - uint32_t s = 0; - + const int roundedSz = (size + 31) / 32; + uint32_t *seq = gold_cache((n_RNTI << 15) + (q << 14) + Nid, roundedSz); #if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__) - uint8_t *s8=(uint8_t *)&s; simde__m128i *llr128 = (simde__m128i*)llr; - s = lte_gold_generic(&x1, &x2, 1); - - for (int i = 0, j = 0; i < ((size >> 5) + ((size & 0x1f) > 0 ? 1 : 0)); i++, j += 4) { + for (int i = 0, j = 0; i < roundedSz; i++, j += 4) { + uint8_t *s8 = (uint8_t *)(seq + i); llr128[j] = simde_mm_mullo_epi16(llr128[j],byte2m128i[s8[0]]); llr128[j+1] = simde_mm_mullo_epi16(llr128[j+1],byte2m128i[s8[1]]); llr128[j+2] = simde_mm_mullo_epi16(llr128[j+2],byte2m128i[s8[2]]); - llr128[j+3] = simde_mm_mullo_epi16(llr128[j+3],byte2m128i[s8[3]]); - s = lte_gold_generic(&x1, &x2, 0); + llr128[j + 3] = simde_mm_mullo_epi16(llr128[j + 3], byte2m128i[s8[3]]); } #else - uint8_t reset = 1; - for (uint32_t i=0; i>(i&0x1f))&1)==1) + if (seq[i / 32] & (1U << (i % 32))) llr[i] = -llr[i]; } #endif @@ -78,18 +64,14 @@ void nr_codeword_unscrambling(int16_t* llr, uint32_t size, uint8_t q, uint32_t N void nr_codeword_unscrambling_init(int16_t *s2, uint32_t size, uint8_t q, uint32_t Nid, uint32_t n_RNTI) { - uint32_t x1; - uint32_t x2 = (n_RNTI << 15) + (q << 14) + Nid; + const int roundedSz = (size + 31) / 32; + uint32_t *seq = gold_cache((n_RNTI << 15) + (q << 14) + Nid, roundedSz); simde__m128i *s128=(simde__m128i *)s2; - - uint32_t s = lte_gold_generic(&x1, &x2, 1); - uint8_t *s8=(uint8_t *)&s; - - for (int i = 0; i < (size +31) >> 5; i++) { + for (int i = 0; i < roundedSz; i++) { + uint8_t *s8 = (uint8_t *)(seq + i); *s128++ = byte2m128i[s8[0]]; *s128++ = byte2m128i[s8[1]]; *s128++ = byte2m128i[s8[2]]; *s128++ = byte2m128i[s8[3]]; - s = lte_gold_generic(&x1, &x2, 0); } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 638d1e2e22..3425c23289 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -57,34 +57,22 @@ void nr_pusch_codeword_scrambling_uci(uint8_t *in, uint32_t size, uint32_t Nid, uint32_t n_RNTI, uint32_t* out) { - uint8_t reset, b_idx; - uint32_t x1 = 0, x2 = 0, s = 0, temp_out = 0; - - reset = 1; - x2 = (n_RNTI<<15) + Nid; - + uint32_t *seq = gold_cache((n_RNTI << 15) + Nid, (size + 31) / 32); for (int i=0; i>31; - + uint32_t temp_out = out[idx - 1]; + out[idx] ^= temp_out >> 31; } } else - *out ^= (((in[i])&1) ^ ((s>>b_idx)&1))<> b_idx) & 1)) << b_idx; //printf("i %d b_idx %d in %d s 0x%08x out 0x%08x\n", i, b_idx, in[i], s, *out); } } From 8e92df78dee9529470d54028b5fbddc36b0250e2 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Sun, 16 Jun 2024 12:25:37 +0200 Subject: [PATCH 36/38] Use gold cache in PUCCH decoding --- openair1/PHY/NR_TRANSPORT/pucch_rx.c | 32 +++++------ openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c | 71 +++++++++---------------- 2 files changed, 39 insertions(+), 64 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index eee3778c6a..b7534322cb 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -43,7 +43,6 @@ #include "PHY/sse_intrin.h" #include "PHY/NR_UE_TRANSPORT/pucch_nr.h" #include -#include "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic() #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_REFSIG/nr_refsig.h" @@ -1146,26 +1145,21 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, // first compute DMRS component - uint32_t x1 = 0, x2 = 0, sGold = 0; - uint8_t *sGold8 = (uint8_t *)&sGold; const int scramble = pucch_pdu->dmrs_scrambling_id * 2; // fixme: when MR2754 will be merged, use the gold sequence cache instead of regenerate each time - x2 = ((1ULL << 17) * ((NR_NUMBER_OF_SYMBOLS_PER_SLOT * slot + pucch_pdu->start_symbol_index + symb + 1) * (scramble + 1)) - + scramble) - % (1U << 31); // c_init calculation according to TS38.211 subclause + uint32_t x2 = + ((1ULL << 17) * ((NR_NUMBER_OF_SYMBOLS_PER_SLOT * slot + pucch_pdu->start_symbol_index + symb + 1) * (scramble + 1)) + + scramble) + % (1U << 31); // c_init calculation according to TS38.211 subclause #ifdef DEBUG_NR_PUCCH_RX printf("slot %d, start_symbol_index %d, symbol %d, dmrs_scrambling_id %d\n", slot,pucch_pdu->start_symbol_index,symb,pucch_pdu->dmrs_scrambling_id); #endif - int reset = 1; - for (int i=0; i<=(pucch_pdu->prb_start>>2); i++) { - sGold = lte_gold_generic(&x1, &x2, reset); - reset = 0; - } - - for (int group = 0; group < ngroup; group++) { + uint32_t *sGold = gold_cache(x2, pucch_pdu->prb_start / 4 + ngroup / 2); + for (int group = 0, goldIdx = pucch_pdu->prb_start / 4; group < ngroup; group++) { // each group has 8*nc_group_size elements, compute 1 complex correlation with DMRS per group // non-coherent combining across groups + uint8_t *sGold8 = (uint8_t *)&sGold[goldIdx]; simde__m64 dmrs_re = byte2m64_re[sGold8[(group & 1) << 1]]; int16_t *dmrs_re16 = (int16_t *)&dmrs_re; simde__m64 dmrs_im = byte2m64_im[sGold8[(group & 1) << 1]]; @@ -1238,22 +1232,22 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, } //aa if ((group & 1) == 1) - sGold = lte_gold_generic(&x1, &x2, 0); + goldIdx++; } // group } // symb - uint32_t x1, x2, sGold = 0; // unscrambling - x2 = ((pucch_pdu->rnti)<<15)+pucch_pdu->data_scrambling_id; - sGold = lte_gold_generic(&x1, &x2, 1); - uint8_t *sGold8 = (uint8_t *)&sGold; + uint32_t x2 = ((pucch_pdu->rnti) << 15) + pucch_pdu->data_scrambling_id; #ifdef DEBUG_NR_PUCCH_RX printf("x2 %x\n", x2); #endif + uint32_t *sGold = gold_cache(x2, pucch_pdu->nr_of_symbols * prb_size_ext / 2); + int goldIdx = 0; for (int symb=0;symbnr_of_symbols;symb++) { simde__m64 c_re[4], c_im[4]; int re_off=0; for (int prb=0;prb #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" +#include "openair1/PHY/NR_REFSIG/nr_refsig.h" #include "T.h" //#define NR_UNIT_TEST 1 @@ -484,46 +485,32 @@ void nr_generate_pucch1(const PHY_VARS_NR_UE *ue, } } -static inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint64_t *B64,uint8_t *btilde) { - uint32_t x1 = 0, x2 = 0, s = 0; - int i; - uint8_t c; +static inline void nr_pucch2_3_4_scrambling(uint16_t M_bit, uint16_t rnti, uint16_t n_id, uint64_t *B64, uint8_t *btilde) +{ // c_init=nRNTI*2^15+n_id according to TS 38.211 Subclause 6.3.2.6.1 - //x2 = (rnti) + ((uint32_t)(1+nr_slot_tx)<<16)*(1+(fp->Nid_cell<<1)); - x2 = ((rnti)<<15)+n_id; + const int roundedSz = (M_bit + 31) / 32; + uint32_t *seq = gold_cache((rnti << 15) + n_id, roundedSz); #ifdef DEBUG_NR_PUCCH_TX printf("\t\t [nr_pucch2_3_4_scrambling] gold sequence s=%x, M_bit %d\n",s,M_bit); #endif - uint8_t *btildep=btilde; - int M_bit2=M_bit > 31 ? 32 : (M_bit&31), M_bit3=M_bit; - uint32_t B; - for (int iprime=0;iprime<=(M_bit>>5);iprime++,btildep+=32) { - s = lte_gold_generic(&x1, &x2, (iprime==0) ? 1 : 0); - B=((uint32_t*)B64)[iprime]; - for (int n=0;n>n)&1, - (B>>(n+1))&1, - (B>>(n+2))&1, - (B>>(n+3))&1, - (B>>(n+4))&1, - (B>>(n+5))&1, - (B>>(n+6))&1, - (B>>(n+7))&1 - ); - for (i=0; i>i)&1); + uint8_t *btildep = btilde; + uint32_t *B32 = (uint32_t *)B64; + + for (int iprime = 0; iprime < roundedSz; iprime++, btildep += 32) { + const uint32_t s = seq[iprime]; + const uint32_t B = B32[iprime]; + LOG_D(PHY, "PUCCH2 encoded: %02x\n", B); + int M_bit2 = iprime == M_bit / 32 ? M_bit % 32 : 32; + for (int i = 0; i < M_bit2; i++) { + uint8_t c = (uint8_t)((s >> i) & 1); btildep[i] = (((B>>i)&1) ^ c); #ifdef DEBUG_NR_PUCCH_TX printf("\t\t\t btilde[%d]=%x from unscrambled bit %d and scrambling %d (%x)\n",i+(iprime<<5),btilde[i],((B>>i)&1),c,s>>i); #endif } - M_bit3-=32; - M_bit2=M_bit3 > 31 ? 32 : (M_bit3&31); } - #ifdef DEBUG_NR_PUCCH_TX printf("\t\t [nr_pucch2_3_4_scrambling] scrambling M_bit=%d bits\n", M_bit); #endif @@ -721,9 +708,7 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, * Implementing TS 38.211 Subclause 6.3.2.5.3 Mapping to physical resources */ // int32_t *txptr; - uint32_t x1 = 0, x2 = 0, s = 0; - int i=0; - int m=0; + int outSample = 0; uint8_t startingSymbolIndex = pucch_pdu->start_symbol_index; uint16_t startingPRB = pucch_pdu->prb_start + pucch_pdu->bwp_start; @@ -732,14 +717,10 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, uint64_t temp_x2 = 1ll << 17; temp_x2 *= 14UL * nr_slot_tx + l + startingSymbolIndex + 1; temp_x2 *= 2UL * pucch_pdu->dmrs_scrambling_id + 1; - x2 = (temp_x2 + 2UL * pucch_pdu->dmrs_scrambling_id) % (1UL << 31); - - int reset = 1; - for (int ii=0; ii<=(startingPRB>>2); ii++) { - s = lte_gold_generic(&x1, &x2, reset); - reset = 0; - } - m = 0; + temp_x2 = (temp_x2 + 2ULL * pucch_pdu->dmrs_scrambling_id) % (1UL << 31); + uint idxGold = startingPRB >> 2; + uint32_t *seq = gold_cache(temp_x2, idxGold + pucch_pdu->prb_size); + int m = 0; for (int rb=0; rbprb_size; rb++) { //startingPRB = startingPRB + rb; const bool nb_rb_is_even = frame_parms->N_RB_DL & 1; @@ -773,7 +754,7 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, } if (n%3 != 1) { // mapping PUCCH according to TS38.211 subclause 6.3.2.5.3 - txdataF[0][re_offset] = d[i + k]; + txdataF[0][re_offset] = d[outSample + k]; #ifdef DEBUG_NR_PUCCH_TX printf( "\t [nr_generate_pucch2] (n=%d,i=%d) mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d " @@ -795,8 +776,8 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, } if (n%3 == 1) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.2 - txdataF[0][re_offset].r = (int16_t)(baseVal * (1 - (2 * ((uint8_t)((s >> (2 * m)) & 1))))); - txdataF[0][re_offset].i = (int16_t)(baseVal * (1 - (2 * ((uint8_t)((s >> (2 * m + 1)) & 1))))); + txdataF[0][re_offset].r = (int16_t)(baseVal * (1 - (2 * ((uint8_t)((seq[idxGold] >> (2 * m)) & 1))))); + txdataF[0][re_offset].i = (int16_t)(baseVal * (1 - (2 * ((uint8_t)((seq[idxGold] >> (2 * m + 1)) & 1))))); m++; #ifdef DEBUG_NR_PUCCH_TX printf( @@ -821,10 +802,10 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, re_offset++; } - i+=8; + outSample += 8; - if ((m&((1<<4)-1))==0) { - s = lte_gold_generic(&x1, &x2, 0); + if (m % 16 == 0) { + idxGold++; m = 0; } } From bb766be0c3d97ec844a33a27c9f6afb418c753ce Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 26 Jul 2024 15:02:22 +0200 Subject: [PATCH 37/38] Reformatting and cleanup --- openair1/PHY/INIT/nr_init_ue.c | 19 ++++++-------- .../nr_dl_channel_estimation.c | 25 ++++++------------- openair1/PHY/defs_nr_UE.h | 4 +-- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 2 +- 4 files changed, 18 insertions(+), 32 deletions(-) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index d0191b0225..3368b6bcfe 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -174,8 +174,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) NR_UE_CSI_RS **const csirs_vars = ue->csirs_vars; NR_UE_SRS **const srs_vars = ue->srs_vars; - int i, gNB_id; - LOG_I(PHY, "Initializing UE vars for gNB TXant %u, UE RXant %u\n", fp->nb_antennas_tx, fp->nb_antennas_rx); phy_init_nr_top(ue); @@ -184,10 +182,10 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) AssertFatal( nb_connected_gNB <= NUMBER_OF_CONNECTED_gNB_MAX, "n_connected_gNB is too large" ); // init phy_vars_ue - for (i=0; iLmax; i++) + for (int i = 0; i < fp->Lmax; i++) ue->measurements.ssb_rsrp_dBm[i] = INT_MIN; - for (i=0; i<4; i++) { + for (int i = 0; i < 4; i++) { ue->rx_gain_max[i] = 135; ue->rx_gain_med[i] = 128; ue->rx_gain_byp[i] = 120; @@ -195,12 +193,11 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) ue->n_connected_gNB = nb_connected_gNB; - for(gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { + for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { ue->total_TBS[gNB_id] = 0; ue->total_TBS_last[gNB_id] = 0; ue->bitrate[gNB_id] = 0; ue->total_received_bits[gNB_id] = 0; - } // init NR modulation lookup tables nr_generate_modulation_table(); @@ -237,13 +234,13 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) /////////// //////////////////////////////////////////////////////////////////////////////////////////// - for (i=0; i<10; i++) + for (int i = 0; i < 10; i++) ue->tx_power_dBm[i]=-127; // init TX buffers common_vars->txData = malloc16(fp->nb_antennas_tx * sizeof(c16_t *)); - for (i=0; inb_antennas_tx; i++) { + for (int i = 0; i < fp->nb_antennas_tx; i++) { common_vars->txData[i] = malloc16_clear((fp->samples_per_frame) * sizeof(c16_t)); } @@ -254,12 +251,12 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) if (ue->sl_mode == 2) num_samples = (SL_NR_PSBCH_REPETITION_IN_FRAMES * fp->samples_per_frame) + fp->ofdm_symbol_size; - for (i=0; inb_antennas_rx; i++) { + for (int i = 0; i < fp->nb_antennas_rx; i++) { common_vars->rxdata[i] = malloc16_clear(num_samples * sizeof(c16_t)); } // DLSCH - for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { + for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { prach_vars[gNB_id] = malloc16_clear(sizeof(NR_UE_PRACH)); csiim_vars[gNB_id] = malloc16_clear(sizeof(NR_UE_CSI_IM)); csirs_vars[gNB_id] = malloc16_clear(sizeof(NR_UE_CSI_RS)); @@ -272,7 +269,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) // ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32) ue->nr_csi_info = malloc16_clear(sizeof(nr_csi_info_t)); ue->nr_csi_info->csi_rs_generated_signal = malloc16(NR_MAX_NB_PORTS * sizeof(int32_t *)); - for (i=0; inr_csi_info->csi_rs_generated_signal[i] = malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t)); } 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 4eec02d240..47bb945b9b 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -1450,8 +1450,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, delay_t delay = {0}; - for (int aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) { - + for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) { #ifdef DEBUG_PDSCH printf("\n============================================\n"); printf("==== Tx port %i, Rx antenna %i, Symbol %i ====\n", p, aarx, symbol); @@ -1459,8 +1458,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, #endif c16_t *rxF = &rxdataF[aarx][symbol_offset + delta]; - c16_t *dl_ch = (c16_t *)&dl_ch_estimates[nl * ue->frame_parms.nb_antennas_rx + aarx][ch_offset]; - memset(dl_ch, 0, sizeof(*dl_ch) * ue->frame_parms.ofdm_symbol_size); + c16_t *dl_ch = (c16_t *)&dl_ch_estimates[nl * fp->nb_antennas_rx + aarx][ch_offset]; + memset(dl_ch, 0, sizeof(*dl_ch) * fp->ofdm_symbol_size); if (config_type == NFAPI_NR_DMRS_TYPE1 && ue->chest_freq == 0) { NFAPI_NR_DMRS_TYPE1_linear_interp(&ue->frame_parms, @@ -1474,7 +1473,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, nvar); } else if (config_type == NFAPI_NR_DMRS_TYPE2 && ue->chest_freq == 0) { - NFAPI_NR_DMRS_TYPE2_linear_interp(&ue->frame_parms, + NFAPI_NR_DMRS_TYPE2_linear_interp(fp, rxF, &pilot[4 * rb_offset], dl_ch, @@ -1486,24 +1485,14 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, nvar); } else if (config_type == NFAPI_NR_DMRS_TYPE1) { - NFAPI_NR_DMRS_TYPE1_average_prb(&ue->frame_parms, - rxF, - &pilot[6 * rb_offset], - dl_ch, - bwp_start_subcarrier, - nb_rb_pdsch); + NFAPI_NR_DMRS_TYPE1_average_prb(fp, rxF, &pilot[6 * rb_offset], dl_ch, bwp_start_subcarrier, nb_rb_pdsch); } else { - NFAPI_NR_DMRS_TYPE2_average_prb(&ue->frame_parms, - rxF, - &pilot[4 * rb_offset], - dl_ch, - bwp_start_subcarrier, - nb_rb_pdsch); + NFAPI_NR_DMRS_TYPE2_average_prb(fp, rxF, &pilot[4 * rb_offset], dl_ch, bwp_start_subcarrier, nb_rb_pdsch); } #ifdef DEBUG_PDSCH - dl_ch = (c16_t *)&dl_ch_estimates[nl * ue->frame_parms.nb_antennas_rx + aarx][ch_offset]; + dl_ch = (c16_t *)&dl_ch_estimates[nl * fp->nb_antennas_rx + aarx][ch_offset]; for (uint16_t idxP = 0; idxP < ceil((float)nb_rb_pdsch * 12 / 8); idxP++) { for (uint8_t idxI = 0; idxI < 8; idxI++) { printf("%4d\t%4d\t", dl_ch[idxP * 8 + idxI].r, dl_ch[idxP * 8 + idxI].i); diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index db3e47aa1d..1b90349051 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -440,15 +440,15 @@ typedef struct PHY_VARS_NR_UE_s { int dlsch_ra_errors[NUMBER_OF_CONNECTED_gNB_MAX]; int dlsch_p_received[NUMBER_OF_CONNECTED_gNB_MAX]; int dlsch_p_errors[NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_mch_received_sf[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; int dlsch_mch_received[NUMBER_OF_CONNECTED_gNB_MAX]; + int current_dlsch_cqi[NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_mch_received_sf[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; int dlsch_mcch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; int dlsch_mtch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; int dlsch_mcch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; int dlsch_mtch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; int dlsch_mcch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; - int current_dlsch_cqi[NUMBER_OF_CONNECTED_gNB_MAX]; uint8_t decode_SIB; uint8_t decode_MIB; uint8_t init_sync_frame; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 6bea4b64c9..725dc1fe45 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -1036,7 +1036,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ } dci_cnt = dci_cnt + nr_ue_pdcch_procedures(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, phy_data, n_ss, rxdataF); } - LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_slot_rx, dci_cnt); + LOG_D(PHY, "[UE %d] Frame %d, nr_slot_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_slot_rx, dci_cnt); phy_pdcch_config->nb_search_space = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT); return sampleShift; From b8089ba9a6200678423e52cf631b337c0e7371c3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 26 Jul 2024 15:02:32 +0200 Subject: [PATCH 38/38] Remove empty file nr_gold.c --- CMakeLists.txt | 1 - openair1/PHY/NR_REFSIG/nr_gold.c | 22 ---------------------- 2 files changed, 23 deletions(-) delete mode 100644 openair1/PHY/NR_REFSIG/nr_gold.c diff --git a/CMakeLists.txt b/CMakeLists.txt index df3ad3d211..7ae49fdecb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1043,7 +1043,6 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c - ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gen_mod_table.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/dmrs_nr.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/ptrs_nr.c diff --git a/openair1/PHY/NR_REFSIG/nr_gold.c b/openair1/PHY/NR_REFSIG/nr_gold.c deleted file mode 100644 index d50ecaa94b..0000000000 --- a/openair1/PHY/NR_REFSIG/nr_gold.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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 "nr_refsig.h"