From e676d0d2cced033c3708416058ed7f9c09b56847 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Thu, 10 Apr 2025 16:32:40 +0200 Subject: [PATCH 1/2] Relax NR_UE_CAPABILITY_SLOT_RX_TO_TX asserts Relax the UEs requirements on k1/k2 value. --- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 4 ++-- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 16aa7dcb8f..b6728df0dc 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -936,7 +936,7 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac, if (rnti_type != TYPE_RA_RNTI_ && rnti_type != TYPE_SI_RNTI_) { if (!get_FeedbackDisabled(mac->sc_info.downlinkHARQ_FeedbackDisabled_r17, dci->harq_pid.val)) { feedback_ti = 1 + dci->pdsch_to_harq_feedback_timing_indicator.val + ntn_ue_koffset; - AssertFatal(feedback_ti > GET_DURATION_RX_TO_TX(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing), + AssertFatal(feedback_ti >= GET_DURATION_RX_TO_TX(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing), "PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%ld).\n", feedback_ti, GET_DURATION_RX_TO_TX(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing)); @@ -1232,7 +1232,7 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac, if (!get_FeedbackDisabled(mac->sc_info.downlinkHARQ_FeedbackDisabled_r17, dci->harq_pid.val)) { feedback_ti = pucch_Config->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0] + ntn_ue_koffset; - AssertFatal(feedback_ti > GET_DURATION_RX_TO_TX(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing), + AssertFatal(feedback_ti >= GET_DURATION_RX_TO_TX(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing), "PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%ld). Min feedback time set in config " "file (min_rxtxtime).\n", feedback_ti, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 2c94de6e70..7a44b0cf73 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1575,7 +1575,7 @@ int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac, *slot_tx = (current_slot + k2 + delta) % slots_per_frame; *frame_tx = (current_frame + (current_slot + k2 + delta) / slots_per_frame) % MAX_FRAME_NUMBER; } else { - AssertFatal(k2 > GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu), + AssertFatal(k2 >= GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu), "Slot offset K2 (%ld) needs to be higher than DURATION_RX_TO_TX (%ld). Please set min_rxtxtime at least to %ld in " "gNB config file or gNBs.[0].min_rxtxtime=%ld via command line.\n", k2, From fc3e9f0efe8ce43c9582dc8809d7ce68657bf1ad Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Wed, 16 Apr 2025 17:41:02 +0200 Subject: [PATCH 2/2] UE TX time budget Measure the UEs TX time budget and warn if its violated. --- executables/nr-ue.c | 33 +++++++++++++++++++++++++++++++++ openair1/PHY/defs_nr_UE.h | 1 + 2 files changed, 34 insertions(+) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 1939c4175b..8849dad1b5 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -43,6 +43,7 @@ #include "position_interface.h" #include "nr_phy_common.h" #include "common/utils/time_manager/time_manager.h" +#include "log.h" /* * NR SLOT PROCESSING SEQUENCE @@ -545,6 +546,28 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action, c16_t **tx } } + if (!IS_SOFTMODEM_RFSIM) { + uint64_t deadline_us = rxtxD->absolute_deadline_us; + struct timespec current_time; + if (clock_gettime(CLOCK_REALTIME, ¤t_time)) { + LOG_E(PHY, "clock_gettime failed\n"); + } + uint64_t current_time_us = current_time.tv_sec * 1e6 + current_time.tv_nsec / 1e3; + if (current_time_us > deadline_us) { + static unsigned int deadline_warning_rate_limit = 0; + if (deadline_warning_rate_limit % 1000 == 0) { + LOG_W(PHY, + "Deadline missed for tx slot %d.%d (current time %lu us, deadline %lu us, missed by %lu)\n", + proc->frame_tx, + proc->nr_slot_tx, + current_time_us, + deadline_us, + current_time_us - deadline_us); + } + deadline_warning_rate_limit++; + } + } + openair0_timestamp writeTimestamp = proc->timestamp_tx; int writeBlockSize = rxtxD->writeBlockSize; // if writeBlockSize gets longer that slot size, fill with dummy @@ -1140,6 +1163,10 @@ void *UE_thread(void *arg) int tmp = UE->rfdevice.trx_read_func(&UE->rfdevice, &rx_timestamp, rxp, readBlockSize, fp->nb_antennas_rx); UEscopeCopy(UE, ueTimeDomainSamples, rxp[0], sizeof(c16_t), 1, readBlockSize, 0); AssertFatal(readBlockSize == tmp, ""); + struct timespec current_time; + if (clock_gettime(CLOCK_REALTIME, ¤t_time)) { + LOG_E(PHY, "clock_gettime failed\n"); + } if(slot_nr == (nb_slot_frame - 1)) { // read in first symbol of next frame and adjust for timing drift @@ -1162,6 +1189,11 @@ void *UE_thread(void *arg) const openair0_timestamp writeTimestamp = rx_timestamp + fp->get_samples_slot_timestamp(slot_nr, fp, duration_rx_to_tx) - firstSymSamp - UE->N_TA_offset - timing_advance; + // Calculate TX deadline, approximately 1 symbol before the first sample should be written + const uint64_t samples_diff = writeTimestamp - rx_timestamp - fp->ofdm_symbol_size; + const float deadline_us = samples_diff / UE->rfdevice.openair0_cfg->sample_rate * 1e6; + const uint64_t absolute_deadline_us = current_time.tv_sec * 1e6 + current_time.tv_nsec / 1e3 + deadline_us; + // but use current UE->timing_advance value to compute writeBlockSize int writeBlockSize = fp->get_samples_per_slot((slot_nr + duration_rx_to_tx) % nb_slot_frame, fp) - iq_shift_to_apply; int new_timing_advance = UE->timing_advance; @@ -1204,6 +1236,7 @@ void *UE_thread(void *arg) curMsgTx->writeBlockSize = writeBlockSize; curMsgTx->proc.timestamp_tx = writeTimestamp; curMsgTx->UE = UE; + curMsgTx->absolute_deadline_us = absolute_deadline_us; int slot = curMsgTx->proc.nr_slot_tx; int slot_and_frame = slot + curMsgTx->proc.frame_tx * UE->frame_parms.slots_per_frame; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index db8524eddd..9d8683481d 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -598,6 +598,7 @@ typedef struct nr_rxtx_thread_data_s { int writeBlockSize; nr_phy_data_t phy_data; dynamic_barrier_t* next_barrier; + uint64_t absolute_deadline_us; } nr_rxtx_thread_data_t; typedef struct LDPCDecode_ue_s {