From 665551e142ec6da8e2dcdbeabb0b94c32dc15052 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Thu, 8 Jan 2026 03:19:21 +0000 Subject: [PATCH 1/6] clean-up: remove static function declartion move function nr_rx_pdsch() to bottom of file and remove static function declaration of other function. --- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 1109 ++++++++--------- 1 file changed, 493 insertions(+), 616 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 8e893226a3..f70b0270c4 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -51,129 +51,6 @@ #define print_ints(s,x) printf("%s = %d %d %d %d\n",s,(x)[0],(x)[1],(x)[2],(x)[3]) #define print_shorts(s,x) printf("%s = [%d+j*%d, %d+j*%d, %d+j*%d, %d+j*%d]\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7]) -/* compute the MMSE up to 4x4 matrices */ -static void nr_dlsch_mmse(uint32_t rx_size_symbol, - unsigned char n_rx, - unsigned char nl, // number of layer - int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], - c16_t dl_ch_mag[][n_rx][rx_size_symbol], - c16_t dl_ch_magb[][n_rx][rx_size_symbol], - c16_t dl_ch_magr[][n_rx][rx_size_symbol], - int32_t dl_ch_estimates_ext[][rx_size_symbol], - unsigned char mod_order, - int shift, - unsigned char symbol, - int length, - uint32_t noise_var); - -/* Apply layer demapping */ -static void nr_dlsch_layer_demapping(int16_t *llr_cw[2], - uint8_t Nl, - uint8_t mod_order, - uint32_t length, - int32_t codeword_TB0, - int32_t codeword_TB1, - uint sz, - int16_t llr_layers[][sz]); - -/* compute LLR */ -static void nr_dlsch_llr(uint32_t rx_size_symbol, - int nbRx, - uint sz, - int16_t layer_llr[][sz], - int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], - c16_t dl_ch_mag[rx_size_symbol], - c16_t dl_ch_magb[rx_size_symbol], - c16_t dl_ch_magr[rx_size_symbol], - NR_DL_UE_HARQ_t *dlsch1_harq, - unsigned char symbol, - uint32_t len, - NR_UE_DLSCH_t dlsch[2], - uint32_t llr_offset_symbol); - -/** \fn nr_dlsch_extract_rbs - \brief This function extracts the received resource blocks, both channel estimates and data symbols, for the current - allocation and for multiple layer antenna gNB transmission. - @param rxdataF Raw FFT output of received signal - @param dl_ch_estimates Channel estimates of current slot - @param rxdataF_ext FFT output for RBs in this allocation - @param dl_ch_estimates_ext Channel estimates for RBs in this allocation - @param Nl nb of antenna layers - @param symbol Symbol to extract - @param n_dmrs_cdm_groups - @param frame_parms Pointer to frame descriptor -*/ -static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz, - c16_t rxdataF[][rxdataF_sz], - uint32_t rx_size_symbol, - uint32_t pdsch_est_size, - int32_t dl_ch_estimates[][pdsch_est_size], - c16_t rxdataF_ext[][rx_size_symbol], - int32_t dl_ch_estimates_ext[][rx_size_symbol], - unsigned char symbol, - uint8_t pilots, - uint8_t config_type, - int startBWP, - const freq_alloc_bitmap_t *freq_alloc, - uint8_t n_dmrs_cdm_groups, - uint8_t Nl, - NR_DL_FRAME_PARMS *fp, - uint16_t dlDmrsSymbPos, - uint32_t csi_res_bitmap, - int chest_time_type); - -static void nr_dlsch_channel_level_median(uint32_t rx_size_symbol, - int32_t dl_ch_estimates_ext[][rx_size_symbol], - int32_t median[MAX_ANT][MAX_ANT], - int n_tx, - int n_rx, - int length); - -/** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation. In addition, it computes the squared-magnitude of the channel with weightings for - 16QAM/64QAM detection as well as dual-stream detection (cross-correlation) - @param rxdataF_ext Frequency-domain received signal in RBs to be demodulated - @param dl_ch_estimates_ext Frequency-domain channel estimates in RBs to be demodulated - @param dl_ch_mag First Channel magnitudes (16QAM/64QAM) - @param dl_ch_magb Second weighted Channel magnitudes (64QAM) - @param rxdataF_comp Compensated received waveform - @param rho Cross-correlation between two spatial channels on each RX antenna - @param frame_parms Pointer to frame descriptor - @param symbol Symbol on which to operate - @param mod_order Modulation order of allocation - @param nb_rb Number of RBs in allocation - @param output_shift Rescaling for compensated output (should be energy-normalizing) - @param phy_measurements Pointer to UE PHY measurements -*/ - -static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, - int nbRx, - c16_t rxdataF_ext[][rx_size_symbol], - int32_t dl_ch_estimates_ext[][rx_size_symbol], - c16_t dl_ch_mag[][nbRx][rx_size_symbol], - c16_t dl_ch_magb[][nbRx][rx_size_symbol], - c16_t dl_ch_magr[][nbRx][rx_size_symbol], - int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], - int ***rho, - NR_DL_FRAME_PARMS *frame_parms, - uint8_t n_layers, - unsigned char symbol, - int length, - unsigned char mod_order, - unsigned short nb_rb, - unsigned char output_shift, - PHY_NR_MEASUREMENTS *measurements); - -static void nr_dlsch_detection_mrc(uint32_t rx_size_symbol, - short nl, - short n_rx, - int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], - int ***rho, - c16_t dl_ch_mag[][n_rx][rx_size_symbol], - c16_t dl_ch_magb[][n_rx][rx_size_symbol], - c16_t dl_ch_magr[][n_rx][rx_size_symbol], - unsigned char symbol, - int length); - static bool overlap_csi_symbol(fapi_nr_dl_config_csirs_pdu_rel15_t *csi_pdu, int symbol) { int num_l0 [18] = {1, 1, 1, 1, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 4, 2, 2, 4}; @@ -250,499 +127,6 @@ static uint32_t build_csi_overlap_bitmap(fapi_nr_dl_config_dlsch_pdu_rel15_t *dl return csi_res_bitmap; } -/* Main Function */ -int nr_rx_pdsch(PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, - NR_UE_DLSCH_t dlsch[2], - const freq_alloc_bitmap_t *freq_alloc, - unsigned char symbol, - bool first_symbol_flag, - unsigned char harq_pid, - uint32_t pdsch_est_size, - int32_t dl_ch_estimates[][pdsch_est_size], - int layer_llr_size, - int16_t layer_llr[][layer_llr_size], - int16_t *llr[2], - uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT], - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP], - uint32_t llr_offset[NR_SYMBOLS_PER_SLOT], - int32_t *log2_maxh, - int rx_size_symbol, - int nbRx, - int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], - c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT], - int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT], - int G, - uint32_t nvar, - pdsch_scope_req_t *scope_req) -{ - NR_DL_FRAME_PARMS *fp = &ue->frame_parms; - const int nl = dlsch[0].Nl; - const int n_rx = fp->nb_antennas_rx; - const int matrixSz = n_rx * nl; - __attribute__((aligned(32))) int32_t dl_ch_estimates_ext[matrixSz][rx_size_symbol]; - memset(dl_ch_estimates_ext, 0, sizeof(dl_ch_estimates_ext)); - - __attribute__((aligned(32))) c16_t dl_ch_mag[nl][n_rx][rx_size_symbol]; - memset(dl_ch_mag, 0, sizeof(dl_ch_mag)); - - __attribute__((aligned(32))) c16_t dl_ch_magb[nl][nbRx][rx_size_symbol]; - memset(dl_ch_magb, 0, sizeof(dl_ch_magb)); - - __attribute__((aligned(32))) c16_t dl_ch_magr[nl][nbRx][rx_size_symbol]; - memset(dl_ch_magr, 0, sizeof(dl_ch_magr)); - NR_UE_COMMON *common_vars = &ue->common_vars; - PHY_NR_MEASUREMENTS *measurements = &ue->measurements; - const int frame = proc->frame_rx; - const int nr_slot_rx = proc->nr_slot_rx; - const int gNB_id = proc->gNB_id; - uint8_t slot = 0; - - int32_t codeword_TB0 = -1; - int32_t codeword_TB1 = -1; - - uint32_t nb_re_pdsch = -1; - - NR_DL_UE_HARQ_t *dlsch0_harq, *dlsch1_harq = NULL; - dlsch0_harq = &ue->dl_harq_processes[0][harq_pid]; - if (NR_MAX_NB_LAYERS>4) - dlsch1_harq = &ue->dl_harq_processes[1][harq_pid]; - - if (dlsch0_harq && dlsch1_harq){ - - LOG_D(PHY, - "AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", - frame, - nr_slot_rx, - symbol, - harq_pid, - dlsch0_harq->status, - dlsch1_harq->status); - - if ((dlsch0_harq->status == ACTIVE) && (dlsch1_harq->status == ACTIVE)){ - codeword_TB0 = dlsch0_harq->codeword; // SV: where is this set? revisit for DL MIMO. - codeword_TB1 = dlsch1_harq->codeword; - dlsch0_harq = &ue->dl_harq_processes[codeword_TB0][harq_pid]; - dlsch1_harq = &ue->dl_harq_processes[codeword_TB1][harq_pid]; - - DEBUG_HARQ("[DEMOD] I am assuming both TBs are active, in cw0 %d and cw1 %d \n", codeword_TB0, codeword_TB1); - - } else if ((dlsch0_harq->status == ACTIVE) && (dlsch1_harq->status != ACTIVE) ) { - codeword_TB0 = dlsch0_harq->codeword; - dlsch0_harq = &ue->dl_harq_processes[codeword_TB0][harq_pid]; - dlsch1_harq = NULL; - - DEBUG_HARQ("[DEMOD] I am assuming only TB0 is active, in cw %d \n", codeword_TB0); - - } else if ((dlsch0_harq->status != ACTIVE) && (dlsch1_harq->status == ACTIVE)){ - codeword_TB1 = dlsch1_harq->codeword; - dlsch0_harq = NULL; - dlsch1_harq = &ue->dl_harq_processes[codeword_TB1][harq_pid]; - - DEBUG_HARQ("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", codeword_TB1); - LOG_E(PHY, "[DEMOD] slot %d TB0 not active and TB1 active case is not supported\n", nr_slot_rx); - return -1; - - } else { - LOG_E(PHY, "[DEMOD] slot %d: no active DLSCH (2 layers case)\n", nr_slot_rx); - return (-1); - } - } else if (dlsch0_harq) { - if (dlsch0_harq->status == ACTIVE) { - codeword_TB0 = dlsch0_harq->codeword; - dlsch0_harq = &ue->dl_harq_processes[0][harq_pid]; - DEBUG_HARQ("[DEMOD] I am assuming only TB0 is active\n"); - } else { - LOG_E(PHY, "[DEMOD] slot %d nr_rx_pdsch no active DLSCH (one layer case)\n", nr_slot_rx); - return (-1); - } - } else { - LOG_E(PHY, "[DEMOD] slot %d Inconsistent call to nr_rx_pdsch (no layer 0)\n", nr_slot_rx); - return -1; - } - - DEBUG_HARQ("[DEMOD] cw for TB0 = %d, cw for TB1 = %d\n", codeword_TB0, codeword_TB1); - fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = &dlsch[0].dlsch_config; - DevAssert(dlsch0_harq); - - if (gNB_id > 2) { - LOG_E(PHY, "Illegal gNB_id %d\n", gNB_id); - return(-1); - } - - if (!common_vars) { - LOG_E(PHY, "dlsch_demodulation.c: Null common_vars\n"); - return(-1); - } - - if(symbol > fp->symbols_per_slot >> 1) - slot = 1; - - uint8_t pilots = (dlsch_config->dlDmrsSymbPos >> symbol) & 1; - uint8_t config_type = dlsch_config->dmrsConfigType; - //---------------------------------------------------------- - //--------------------- RBs extraction --------------------- - //---------------------------------------------------------- - const bool meas_enabled = cpumeas(CPUMEAS_GETSTATE); - int nb_rb_pdsch = freq_alloc->num_rbs; - { - start_meas_nr_ue_phy(ue, DLSCH_EXTRACT_RBS_STATS); - __attribute__((aligned(32))) c16_t rxdataF_ext[nbRx][rx_size_symbol]; - memset(rxdataF_ext, 0, sizeof(rxdataF_ext)); - - uint32_t csi_res_bitmap = build_csi_overlap_bitmap(dlsch_config, symbol); - - LOG_D(PHY, "%d.%d symbol %d csi overlap bitmap %d\n", frame, nr_slot_rx, symbol, csi_res_bitmap); - - nr_dlsch_extract_rbs(fp->samples_per_slot_wCP, - rxdataF, - rx_size_symbol, - pdsch_est_size, - dl_ch_estimates, - rxdataF_ext, - dl_ch_estimates_ext, - symbol, - pilots, - config_type, - dlsch_config->BWPStart, - freq_alloc, - dlsch_config->n_dmrs_cdm_groups, - nl, - fp, - dlsch_config->dlDmrsSymbPos, - csi_res_bitmap, - ue->chest_time); - stop_meas_nr_ue_phy(ue, DLSCH_EXTRACT_RBS_STATS); - if (scope_req->copy_chanest_to_scope) { - size_t size = sizeof(c16_t) * nb_rb_pdsch * NR_NB_SC_PER_RB; - int copy_index = symbol - dlsch_config->start_symbol; - int offset = copy_index * size; - UEscopeCopyUnsafe(ue, pdschChanEstimates, dl_ch_estimates_ext[0], size, offset, copy_index); - } - if (meas_enabled) { - LOG_D(PHY, - "[AbsSFN %u.%d] Slot%d Symbol %d: Pilot/Data extraction %5.2f \n", - frame, - nr_slot_rx, - slot, - symbol, - ue->phy_cpu_stats.cpu_time_stats[DLSCH_EXTRACT_RBS_STATS].p_time / (cpuf * 1000.0)); - } - if (ue->phy_sim_pdsch_rxdataF_ext) - memcpy(ue->phy_sim_pdsch_rxdataF_ext + symbol * sizeof(rxdataF_ext), rxdataF_ext, sizeof(rxdataF_ext)); - - nb_re_pdsch = (pilots == 1) ? ((config_type == NFAPI_NR_DMRS_TYPE1) ? nb_rb_pdsch * (12 - 6 * dlsch_config->n_dmrs_cdm_groups) - : nb_rb_pdsch * (12 - 4 * dlsch_config->n_dmrs_cdm_groups)) - : (nb_rb_pdsch * 12); - // Subtract CSI-RS REs from PDSCH RE count - if (csi_res_bitmap != 0) { - uint32_t csi_re_count = 0; - uint32_t csi_res_even = csi_res_bitmap & 0xfff; - uint32_t csi_res_odd = (csi_res_bitmap >> 16) & 0xfff; - int start = freq_alloc->start[0] + dlsch_config->BWPStart; - int end = freq_alloc->end[freq_alloc->num_blocks - 1] + 1; - for (int rb = start; rb < end; rb++) { - if ((freq_alloc->bitmap[rb / 8] >> (rb % 8)) & 0x01) { - uint32_t rb_csi_pattern = (rb % 2 == 0) ? csi_res_even : csi_res_odd; - csi_re_count += __builtin_popcount(rb_csi_pattern); - } - } - nb_re_pdsch = (nb_re_pdsch > csi_re_count) ? (nb_re_pdsch - csi_re_count) : 0; - if (csi_re_count > 0) { - LOG_D(NR_PHY, - "[CSI OVERLAP] Frame/Slot %d.%d Symbol %d: CSI-RS overlapping PDSCH - %d CSI-RS REs skipped, %d data REs extracted\n", - frame, - nr_slot_rx, - symbol, - csi_re_count, - nb_re_pdsch); - } - } - - if (scope_req->copy_rxdataF_to_scope) { - size_t size = sizeof(c16_t) * nb_re_pdsch; - int copy_index = symbol - dlsch_config->start_symbol; - UEscopeCopyUnsafe(ue, pdschRxdataF, rxdataF_ext[0], size, scope_req->scope_rxdataF_offset, copy_index); - scope_req->scope_rxdataF_offset += size; - } - //---------------------------------------------------------- - //--------------------- Channel Scaling -------------------- - //---------------------------------------------------------- - start_meas_nr_ue_phy(ue, DLSCH_CHANNEL_SCALE_STATS); - nr_scale_channel(rx_size_symbol, dl_ch_estimates_ext, 0, nb_re_pdsch, nl, n_rx, 0); - stop_meas_nr_ue_phy(ue, DLSCH_CHANNEL_SCALE_STATS); - if (meas_enabled) { - LOG_D(PHY, - "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n", - frame, - nr_slot_rx, - slot, - symbol, - ue->phy_cpu_stats.cpu_time_stats[DLSCH_CHANNEL_SCALE_STATS].p_time / (cpuf * 1000.0)); - } - - //---------------------------------------------------------- - //--------------------- Channel Level Calc. ---------------- - //---------------------------------------------------------- - start_meas_nr_ue_phy(ue, DLSCH_CHANNEL_LEVEL_STATS); - if (first_symbol_flag) { - int32_t avg[nl * n_rx]; - if (nb_re_pdsch) - nr_channel_level(0, rx_size_symbol, (c16_t (*)[rx_size_symbol])dl_ch_estimates_ext, n_rx, nl, avg, nb_re_pdsch); - else - LOG_E(NR_PHY, "Average channel level is 0: nb_rb_pdsch = %d, nb_re_pdsch = %d\n", nb_rb_pdsch, nb_re_pdsch); - int avgs = 0; - int32_t median[MAX_ANT][MAX_ANT]; - for (int l = 0; l < nl; l++) - for (int aarx = 0; aarx < n_rx; aarx++) { - avgs = cmax(avgs, avg[l * n_rx + aarx]); - LOG_D(PHY, "nb_rb %d avg_%d_%d Power per SC is %d\n", nb_rb_pdsch, aarx, l, avg[l * n_rx + aarx]); - LOG_D(PHY, "avgs Power per SC is %d\n", avgs); - median[l][aarx] = avg[l * n_rx + aarx]; - } - if (nl > 1) { - nr_dlsch_channel_level_median(rx_size_symbol, dl_ch_estimates_ext, median, nl, n_rx, nb_re_pdsch); - for (int l = 0; l < nl; l++) { - for (int aarx = 0; aarx < n_rx; aarx++) { - avgs = cmax(avgs, median[l][aarx]); - } - } - } - *log2_maxh = (log2_approx(avgs) / 2) + 1; - LOG_D(PHY, "[DLSCH] AbsSubframe %d.%d log2_maxh = %d (%d)\n", frame % 1024, nr_slot_rx, *log2_maxh, avgs); -#if T_TRACER - T(T_UE_PHY_PDSCH_ENERGY, - T_INT(gNB_id), - T_INT(frame % 1024), - T_INT(nr_slot_rx), - T_INT(avg[0]), // layer 0, antenna 0 - T_INT(n_rx > 1 ? avg[1] : 0), // layer 0, antenna 1 - T_INT(nl > 1 ? avg[n_rx] : 0), // layer 1, antenna 0 - T_INT(nl > 1 && n_rx > 1 ? avg[n_rx + 1] : 0)); // layer 1, antenna 1 -#endif - } - stop_meas_nr_ue_phy(ue, DLSCH_CHANNEL_LEVEL_STATS); - if (meas_enabled) { - LOG_D(PHY, - "[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n", - frame, - nr_slot_rx, - slot, - symbol, - first_symbol_flag, - ue->phy_cpu_stats.cpu_time_stats[DLSCH_CHANNEL_LEVEL_STATS].p_time / (cpuf * 1000.0)); - } - - //---------------------------------------------------------- - //--------------------- channel compensation --------------- - //---------------------------------------------------------- - // Disable correlation measurement for optimizing UE - start_meas_nr_ue_phy(ue, DLSCH_CHANNEL_COMPENSATION_STATS); - nr_dlsch_channel_compensation(rx_size_symbol, - nbRx, - rxdataF_ext, - dl_ch_estimates_ext, - dl_ch_mag, - dl_ch_magb, - dl_ch_magr, - rxdataF_comp, - NULL, - fp, - nl, - symbol, - nb_re_pdsch, - dlsch_config->qamModOrder, - nb_rb_pdsch, - *log2_maxh, - measurements); // log2_maxh+I0_shift - stop_meas_nr_ue_phy(ue, DLSCH_CHANNEL_COMPENSATION_STATS); - if (meas_enabled) { - LOG_D(PHY, - "[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d Channel Comp %5.2f \n", - frame, - nr_slot_rx, - slot, - symbol, - *log2_maxh, - ue->phy_cpu_stats.cpu_time_stats[DLSCH_CHANNEL_COMPENSATION_STATS].p_time / (cpuf * 1000.0)); - } - // Please keep it: useful for debugging -#ifdef DEBUG_PDSCH_RX - char filename[50]; - - snprintf(filename, 50, "rxdataF0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx); - write_output(filename, "rxdataF0", &rxdataF[0][symbol * fp->ofdm_symbol_size], fp->ofdm_symbol_size, 1, 1); - - snprintf(filename, 50, "dl_ch_estimates0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx); - write_output(filename, "dl_ch_estimates0", &dl_ch_estimates[0][symbol * fp->ofdm_symbol_size], fp->ofdm_symbol_size, 1, 1); - - snprintf(filename, 50, "rxdataF_ext0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx); - write_output(filename, "rxdataF_ext0", &rxdataF_ext[0][0], rx_size_symbol, 1, 1); - - snprintf(filename, 50, "dl_ch_estimates_ext0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx); - write_output(filename, "dl_ch_estimates_ext0", &dl_ch_estimates_ext[0][0], rx_size_symbol, 1, 1); - - snprintf(filename, 50, "rxdataF_comp00_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx); - write_output(filename, "rxdataF_comp00", &rxdataF_comp[0][0][symbol * rx_size_symbol], rx_size_symbol, 1, 1); -#endif - } - - start_meas_nr_ue_phy(ue, DLSCH_MRC_MMSE_STATS); - if (n_rx > 1) { - nr_dlsch_detection_mrc(rx_size_symbol, - nl, - n_rx, - rxdataF_comp, - NULL, - dl_ch_mag, - dl_ch_magb, - dl_ch_magr, - symbol, - nb_re_pdsch); - if (nl >= 2) // Apply MMSE for 2, 3, and 4 Tx layers - if (nb_re_pdsch) - nr_dlsch_mmse(rx_size_symbol, - n_rx, - nl, - rxdataF_comp, - dl_ch_mag, - dl_ch_magb, - dl_ch_magr, - dl_ch_estimates_ext, - dlsch_config->qamModOrder, - *log2_maxh, - symbol, - nb_re_pdsch, - nvar); - } - stop_meas_nr_ue_phy(ue, DLSCH_MRC_MMSE_STATS); - - if (meas_enabled) { - LOG_D(PHY, - "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine and MMSE %5.2f \n", - frame, - nr_slot_rx, - slot, - symbol, - ue->phy_cpu_stats.cpu_time_stats[DLSCH_MRC_MMSE_STATS].p_time / (cpuf * 1000.0)); - } - - - - /* Store the valid DL RE's */ - dl_valid_re[symbol] = nb_re_pdsch; - int startSymbIdx = 0; - int nbSymb = 0; - int pduBitmap = 0; - - if(dlsch0_harq->status == ACTIVE) { - startSymbIdx = dlsch_config->start_symbol; - nbSymb = dlsch_config->number_symbols; - pduBitmap = dlsch_config->pduBitmap; - } - - /* Check for PTRS bitmap and process it respectively */ - if((pduBitmap & 0x1) && (dlsch[0].rnti_type == TYPE_C_RNTI_)) { - nr_pdsch_ptrs_processing(nbRx, - ptrs_phase_per_slot, - ptrs_re_per_slot, - rx_size_symbol, - rxdataF_comp, - fp, - dlsch0_harq, - dlsch1_harq, - nr_slot_rx, - symbol, - dlsch[0].rnti, - dlsch); - dl_valid_re[symbol] -= ptrs_re_per_slot[0][symbol]; - } - start_meas_nr_ue_phy(ue, DLSCH_LLR_STATS); - nr_dlsch_llr(rx_size_symbol, - nbRx, - layer_llr_size, - layer_llr, - rxdataF_comp, - dl_ch_mag[0][0], - dl_ch_magb[0][0], - dl_ch_magr[0][0], - dlsch1_harq, - symbol, - dl_valid_re[symbol], - dlsch, - llr_offset[symbol]); - if (symbol < startSymbIdx + nbSymb - 1) // up to the penultimate symbol - llr_offset[symbol + 1] = dl_valid_re[symbol] * dlsch_config->qamModOrder + llr_offset[symbol]; - stop_meas_nr_ue_phy(ue, DLSCH_LLR_STATS); - /* at last symbol in a slot calculate LLR's for whole slot */ - if (symbol == (startSymbIdx + nbSymb - 1)) { - start_meas_nr_ue_phy(ue, DLSCH_LAYER_DEMAPPING); - nr_dlsch_layer_demapping(llr, dlsch[0].Nl, dlsch_config->qamModOrder, G, codeword_TB0, codeword_TB1, layer_llr_size, layer_llr); - stop_meas_nr_ue_phy(ue, DLSCH_LAYER_DEMAPPING); - /* - for (int i=0; i < 2; i++){ - snprintf(filename, 50, "llr%d_symb_%d_nr_slot_rx_%d.m", i, symbol, nr_slot_rx); - write_output(filename,"llr", &llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb_pdsch*NR_NB_SC_PER_RB*dlsch1_harq->Qm) - 4*(nb_rb_pdsch*4*dlsch1_harq->Qm), 1, 0); - } - */ - if (UEScopeHasTryLock(ue)) { - metadata mt = {.frame = proc->frame_rx, .slot = proc->nr_slot_rx }; - int total_valid_res = 0; - for (int i = startSymbIdx; i < startSymbIdx + nbSymb; i++) { - total_valid_res += dl_valid_re[i]; - } - if (UETryLockScopeData(ue, pdschRxdataF_comp, sizeof(c16_t), 1, total_valid_res, &mt)) { - size_t offset = 0; - for (int i = startSymbIdx; i < startSymbIdx + nbSymb; i++) { - size_t data_size = sizeof(c16_t) * dl_valid_re[i]; - UEscopeCopyUnsafe(ue, pdschRxdataF_comp, &rxdataF_comp[0][0][rx_size_symbol * i], data_size, offset, i); - offset += data_size; - } - UEunlockScopeData(ue, pdschRxdataF_comp) - } - } else { - UEscopeCopy(ue, pdschRxdataF_comp, rxdataF_comp[0], sizeof(c16_t), nbRx, rx_size_symbol * fp->symbols_per_slot, 0); - } - } - - if (meas_enabled) { - LOG_D(PHY, - "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n", - frame, - nr_slot_rx, - slot, - symbol, - ue->phy_cpu_stats.cpu_time_stats[DLSCH_LLR_STATS].p_time / (cpuf * 1000.0)); - } - -#if T_TRACER - T(T_UE_PHY_PDSCH_IQ, - T_INT(gNB_id), - T_INT(frame % 1024), - T_INT(nr_slot_rx), - T_INT(nb_rb_pdsch), - T_INT(fp->N_RB_UL), - T_INT(fp->symbols_per_slot), - T_BUFFER(&rxdataF_comp[gNB_id][0], 2 * fp->N_RB_UL * 12 * fp->symbols_per_slot * 2)); -#endif - - if (ue->phy_sim_pdsch_rxdataF_comp) - for (int a = 0; a < nbRx; a++) { - for (int l = 0; l < nl; l++) { - int offset = (void *)rxdataF_comp[l][a] - (void *)rxdataF_comp[0] + symbol * rx_size_symbol * sizeof(c16_t); - memcpy(ue->phy_sim_pdsch_rxdataF_comp + offset, - rxdataF_comp[l][a] + symbol * rx_size_symbol, - sizeof(c16_t) * rx_size_symbol); - } - memcpy((c16_t *)ue->phy_sim_pdsch_dl_ch_estimates + pdsch_est_size * a, dl_ch_estimates, pdsch_est_size * sizeof(c16_t)); - } - if (ue->phy_sim_pdsch_dl_ch_estimates_ext) - memcpy(ue->phy_sim_pdsch_dl_ch_estimates_ext + symbol * sizeof(dl_ch_estimates_ext), - dl_ch_estimates_ext, - sizeof(dl_ch_estimates_ext)); - return 0; -} - //============================================================================================== // Pre-processing for LLR computation //============================================================================================== @@ -1590,3 +974,496 @@ static void nr_dlsch_llr(uint32_t rx_size_symbol, } } //============================================================================================== + +/* Main Function */ +int nr_rx_pdsch(PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + NR_UE_DLSCH_t dlsch[2], + const freq_alloc_bitmap_t *freq_alloc, + unsigned char symbol, + bool first_symbol_flag, + unsigned char harq_pid, + uint32_t pdsch_est_size, + int32_t dl_ch_estimates[][pdsch_est_size], + int layer_llr_size, + int16_t layer_llr[][layer_llr_size], + int16_t *llr[2], + uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT], + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP], + uint32_t llr_offset[NR_SYMBOLS_PER_SLOT], + int32_t *log2_maxh, + int rx_size_symbol, + int nbRx, + int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT], + int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT], + int G, + uint32_t nvar, + pdsch_scope_req_t *scope_req) +{ + NR_DL_FRAME_PARMS *fp = &ue->frame_parms; + const int nl = dlsch[0].Nl; + const int n_rx = fp->nb_antennas_rx; + const int matrixSz = n_rx * nl; + __attribute__((aligned(32))) int32_t dl_ch_estimates_ext[matrixSz][rx_size_symbol]; + memset(dl_ch_estimates_ext, 0, sizeof(dl_ch_estimates_ext)); + + __attribute__((aligned(32))) c16_t dl_ch_mag[nl][n_rx][rx_size_symbol]; + memset(dl_ch_mag, 0, sizeof(dl_ch_mag)); + + __attribute__((aligned(32))) c16_t dl_ch_magb[nl][nbRx][rx_size_symbol]; + memset(dl_ch_magb, 0, sizeof(dl_ch_magb)); + + __attribute__((aligned(32))) c16_t dl_ch_magr[nl][nbRx][rx_size_symbol]; + memset(dl_ch_magr, 0, sizeof(dl_ch_magr)); + NR_UE_COMMON *common_vars = &ue->common_vars; + PHY_NR_MEASUREMENTS *measurements = &ue->measurements; + const int frame = proc->frame_rx; + const int nr_slot_rx = proc->nr_slot_rx; + const int gNB_id = proc->gNB_id; + uint8_t slot = 0; + + int32_t codeword_TB0 = -1; + int32_t codeword_TB1 = -1; + + uint32_t nb_re_pdsch = -1; + + NR_DL_UE_HARQ_t *dlsch0_harq, *dlsch1_harq = NULL; + dlsch0_harq = &ue->dl_harq_processes[0][harq_pid]; + if (NR_MAX_NB_LAYERS>4) + dlsch1_harq = &ue->dl_harq_processes[1][harq_pid]; + + if (dlsch0_harq && dlsch1_harq){ + + LOG_D(PHY, + "AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", + frame, + nr_slot_rx, + symbol, + harq_pid, + dlsch0_harq->status, + dlsch1_harq->status); + + if ((dlsch0_harq->status == ACTIVE) && (dlsch1_harq->status == ACTIVE)){ + codeword_TB0 = dlsch0_harq->codeword; // SV: where is this set? revisit for DL MIMO. + codeword_TB1 = dlsch1_harq->codeword; + dlsch0_harq = &ue->dl_harq_processes[codeword_TB0][harq_pid]; + dlsch1_harq = &ue->dl_harq_processes[codeword_TB1][harq_pid]; + + DEBUG_HARQ("[DEMOD] I am assuming both TBs are active, in cw0 %d and cw1 %d \n", codeword_TB0, codeword_TB1); + + } else if ((dlsch0_harq->status == ACTIVE) && (dlsch1_harq->status != ACTIVE) ) { + codeword_TB0 = dlsch0_harq->codeword; + dlsch0_harq = &ue->dl_harq_processes[codeword_TB0][harq_pid]; + dlsch1_harq = NULL; + + DEBUG_HARQ("[DEMOD] I am assuming only TB0 is active, in cw %d \n", codeword_TB0); + + } else if ((dlsch0_harq->status != ACTIVE) && (dlsch1_harq->status == ACTIVE)){ + codeword_TB1 = dlsch1_harq->codeword; + dlsch0_harq = NULL; + dlsch1_harq = &ue->dl_harq_processes[codeword_TB1][harq_pid]; + + DEBUG_HARQ("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", codeword_TB1); + LOG_E(PHY, "[DEMOD] slot %d TB0 not active and TB1 active case is not supported\n", nr_slot_rx); + return -1; + + } else { + LOG_E(PHY, "[DEMOD] slot %d: no active DLSCH (2 layers case)\n", nr_slot_rx); + return (-1); + } + } else if (dlsch0_harq) { + if (dlsch0_harq->status == ACTIVE) { + codeword_TB0 = dlsch0_harq->codeword; + dlsch0_harq = &ue->dl_harq_processes[0][harq_pid]; + DEBUG_HARQ("[DEMOD] I am assuming only TB0 is active\n"); + } else { + LOG_E(PHY, "[DEMOD] slot %d nr_rx_pdsch no active DLSCH (one layer case)\n", nr_slot_rx); + return (-1); + } + } else { + LOG_E(PHY, "[DEMOD] slot %d Inconsistent call to nr_rx_pdsch (no layer 0)\n", nr_slot_rx); + return -1; + } + + DEBUG_HARQ("[DEMOD] cw for TB0 = %d, cw for TB1 = %d\n", codeword_TB0, codeword_TB1); + fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = &dlsch[0].dlsch_config; + DevAssert(dlsch0_harq); + + if (gNB_id > 2) { + LOG_E(PHY, "Illegal gNB_id %d\n", gNB_id); + return(-1); + } + + if (!common_vars) { + LOG_E(PHY, "dlsch_demodulation.c: Null common_vars\n"); + return(-1); + } + + if(symbol > fp->symbols_per_slot >> 1) + slot = 1; + + uint8_t pilots = (dlsch_config->dlDmrsSymbPos >> symbol) & 1; + uint8_t config_type = dlsch_config->dmrsConfigType; + //---------------------------------------------------------- + //--------------------- RBs extraction --------------------- + //---------------------------------------------------------- + const bool meas_enabled = cpumeas(CPUMEAS_GETSTATE); + int nb_rb_pdsch = freq_alloc->num_rbs; + { + start_meas_nr_ue_phy(ue, DLSCH_EXTRACT_RBS_STATS); + __attribute__((aligned(32))) c16_t rxdataF_ext[nbRx][rx_size_symbol]; + memset(rxdataF_ext, 0, sizeof(rxdataF_ext)); + + uint32_t csi_res_bitmap = build_csi_overlap_bitmap(dlsch_config, symbol); + + LOG_D(PHY, "%d.%d symbol %d csi overlap bitmap %d\n", frame, nr_slot_rx, symbol, csi_res_bitmap); + + nr_dlsch_extract_rbs(fp->samples_per_slot_wCP, + rxdataF, + rx_size_symbol, + pdsch_est_size, + dl_ch_estimates, + rxdataF_ext, + dl_ch_estimates_ext, + symbol, + pilots, + config_type, + dlsch_config->BWPStart, + freq_alloc, + dlsch_config->n_dmrs_cdm_groups, + nl, + fp, + dlsch_config->dlDmrsSymbPos, + csi_res_bitmap, + ue->chest_time); + stop_meas_nr_ue_phy(ue, DLSCH_EXTRACT_RBS_STATS); + if (scope_req->copy_chanest_to_scope) { + size_t size = sizeof(c16_t) * nb_rb_pdsch * NR_NB_SC_PER_RB; + int copy_index = symbol - dlsch_config->start_symbol; + int offset = copy_index * size; + UEscopeCopyUnsafe(ue, pdschChanEstimates, dl_ch_estimates_ext[0], size, offset, copy_index); + } + if (meas_enabled) { + LOG_D(PHY, + "[AbsSFN %u.%d] Slot%d Symbol %d: Pilot/Data extraction %5.2f \n", + frame, + nr_slot_rx, + slot, + symbol, + ue->phy_cpu_stats.cpu_time_stats[DLSCH_EXTRACT_RBS_STATS].p_time / (cpuf * 1000.0)); + } + if (ue->phy_sim_pdsch_rxdataF_ext) + memcpy(ue->phy_sim_pdsch_rxdataF_ext + symbol * sizeof(rxdataF_ext), rxdataF_ext, sizeof(rxdataF_ext)); + + nb_re_pdsch = (pilots == 1) ? ((config_type == NFAPI_NR_DMRS_TYPE1) ? nb_rb_pdsch * (12 - 6 * dlsch_config->n_dmrs_cdm_groups) + : nb_rb_pdsch * (12 - 4 * dlsch_config->n_dmrs_cdm_groups)) + : (nb_rb_pdsch * 12); + // Subtract CSI-RS REs from PDSCH RE count + if (csi_res_bitmap != 0) { + uint32_t csi_re_count = 0; + uint32_t csi_res_even = csi_res_bitmap & 0xfff; + uint32_t csi_res_odd = (csi_res_bitmap >> 16) & 0xfff; + int start = freq_alloc->start[0] + dlsch_config->BWPStart; + int end = freq_alloc->end[freq_alloc->num_blocks - 1] + 1; + for (int rb = start; rb < end; rb++) { + if ((freq_alloc->bitmap[rb / 8] >> (rb % 8)) & 0x01) { + uint32_t rb_csi_pattern = (rb % 2 == 0) ? csi_res_even : csi_res_odd; + csi_re_count += __builtin_popcount(rb_csi_pattern); + } + } + nb_re_pdsch = (nb_re_pdsch > csi_re_count) ? (nb_re_pdsch - csi_re_count) : 0; + if (csi_re_count > 0) { + LOG_D(NR_PHY, + "[CSI OVERLAP] Frame/Slot %d.%d Symbol %d: CSI-RS overlapping PDSCH - %d CSI-RS REs skipped, %d data REs extracted\n", + frame, + nr_slot_rx, + symbol, + csi_re_count, + nb_re_pdsch); + } + } + + if (scope_req->copy_rxdataF_to_scope) { + size_t size = sizeof(c16_t) * nb_re_pdsch; + int copy_index = symbol - dlsch_config->start_symbol; + UEscopeCopyUnsafe(ue, pdschRxdataF, rxdataF_ext[0], size, scope_req->scope_rxdataF_offset, copy_index); + scope_req->scope_rxdataF_offset += size; + } + //---------------------------------------------------------- + //--------------------- Channel Scaling -------------------- + //---------------------------------------------------------- + start_meas_nr_ue_phy(ue, DLSCH_CHANNEL_SCALE_STATS); + nr_scale_channel(rx_size_symbol, dl_ch_estimates_ext, 0, nb_re_pdsch, nl, n_rx, 0); + stop_meas_nr_ue_phy(ue, DLSCH_CHANNEL_SCALE_STATS); + if (meas_enabled) { + LOG_D(PHY, + "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n", + frame, + nr_slot_rx, + slot, + symbol, + ue->phy_cpu_stats.cpu_time_stats[DLSCH_CHANNEL_SCALE_STATS].p_time / (cpuf * 1000.0)); + } + + //---------------------------------------------------------- + //--------------------- Channel Level Calc. ---------------- + //---------------------------------------------------------- + start_meas_nr_ue_phy(ue, DLSCH_CHANNEL_LEVEL_STATS); + if (first_symbol_flag) { + int32_t avg[nl * n_rx]; + if (nb_re_pdsch) + nr_channel_level(0, rx_size_symbol, (c16_t (*)[rx_size_symbol])dl_ch_estimates_ext, n_rx, nl, avg, nb_re_pdsch); + else + LOG_E(NR_PHY, "Average channel level is 0: nb_rb_pdsch = %d, nb_re_pdsch = %d\n", nb_rb_pdsch, nb_re_pdsch); + int avgs = 0; + int32_t median[MAX_ANT][MAX_ANT]; + for (int l = 0; l < nl; l++) + for (int aarx = 0; aarx < n_rx; aarx++) { + avgs = cmax(avgs, avg[l * n_rx + aarx]); + LOG_D(PHY, "nb_rb %d avg_%d_%d Power per SC is %d\n", nb_rb_pdsch, aarx, l, avg[l * n_rx + aarx]); + LOG_D(PHY, "avgs Power per SC is %d\n", avgs); + median[l][aarx] = avg[l * n_rx + aarx]; + } + if (nl > 1) { + nr_dlsch_channel_level_median(rx_size_symbol, dl_ch_estimates_ext, median, nl, n_rx, nb_re_pdsch); + for (int l = 0; l < nl; l++) { + for (int aarx = 0; aarx < n_rx; aarx++) { + avgs = cmax(avgs, median[l][aarx]); + } + } + } + *log2_maxh = (log2_approx(avgs) / 2) + 1; + LOG_D(PHY, "[DLSCH] AbsSubframe %d.%d log2_maxh = %d (%d)\n", frame % 1024, nr_slot_rx, *log2_maxh, avgs); +#if T_TRACER + T(T_UE_PHY_PDSCH_ENERGY, + T_INT(gNB_id), + T_INT(frame % 1024), + T_INT(nr_slot_rx), + T_INT(avg[0]), // layer 0, antenna 0 + T_INT(n_rx > 1 ? avg[1] : 0), // layer 0, antenna 1 + T_INT(nl > 1 ? avg[n_rx] : 0), // layer 1, antenna 0 + T_INT(nl > 1 && n_rx > 1 ? avg[n_rx + 1] : 0)); // layer 1, antenna 1 +#endif + } + stop_meas_nr_ue_phy(ue, DLSCH_CHANNEL_LEVEL_STATS); + if (meas_enabled) { + LOG_D(PHY, + "[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n", + frame, + nr_slot_rx, + slot, + symbol, + first_symbol_flag, + ue->phy_cpu_stats.cpu_time_stats[DLSCH_CHANNEL_LEVEL_STATS].p_time / (cpuf * 1000.0)); + } + + //---------------------------------------------------------- + //--------------------- channel compensation --------------- + //---------------------------------------------------------- + // Disable correlation measurement for optimizing UE + start_meas_nr_ue_phy(ue, DLSCH_CHANNEL_COMPENSATION_STATS); + nr_dlsch_channel_compensation(rx_size_symbol, + nbRx, + rxdataF_ext, + dl_ch_estimates_ext, + dl_ch_mag, + dl_ch_magb, + dl_ch_magr, + rxdataF_comp, + NULL, + fp, + nl, + symbol, + nb_re_pdsch, + dlsch_config->qamModOrder, + nb_rb_pdsch, + *log2_maxh, + measurements); // log2_maxh+I0_shift + stop_meas_nr_ue_phy(ue, DLSCH_CHANNEL_COMPENSATION_STATS); + if (meas_enabled) { + LOG_D(PHY, + "[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d Channel Comp %5.2f \n", + frame, + nr_slot_rx, + slot, + symbol, + *log2_maxh, + ue->phy_cpu_stats.cpu_time_stats[DLSCH_CHANNEL_COMPENSATION_STATS].p_time / (cpuf * 1000.0)); + } + // Please keep it: useful for debugging +#ifdef DEBUG_PDSCH_RX + char filename[50]; + + snprintf(filename, 50, "rxdataF0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx); + write_output(filename, "rxdataF0", &rxdataF[0][symbol * fp->ofdm_symbol_size], fp->ofdm_symbol_size, 1, 1); + + snprintf(filename, 50, "dl_ch_estimates0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx); + write_output(filename, "dl_ch_estimates0", &dl_ch_estimates[0][symbol * fp->ofdm_symbol_size], fp->ofdm_symbol_size, 1, 1); + + snprintf(filename, 50, "rxdataF_ext0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx); + write_output(filename, "rxdataF_ext0", &rxdataF_ext[0][0], rx_size_symbol, 1, 1); + + snprintf(filename, 50, "dl_ch_estimates_ext0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx); + write_output(filename, "dl_ch_estimates_ext0", &dl_ch_estimates_ext[0][0], rx_size_symbol, 1, 1); + + snprintf(filename, 50, "rxdataF_comp00_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx); + write_output(filename, "rxdataF_comp00", &rxdataF_comp[0][0][symbol * rx_size_symbol], rx_size_symbol, 1, 1); +#endif + } + + start_meas_nr_ue_phy(ue, DLSCH_MRC_MMSE_STATS); + if (n_rx > 1) { + nr_dlsch_detection_mrc(rx_size_symbol, + nl, + n_rx, + rxdataF_comp, + NULL, + dl_ch_mag, + dl_ch_magb, + dl_ch_magr, + symbol, + nb_re_pdsch); + if (nl >= 2) // Apply MMSE for 2, 3, and 4 Tx layers + if (nb_re_pdsch) + nr_dlsch_mmse(rx_size_symbol, + n_rx, + nl, + rxdataF_comp, + dl_ch_mag, + dl_ch_magb, + dl_ch_magr, + dl_ch_estimates_ext, + dlsch_config->qamModOrder, + *log2_maxh, + symbol, + nb_re_pdsch, + nvar); + } + stop_meas_nr_ue_phy(ue, DLSCH_MRC_MMSE_STATS); + + if (meas_enabled) { + LOG_D(PHY, + "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine and MMSE %5.2f \n", + frame, + nr_slot_rx, + slot, + symbol, + ue->phy_cpu_stats.cpu_time_stats[DLSCH_MRC_MMSE_STATS].p_time / (cpuf * 1000.0)); + } + + + + /* Store the valid DL RE's */ + dl_valid_re[symbol] = nb_re_pdsch; + int startSymbIdx = 0; + int nbSymb = 0; + int pduBitmap = 0; + + if(dlsch0_harq->status == ACTIVE) { + startSymbIdx = dlsch_config->start_symbol; + nbSymb = dlsch_config->number_symbols; + pduBitmap = dlsch_config->pduBitmap; + } + + /* Check for PTRS bitmap and process it respectively */ + if((pduBitmap & 0x1) && (dlsch[0].rnti_type == TYPE_C_RNTI_)) { + nr_pdsch_ptrs_processing(nbRx, + ptrs_phase_per_slot, + ptrs_re_per_slot, + rx_size_symbol, + rxdataF_comp, + fp, + dlsch0_harq, + dlsch1_harq, + nr_slot_rx, + symbol, + dlsch[0].rnti, + dlsch); + dl_valid_re[symbol] -= ptrs_re_per_slot[0][symbol]; + } + start_meas_nr_ue_phy(ue, DLSCH_LLR_STATS); + nr_dlsch_llr(rx_size_symbol, + nbRx, + layer_llr_size, + layer_llr, + rxdataF_comp, + dl_ch_mag[0][0], + dl_ch_magb[0][0], + dl_ch_magr[0][0], + dlsch1_harq, + symbol, + dl_valid_re[symbol], + dlsch, + llr_offset[symbol]); + if (symbol < startSymbIdx + nbSymb - 1) // up to the penultimate symbol + llr_offset[symbol + 1] = dl_valid_re[symbol] * dlsch_config->qamModOrder + llr_offset[symbol]; + stop_meas_nr_ue_phy(ue, DLSCH_LLR_STATS); + /* at last symbol in a slot calculate LLR's for whole slot */ + if (symbol == (startSymbIdx + nbSymb - 1)) { + start_meas_nr_ue_phy(ue, DLSCH_LAYER_DEMAPPING); + nr_dlsch_layer_demapping(llr, dlsch[0].Nl, dlsch_config->qamModOrder, G, codeword_TB0, codeword_TB1, layer_llr_size, layer_llr); + stop_meas_nr_ue_phy(ue, DLSCH_LAYER_DEMAPPING); + /* + for (int i=0; i < 2; i++){ + snprintf(filename, 50, "llr%d_symb_%d_nr_slot_rx_%d.m", i, symbol, nr_slot_rx); + write_output(filename,"llr", &llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb_pdsch*NR_NB_SC_PER_RB*dlsch1_harq->Qm) - 4*(nb_rb_pdsch*4*dlsch1_harq->Qm), 1, 0); + } + */ + if (UEScopeHasTryLock(ue)) { + metadata mt = {.frame = proc->frame_rx, .slot = proc->nr_slot_rx }; + int total_valid_res = 0; + for (int i = startSymbIdx; i < startSymbIdx + nbSymb; i++) { + total_valid_res += dl_valid_re[i]; + } + if (UETryLockScopeData(ue, pdschRxdataF_comp, sizeof(c16_t), 1, total_valid_res, &mt)) { + size_t offset = 0; + for (int i = startSymbIdx; i < startSymbIdx + nbSymb; i++) { + size_t data_size = sizeof(c16_t) * dl_valid_re[i]; + UEscopeCopyUnsafe(ue, pdschRxdataF_comp, &rxdataF_comp[0][0][rx_size_symbol * i], data_size, offset, i); + offset += data_size; + } + UEunlockScopeData(ue, pdschRxdataF_comp) + } + } else { + UEscopeCopy(ue, pdschRxdataF_comp, rxdataF_comp[0], sizeof(c16_t), nbRx, rx_size_symbol * fp->symbols_per_slot, 0); + } + } + + if (meas_enabled) { + LOG_D(PHY, + "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n", + frame, + nr_slot_rx, + slot, + symbol, + ue->phy_cpu_stats.cpu_time_stats[DLSCH_LLR_STATS].p_time / (cpuf * 1000.0)); + } + +#if T_TRACER + T(T_UE_PHY_PDSCH_IQ, + T_INT(gNB_id), + T_INT(frame % 1024), + T_INT(nr_slot_rx), + T_INT(nb_rb_pdsch), + T_INT(fp->N_RB_UL), + T_INT(fp->symbols_per_slot), + T_BUFFER(&rxdataF_comp[gNB_id][0], 2 * fp->N_RB_UL * 12 * fp->symbols_per_slot * 2)); +#endif + + if (ue->phy_sim_pdsch_rxdataF_comp) + for (int a = 0; a < nbRx; a++) { + for (int l = 0; l < nl; l++) { + int offset = (void *)rxdataF_comp[l][a] - (void *)rxdataF_comp[0] + symbol * rx_size_symbol * sizeof(c16_t); + memcpy(ue->phy_sim_pdsch_rxdataF_comp + offset, + rxdataF_comp[l][a] + symbol * rx_size_symbol, + sizeof(c16_t) * rx_size_symbol); + } + memcpy((c16_t *)ue->phy_sim_pdsch_dl_ch_estimates + pdsch_est_size * a, dl_ch_estimates, pdsch_est_size * sizeof(c16_t)); + } + if (ue->phy_sim_pdsch_dl_ch_estimates_ext) + memcpy(ue->phy_sim_pdsch_dl_ch_estimates_ext + symbol * sizeof(dl_ch_estimates_ext), + dl_ch_estimates_ext, + sizeof(dl_ch_estimates_ext)); + return 0; +} From b3add42c0f9da28b6619c57190916b6c10525f2b Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Sun, 22 Feb 2026 23:56:32 +0000 Subject: [PATCH 2/6] clean-up: invert if condition, eliminate nesting --- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 337 ++++++++++---------- 1 file changed, 169 insertions(+), 168 deletions(-) diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index fb99c29965..25ca63f364 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -571,197 +571,198 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, int nr_slot_rx = proc->nr_slot_rx; // We handle only one CW now - if (!(NR_MAX_NB_LAYERS>4)) { - NR_UE_DLSCH_t *dlsch0 = &dlsch[0]; - fapi_nr_dl_config_dlsch_pdu_rel15_t *dlschCfg = &dlsch0->dlsch_config; - int harq_pid = dlschCfg->harq_process_nbr; - // dlsch0_harq contains the previous transmissions data for this harq pid - NR_DL_UE_HARQ_t *dlsch0_harq = &ue->dl_harq_processes[0][harq_pid]; + if (NR_MAX_NB_LAYERS > 4) { + LOG_E(NR_PHY, "Handling of more than one CW not implemented\n"); + return -1; + } + NR_UE_DLSCH_t *dlsch0 = &dlsch[0]; + fapi_nr_dl_config_dlsch_pdu_rel15_t *dlschCfg = &dlsch0->dlsch_config; + int harq_pid = dlschCfg->harq_process_nbr; + // dlsch0_harq contains the previous transmissions data for this harq pid + NR_DL_UE_HARQ_t *dlsch0_harq = &ue->dl_harq_processes[0][harq_pid]; - freq_alloc_bitmap_t freq_alloc = {0}; - if (dlschCfg->resource_alloc == 0) { - int alloc_size = (dlschCfg->BWPSize / 8) + (dlschCfg->BWPSize % 8 > 0); - freq_alloc = set_start_end_from_bitmap(dlschCfg->BWPSize, alloc_size, dlschCfg->rb_bitmap); - } else - freq_alloc = set_bitmap_from_start_size(dlschCfg->start_rb, dlschCfg->number_rbs); + freq_alloc_bitmap_t freq_alloc = {0}; + if (dlschCfg->resource_alloc == 0) { + int alloc_size = (dlschCfg->BWPSize / 8) + (dlschCfg->BWPSize % 8 > 0); + freq_alloc = set_start_end_from_bitmap(dlschCfg->BWPSize, alloc_size, dlschCfg->rb_bitmap); + } else + freq_alloc = set_bitmap_from_start_size(dlschCfg->start_rb, dlschCfg->number_rbs); - LOG_D(PHY, - "[UE %d] frame_rx %d, nr_slot_rx %d, harq_pid %d (%d), BWP start %d, start RB %d, end RB %d, symbol_start %d, nb_symbols %d, DMRS mask " - "%x, Nl %d\n", - ue->Mod_id, - frame_rx, - nr_slot_rx, - harq_pid, - dlsch0_harq->status, - dlschCfg->BWPStart, - freq_alloc.start[0], - freq_alloc.end[freq_alloc.num_blocks - 1], - dlschCfg->start_symbol, - dlschCfg->number_symbols, - dlschCfg->dlDmrsSymbPos, - dlsch0->Nl); + LOG_D(PHY, + "[UE %d] frame_rx %d, nr_slot_rx %d, harq_pid %d (%d), BWP start %d, start RB %d, end RB %d, symbol_start %d, nb_symbols " + "%d, DMRS mask " + "%x, Nl %d\n", + ue->Mod_id, + frame_rx, + nr_slot_rx, + harq_pid, + dlsch0_harq->status, + dlschCfg->BWPStart, + freq_alloc.start[0], + freq_alloc.end[freq_alloc.num_blocks - 1], + dlschCfg->start_symbol, + dlschCfg->number_symbols, + dlschCfg->dlDmrsSymbPos, + dlsch0->Nl); - const uint32_t pdsch_est_size = ((ue->frame_parms.symbols_per_slot * ue->frame_parms.ofdm_symbol_size + 15) / 16) * 16; - fourDimArray_t *toFree = NULL; - allocCast2D(pdsch_dl_ch_estimates, int32_t, toFree, ue->frame_parms.nb_antennas_rx * dlsch0->Nl, pdsch_est_size, false); + const uint32_t pdsch_est_size = ((ue->frame_parms.symbols_per_slot * ue->frame_parms.ofdm_symbol_size + 15) / 16) * 16; + fourDimArray_t *toFree = NULL; + allocCast2D(pdsch_dl_ch_estimates, int32_t, toFree, ue->frame_parms.nb_antennas_rx * dlsch0->Nl, pdsch_est_size, false); - c16_t ptrs_phase_per_slot[ue->frame_parms.nb_antennas_rx][NR_SYMBOLS_PER_SLOT]; - memset(ptrs_phase_per_slot, 0, sizeof(ptrs_phase_per_slot)); + c16_t ptrs_phase_per_slot[ue->frame_parms.nb_antennas_rx][NR_SYMBOLS_PER_SLOT]; + memset(ptrs_phase_per_slot, 0, sizeof(ptrs_phase_per_slot)); - int32_t ptrs_re_per_slot[ue->frame_parms.nb_antennas_rx][NR_SYMBOLS_PER_SLOT]; - memset(ptrs_re_per_slot, 0, sizeof(ptrs_re_per_slot)); + int32_t ptrs_re_per_slot[ue->frame_parms.nb_antennas_rx][NR_SYMBOLS_PER_SLOT]; + memset(ptrs_re_per_slot, 0, sizeof(ptrs_re_per_slot)); - const uint32_t rx_size_symbol = (freq_alloc.num_rbs * NR_NB_SC_PER_RB + 15) & ~15; - fourDimArray_t *toFree2 = NULL; - allocCast3D(rxdataF_comp, - int32_t, - toFree2, - dlsch[0].Nl, - ue->frame_parms.nb_antennas_rx, - rx_size_symbol * ue->frame_parms.symbols_per_slot, - false); + const uint32_t rx_size_symbol = (freq_alloc.num_rbs * NR_NB_SC_PER_RB + 15) & ~15; + fourDimArray_t *toFree2 = NULL; + allocCast3D(rxdataF_comp, + int32_t, + toFree2, + dlsch[0].Nl, + ue->frame_parms.nb_antennas_rx, + rx_size_symbol * ue->frame_parms.symbols_per_slot, + false); - uint32_t nvar = 0; + uint32_t nvar = 0; - start_meas_nr_ue_phy(ue, DLSCH_CHANNEL_ESTIMATION_STATS); - for (int m = dlschCfg->start_symbol; m < (dlschCfg->start_symbol + dlschCfg->number_symbols); m++) { - if (dlschCfg->dlDmrsSymbPos & (1 << m)) { - for (int nl = 0; nl < dlsch0->Nl; nl++) { //for MIMO Config: it shall loop over no_layers - LOG_D(PHY,"PDSCH Channel estimation layer %d, slot %d, symbol %d\n", nl, nr_slot_rx, m); - uint32_t nvar_tmp = 0; - nr_pdsch_channel_estimation(ue, - proc, - dlschCfg, - &freq_alloc, - nl, - get_dmrs_port(nl, dlschCfg->dmrs_ports), - m, - pdsch_est_size, - pdsch_dl_ch_estimates, - ue->frame_parms.samples_per_slot_wCP, - rxdataF, - &nvar_tmp); - nvar += nvar_tmp; + start_meas_nr_ue_phy(ue, DLSCH_CHANNEL_ESTIMATION_STATS); + for (int m = dlschCfg->start_symbol; m < (dlschCfg->start_symbol + dlschCfg->number_symbols); m++) { + if (dlschCfg->dlDmrsSymbPos & (1 << m)) { + for (int nl = 0; nl < dlsch0->Nl; nl++) { // for MIMO Config: it shall loop over no_layers + LOG_D(PHY, "PDSCH Channel estimation layer %d, slot %d, symbol %d\n", nl, nr_slot_rx, m); + uint32_t nvar_tmp = 0; + nr_pdsch_channel_estimation(ue, + proc, + dlschCfg, + &freq_alloc, + nl, + get_dmrs_port(nl, dlschCfg->dmrs_ports), + m, + pdsch_est_size, + pdsch_dl_ch_estimates, + ue->frame_parms.samples_per_slot_wCP, + rxdataF, + &nvar_tmp); + nvar += nvar_tmp; #if 0 - ///LOG_M: the channel estimation - char filename[100]; - for (uint8_t aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { - sprintf(filename,"PDSCH_CHANNEL_frame%d_slot%d_sym%d_port%d_rx%d.m", frame_rx, nr_slot_rx, m, nl, aarx); - int **dl_ch_estimates = ue->pdsch_vars[gNB_id]->dl_ch_estimates; - LOG_M(filename,"channel_F",&dl_ch_estimates[nl*ue->frame_parms.nb_antennas_rx+aarx][ue->frame_parms.ofdm_symbol_size*m],ue->frame_parms.ofdm_symbol_size, 1, 1); - } -#endif + ///LOG_M: the channel estimation + char filename[100]; + for (uint8_t aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { + sprintf(filename,"PDSCH_CHANNEL_frame%d_slot%d_sym%d_port%d_rx%d.m", frame_rx, nr_slot_rx, m, nl, aarx); + int **dl_ch_estimates = ue->pdsch_vars[gNB_id]->dl_ch_estimates; + LOG_M(filename,"channel_F",&dl_ch_estimates[nl*ue->frame_parms.nb_antennas_rx+aarx][ue->frame_parms.ofdm_symbol_size*m],ue->frame_parms.ofdm_symbol_size, 1, 1); } +#endif } } - stop_meas_nr_ue_phy(ue, DLSCH_CHANNEL_ESTIMATION_STATS); - nvar /= (dlschCfg->number_symbols * dlsch0->Nl * ue->frame_parms.nb_antennas_rx); - nr_ue_measurement_procedures(2, ue, proc, freq_alloc.num_rbs, pdsch_est_size, pdsch_dl_ch_estimates); + } + stop_meas_nr_ue_phy(ue, DLSCH_CHANNEL_ESTIMATION_STATS); + nvar /= (dlschCfg->number_symbols * dlsch0->Nl * ue->frame_parms.nb_antennas_rx); + nr_ue_measurement_procedures(2, ue, proc, freq_alloc.num_rbs, pdsch_est_size, pdsch_dl_ch_estimates); - if (ue->chest_time == 1) { // averaging time domain channel estimates - nr_chest_time_domain_avg(&ue->frame_parms, - (int32_t **)pdsch_dl_ch_estimates, - dlschCfg->number_symbols, - dlschCfg->start_symbol, - dlschCfg->dlDmrsSymbPos, - freq_alloc.num_rbs); - } + if (ue->chest_time == 1) { // averaging time domain channel estimates + nr_chest_time_domain_avg(&ue->frame_parms, + (int32_t **)pdsch_dl_ch_estimates, + dlschCfg->number_symbols, + dlschCfg->start_symbol, + dlschCfg->dlDmrsSymbPos, + freq_alloc.num_rbs); + } - uint16_t first_symbol_with_data = dlschCfg->start_symbol; - uint32_t dmrs_data_re; + uint16_t first_symbol_with_data = dlschCfg->start_symbol; + uint32_t dmrs_data_re; - if (dlschCfg->dmrsConfigType == NFAPI_NR_DMRS_TYPE1) - dmrs_data_re = 12 - 6 * dlschCfg->n_dmrs_cdm_groups; - else - dmrs_data_re = 12 - 4 * dlschCfg->n_dmrs_cdm_groups; + if (dlschCfg->dmrsConfigType == NFAPI_NR_DMRS_TYPE1) + dmrs_data_re = 12 - 6 * dlschCfg->n_dmrs_cdm_groups; + else + dmrs_data_re = 12 - 4 * dlschCfg->n_dmrs_cdm_groups; - while ((dmrs_data_re == 0) && (dlschCfg->dlDmrsSymbPos & (1 << first_symbol_with_data))) { - first_symbol_with_data++; - } + while ((dmrs_data_re == 0) && (dlschCfg->dlDmrsSymbPos & (1 << first_symbol_with_data))) { + first_symbol_with_data++; + } - uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT] = {0}; - uint32_t llr_offset[NR_SYMBOLS_PER_SLOT] = {0}; + uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT] = {0}; + uint32_t llr_offset[NR_SYMBOLS_PER_SLOT] = {0}; - int32_t log2_maxh = 0; + int32_t log2_maxh = 0; - const uint32_t rx_llr_layer_size = (G + dlsch[0].Nl - 1) / dlsch[0].Nl; + const uint32_t rx_llr_layer_size = (G + dlsch[0].Nl - 1) / dlsch[0].Nl; - if (dlsch[0].Nl == 0 || rx_llr_layer_size == 0 || rx_llr_layer_size > 10 * 1000 * 1000) { - LOG_E(PHY, "rx_llr_layer_size %d, G %d, Nl, %d, discarding this pdsch\n", rx_llr_layer_size, G, dlsch[0].Nl); + if (dlsch[0].Nl == 0 || rx_llr_layer_size == 0 || rx_llr_layer_size > 10 * 1000 * 1000) { + LOG_E(PHY, "rx_llr_layer_size %d, G %d, Nl, %d, discarding this pdsch\n", rx_llr_layer_size, G, dlsch[0].Nl); + return -1; + } + __attribute__((aligned(32))) int16_t layer_llr[dlsch[0].Nl][rx_llr_layer_size]; + + start_meas_nr_ue_phy(ue, RX_PDSCH_STATS); + pdsch_scope_req_t scope_req = {.copy_chanest_to_scope = false, .copy_rxdataF_to_scope = false, .scope_rxdataF_offset = 0}; + if (UEScopeHasTryLock(ue)) { + metadata mt = {.frame = proc->frame_rx, .slot = proc->nr_slot_rx}; + scope_req.copy_chanest_to_scope = UETryLockScopeData(ue, + pdschChanEstimates, + sizeof(c16_t), + 1, + freq_alloc.num_rbs * NR_NB_SC_PER_RB * dlschCfg->number_symbols, + &mt); + scope_req.copy_rxdataF_to_scope = UETryLockScopeData(ue, + pdschRxdataF, + sizeof(c16_t), + 1, + freq_alloc.num_rbs * NR_NB_SC_PER_RB * dlschCfg->number_symbols, + &mt); + } + for (int m = dlschCfg->start_symbol; m < (dlschCfg->number_symbols + dlschCfg->start_symbol); m++) { + bool first_symbol_flag = false; + if (m == first_symbol_with_data) + first_symbol_flag = true; + + // process DLSCH received symbols in the slot + // symbol by symbol processing (if data/DMRS are multiplexed is checked inside the function) + if (nr_rx_pdsch(ue, + proc, + dlsch, + &freq_alloc, + m, + first_symbol_flag, + harq_pid, + pdsch_est_size, + pdsch_dl_ch_estimates, + rx_llr_layer_size, + layer_llr, + llr, + dl_valid_re, + rxdataF, + llr_offset, + &log2_maxh, + rx_size_symbol, + ue->frame_parms.nb_antennas_rx, + rxdataF_comp, + ptrs_phase_per_slot, + ptrs_re_per_slot, + G, + nvar, + &scope_req) + < 0) { + if (scope_req.copy_chanest_to_scope) { + UEunlockScopeData(ue, pdschChanEstimates); + } + if (scope_req.copy_rxdataF_to_scope) { + UEunlockScopeData(ue, pdschRxdataF); + } return -1; } - __attribute__((aligned(32))) int16_t layer_llr[dlsch[0].Nl][rx_llr_layer_size]; - - start_meas_nr_ue_phy(ue, RX_PDSCH_STATS); - pdsch_scope_req_t scope_req = { .copy_chanest_to_scope = false, - .copy_rxdataF_to_scope = false, - .scope_rxdataF_offset = 0 }; - if (UEScopeHasTryLock(ue)) { - metadata mt = {.frame = proc->frame_rx, .slot = proc->nr_slot_rx}; - scope_req.copy_chanest_to_scope = UETryLockScopeData(ue, - pdschChanEstimates, - sizeof(c16_t), - 1, - freq_alloc.num_rbs * NR_NB_SC_PER_RB * dlschCfg->number_symbols, - &mt); - scope_req.copy_rxdataF_to_scope = UETryLockScopeData(ue, - pdschRxdataF, - sizeof(c16_t), - 1, - freq_alloc.num_rbs * NR_NB_SC_PER_RB * dlschCfg->number_symbols, - &mt); - } - for (int m = dlschCfg->start_symbol; m < (dlschCfg->number_symbols + dlschCfg->start_symbol); m++) { - bool first_symbol_flag = false; - if (m == first_symbol_with_data) - first_symbol_flag = true; - - // process DLSCH received symbols in the slot - // symbol by symbol processing (if data/DMRS are multiplexed is checked inside the function) - if (nr_rx_pdsch(ue, - proc, - dlsch, - &freq_alloc, - m, - first_symbol_flag, - harq_pid, - pdsch_est_size, - pdsch_dl_ch_estimates, - rx_llr_layer_size, - layer_llr, - llr, - dl_valid_re, - rxdataF, - llr_offset, - &log2_maxh, - rx_size_symbol, - ue->frame_parms.nb_antennas_rx, - rxdataF_comp, - ptrs_phase_per_slot, - ptrs_re_per_slot, - G, - nvar, - &scope_req) - < 0) { - if (scope_req.copy_chanest_to_scope) { - UEunlockScopeData(ue, pdschChanEstimates); - } - if (scope_req.copy_rxdataF_to_scope) { - UEunlockScopeData(ue, pdschRxdataF); - } - return -1; - } - } // CRNTI active - stop_meas_nr_ue_phy(ue, RX_PDSCH_STATS); - if (scope_req.copy_chanest_to_scope) { - UEunlockScopeData(ue, pdschChanEstimates); - } - if (scope_req.copy_rxdataF_to_scope) { - UEunlockScopeData(ue, pdschRxdataF); - } - free(toFree); - free(toFree2); + } // CRNTI active + stop_meas_nr_ue_phy(ue, RX_PDSCH_STATS); + if (scope_req.copy_chanest_to_scope) { + UEunlockScopeData(ue, pdschChanEstimates); } + if (scope_req.copy_rxdataF_to_scope) { + UEunlockScopeData(ue, pdschRxdataF); + } + free(toFree); + free(toFree2); return 0; } From cb8e12939758e16c86a2e1bea7bde4b9b5dac7d2 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 18 Mar 2026 18:26:18 +0000 Subject: [PATCH 3/6] clean-up: change type from int32_t to c16_t Change rxdataF_comp buffer of PDSCH and PUSCH to c16_t and the functions that use the buffer. --- openair1/PHY/INIT/nr_init.c | 4 ++-- .../PHY/NR_ESTIMATION/nr_ul_channel_estimation.c | 6 +++--- openair1/PHY/NR_REFSIG/ptrs_nr.c | 10 +++------- openair1/PHY/NR_REFSIG/ptrs_nr.h | 2 +- openair1/PHY/NR_TRANSPORT/nr_transport_proto.h | 2 +- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 16 ++++++++-------- .../PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c | 2 +- .../NR_UE_ESTIMATION/nr_dl_channel_estimation.c | 8 ++++---- openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h | 2 +- .../PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 15 +++++++-------- .../PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h | 2 +- openair1/PHY/defs_gNB.h | 2 +- openair1/PHY/nr_phy_common/inc/nr_phy_common.h | 8 ++++---- openair1/PHY/nr_phy_common/src/nr_phy_common.c | 10 +++++----- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 2 +- 15 files changed, 43 insertions(+), 48 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 9f1ddf8f92..34c55e2a27 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -204,11 +204,11 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB) NR_gNB_PUSCH *pusch = &gNB->pusch_vars[ULSCH_id]; pusch->ul_ch_estimates = (int32_t **)malloc16(n_buf * sizeof(int32_t *)); pusch->ptrs_phase_per_slot = (int32_t **)malloc16(n_buf * sizeof(int32_t *)); - pusch->rxdataF_comp = (int32_t **)malloc16(n_buf * sizeof(int32_t *)); + pusch->rxdataF_comp = (c16_t **)malloc16(n_buf * sizeof(*pusch->rxdataF_comp)); for (int i = 0; i < n_buf; i++) { pusch->ul_ch_estimates[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * fp->ofdm_symbol_size * fp->symbols_per_slot); pusch->ptrs_phase_per_slot[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * fp->symbols_per_slot); // symbols per slot - pusch->rxdataF_comp[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * nb_re_pusch2 * fp->symbols_per_slot); + pusch->rxdataF_comp[i] = (c16_t *)malloc16_clear(sizeof(**pusch->rxdataF_comp) * nb_re_pusch2 * fp->symbols_per_slot); } for (int i = 0; i < max_ul_mimo_layers; i++) { diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 45fe87e040..0a57aebd20 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -725,7 +725,7 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, *nb_rb, rel15_ul->rnti, frame_parms->ofdm_symbol_size, - (int16_t *)&pusch_vars->rxdataF_comp[aarx][(symbol * nb_re_pusch)], + &pusch_vars->rxdataF_comp[aarx][(symbol * nb_re_pusch)], gold, (int16_t *)&phase_per_symbol[symbol], ptrs_re_symbol); @@ -754,9 +754,9 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, #ifdef DEBUG_UL_PTRS printf("[PHY][UL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r, phase_per_symbol[i].i); #endif - rotate_cpx_vector((c16_t *)&pusch_vars->rxdataF_comp[aarx][i * nb_re_pusch], + rotate_cpx_vector(&pusch_vars->rxdataF_comp[aarx][i * nb_re_pusch], &phase_per_symbol[i], - (c16_t *)&pusch_vars->rxdataF_comp[aarx][i * nb_re_pusch], + &pusch_vars->rxdataF_comp[aarx][i * nb_re_pusch], ((*nb_rb) * NR_NB_SC_PER_RB), 15); } // if not DMRS Symbol diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.c b/openair1/PHY/NR_REFSIG/ptrs_nr.c index 53cc36cb26..82b1848b76 100644 --- a/openair1/PHY/NR_REFSIG/ptrs_nr.c +++ b/openair1/PHY/NR_REFSIG/ptrs_nr.c @@ -195,7 +195,7 @@ void nr_ptrs_cpe_estimation(uint8_t K_ptrs, uint16_t nb_rb, uint16_t rnti, uint16_t ofdm_symbol_size, - int16_t *rxF_comp, + c16_t *rxF_comp, const uint32_t *gold_seq, int16_t *error_est, int32_t *ptrs_sc) @@ -223,15 +223,11 @@ void nr_ptrs_cpe_estimation(uint8_t K_ptrs, 0,// start_re is 0 here ofdm_symbol_size); if(is_ptrs_re) { - dmrs_comp_p[re_cnt].r = rxF_comp[re *2]; - dmrs_comp_p[re_cnt].i = rxF_comp[(re *2)+1]; - re_cnt++; + dmrs_comp_p[re_cnt++] = rxF_comp[re]; } else { /* Skip PTRS symbols and keep data in a continuous vector */ - rxF_comp[cnt *2]= rxF_comp[re *2]; - rxF_comp[(cnt *2)+1]= rxF_comp[(re *2)+1]; - cnt++; + rxF_comp[cnt++] = rxF_comp[re]; } }/* RE loop */ /* update the total ptrs RE in a symbol */ diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.h b/openair1/PHY/NR_REFSIG/ptrs_nr.h index 68e5f503b7..e55b414702 100644 --- a/openair1/PHY/NR_REFSIG/ptrs_nr.h +++ b/openair1/PHY/NR_REFSIG/ptrs_nr.h @@ -80,7 +80,7 @@ void nr_ptrs_cpe_estimation(uint8_t K_ptrs, uint16_t nb_rb, uint16_t rnti, uint16_t ofdm_symbol_size, - int16_t *rxF_comp, + c16_t *rxF_comp, const uint32_t *gold_seq, int16_t *error_est, int32_t *ptrs_sc); diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index a38bf9b6bb..cabfea0310 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -163,7 +163,7 @@ void nr_ulsch_qam64_qam64(c16_t *stream0_in, @param symbol OFDM symbol index in sub-frame @param mod_order modulation order */ -void nr_ulsch_compute_llr(int32_t *rxdataF_comp, +void nr_ulsch_compute_llr(c16_t *rxdataF_comp, c16_t *ul_ch_mag, c16_t *ul_ch_magb, c16_t *ul_ch_magc, diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index e76cc3a3fd..0b4a94079b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -181,7 +181,7 @@ static void nr_ulsch_channel_compensation(uint32_t buffer_length, c16_t ul_ch_maga[][buffer_length], c16_t ul_ch_magb[][buffer_length], c16_t ul_ch_magc[][buffer_length], - int32_t **rxComp, + c16_t **rxComp, int nb_layers, c16_t rho[][nb_layers][buffer_length], nfapi_nr_pusch_pdu_t *rel15_ul, @@ -472,7 +472,7 @@ static void nr_ulsch_construct_HhH_elements(c16_t *conjch00_ch00, } // MMSE Rx function: nr_ulsch_mmse_2layers() -static uint8_t nr_ulsch_mmse_2layers(int **rxdataF_comp, +static uint8_t nr_ulsch_mmse_2layers(c16_t **rxdataF_comp, uint32_t buffer_length, int nb_rx_ant, c16_t ul_ch_mag[][buffer_length], @@ -948,13 +948,13 @@ static void inner_rx(PHY_VARS_gNB *gNB, if (nb_layer == 1 && rel15_ul->transform_precoding == transformPrecoder_enabled && rel15_ul->qam_mod_order <= 6) { if (rel15_ul->qam_mod_order > 2) nr_freq_equalization(frame_parms, - (c16_t *)&pusch_vars->rxdataF_comp[0][symbol * buffer_length], + &pusch_vars->rxdataF_comp[0][symbol * buffer_length], rxF_ch_maga[0], rxF_ch_magb[0], symbol, pusch_vars->ul_valid_re_per_slot[symbol], rel15_ul->qam_mod_order); - nr_idft(&pusch_vars->rxdataF_comp[0][symbol * buffer_length], pusch_vars->ul_valid_re_per_slot[symbol]); + nr_idft((int32_t *)&pusch_vars->rxdataF_comp[0][symbol * buffer_length], pusch_vars->ul_valid_re_per_slot[symbol]); } if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { nr_pusch_ptrs_processing(gNB, @@ -971,8 +971,8 @@ static void inner_rx(PHY_VARS_gNB *gNB, if (rel15_ul->qam_mod_order <= 6) { nr_ulsch_compute_ML_llr(pusch_vars, symbol, - (c16_t *)&pusch_vars->rxdataF_comp[0][symbol * buffer_length], - (c16_t *)&pusch_vars->rxdataF_comp[nb_rx_ant][symbol * buffer_length], + &pusch_vars->rxdataF_comp[0][symbol * buffer_length], + &pusch_vars->rxdataF_comp[nb_rx_ant][symbol * buffer_length], rxF_ch_maga[0], rxF_ch_maga[1], llr[0], @@ -983,7 +983,7 @@ static void inner_rx(PHY_VARS_gNB *gNB, rel15_ul->qam_mod_order); } else { - nr_ulsch_mmse_2layers((int32_t **)pusch_vars->rxdataF_comp, + nr_ulsch_mmse_2layers(pusch_vars->rxdataF_comp, buffer_length, nb_rx_ant, rxF_ch_maga, @@ -1000,7 +1000,7 @@ static void inner_rx(PHY_VARS_gNB *gNB, } if (nb_layer != 2 || rel15_ul->qam_mod_order > 6) for (int aatx = 0; aatx < nb_layer; aatx++) - nr_ulsch_compute_llr((int32_t *)&pusch_vars->rxdataF_comp[aatx * nb_rx_ant][symbol * buffer_length], + nr_ulsch_compute_llr(&pusch_vars->rxdataF_comp[aatx * nb_rx_ant][symbol * buffer_length], rxF_ch_maga[aatx], rxF_ch_magb[aatx], rxF_ch_magc[aatx], diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c index 3f4660744d..1142487523 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c @@ -38,7 +38,7 @@ #define USE_128BIT #endif -void nr_ulsch_compute_llr(int32_t *rxdataF_comp, +void nr_ulsch_compute_llr(c16_t *rxdataF_comp, c16_t *ul_ch_mag, c16_t *ul_ch_magb, c16_t *ul_ch_magc, 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 f0e53a1c04..762ee5c133 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -1384,7 +1384,7 @@ void nr_pdsch_ptrs_processing(int nbRx, c16_t ptrs_phase_per_slot[][14], int32_t ptrs_re_per_slot[][14], uint32_t rx_size_symbol, - int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], NR_DL_FRAME_PARMS *frame_parms, NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, @@ -1477,7 +1477,7 @@ void nr_pdsch_ptrs_processing(int nbRx, *nb_rb, rnti, frame_parms->ofdm_symbol_size, - (int16_t *)(rxdataF_comp[0][aarx] + symbol * rx_size_symbol), + rxdataF_comp[0][aarx] + symbol * rx_size_symbol, gold, (int16_t *)&phase_per_symbol[symbol], &ptrs_re_symbol[symbol]); @@ -1510,9 +1510,9 @@ void nr_pdsch_ptrs_processing(int nbRx, #ifdef DEBUG_DL_PTRS printf("[PHY][DL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r,phase_per_symbol[i].i); #endif - rotate_cpx_vector((c16_t *)&rxdataF_comp[0][aarx][i * rx_size_symbol], + rotate_cpx_vector(&rxdataF_comp[0][aarx][i * rx_size_symbol], &phase_per_symbol[i], - (c16_t *)&rxdataF_comp[0][aarx][i * rx_size_symbol], + &rxdataF_comp[0][aarx][i * rx_size_symbol], ((*nb_rb) * NR_NB_SC_PER_RB), 15); }// if not DMRS Symbol diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 78657510d0..a858379c42 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -141,7 +141,7 @@ void nr_pdsch_ptrs_processing(int nbRx, c16_t ptrs_phase_per_slot[][14], int32_t ptrs_re_per_slot[][14], uint32_t rx_size_symbol, - int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], NR_DL_FRAME_PARMS *frame_parms, NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index f70b0270c4..ed10130e13 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -138,7 +138,7 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, c16_t dl_ch_mag[][nbRx][rx_size_symbol], c16_t dl_ch_magb[][nbRx][rx_size_symbol], c16_t dl_ch_magr[][nbRx][rx_size_symbol], - int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], int ***rho, NR_DL_FRAME_PARMS *frame_parms, uint8_t n_layers, @@ -387,11 +387,10 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz, } } - static void nr_dlsch_detection_mrc(uint32_t rx_size_symbol, short nl, short n_rx, - int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + c16_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], int ***rho, c16_t dl_ch_mag[][n_rx][rx_size_symbol], c16_t dl_ch_magb[][n_rx][rx_size_symbol], @@ -720,7 +719,7 @@ void nr_conjch0_mult_ch1(c16_t *ch0, c16_t *ch1, c16_t *ch0conj_ch1, unsigned sh static void nr_dlsch_mmse(uint32_t rx_size_symbol, unsigned char n_rx, unsigned char nl, // number of layer - int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + c16_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], c16_t dl_ch_mag[][n_rx][rx_size_symbol], c16_t dl_ch_magb[][n_rx][rx_size_symbol], c16_t dl_ch_magr[][n_rx][rx_size_symbol], @@ -803,7 +802,7 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, // print_shorts(" H_h_H=",(int16_t*)&conjH_H_elements[ctx*nl+rtx][0][0]); // print_shorts(" Inv_H_h_H=",(int16_t*)&inv_H_h_H[ctx*nl+rtx][0]); mult_complex_vectors(inv_H_h_H[ctx][rtx], - (c16_t *)(rxdataF_comp[ctx][0] + symbol * rx_size_symbol), + rxdataF_comp[ctx][0] + symbol * rx_size_symbol, outtemp, sizeofArray(outtemp), shift - (fp_flag == 1 ? 1 : 0)); @@ -819,7 +818,7 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, //Copy zero_forcing out to output array for (int rtx = 0; rtx < nl; rtx++) - nr_element_sign(rxdataF_zforcing[rtx], (c16_t *)(rxdataF_comp[rtx][0] + symbol * rx_size_symbol), nb_rb_0, + 1); + nr_element_sign(rxdataF_zforcing[rtx], rxdataF_comp[rtx][0] + symbol * rx_size_symbol, nb_rb_0, +1); //Update LLR thresholds with the Matrix determinant simde__m128i *dl_ch_mag128_0=NULL,*dl_ch_mag128b_0=NULL,*dl_ch_mag128r_0=NULL,*determ_fin_128; @@ -912,7 +911,7 @@ static void nr_dlsch_llr(uint32_t rx_size_symbol, int nbRx, uint sz, int16_t layer_llr[][sz], - int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], c16_t dl_ch_mag[rx_size_symbol], c16_t dl_ch_magb[rx_size_symbol], c16_t dl_ch_magr[rx_size_symbol], @@ -994,7 +993,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, int32_t *log2_maxh, int rx_size_symbol, int nbRx, - int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT], int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT], int G, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index d77a168c41..7a1076c3c8 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -318,7 +318,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, int32_t *log2_maxh, int rx_size_symbol, int nbRx, - int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT], int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT], int G, diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 92523d94ee..695f6c6363 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -236,7 +236,7 @@ typedef struct { /// \brief Holds the compensated signal. /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **rxdataF_comp; + c16_t **rxdataF_comp; /// \f$\log_2(\max|H_i|^2)\f$ int16_t log2_maxh; /// measured RX power based on DRS diff --git a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h index 67bed6eef4..8baf8df8bb 100644 --- a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h +++ b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h @@ -349,10 +349,10 @@ typedef struct { } csi_mapping_parms_t; csi_mapping_parms_t get_csi_mapping_parms(int row, int b, int l0, int l1); int get_cdm_group_size(int cdm_type); -void nr_qpsk_llr(int32_t *rxdataF_comp, int16_t *llr, uint32_t nb_re); -void nr_16qam_llr(int32_t *rxdataF_comp, c16_t *ch_mag_in, int16_t *llr, uint32_t nb_re); -void nr_64qam_llr(int32_t *rxdataF_comp, c16_t *ch_mag, c16_t *ch_mag2, int16_t *llr, uint32_t nb_re); -void nr_256qam_llr(int32_t *rxdataF_comp, c16_t *ch_mag, c16_t *ch_mag2, c16_t *ch_mag3, int16_t *llr, uint32_t nb_re); +void nr_qpsk_llr(c16_t *rxdataF_comp, int16_t *llr, uint32_t nb_re); +void nr_16qam_llr(c16_t *rxdataF_comp, c16_t *ch_mag_in, int16_t *llr, uint32_t nb_re); +void nr_64qam_llr(c16_t *rxdataF_comp, c16_t *ch_mag, c16_t *ch_mag2, int16_t *llr, uint32_t nb_re); +void nr_256qam_llr(c16_t *rxdataF_comp, c16_t *ch_mag, c16_t *ch_mag2, c16_t *ch_mag3, int16_t *llr, uint32_t nb_re); void freq2time(uint16_t ofdm_symbol_size, int16_t *freq_signal, int16_t *time_signal); void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates_time, delay_t *delay); unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int total_nb_rb, int nb_rb); diff --git a/openair1/PHY/nr_phy_common/src/nr_phy_common.c b/openair1/PHY/nr_phy_common/src/nr_phy_common.c index c29a3a4936..203c19814b 100644 --- a/openair1/PHY/nr_phy_common/src/nr_phy_common.c +++ b/openair1/PHY/nr_phy_common/src/nr_phy_common.c @@ -66,9 +66,9 @@ static inline c16_t saturating_sub(c16_t a, c16_t b) //---------------------------------------------------------------------------------------------- // QPSK //---------------------------------------------------------------------------------------------- -void nr_qpsk_llr(int32_t *rxdataF_comp, int16_t *llr, uint32_t nb_re) +void nr_qpsk_llr(c16_t *rxdataF_comp, int16_t *llr, uint32_t nb_re) { - c16_t *rxF = (c16_t *)rxdataF_comp; + c16_t *rxF = rxdataF_comp; c16_t *llr32 = (c16_t *)llr; for (int i = 0; i < nb_re; i++) { llr32[i].r = rxF[i].r >> 4; @@ -80,7 +80,7 @@ void nr_qpsk_llr(int32_t *rxdataF_comp, int16_t *llr, uint32_t nb_re) // 16-QAM //---------------------------------------------------------------------------------------------- -void nr_16qam_llr(int32_t *rxdataF_comp, c16_t *ch_mag_in, int16_t *llr, uint32_t nb_re) +void nr_16qam_llr(c16_t *rxdataF_comp, c16_t *ch_mag_in, int16_t *llr, uint32_t nb_re) { simde__m256i *rxF_256 = (simde__m256i *)rxdataF_comp; simde__m256i *ch_mag256 = (simde__m256i *)ch_mag_in; @@ -148,7 +148,7 @@ void nr_16qam_llr(int32_t *rxdataF_comp, c16_t *ch_mag_in, int16_t *llr, uint32_ // 64-QAM //---------------------------------------------------------------------------------------------- -void nr_64qam_llr(int32_t *rxdataF_comp, c16_t *ch_mag, c16_t *ch_mag2, int16_t *llr, uint32_t nb_re) +void nr_64qam_llr(c16_t *rxdataF_comp, c16_t *ch_mag, c16_t *ch_mag2, int16_t *llr, uint32_t nb_re) { simde__m256i *rxF = (simde__m256i *)rxdataF_comp; @@ -251,7 +251,7 @@ void nr_64qam_llr(int32_t *rxdataF_comp, c16_t *ch_mag, c16_t *ch_mag2, int16_t } } -void nr_256qam_llr(int32_t *rxdataF_comp, c16_t *ch_mag, c16_t *ch_mag2, c16_t *ch_mag3, int16_t *llr, uint32_t nb_re) +void nr_256qam_llr(c16_t *rxdataF_comp, c16_t *ch_mag, c16_t *ch_mag2, c16_t *ch_mag3, int16_t *llr, uint32_t nb_re) { simde__m256i *rxF_256 = (simde__m256i *)rxdataF_comp; simde__m256i *llr256 = (simde__m256i *)llr; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 25ca63f364..2f58d21c48 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -618,7 +618,7 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, const uint32_t rx_size_symbol = (freq_alloc.num_rbs * NR_NB_SC_PER_RB + 15) & ~15; fourDimArray_t *toFree2 = NULL; allocCast3D(rxdataF_comp, - int32_t, + c16_t, toFree2, dlsch[0].Nl, ue->frame_parms.nb_antennas_rx, From 7c360116695a9e5b04fce3b6c38677b99298515e Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Thu, 8 Jan 2026 02:51:41 +0000 Subject: [PATCH 4/6] refactor: make rxdataF_comp 4D array put symbol index as first dimension. It is necessary because the offset for the buffer to start of a symbol can be arbitrary and hence not aligned to 32 byte boundary. Having each symbol in a separate dimension ensures alignment. --- .../nr_dl_channel_estimation.c | 9 ++-- openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h | 3 +- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 53 ++++++++++--------- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 2 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 5 +- 5 files changed, 38 insertions(+), 34 deletions(-) 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 762ee5c133..978840ae2d 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -1384,7 +1384,8 @@ void nr_pdsch_ptrs_processing(int nbRx, c16_t ptrs_phase_per_slot[][14], int32_t ptrs_re_per_slot[][14], uint32_t rx_size_symbol, - c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + int nl, + c16_t rxdataF_comp[][nl][nbRx][rx_size_symbol], NR_DL_FRAME_PARMS *frame_parms, NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, @@ -1477,7 +1478,7 @@ void nr_pdsch_ptrs_processing(int nbRx, *nb_rb, rnti, frame_parms->ofdm_symbol_size, - rxdataF_comp[0][aarx] + symbol * rx_size_symbol, + rxdataF_comp[symbol][0][aarx], gold, (int16_t *)&phase_per_symbol[symbol], &ptrs_re_symbol[symbol]); @@ -1510,9 +1511,9 @@ void nr_pdsch_ptrs_processing(int nbRx, #ifdef DEBUG_DL_PTRS printf("[PHY][DL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r,phase_per_symbol[i].i); #endif - rotate_cpx_vector(&rxdataF_comp[0][aarx][i * rx_size_symbol], + rotate_cpx_vector(rxdataF_comp[i][0][aarx], &phase_per_symbol[i], - &rxdataF_comp[0][aarx][i * rx_size_symbol], + rxdataF_comp[i][0][aarx], ((*nb_rb) * NR_NB_SC_PER_RB), 15); }// if not DMRS Symbol diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index a858379c42..154554b06d 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -141,7 +141,8 @@ void nr_pdsch_ptrs_processing(int nbRx, c16_t ptrs_phase_per_slot[][14], int32_t ptrs_re_per_slot[][14], uint32_t rx_size_symbol, - c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + int nl, + c16_t rxdataF_comp[][nl][nbRx][rx_size_symbol], NR_DL_FRAME_PARMS *frame_parms, NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index ed10130e13..b695da4825 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -133,15 +133,15 @@ static uint32_t build_csi_overlap_bitmap(fapi_nr_dl_config_dlsch_pdu_rel15_t *dl static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, int nbRx, + uint8_t n_layers, c16_t rxdataF_ext[][rx_size_symbol], int32_t dl_ch_estimates_ext[][rx_size_symbol], c16_t dl_ch_mag[][nbRx][rx_size_symbol], c16_t dl_ch_magb[][nbRx][rx_size_symbol], c16_t dl_ch_magr[][nbRx][rx_size_symbol], - c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + c16_t rxdataF_comp[][n_layers][nbRx][rx_size_symbol], int ***rho, NR_DL_FRAME_PARMS *frame_parms, - uint8_t n_layers, unsigned char symbol, int length, unsigned char mod_order, @@ -175,7 +175,7 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, dl_ch_mag128b = (simde__m128i *)dl_ch_magb[l][aarx]; dl_ch_mag128r = (simde__m128i *)dl_ch_magr[l][aarx]; rxdataF128 = (simde__m128i *)rxdataF_ext[aarx]; - rxdataF_comp128 = (simde__m128i *)(rxdataF_comp[l][aarx] + symbol * rx_size_symbol); + rxdataF_comp128 = (simde__m128i *)(rxdataF_comp[symbol][l][aarx]); for (int rb = 0; rb < nb_rb_0; rb++) { if (mod_order > 2) { @@ -390,7 +390,7 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz, static void nr_dlsch_detection_mrc(uint32_t rx_size_symbol, short nl, short n_rx, - c16_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + c16_t rxdataF_comp[][nl][n_rx][rx_size_symbol], int ***rho, c16_t dl_ch_mag[][n_rx][rx_size_symbol], c16_t dl_ch_magb[][n_rx][rx_size_symbol], @@ -403,12 +403,12 @@ static void nr_dlsch_detection_mrc(uint32_t rx_size_symbol, if (n_rx > 1) { for (int l = 0; l < nl; l++) { - rxdataF_comp128_0 = (simde__m128i *)(rxdataF_comp[l][0] + symbol * rx_size_symbol); + rxdataF_comp128_0 = (simde__m128i *)(rxdataF_comp[symbol][l][0]); dl_ch_mag128_0 = (simde__m128i *)dl_ch_mag[l][0]; dl_ch_mag128_0b = (simde__m128i *)dl_ch_magb[l][0]; dl_ch_mag128_0r = (simde__m128i *)dl_ch_magr[l][0]; for (int aarx = 1; aarx < n_rx; aarx++) { - rxdataF_comp128_1 = (simde__m128i *)(rxdataF_comp[l][aarx] + symbol * rx_size_symbol); + rxdataF_comp128_1 = (simde__m128i *)(rxdataF_comp[symbol][l][aarx]); dl_ch_mag128_1 = (simde__m128i *)dl_ch_mag[l][aarx]; dl_ch_mag128_1b = (simde__m128i *)dl_ch_magb[l][aarx]; dl_ch_mag128_1r = (simde__m128i *)dl_ch_magr[l][aarx]; @@ -719,7 +719,7 @@ void nr_conjch0_mult_ch1(c16_t *ch0, c16_t *ch1, c16_t *ch0conj_ch1, unsigned sh static void nr_dlsch_mmse(uint32_t rx_size_symbol, unsigned char n_rx, unsigned char nl, // number of layer - c16_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + c16_t rxdataF_comp[][nl][n_rx][rx_size_symbol], c16_t dl_ch_mag[][n_rx][rx_size_symbol], c16_t dl_ch_magb[][n_rx][rx_size_symbol], c16_t dl_ch_magr[][n_rx][rx_size_symbol], @@ -802,7 +802,7 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, // print_shorts(" H_h_H=",(int16_t*)&conjH_H_elements[ctx*nl+rtx][0][0]); // print_shorts(" Inv_H_h_H=",(int16_t*)&inv_H_h_H[ctx*nl+rtx][0]); mult_complex_vectors(inv_H_h_H[ctx][rtx], - rxdataF_comp[ctx][0] + symbol * rx_size_symbol, + rxdataF_comp[symbol][ctx][0], outtemp, sizeofArray(outtemp), shift - (fp_flag == 1 ? 1 : 0)); @@ -818,7 +818,7 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, //Copy zero_forcing out to output array for (int rtx = 0; rtx < nl; rtx++) - nr_element_sign(rxdataF_zforcing[rtx], rxdataF_comp[rtx][0] + symbol * rx_size_symbol, nb_rb_0, +1); + nr_element_sign(rxdataF_zforcing[rtx], rxdataF_comp[symbol][rtx][0], nb_rb_0, +1); //Update LLR thresholds with the Matrix determinant simde__m128i *dl_ch_mag128_0=NULL,*dl_ch_mag128b_0=NULL,*dl_ch_mag128r_0=NULL,*determ_fin_128; @@ -910,8 +910,9 @@ static void nr_dlsch_layer_demapping(int16_t *llr_cw[2], static void nr_dlsch_llr(uint32_t rx_size_symbol, int nbRx, uint sz, + int nl, int16_t layer_llr[][sz], - c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + c16_t rxdataF_comp[][nl][nbRx][rx_size_symbol], c16_t dl_ch_mag[rx_size_symbol], c16_t dl_ch_magb[rx_size_symbol], c16_t dl_ch_magr[rx_size_symbol], @@ -924,22 +925,22 @@ static void nr_dlsch_llr(uint32_t rx_size_symbol, switch (dlsch[0].dlsch_config.qamModOrder) { case 2 : for(int l = 0; l < dlsch[0].Nl; l++) - nr_qpsk_llr(&rxdataF_comp[l][0][symbol * rx_size_symbol], layer_llr[l] + llr_offset_symbol, len); + nr_qpsk_llr(&rxdataF_comp[symbol][l][0][0], layer_llr[l] + llr_offset_symbol, len); break; case 4 : for(int l = 0; l < dlsch[0].Nl; l++) - nr_16qam_llr(&rxdataF_comp[l][0][symbol * rx_size_symbol], dl_ch_mag, layer_llr[l] + llr_offset_symbol, len); + nr_16qam_llr(&rxdataF_comp[symbol][l][0][0], dl_ch_mag, layer_llr[l] + llr_offset_symbol, len); break; case 6 : for(int l=0; l < dlsch[0].Nl; l++) - nr_64qam_llr(&rxdataF_comp[l][0][symbol * rx_size_symbol], dl_ch_mag, dl_ch_magb, layer_llr[l] + llr_offset_symbol, len); + nr_64qam_llr(&rxdataF_comp[symbol][l][0][0], dl_ch_mag, dl_ch_magb, layer_llr[l] + llr_offset_symbol, len); break; case 8: for(int l=0; l < dlsch[0].Nl; l++) - nr_256qam_llr(&rxdataF_comp[l][0][symbol * rx_size_symbol], dl_ch_mag, dl_ch_magb, dl_ch_magr, layer_llr[l] + llr_offset_symbol, len); + nr_256qam_llr(&rxdataF_comp[symbol][l][0][0], dl_ch_mag, dl_ch_magb, dl_ch_magr, layer_llr[l] + llr_offset_symbol, len); break; default: @@ -951,19 +952,19 @@ static void nr_dlsch_llr(uint32_t rx_size_symbol, if (dlsch1_harq) { switch (dlsch[1].dlsch_config.qamModOrder) { case 2 : - nr_qpsk_llr(&rxdataF_comp[0][0][symbol * rx_size_symbol], layer_llr[0] + llr_offset_symbol, len); + nr_qpsk_llr(&rxdataF_comp[symbol][0][0][0], layer_llr[0] + llr_offset_symbol, len); break; case 4: - nr_16qam_llr(&rxdataF_comp[0][0][symbol * rx_size_symbol], dl_ch_mag, layer_llr[0] + llr_offset_symbol, len); + nr_16qam_llr(&rxdataF_comp[symbol][0][0][0], dl_ch_mag, layer_llr[0] + llr_offset_symbol, len); break; case 6 : - nr_64qam_llr(&rxdataF_comp[0][0][symbol * rx_size_symbol], dl_ch_mag, dl_ch_magb, layer_llr[0] + llr_offset_symbol, len); + nr_64qam_llr(&rxdataF_comp[symbol][0][0][0], dl_ch_mag, dl_ch_magb, layer_llr[0] + llr_offset_symbol, len); break; case 8 : - nr_256qam_llr(&rxdataF_comp[0][0][symbol * rx_size_symbol], dl_ch_mag, dl_ch_magb, dl_ch_magr, layer_llr[0] + llr_offset_symbol, len); + nr_256qam_llr(&rxdataF_comp[symbol][0][0][0], dl_ch_mag, dl_ch_magb, dl_ch_magr, layer_llr[0] + llr_offset_symbol, len); break; default: @@ -993,7 +994,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, int32_t *log2_maxh, int rx_size_symbol, int nbRx, - c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + c16_t rxdataF_comp[][dlsch->Nl][nbRx][rx_size_symbol], c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT], int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT], int G, @@ -1264,6 +1265,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, start_meas_nr_ue_phy(ue, DLSCH_CHANNEL_COMPENSATION_STATS); nr_dlsch_channel_compensation(rx_size_symbol, nbRx, + nl, rxdataF_ext, dl_ch_estimates_ext, dl_ch_mag, @@ -1272,7 +1274,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, rxdataF_comp, NULL, fp, - nl, symbol, nb_re_pdsch, dlsch_config->qamModOrder, @@ -1371,6 +1372,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, ptrs_phase_per_slot, ptrs_re_per_slot, rx_size_symbol, + nl, rxdataF_comp, fp, dlsch0_harq, @@ -1385,6 +1387,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, nr_dlsch_llr(rx_size_symbol, nbRx, layer_llr_size, + nl, layer_llr, rxdataF_comp, dl_ch_mag[0][0], @@ -1419,13 +1422,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, size_t offset = 0; for (int i = startSymbIdx; i < startSymbIdx + nbSymb; i++) { size_t data_size = sizeof(c16_t) * dl_valid_re[i]; - UEscopeCopyUnsafe(ue, pdschRxdataF_comp, &rxdataF_comp[0][0][rx_size_symbol * i], data_size, offset, i); + UEscopeCopyUnsafe(ue, pdschRxdataF_comp, &rxdataF_comp[i][0][0][0], data_size, offset, i); offset += data_size; } UEunlockScopeData(ue, pdschRxdataF_comp) } } else { - UEscopeCopy(ue, pdschRxdataF_comp, rxdataF_comp[0], sizeof(c16_t), nbRx, rx_size_symbol * fp->symbols_per_slot, 0); + UEscopeCopy(ue, pdschRxdataF_comp, rxdataF_comp[0], sizeof(c16_t), nbRx, rx_size_symbol, 0); } } @@ -1453,10 +1456,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, if (ue->phy_sim_pdsch_rxdataF_comp) for (int a = 0; a < nbRx; a++) { for (int l = 0; l < nl; l++) { - int offset = (void *)rxdataF_comp[l][a] - (void *)rxdataF_comp[0] + symbol * rx_size_symbol * sizeof(c16_t); - memcpy(ue->phy_sim_pdsch_rxdataF_comp + offset, - rxdataF_comp[l][a] + symbol * rx_size_symbol, - sizeof(c16_t) * rx_size_symbol); + int offset = (void *)rxdataF_comp[symbol][l][a] - (void *)rxdataF_comp[0]; + memcpy(ue->phy_sim_pdsch_rxdataF_comp + offset, rxdataF_comp[symbol][l][a], sizeof(c16_t) * rx_size_symbol); } memcpy((c16_t *)ue->phy_sim_pdsch_dl_ch_estimates + pdsch_est_size * a, dl_ch_estimates, pdsch_est_size * sizeof(c16_t)); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 7a1076c3c8..97df9cb2ad 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -318,7 +318,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, int32_t *log2_maxh, int rx_size_symbol, int nbRx, - c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + c16_t rxdataF_comp[][dlsch->Nl][nbRx][rx_size_symbol], c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT], int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT], int G, diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 2f58d21c48..6719b4b407 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -617,12 +617,13 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, const uint32_t rx_size_symbol = (freq_alloc.num_rbs * NR_NB_SC_PER_RB + 15) & ~15; fourDimArray_t *toFree2 = NULL; - allocCast3D(rxdataF_comp, + allocCast4D(rxdataF_comp, c16_t, toFree2, + ue->frame_parms.symbols_per_slot, dlsch[0].Nl, ue->frame_parms.nb_antennas_rx, - rx_size_symbol * ue->frame_parms.symbols_per_slot, + rx_size_symbol, false); uint32_t nvar = 0; From 07f5e01ee85fc8ee8325f50b2b5d1a4a83f13490 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Fri, 9 Jan 2026 00:39:21 +0000 Subject: [PATCH 5/6] bugfix: PTRS phase compensation PTRS phase error is estimated in each symbol and should be compesation in the last symbol. So far nr_dlsch_llr() used rxdataF_comp before PTRS phase correction for all symbol except the last one. This commit fixes it by calling nr_dlsch_llr() for all symbols after rxdataF_comp is compensated for PTRS phase error. To do so, dl_ch_mag arrays are moved out of nr_rx_pdsch() to hold values of all symbols. --- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 76 ++++++++++--------- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 5 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 43 ++++++++--- 3 files changed, 76 insertions(+), 48 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index b695da4825..9e17c141f2 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -985,8 +985,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, unsigned char harq_pid, uint32_t pdsch_est_size, int32_t dl_ch_estimates[][pdsch_est_size], - int layer_llr_size, - int16_t layer_llr[][layer_llr_size], int16_t *llr[2], uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT], c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP], @@ -995,6 +993,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, int rx_size_symbol, int nbRx, c16_t rxdataF_comp[][dlsch->Nl][nbRx][rx_size_symbol], + c16_t dl_ch_mag[][dlsch->Nl][nbRx][rx_size_symbol], + c16_t dl_ch_magb[][dlsch->Nl][nbRx][rx_size_symbol], + c16_t dl_ch_magr[][dlsch->Nl][nbRx][rx_size_symbol], c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT], int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT], int G, @@ -1008,14 +1009,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, __attribute__((aligned(32))) int32_t dl_ch_estimates_ext[matrixSz][rx_size_symbol]; memset(dl_ch_estimates_ext, 0, sizeof(dl_ch_estimates_ext)); - __attribute__((aligned(32))) c16_t dl_ch_mag[nl][n_rx][rx_size_symbol]; - memset(dl_ch_mag, 0, sizeof(dl_ch_mag)); - - __attribute__((aligned(32))) c16_t dl_ch_magb[nl][nbRx][rx_size_symbol]; - memset(dl_ch_magb, 0, sizeof(dl_ch_magb)); - - __attribute__((aligned(32))) c16_t dl_ch_magr[nl][nbRx][rx_size_symbol]; - memset(dl_ch_magr, 0, sizeof(dl_ch_magr)); NR_UE_COMMON *common_vars = &ue->common_vars; PHY_NR_MEASUREMENTS *measurements = &ue->measurements; const int frame = proc->frame_rx; @@ -1268,9 +1261,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, nl, rxdataF_ext, dl_ch_estimates_ext, - dl_ch_mag, - dl_ch_magb, - dl_ch_magr, + dl_ch_mag[symbol], + dl_ch_magb[symbol], + dl_ch_magr[symbol], rxdataF_comp, NULL, fp, @@ -1319,9 +1312,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, n_rx, rxdataF_comp, NULL, - dl_ch_mag, - dl_ch_magb, - dl_ch_magr, + dl_ch_mag[symbol], + dl_ch_magb[symbol], + dl_ch_magr[symbol], symbol, nb_re_pdsch); if (nl >= 2) // Apply MMSE for 2, 3, and 4 Tx layers @@ -1330,9 +1323,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, n_rx, nl, rxdataF_comp, - dl_ch_mag, - dl_ch_magb, - dl_ch_magr, + dl_ch_mag[symbol], + dl_ch_magb[symbol], + dl_ch_magr[symbol], dl_ch_estimates_ext, dlsch_config->qamModOrder, *log2_maxh, @@ -1383,28 +1376,39 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dlsch); dl_valid_re[symbol] -= ptrs_re_per_slot[0][symbol]; } - start_meas_nr_ue_phy(ue, DLSCH_LLR_STATS); - nr_dlsch_llr(rx_size_symbol, - nbRx, - layer_llr_size, - nl, - layer_llr, - rxdataF_comp, - dl_ch_mag[0][0], - dl_ch_magb[0][0], - dl_ch_magr[0][0], - dlsch1_harq, - symbol, - dl_valid_re[symbol], - dlsch, - llr_offset[symbol]); if (symbol < startSymbIdx + nbSymb - 1) // up to the penultimate symbol llr_offset[symbol + 1] = dl_valid_re[symbol] * dlsch_config->qamModOrder + llr_offset[symbol]; - stop_meas_nr_ue_phy(ue, DLSCH_LLR_STATS); /* at last symbol in a slot calculate LLR's for whole slot */ if (symbol == (startSymbIdx + nbSymb - 1)) { + const uint32_t rx_llr_layer_size = (G + dlsch[0].Nl - 1) / dlsch[0].Nl; + + if (dlsch[0].Nl == 0 || rx_llr_layer_size == 0 || rx_llr_layer_size > 10 * 1000 * 1000) { + LOG_E(PHY, "rx_llr_layer_size %d, G %d, Nl, %d, discarding this pdsch\n", rx_llr_layer_size, G, dlsch[0].Nl); + return -1; + } + __attribute__((aligned(32))) int16_t layer_llr[dlsch[0].Nl][rx_llr_layer_size]; + + // Generate LLR from PTRS compensated signal + start_meas_nr_ue_phy(ue, DLSCH_LLR_STATS); + for (int llr_sym = startSymbIdx; llr_sym < startSymbIdx + nbSymb; llr_sym++) { + nr_dlsch_llr(rx_size_symbol, + nbRx, + rx_llr_layer_size, + nl, + layer_llr, + rxdataF_comp, + dl_ch_mag[llr_sym][0][0], + dl_ch_magb[llr_sym][0][0], + dl_ch_magr[llr_sym][0][0], + dlsch1_harq, + llr_sym, + dl_valid_re[llr_sym], + dlsch, + llr_offset[llr_sym]); + } + stop_meas_nr_ue_phy(ue, DLSCH_LLR_STATS); start_meas_nr_ue_phy(ue, DLSCH_LAYER_DEMAPPING); - nr_dlsch_layer_demapping(llr, dlsch[0].Nl, dlsch_config->qamModOrder, G, codeword_TB0, codeword_TB1, layer_llr_size, layer_llr); + nr_dlsch_layer_demapping(llr, dlsch[0].Nl, dlsch_config->qamModOrder, G, codeword_TB0, codeword_TB1, rx_llr_layer_size, layer_llr); stop_meas_nr_ue_phy(ue, DLSCH_LAYER_DEMAPPING); /* for (int i=0; i < 2; i++){ diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 97df9cb2ad..4aeac61e1f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -309,8 +309,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, unsigned char harq_pid, uint32_t pdsch_est_size, int32_t dl_ch_estimates[][pdsch_est_size], - int layer_llr_size, - int16_t layer_llr[][layer_llr_size], int16_t *llr[2], uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT], c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP], @@ -319,6 +317,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, int rx_size_symbol, int nbRx, c16_t rxdataF_comp[][dlsch->Nl][nbRx][rx_size_symbol], + c16_t dl_ch_mag[][dlsch->Nl][nbRx][rx_size_symbol], + c16_t dl_ch_magb[][dlsch->Nl][nbRx][rx_size_symbol], + c16_t dl_ch_magr[][dlsch->Nl][nbRx][rx_size_symbol], c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT], int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT], int G, diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 6719b4b407..347e259554 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -689,14 +689,6 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, int32_t log2_maxh = 0; - const uint32_t rx_llr_layer_size = (G + dlsch[0].Nl - 1) / dlsch[0].Nl; - - if (dlsch[0].Nl == 0 || rx_llr_layer_size == 0 || rx_llr_layer_size > 10 * 1000 * 1000) { - LOG_E(PHY, "rx_llr_layer_size %d, G %d, Nl, %d, discarding this pdsch\n", rx_llr_layer_size, G, dlsch[0].Nl); - return -1; - } - __attribute__((aligned(32))) int16_t layer_llr[dlsch[0].Nl][rx_llr_layer_size]; - start_meas_nr_ue_phy(ue, RX_PDSCH_STATS); pdsch_scope_req_t scope_req = {.copy_chanest_to_scope = false, .copy_rxdataF_to_scope = false, .scope_rxdataF_offset = 0}; if (UEScopeHasTryLock(ue)) { @@ -714,6 +706,33 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, freq_alloc.num_rbs * NR_NB_SC_PER_RB * dlschCfg->number_symbols, &mt); } + fourDimArray_t *toFree3 = NULL; + allocCast4D(dl_ch_mag, + c16_t, + toFree3, + NR_SYMBOLS_PER_SLOT, + dlsch[0].Nl, + ue->frame_parms.nb_antennas_rx, + rx_size_symbol, + false); + fourDimArray_t *toFree4 = NULL; + allocCast4D(dl_ch_magb, + c16_t, + toFree4, + NR_SYMBOLS_PER_SLOT, + dlsch[0].Nl, + ue->frame_parms.nb_antennas_rx, + rx_size_symbol, + false); + fourDimArray_t *toFree5 = NULL; + allocCast4D(dl_ch_magr, + c16_t, + toFree5, + NR_SYMBOLS_PER_SLOT, + dlsch[0].Nl, + ue->frame_parms.nb_antennas_rx, + rx_size_symbol, + false); for (int m = dlschCfg->start_symbol; m < (dlschCfg->number_symbols + dlschCfg->start_symbol); m++) { bool first_symbol_flag = false; if (m == first_symbol_with_data) @@ -730,8 +749,6 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, harq_pid, pdsch_est_size, pdsch_dl_ch_estimates, - rx_llr_layer_size, - layer_llr, llr, dl_valid_re, rxdataF, @@ -740,6 +757,9 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, rx_size_symbol, ue->frame_parms.nb_antennas_rx, rxdataF_comp, + dl_ch_mag, + dl_ch_magb, + dl_ch_magr, ptrs_phase_per_slot, ptrs_re_per_slot, G, @@ -764,6 +784,9 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, } free(toFree); free(toFree2); + free(toFree3); + free(toFree4); + free(toFree5); return 0; } From 04d35f90ecb23cbd0a6a87952eca502cf9270e40 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Thu, 8 Jan 2026 05:14:06 +0000 Subject: [PATCH 6/6] ue: simplify dlsch LLR functions Change layer_llr buffer from 2D to 3D with symbol as first dimenstion. Refactor layer demapping function. --- common/utils/utils.h | 11 ++ .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 158 +++++++----------- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 1 - .../PHY/nr_phy_common/inc/nr_phy_common.h | 8 +- .../PHY/nr_phy_common/src/nr_phy_common.c | 10 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 4 +- 6 files changed, 86 insertions(+), 106 deletions(-) diff --git a/common/utils/utils.h b/common/utils/utils.h index 432e754875..752ba2264b 100644 --- a/common/utils/utils.h +++ b/common/utils/utils.h @@ -20,6 +20,17 @@ extern "C" { #define sizeofArray(a) (sizeof(a)/sizeof(*(a))) #define CHECK_INDEX(ARRAY, INDEX) assert((INDEX) < sizeofArray(ARRAY)) +#define GET_ARRAY_MAX(arr, size, max_val) \ + do { \ + DevAssert((size) > 0); \ + (max_val) = (arr)[0]; \ + for (size_t _i = 1; _i < (size); _i++) { \ + if ((arr)[_i] > (max_val)) { \ + (max_val) = (arr)[_i]; \ + } \ + } \ + } while (0) + // Prevent double evaluation in max macro #define cmax(a,b) ({ __typeof__ (a) _a = (a); \ __typeof__ (b) _b = (b); \ diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 9e17c141f2..693cb028dd 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -868,79 +868,83 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, } } -static void nr_dlsch_layer_demapping(int16_t *llr_cw[2], - uint8_t Nl, - uint8_t mod_order, - uint32_t length, - int32_t codeword_TB0, - int32_t codeword_TB1, - uint sz, - int16_t llr_layers[][sz]) +static void nr_dlsch_layer_demapping(const uint8_t Nl, + const uint8_t mod_order, + const int llrLayerSize, + const int16_t llr_layers[NR_SYMBOLS_PER_SLOT][Nl][llrLayerSize], + const NR_UE_DLSCH_t *dlsch, + const uint32_t re_len[NR_SYMBOLS_PER_SLOT], + int16_t *llr) { + const int s0 = dlsch->dlsch_config.start_symbol; + const int s1 = dlsch->dlsch_config.number_symbols; + + int k = 0; switch (Nl) { case 1: - if (codeword_TB1 == -1) - memcpy(llr_cw[0], llr_layers[0], (length)*sizeof(int16_t)); - else if (codeword_TB0 == -1) - memcpy(llr_cw[1], llr_layers[0], (length)*sizeof(int16_t)); - - break; + for (int i = s0; i < (s0 + s1); i++) { + memcpy(llr + k, llr_layers[i][0], re_len[i] * mod_order * sizeof(int16_t)); + k += re_len[i] * mod_order; + } + break; case 2: case 3: case 4: - for (int i=0; i<(length/Nl/mod_order); i++){ - for (int l=0; l0 1 2 3 - else if (codeword_TB0 == -1) - llr_cw[1][Nl*mod_order*i+l*mod_order+m] = llr_layers[l][i*mod_order+m];//i:0 -->0 1 2 3 - //if (i<4) printf("length%d: llr_layers[l%d][m%d]=%d: \n",length,l,m,llr_layers[l][i*mod_order+m]); - } + for (int i = s0; i < (s0 + s1); i++) { + int m = 0; + for (int j = 0; j < re_len[i]; j++) { + for (int l = 0; l < Nl; l++) { + memcpy(llr + k, llr_layers[i][l] + m * mod_order, sizeof(int16_t) * mod_order); + k += mod_order; + // if (i<4) printf("length%d: llr_layers[l%d][m%d]=%d: \n",length,l,m,llr_layers[l][i*mod_order+m]); } + m++; } - break; + } + break; - default: - AssertFatal(0, "Not supported number of layers %d\n", Nl); + default: + AssertFatal(0, "Not supported number of layers %d\n", Nl); } } -static void nr_dlsch_llr(uint32_t rx_size_symbol, - int nbRx, - uint sz, - int nl, - int16_t layer_llr[][sz], - c16_t rxdataF_comp[][nl][nbRx][rx_size_symbol], - c16_t dl_ch_mag[rx_size_symbol], - c16_t dl_ch_magb[rx_size_symbol], - c16_t dl_ch_magr[rx_size_symbol], - NR_DL_UE_HARQ_t *dlsch1_harq, - unsigned char symbol, - uint32_t len, - NR_UE_DLSCH_t dlsch[2], - uint32_t llr_offset_symbol) +/* Computes LLRs from compensated PDSCH signal per OFDM symbol for all layers */ +static int nr_dlsch_llr(const NR_UE_DLSCH_t *dlsch, + const int len, + const int rx_size_symbol, + const c16_t dl_ch_mag[rx_size_symbol], + const c16_t dl_ch_magb[rx_size_symbol], + const c16_t dl_ch_magr[rx_size_symbol], + const int nb_antennas_rx, + const c16_t rxdataF_comp[dlsch->Nl][nb_antennas_rx][rx_size_symbol], + const int llrSize, + int16_t layer_llr[dlsch->Nl][llrSize]) { - switch (dlsch[0].dlsch_config.qamModOrder) { + switch (dlsch->dlsch_config.qamModOrder) { case 2 : - for(int l = 0; l < dlsch[0].Nl; l++) - nr_qpsk_llr(&rxdataF_comp[symbol][l][0][0], layer_llr[l] + llr_offset_symbol, len); + for (int l = 0; l < dlsch[0].Nl; l++) + nr_qpsk_llr(rxdataF_comp[l][0], layer_llr[l], len); break; case 4 : - for(int l = 0; l < dlsch[0].Nl; l++) - nr_16qam_llr(&rxdataF_comp[symbol][l][0][0], dl_ch_mag, layer_llr[l] + llr_offset_symbol, len); + for (int l = 0; l < dlsch[0].Nl; l++) + nr_16qam_llr(rxdataF_comp[l][0], dl_ch_mag, layer_llr[l], len); break; case 6 : for(int l=0; l < dlsch[0].Nl; l++) - nr_64qam_llr(&rxdataF_comp[symbol][l][0][0], dl_ch_mag, dl_ch_magb, layer_llr[l] + llr_offset_symbol, len); + nr_64qam_llr(rxdataF_comp[l][0], dl_ch_mag, dl_ch_magb, layer_llr[l], len); break; case 8: for(int l=0; l < dlsch[0].Nl; l++) - nr_256qam_llr(&rxdataF_comp[symbol][l][0][0], dl_ch_mag, dl_ch_magb, dl_ch_magr, layer_llr[l] + llr_offset_symbol, len); + nr_256qam_llr(rxdataF_comp[l][0], + dl_ch_mag, + dl_ch_magb, + dl_ch_magr, + layer_llr[l], + len); break; default: @@ -948,30 +952,7 @@ static void nr_dlsch_llr(uint32_t rx_size_symbol, break; } - //TODO: Revisited for Nl>4 - if (dlsch1_harq) { - switch (dlsch[1].dlsch_config.qamModOrder) { - case 2 : - nr_qpsk_llr(&rxdataF_comp[symbol][0][0][0], layer_llr[0] + llr_offset_symbol, len); - break; - - case 4: - nr_16qam_llr(&rxdataF_comp[symbol][0][0][0], dl_ch_mag, layer_llr[0] + llr_offset_symbol, len); - break; - - case 6 : - nr_64qam_llr(&rxdataF_comp[symbol][0][0][0], dl_ch_mag, dl_ch_magb, layer_llr[0] + llr_offset_symbol, len); - break; - - case 8 : - nr_256qam_llr(&rxdataF_comp[symbol][0][0][0], dl_ch_mag, dl_ch_magb, dl_ch_magr, layer_llr[0] + llr_offset_symbol, len); - break; - - default: - AssertFatal(false, "Unknown mod_order!!!!\n"); - break; - } - } + return 0; } //============================================================================================== @@ -988,7 +969,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, int16_t *llr[2], uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT], c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP], - uint32_t llr_offset[NR_SYMBOLS_PER_SLOT], int32_t *log2_maxh, int rx_size_symbol, int nbRx, @@ -1376,39 +1356,31 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dlsch); dl_valid_re[symbol] -= ptrs_re_per_slot[0][symbol]; } - if (symbol < startSymbIdx + nbSymb - 1) // up to the penultimate symbol - llr_offset[symbol + 1] = dl_valid_re[symbol] * dlsch_config->qamModOrder + llr_offset[symbol]; /* at last symbol in a slot calculate LLR's for whole slot */ if (symbol == (startSymbIdx + nbSymb - 1)) { - const uint32_t rx_llr_layer_size = (G + dlsch[0].Nl - 1) / dlsch[0].Nl; - - if (dlsch[0].Nl == 0 || rx_llr_layer_size == 0 || rx_llr_layer_size > 10 * 1000 * 1000) { - LOG_E(PHY, "rx_llr_layer_size %d, G %d, Nl, %d, discarding this pdsch\n", rx_llr_layer_size, G, dlsch[0].Nl); - return -1; - } - __attribute__((aligned(32))) int16_t layer_llr[dlsch[0].Nl][rx_llr_layer_size]; + /* create LLR layer buffer */ + int max_symb_re = 0; + GET_ARRAY_MAX(dl_valid_re, NR_SYMBOLS_PER_SLOT, max_symb_re); + const int llr_per_symbol = max_symb_re * dlsch->dlsch_config.qamModOrder; + __attribute__((aligned(32))) int16_t layer_llr[NR_SYMBOLS_PER_SLOT][nl][llr_per_symbol]; // Generate LLR from PTRS compensated signal start_meas_nr_ue_phy(ue, DLSCH_LLR_STATS); for (int llr_sym = startSymbIdx; llr_sym < startSymbIdx + nbSymb; llr_sym++) { - nr_dlsch_llr(rx_size_symbol, - nbRx, - rx_llr_layer_size, - nl, - layer_llr, - rxdataF_comp, + nr_dlsch_llr(dlsch, + dl_valid_re[llr_sym], + rx_size_symbol, dl_ch_mag[llr_sym][0][0], dl_ch_magb[llr_sym][0][0], dl_ch_magr[llr_sym][0][0], - dlsch1_harq, - llr_sym, - dl_valid_re[llr_sym], - dlsch, - llr_offset[llr_sym]); + n_rx, + rxdataF_comp[llr_sym], + llr_per_symbol, + layer_llr[llr_sym]); } stop_meas_nr_ue_phy(ue, DLSCH_LLR_STATS); start_meas_nr_ue_phy(ue, DLSCH_LAYER_DEMAPPING); - nr_dlsch_layer_demapping(llr, dlsch[0].Nl, dlsch_config->qamModOrder, G, codeword_TB0, codeword_TB1, rx_llr_layer_size, layer_llr); + nr_dlsch_layer_demapping(nl, dlsch_config->qamModOrder, llr_per_symbol, layer_llr, dlsch, dl_valid_re, llr[0]); stop_meas_nr_ue_phy(ue, DLSCH_LAYER_DEMAPPING); /* for (int i=0; i < 2; i++){ diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 4aeac61e1f..f0d8617a18 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -312,7 +312,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, int16_t *llr[2], uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT], c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP], - uint32_t llr_offset[NR_SYMBOLS_PER_SLOT], int32_t *log2_maxh, int rx_size_symbol, int nbRx, diff --git a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h index 8baf8df8bb..f4e513cdb7 100644 --- a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h +++ b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h @@ -349,10 +349,10 @@ typedef struct { } csi_mapping_parms_t; csi_mapping_parms_t get_csi_mapping_parms(int row, int b, int l0, int l1); int get_cdm_group_size(int cdm_type); -void nr_qpsk_llr(c16_t *rxdataF_comp, int16_t *llr, uint32_t nb_re); -void nr_16qam_llr(c16_t *rxdataF_comp, c16_t *ch_mag_in, int16_t *llr, uint32_t nb_re); -void nr_64qam_llr(c16_t *rxdataF_comp, c16_t *ch_mag, c16_t *ch_mag2, int16_t *llr, uint32_t nb_re); -void nr_256qam_llr(c16_t *rxdataF_comp, c16_t *ch_mag, c16_t *ch_mag2, c16_t *ch_mag3, int16_t *llr, uint32_t nb_re); +void nr_qpsk_llr(const c16_t *rxdataF_comp, int16_t *llr, uint32_t nb_re); +void nr_16qam_llr(const c16_t *rxdataF_comp, const c16_t *ch_mag_in, int16_t *llr, uint32_t nb_re); +void nr_64qam_llr(const c16_t *rxdataF_comp, const c16_t *ch_mag, const c16_t *ch_mag2, int16_t *llr, uint32_t nb_re); +void nr_256qam_llr(const c16_t *rxdataF_comp, const c16_t *ch_mag, const c16_t *ch_mag2, const c16_t *ch_mag3, int16_t *llr, uint32_t nb_re); void freq2time(uint16_t ofdm_symbol_size, int16_t *freq_signal, int16_t *time_signal); void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates_time, delay_t *delay); unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int total_nb_rb, int nb_rb); diff --git a/openair1/PHY/nr_phy_common/src/nr_phy_common.c b/openair1/PHY/nr_phy_common/src/nr_phy_common.c index 203c19814b..e61db67bbb 100644 --- a/openair1/PHY/nr_phy_common/src/nr_phy_common.c +++ b/openair1/PHY/nr_phy_common/src/nr_phy_common.c @@ -66,9 +66,9 @@ static inline c16_t saturating_sub(c16_t a, c16_t b) //---------------------------------------------------------------------------------------------- // QPSK //---------------------------------------------------------------------------------------------- -void nr_qpsk_llr(c16_t *rxdataF_comp, int16_t *llr, uint32_t nb_re) +void nr_qpsk_llr(const c16_t *rxdataF_comp, int16_t *llr, uint32_t nb_re) { - c16_t *rxF = rxdataF_comp; + const c16_t *rxF = rxdataF_comp; c16_t *llr32 = (c16_t *)llr; for (int i = 0; i < nb_re; i++) { llr32[i].r = rxF[i].r >> 4; @@ -80,7 +80,7 @@ void nr_qpsk_llr(c16_t *rxdataF_comp, int16_t *llr, uint32_t nb_re) // 16-QAM //---------------------------------------------------------------------------------------------- -void nr_16qam_llr(c16_t *rxdataF_comp, c16_t *ch_mag_in, int16_t *llr, uint32_t nb_re) +void nr_16qam_llr(const c16_t *rxdataF_comp, const c16_t *ch_mag_in, int16_t *llr, uint32_t nb_re) { simde__m256i *rxF_256 = (simde__m256i *)rxdataF_comp; simde__m256i *ch_mag256 = (simde__m256i *)ch_mag_in; @@ -148,7 +148,7 @@ void nr_16qam_llr(c16_t *rxdataF_comp, c16_t *ch_mag_in, int16_t *llr, uint32_t // 64-QAM //---------------------------------------------------------------------------------------------- -void nr_64qam_llr(c16_t *rxdataF_comp, c16_t *ch_mag, c16_t *ch_mag2, int16_t *llr, uint32_t nb_re) +void nr_64qam_llr(const c16_t *rxdataF_comp, const c16_t *ch_mag, const c16_t *ch_mag2, int16_t *llr, uint32_t nb_re) { simde__m256i *rxF = (simde__m256i *)rxdataF_comp; @@ -251,7 +251,7 @@ void nr_64qam_llr(c16_t *rxdataF_comp, c16_t *ch_mag, c16_t *ch_mag2, int16_t *l } } -void nr_256qam_llr(c16_t *rxdataF_comp, c16_t *ch_mag, c16_t *ch_mag2, c16_t *ch_mag3, int16_t *llr, uint32_t nb_re) +void nr_256qam_llr(const c16_t *rxdataF_comp, const c16_t *ch_mag, const c16_t *ch_mag2, const c16_t *ch_mag3, int16_t *llr, uint32_t nb_re) { simde__m256i *rxF_256 = (simde__m256i *)rxdataF_comp; simde__m256i *llr256 = (simde__m256i *)llr; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 347e259554..7f500b00a4 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -685,7 +685,6 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, } uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT] = {0}; - uint32_t llr_offset[NR_SYMBOLS_PER_SLOT] = {0}; int32_t log2_maxh = 0; @@ -752,7 +751,6 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, llr, dl_valid_re, rxdataF, - llr_offset, &log2_maxh, rx_size_symbol, ue->frame_parms.nb_antennas_rx, @@ -1319,7 +1317,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_ unav_res, dlsch_config->qamModOrder, dlsch[0].Nl); - const uint32_t rx_llr_buf_sz = ((G + 15) / 16) * 16; + const uint32_t rx_llr_buf_sz = ALIGNARRAYSIZE(G, 32); // each LLR is 2 bytes hence 64 byte aligned const uint32_t nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1; int16_t* llr[2]; for (int i = 0; i < nb_codewords; i++)