From 7eb65f2adc78301f9b1e3873972e8161064ef7b0 Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 24 Jun 2025 17:04:25 +0200 Subject: [PATCH] adapt nr_dlsch_extract_rbs for type0 PDSCH freq allocation --- .../nr_dl_channel_estimation.c | 30 +++-- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 124 +++++++++--------- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 1 + .../PHY/NR_UE_TRANSPORT/nr_transport_ue.h | 6 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 32 +++-- 5 files changed, 105 insertions(+), 88 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 9e76b2f85f..356e044cb4 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -938,12 +938,13 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, } void NFAPI_NR_DMRS_TYPE1_linear_interp(NR_DL_FRAME_PARMS *frame_parms, - const freq_alloc_bitmap_t *freq_alloc, c16_t *rxF, c16_t *pil, c16_t *dl_ch, unsigned short bwp_start_subcarrier, - unsigned short nb_rb_pdsch, + int rb_offset, + int nb_rb_pdsch, + const uint8_t bitmap[36], delay_t *delay, uint32_t *nvar) { @@ -952,8 +953,8 @@ void NFAPI_NR_DMRS_TYPE1_linear_interp(NR_DL_FRAME_PARMS *frame_parms, c16_t dl_ls_est[frame_parms->ofdm_symbol_size] __attribute__((aligned(32))); memset(dl_ls_est, 0, sizeof(dl_ls_est)); int idx = 0; - for (int rb = freq_alloc->start; rb < freq_alloc->start + nb_rb_pdsch; rb++) { - bool allocated_rb = (freq_alloc->bitmap[rb / 8] >> (rb % 8)) & 0x01; + for (int rb = rb_offset; rb < rb_offset + nb_rb_pdsch; rb++) { + bool allocated_rb = (bitmap[rb / 8] >> (rb % 8)) & 0x01; if (allocated_rb) { for (int pilot_cnt = 0; pilot_cnt < 6; pilot_cnt += 2) { c16_t ch_l = c16mulShift(*pil, rxF[re_offset], 15); @@ -1103,12 +1104,13 @@ void NFAPI_NR_DMRS_TYPE1_average_prb(NR_DL_FRAME_PARMS *frame_parms, } void NFAPI_NR_DMRS_TYPE2_linear_interp(NR_DL_FRAME_PARMS *frame_parms, - const freq_alloc_bitmap_t *freq_alloc, c16_t *rxF, c16_t *pil, c16_t *dl_ch, unsigned short bwp_start_subcarrier, - unsigned short nb_rb_pdsch, + int rb_offset, + int nb_rb_pdsch, + const uint8_t bitmap[36], delay_t *delay, uint32_t *nvar) { @@ -1117,8 +1119,8 @@ void NFAPI_NR_DMRS_TYPE2_linear_interp(NR_DL_FRAME_PARMS *frame_parms, c16_t dl_ls_est[frame_parms->ofdm_symbol_size] __attribute__((aligned(32))); memset(dl_ls_est, 0, sizeof(dl_ls_est)); int idx = 0; - for (int rb = freq_alloc->start; rb < freq_alloc->start + nb_rb_pdsch; rb++) { - bool allocated_rb = (freq_alloc->bitmap[rb / 8] >> (rb % 8)) & 0x01; + for (int rb = rb_offset; rb < rb_offset + nb_rb_pdsch; rb++) { + bool allocated_rb = (bitmap[rb / 8] >> (rb % 8)) & 0x01; if (allocated_rb) { for (int pilot_cnt = 0; pilot_cnt < 4; pilot_cnt += 2) { c16_t ch_l = c16mulShift(*pil, rxF[re_offset], 15); @@ -1286,7 +1288,7 @@ void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, NR_DL_FRAME_PARMS *fp = &ue->frame_parms; const int ch_offset = fp->ofdm_symbol_size * symbol; const int symbol_offset = fp->ofdm_symbol_size * symbol; - int bwp_start_subcarrier = fp->first_carrier_offset + (dlsch->BWPStart + freq_alloc->start) * 12; + int bwp_start_subcarrier = fp->first_carrier_offset + (dlsch->BWPStart + freq_alloc->start[0]) * 12; #ifdef DEBUG_PDSCH printf( @@ -1303,8 +1305,8 @@ void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, // generate pilot for gNB port number 1000+p int config_type = dlsch->dmrsConfigType; - int rb_offset = freq_alloc->start + (dlsch->refPoint ? 0 : dlsch->BWPStart); - int nb_rb_pdsch = freq_alloc->end - freq_alloc->start + 1; + int rb_offset = freq_alloc->start[0] + (dlsch->refPoint ? 0 : dlsch->BWPStart); + int nb_rb_pdsch = freq_alloc->end[freq_alloc->num_blocks - 1] - freq_alloc->start[0] + 1; int8_t delta = get_delta(p, config_type); c16_t pilot[3280] __attribute__((aligned(16))); // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS @@ -1328,23 +1330,25 @@ void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, if (config_type == NFAPI_NR_DMRS_TYPE1 && ue->chest_freq == 0) { NFAPI_NR_DMRS_TYPE1_linear_interp(fp, - freq_alloc, rxF, &pilot[6 * rb_offset], dl_ch, bwp_start_subcarrier, + freq_alloc->start[0], nb_rb_pdsch, + freq_alloc->bitmap, &delay, nvar); } else if (config_type == NFAPI_NR_DMRS_TYPE2 && ue->chest_freq == 0) { NFAPI_NR_DMRS_TYPE2_linear_interp(fp, - freq_alloc, rxF, &pilot[4 * rb_offset], dl_ch, bwp_start_subcarrier, + freq_alloc->start[0], nb_rb_pdsch, + freq_alloc->bitmap, &delay, nvar); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index e281e1851d..6b6d322988 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -141,8 +141,8 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz, unsigned char symbol, uint8_t pilots, uint8_t config_type, - unsigned short start_rb, - unsigned short nb_rb_pdsch, + int startBWP, + const freq_alloc_bitmap_t *freq_alloc, uint8_t n_dmrs_cdm_groups, uint8_t Nl, NR_DL_FRAME_PARMS *frame_parms, @@ -293,6 +293,7 @@ static uint32_t build_csi_overlap_bitmap(fapi_nr_dl_config_dlsch_pdu_rel15_t *dl 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, @@ -393,13 +394,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, 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; - int start_rb = dlsch_config->start_rb; - int nb_rb_pdsch = dlsch_config->number_rbs; - DevAssert(dlsch0_harq); if (gNB_id > 2) { - LOG_E(PHY, "In %s: Illegal gNB_id %d\n", __FUNCTION__, gNB_id); + LOG_E(PHY, "Illegal gNB_id %d\n", gNB_id); return(-1); } @@ -423,7 +421,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, //---------------------------------------------------------- const int n_rx = frame_parms->nb_antennas_rx; 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]; @@ -443,8 +441,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, symbol, pilots, config_type, - start_rb + dlsch_config->BWPStart, - nb_rb_pdsch, + dlsch_config->BWPStart, + freq_alloc, dlsch_config->n_dmrs_cdm_groups, nl, frame_parms, @@ -453,7 +451,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, 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) * dlsch_config->number_rbs * NR_NB_SC_PER_RB; + 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); @@ -478,14 +476,15 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, 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 = start_rb + dlsch_config->BWPStart; - for (int rb = start; rb < start + nb_rb_pdsch; rb++) { - uint32_t rb_csi_pattern = (rb % 2 == 0) ? csi_res_even : csi_res_odd; - csi_re_count += __builtin_popcount(rb_csi_pattern); + 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", @@ -778,7 +777,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, 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); + return 0; } //============================================================================================== @@ -1019,8 +1018,8 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz, unsigned char symbol, uint8_t pilots, uint8_t config_type, - unsigned short start_rb, - unsigned short nb_rb_pdsch, + int startBWP, + const freq_alloc_bitmap_t *freq_alloc, uint8_t n_dmrs_cdm_groups, uint8_t Nl, NR_DL_FRAME_PARMS *frame_parms, @@ -1029,7 +1028,7 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz, int chest_time_type) { if (config_type == NFAPI_NR_DMRS_TYPE1) - AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2, "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); + AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2, "n_dmrs_cdm_groups %d is illegal\n", n_dmrs_cdm_groups); else AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2 || n_dmrs_cdm_groups == 3, "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); @@ -1052,61 +1051,60 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz, AssertFatal((dmrs_rb_bitmap & csi_res_odd) == 0, "DMRS RE overlapping with CSI RE, it shouldn't happen\n"); uint32_t dmrs_csi_overlap_even = csi_res_even + dmrs_rb_bitmap; uint32_t dmrs_csi_overlap_odd = csi_res_odd + dmrs_rb_bitmap; - - const unsigned short start_re = (frame_parms->first_carrier_offset + start_rb * NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; int8_t validDmrsEst; - if (chest_time_type == 0) - validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos,symbol); + validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos, symbol); else - validDmrsEst = get_next_dmrs_symbol_in_slot(dlDmrsSymbPos,0,14); // get first dmrs symbol index + validDmrsEst = get_next_dmrs_symbol_in_slot(dlDmrsSymbPos, 0, 14); // get first dmrs symbol index - for (unsigned char aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { - c16_t *rxF_ext = rxdataF_ext[aarx]; - c16_t *rxF = &rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size]; - - for (unsigned char l = 0; l < Nl; l++) { - - int32_t *dl_ch0 = &dl_ch_estimates[(l * frame_parms->nb_antennas_rx) + aarx][validDmrsEst * frame_parms->ofdm_symbol_size]; - int32_t *dl_ch0_ext = dl_ch_estimates_ext[(l * frame_parms->nb_antennas_rx) + aarx]; - - if (pilots == 0 && csi_res_bitmap == 0) { // data symbol only - if (l == 0) { - if (start_re + nb_rb_pdsch * NR_NB_SC_PER_RB <= frame_parms->ofdm_symbol_size) { - memcpy(rxF_ext, &rxF[start_re], nb_rb_pdsch * NR_NB_SC_PER_RB * sizeof(int32_t)); - } else { - int neg_length = frame_parms->ofdm_symbol_size - start_re; - int pos_length = nb_rb_pdsch * NR_NB_SC_PER_RB - neg_length; - memcpy(rxF_ext, &rxF[start_re], neg_length * sizeof(int32_t)); - memcpy(&rxF_ext[neg_length], rxF, pos_length * sizeof(int32_t)); - } - } - memcpy(dl_ch0_ext, dl_ch0, nb_rb_pdsch * NR_NB_SC_PER_RB * sizeof(int32_t)); - } - else { - int j = 0; - int k = start_re; - for (int rb = 0; rb < nb_rb_pdsch; rb++) { - uint32_t overlap_map = rb % 2 ? dmrs_csi_overlap_odd : dmrs_csi_overlap_even; - for (int re = 0; re < 12; re++) { - if (((overlap_map >> re) & 0x01) == 0) { - // DATA RE - if (l == 0) - rxF_ext[j] = rxF[k]; - dl_ch0_ext[j] = dl_ch0[re]; - j++; + for (int b = 0; b < freq_alloc->num_blocks; b++) { + int start_rb = freq_alloc->start[b] + startBWP; + int nb_rb = freq_alloc->end[b] - freq_alloc->start[b] + 1; + const int start_re = (frame_parms->first_carrier_offset + start_rb * NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; + for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { + c16_t *rxF_ext = rxdataF_ext[aarx]; + c16_t *rxF = &rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size]; + for (int l = 0; l < Nl; l++) { + int32_t *dl_ch0 = &dl_ch_estimates[(l * frame_parms->nb_antennas_rx) + aarx][validDmrsEst * frame_parms->ofdm_symbol_size]; + int32_t *dl_ch0_ext = dl_ch_estimates_ext[(l * frame_parms->nb_antennas_rx) + aarx]; + if (pilots == 0 && csi_res_bitmap == 0) { // data symbol only + if (l == 0) { + if (start_re + nb_rb * NR_NB_SC_PER_RB <= frame_parms->ofdm_symbol_size) { + memcpy(rxF_ext, &rxF[start_re], nb_rb * NR_NB_SC_PER_RB * sizeof(int32_t)); + } else { + int neg_length = frame_parms->ofdm_symbol_size - start_re; + int pos_length = nb_rb * NR_NB_SC_PER_RB - neg_length; + memcpy(rxF_ext, &rxF[start_re], neg_length * sizeof(int32_t)); + memcpy(&rxF_ext[neg_length], rxF, pos_length * sizeof(int32_t)); } - k++; - if (k >= frame_parms->ofdm_symbol_size) - k -= frame_parms->ofdm_symbol_size; } - dl_ch0 += 12; + memcpy(dl_ch0_ext, dl_ch0, nb_rb * NR_NB_SC_PER_RB * sizeof(int32_t)); + } else { + int j = 0; + int k = start_re; + for (int rb = start_rb; rb < start_rb + nb_rb; rb++) { + uint32_t overlap_map = rb % 2 ? dmrs_csi_overlap_odd : dmrs_csi_overlap_even; + for (int re = 0; re < NR_NB_SC_PER_RB; re++) { + if (((overlap_map >> re) & 0x01) == 0) { + // DATA RE + if (l == 0) + rxF_ext[j] = rxF[k]; + dl_ch0_ext[j] = dl_ch0[re]; + j++; + } + k++; + if (k >= frame_parms->ofdm_symbol_size) + k -= frame_parms->ofdm_symbol_size; + } + dl_ch0 += 12; + } } } } } } + static void nr_dlsch_detection_mrc(uint32_t rx_size_symbol, short nl, short n_rx, 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 6eaa0ecec1..41747a9ef1 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -315,6 +315,7 @@ void nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, 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, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index fd4fe3a1b7..596916f091 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -38,10 +38,12 @@ #include "nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h" #include "../NR_TRANSPORT/nr_transport_common_proto.h" +#define MAX_FA_BLOCKS 10 typedef struct { - int start; - int end; + int start[MAX_FA_BLOCKS]; + int end[MAX_FA_BLOCKS]; int num_rbs; + int num_blocks; uint8_t bitmap[36]; } freq_alloc_bitmap_t; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 591ea711f3..f22d13c5fc 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -578,19 +578,29 @@ static freq_alloc_bitmap_t set_start_end_from_bitmap(int size, int alloc_size, c { freq_alloc_bitmap_t alloc = { .num_rbs = 0, - .start = size, - .end = 0 + .num_blocks = 0 }; + bool pos_bit = false; for (int i = 0; i < size; i++) { if ((bitmap[i / 8] >> i % 8) & 0x1) { - if (alloc.start == size) - alloc.start = i; - alloc.end = i; + if (!pos_bit) { + pos_bit = true; + alloc.start[alloc.num_blocks] = i; + AssertFatal(alloc.num_blocks < MAX_FA_BLOCKS, "Number of type0 PDSCH RBG exceeting %d\n", MAX_FA_BLOCKS); + alloc.num_blocks++; + } alloc.num_rbs++; + } else { + if (pos_bit) { + pos_bit = false; + alloc.end[alloc.num_blocks - 1] = i - 1; + } } } - AssertFatal(alloc.end > 0, "Frequency allocation bitmap empty\n"); + if (pos_bit) + alloc.end[alloc.num_blocks - 1] = size - 1; + AssertFatal(alloc.num_blocks > 0, "Frequency allocation bitmap empty\n"); memcpy(alloc.bitmap, bitmap, alloc_size * sizeof(uint8_t)); return alloc; } @@ -599,8 +609,9 @@ static freq_alloc_bitmap_t set_bitmap_from_start_size(int start, int size) { freq_alloc_bitmap_t alloc = { .num_rbs = size, - .start = start, - .end = start + size - 1 + .num_blocks = 1, + .start[0] = start, + .end[0] = start + size - 1 }; memset(alloc.bitmap, 0, 36 * sizeof(uint8_t)); for (int i = start; i < size + start; i++) @@ -642,8 +653,8 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, harq_pid, dlsch0_harq->status, dlschCfg->BWPStart, - freq_alloc.start, - freq_alloc.end, + freq_alloc.start[0], + freq_alloc.end[freq_alloc.num_blocks - 1], dlschCfg->start_symbol, dlschCfg->number_symbols, dlschCfg->dlDmrsSymbPos, @@ -769,6 +780,7 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, if (nr_rx_pdsch(ue, proc, dlsch, + &freq_alloc, m, first_symbol_flag, harq_pid,