diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index 4429cad56b..43b8367e3b 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -279,6 +279,7 @@ These modes of operation are supported: - DCI formats: 00, 10, 01 and 11 * Reception of NR-PDSCH (including Segmentation, LDPC decoding, rate de-matching, de-scrambling, de-modulation, RB de-mapping, etc). - PDSCH mapping type A and B + - Downlink resource allocation type 0 and 1 - DMRS configuration type 1 and 2 - Single and multiple DMRS symbols - PTRS support diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 6bea8f55cc..dc52f1de2a 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -476,9 +476,7 @@ typedef struct { uint16_t start_rb; uint16_t number_symbols; uint16_t start_symbol; - // TODO this is a workaround to make it work - // implementation is also a bunch of workarounds - uint16_t rb_offset; + uint8_t refPoint; uint16_t dlDmrsSymbPos; uint8_t dmrsConfigType; uint8_t prb_bundling_size_ind; 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 8703c1c774..296606a426 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -942,51 +942,57 @@ void NFAPI_NR_DMRS_TYPE1_linear_interp(NR_DL_FRAME_PARMS *frame_parms, 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) { c16_t *dl_ch0 = dl_ch; int re_offset = bwp_start_subcarrier % frame_parms->ofdm_symbol_size; - c16_t dl_ls_est[frame_parms->ofdm_symbol_size] __attribute__((aligned(32))); memset(dl_ls_est, 0, sizeof(dl_ls_est)); - - int nest_count = 0; - uint64_t noise_amp2 = 0; - - for (int pilot_cnt = 0; pilot_cnt < 6 * nb_rb_pdsch; pilot_cnt += 2) { - c16_t ch_l = c16mulShift(*pil, rxF[re_offset], 15); + int idx = 0; + 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); #ifdef DEBUG_PDSCH - printf("pilot %3d: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d) \n", pilot_cnt, pil->r, pil->i, rxF[re_offset].r, rxF[re_offset].i, ch_l.r, ch_l.i); + printf("pilot %3d: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d) \n", pilot_cnt, pil->r, pil->i, rxF[re_offset].r, rxF[re_offset].i, ch_l.r, ch_l.i); #endif - pil++; - re_offset = (re_offset + 2) % frame_parms->ofdm_symbol_size; - c16_t ch_r = c16mulShift(*pil, rxF[re_offset], 15); + pil++; + re_offset = (re_offset + 2) % frame_parms->ofdm_symbol_size; + c16_t ch_r = c16mulShift(*pil, rxF[re_offset], 15); #ifdef DEBUG_PDSCH - printf("pilot %3d: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d) \n", pilot_cnt + 1, pil->r, pil->i, rxF[re_offset].r, rxF[re_offset].i, ch_r.r, ch_r.i); + printf("pilot %3d: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d) \n", pilot_cnt + 1, pil->r, pil->i, rxF[re_offset].r, rxF[re_offset].i, ch_r.r, ch_r.i); #endif - c16_t ch = c16addShift(ch_l, ch_r, 1); - pil++; - re_offset = (re_offset + 2) % frame_parms->ofdm_symbol_size; - for (int k = pilot_cnt << 1; k < (pilot_cnt << 1) + 4; k++) { - dl_ls_est[k] = ch; + c16_t ch = c16addShift(ch_l, ch_r, 1); + pil++; + re_offset = (re_offset + 2) % frame_parms->ofdm_symbol_size; + for (int k = 0; k < 4; k++) { + dl_ls_est[idx] = ch; + idx++; + } + } + } else { + pil += 6; + re_offset = (re_offset + 12) % frame_parms->ofdm_symbol_size; } } - c16_t ch_estimates_time[frame_parms->ofdm_symbol_size] __attribute__((aligned(32))); nr_est_delay(frame_parms->ofdm_symbol_size, dl_ls_est, ch_estimates_time, delay); int delay_idx = get_delay_idx(delay->est_delay, MAX_DELAY_COMP); c16_t *dl_delay_table = frame_parms->delay_table[delay_idx]; - for (int pilot_cnt = 0; pilot_cnt < 6 * nb_rb_pdsch; pilot_cnt++) { + for (int pilot_cnt = 0; pilot_cnt < idx >> 1; pilot_cnt++) { int k = pilot_cnt << 1; c16_t ch = c16mulShift(dl_ls_est[k], dl_delay_table[k], 8); if (pilot_cnt == 0) { // Treat first pilot c16multaddVectRealComplex(filt16_ul_p0, &ch, dl_ch, 16); } else if (pilot_cnt == 1 || pilot_cnt == 2) { c16multaddVectRealComplex(filt16_ul_p1p2, &ch, dl_ch, 16); - } else if (pilot_cnt == 6 * nb_rb_pdsch - 1) { // Treat last pilot + } else if (pilot_cnt == (idx >> 1) - 1) { // Treat last pilot c16multaddVectRealComplex(filt16_ul_last, &ch, dl_ch, 16); } else { // Treat middle pilots c16multaddVectRealComplex(filt16_ul_middle, &ch, dl_ch, 16); @@ -998,9 +1004,11 @@ void NFAPI_NR_DMRS_TYPE1_linear_interp(NR_DL_FRAME_PARMS *frame_parms, // Revert delay dl_ch = dl_ch0; + int nest_count = 0; + uint64_t noise_amp2 = 0; int inv_delay_idx = get_delay_idx(-delay->est_delay, MAX_DELAY_COMP); c16_t *dl_inv_delay_table = frame_parms->delay_table[inv_delay_idx]; - for (int k = 0; k < 12 * nb_rb_pdsch; k++) { + for (int k = 0; k < idx; k++) { dl_ch[k] = c16mulShift(dl_ch[k], dl_inv_delay_table[k], 8); noise_amp2 += c16amp2(c16sub(dl_ls_est[k], dl_ch[k])); nest_count++; @@ -1100,51 +1108,58 @@ void NFAPI_NR_DMRS_TYPE2_linear_interp(NR_DL_FRAME_PARMS *frame_parms, 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) { int re_offset = bwp_start_subcarrier % frame_parms->ofdm_symbol_size; c16_t *dl_ch0 = dl_ch; - c16_t dl_ls_est[frame_parms->ofdm_symbol_size] __attribute__((aligned(32))); memset(dl_ls_est, 0, sizeof(dl_ls_est)); - - int nest_count = 0; - uint64_t noise_amp2 = 0; - - for (int pilot_cnt = 0; pilot_cnt < 4 * nb_rb_pdsch; pilot_cnt += 2) { - c16_t ch_l = c16mulShift(*pil, rxF[re_offset], 15); + int idx = 0; + 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); #ifdef DEBUG_PDSCH - printf("pilot %3d: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d) \n", pilot_cnt, pil->r, pil->i, rxF[re_offset].r, rxF[re_offset].i, ch_l.r, ch_l.i); + printf("pilot %3d: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d) \n", pilot_cnt, pil->r, pil->i, rxF[re_offset].r, rxF[re_offset].i, ch_l.r, ch_l.i); #endif - pil++; - re_offset = (re_offset + 1) % frame_parms->ofdm_symbol_size; - c16_t ch_r = c16mulShift(*pil, rxF[re_offset], 15); + pil++; + re_offset = (re_offset + 1) % frame_parms->ofdm_symbol_size; + c16_t ch_r = c16mulShift(*pil, rxF[re_offset], 15); #ifdef DEBUG_PDSCH - printf("pilot %3d: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d) \n", pilot_cnt + 1, pil->r, pil->i, rxF[re_offset].r, rxF[re_offset].i, ch_r.r, ch_r.i); + printf("pilot %3d: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d) \n", pilot_cnt + 1, pil->r, pil->i, rxF[re_offset].r, rxF[re_offset].i, ch_r.r, ch_r.i); #endif - c16_t ch = c16addShift(ch_l, ch_r, 1); - for (int k = 3 * pilot_cnt; k < (3 * pilot_cnt) + 6; k++) { - dl_ls_est[k] = ch; + c16_t ch = c16addShift(ch_l, ch_r, 1); + pil++; + re_offset = (re_offset + 5) % frame_parms->ofdm_symbol_size; + for (int k = 0; k < 6; k++) { + dl_ls_est[idx] = ch; + idx++; + } + } + } else { + pil += 4; + re_offset = (re_offset + 12) % frame_parms->ofdm_symbol_size; } - pil++; - re_offset = (re_offset + 5) % frame_parms->ofdm_symbol_size; } c16_t ch_estimates_time[frame_parms->ofdm_symbol_size] __attribute__((aligned(32))); nr_est_delay(frame_parms->ofdm_symbol_size, dl_ls_est, ch_estimates_time, delay); int delay_idx = get_delay_idx(delay->est_delay, MAX_DELAY_COMP); c16_t *dl_delay_table = frame_parms->delay_table[delay_idx]; - - for (int pilot_cnt = 0; pilot_cnt < 6 * nb_rb_pdsch; pilot_cnt++) { - int k = (pilot_cnt / 3) * 6; + // kept the same as before but unclear why would it be nb_rb_pdsch / 2 and not / 3 + for (int pilot_cnt = 0; pilot_cnt < idx >> 1; pilot_cnt++) { + int k = pilot_cnt << 1; c16_t ch = c16mulShift(dl_ls_est[k], dl_delay_table[k], 8); if (pilot_cnt == 0) { // Treat first pilot c16multaddVectRealComplex(filt16_ul_p0, &ch, dl_ch, 16); } else if (pilot_cnt == 1 || pilot_cnt == 2) { c16multaddVectRealComplex(filt16_ul_p1p2, &ch, dl_ch, 16); - } else if (pilot_cnt == 6 * nb_rb_pdsch - 1) { // Treat last pilot + } else if (pilot_cnt == (idx >> 1) - 1) { // Treat last pilot c16multaddVectRealComplex(filt16_ul_last, &ch, dl_ch, 16); } else { // Treat middle pilots c16multaddVectRealComplex(filt16_ul_middle, &ch, dl_ch, 16); @@ -1156,9 +1171,11 @@ void NFAPI_NR_DMRS_TYPE2_linear_interp(NR_DL_FRAME_PARMS *frame_parms, // Revert delay dl_ch = dl_ch0; + int nest_count = 0; + uint64_t noise_amp2 = 0; int inv_delay_idx = get_delay_idx(-delay->est_delay, MAX_DELAY_COMP); c16_t *dl_inv_delay_table = frame_parms->delay_table[inv_delay_idx]; - for (int k = 0; k < 12 * nb_rb_pdsch; k++) { + for (int k = 0; k < idx; k++) { dl_ch[k] = c16mulShift(dl_ch[k], dl_inv_delay_table[k], 8); noise_amp2 += c16amp2(c16sub(dl_ls_est[k], dl_ch[k])); nest_count++; @@ -1253,30 +1270,25 @@ void NFAPI_NR_DMRS_TYPE2_average_prb(NR_DL_FRAME_PARMS *frame_parms, #endif } -int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, - int nl, - unsigned short p, - unsigned char symbol, - unsigned char nscid, - unsigned short scrambling_id, - unsigned short BWPStart, - uint8_t config_type, - int n_dmrs_cdm_groups, - uint16_t rb_offset, - unsigned short bwp_start_subcarrier, - unsigned short nb_rb_pdsch, - uint32_t pdsch_est_size, - int32_t dl_ch_estimates[][pdsch_est_size], - int rxdataFsize, - c16_t rxdataF[][rxdataFsize], - uint32_t *nvar) +void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + const fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch, + const freq_alloc_bitmap_t *freq_alloc, + int nl, + unsigned short p, + unsigned char symbol, + uint32_t pdsch_est_size, + int32_t dl_ch_estimates[][pdsch_est_size], + int rxdataFsize, + c16_t rxdataF[][rxdataFsize], + uint32_t *nvar) { // int gNB_id = proc->gNB_id; int slot = proc->nr_slot_rx; NR_DL_FRAME_PARMS *fp = &ue->frame_parms; const int ch_offset = fp->ofdm_symbol_size * symbol; const int symbol_offset = fp->ofdm_symbol_size * symbol; + int bwp_start_subcarrier = fp->first_carrier_offset + (dlsch->BWPStart + freq_alloc->start[0]) * 12; #ifdef DEBUG_PDSCH printf( @@ -1292,13 +1304,15 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, #endif // generate pilot for gNB port number 1000+p + int config_type = dlsch->dmrsConfigType; + 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 - float beta_dmrs_pdsch = get_beta_dmrs(n_dmrs_cdm_groups, config_type == NFAPI_NR_DMRS_TYPE2); + float beta_dmrs_pdsch = get_beta_dmrs(dlsch->n_dmrs_cdm_groups, config_type == NFAPI_NR_DMRS_TYPE2); int16_t dmrs_scaling = (int16_t)((1 / beta_dmrs_pdsch) * (1 << 14)); - const uint32_t *gold = nr_gold_pdsch(fp->N_RB_DL, fp->symbols_per_slot, scrambling_id, nscid, slot, symbol); + const uint32_t *gold = nr_gold_pdsch(fp->N_RB_DL, fp->symbols_per_slot, dlsch->dlDmrsScramblingId, dlsch->nscid, slot, symbol); nr_pdsch_dmrs_rx(ue, slot, gold, pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type, dmrs_scaling); delay_t delay = {0}; @@ -1315,12 +1329,14 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, memset(dl_ch, 0, sizeof(*dl_ch) * fp->ofdm_symbol_size); if (config_type == NFAPI_NR_DMRS_TYPE1 && ue->chest_freq == 0) { - NFAPI_NR_DMRS_TYPE1_linear_interp(&ue->frame_parms, + NFAPI_NR_DMRS_TYPE1_linear_interp(fp, rxF, &pilot[6 * rb_offset], dl_ch, bwp_start_subcarrier, + freq_alloc->start[0], nb_rb_pdsch, + freq_alloc->bitmap, &delay, nvar); @@ -1330,14 +1346,18 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, &pilot[4 * 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_TYPE1) { + AssertFatal(dlsch->resource_alloc == 1, "PRB average in channel estimation not supported for type0 DLSCH\n"); NFAPI_NR_DMRS_TYPE1_average_prb(fp, rxF, &pilot[6 * rb_offset], dl_ch, bwp_start_subcarrier, nb_rb_pdsch); } else { + AssertFatal(dlsch->resource_alloc == 1, "PRB average in channel estimation not supported for type0 DLSCH\n"); NFAPI_NR_DMRS_TYPE2_average_prb(fp, rxF, &pilot[4 * rb_offset], dl_ch, bwp_start_subcarrier, nb_rb_pdsch); } @@ -1351,7 +1371,6 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, } #endif } - return 0; } /******************************************************************* @@ -1369,7 +1388,6 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, * uint8_t : gNB_id, * uint8_t : nr_slot_rx, * unsigned char : symbol, - * uint32_t : nb_re_pdsch, * uint16_t : rnti * RX_type_t : rx_type * RETURN : Nothing @@ -1392,7 +1410,6 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t nr_slot_rx, unsigned char symbol, - uint32_t nb_re_pdsch, uint16_t rnti, NR_UE_DLSCH_t dlsch[2]) { diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index b1bc3ca8e1..66339e25a2 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -78,24 +78,18 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp, bool sidelink, uint Nid); -int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, - int nl, - unsigned short p, - unsigned char symbol, - unsigned char nscid, - unsigned short scrambling_id, - unsigned short BWPStart, - uint8_t config_type, - int n_dmrs_cdm_groups, - uint16_t rb_offset, - unsigned short bwp_start_subcarrier, - unsigned short nb_rb_pdsch, - uint32_t pdsch_est_size, - int32_t dl_ch_estimates[][pdsch_est_size], - int rxdataFsize, - c16_t rxdataF[][rxdataFsize], - uint32_t *nvar); +void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + const fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch, + const freq_alloc_bitmap_t *freq_alloc, + int nl, + unsigned short p, + unsigned char symbol, + uint32_t pdsch_est_size, + int32_t dl_ch_estimates[][pdsch_est_size], + int rxdataFsize, + c16_t rxdataF[][rxdataFsize], + uint32_t *nvar); int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, PHY_VARS_NR_UE *ue, @@ -108,7 +102,7 @@ int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, void nr_ue_measurements(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, - NR_UE_DLSCH_t *dlsch, + int number_rbs, uint32_t pdsch_est_size, int32_t dl_ch_estimates[][pdsch_est_size]); @@ -143,7 +137,6 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t nr_slot_rx, unsigned char symbol, - uint32_t nb_re_pdsch, uint16_t rnti, NR_UE_DLSCH_t dlsch[2]); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index 73776ebf26..36b8d8a673 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -48,7 +48,7 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, - NR_UE_DLSCH_t *dlsch, + int number_rbs, uint32_t pdsch_est_size, int32_t dl_ch_estimates[][pdsch_est_size]) { @@ -56,8 +56,6 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, int aarx, aatx, gNB_id = 0; NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; int ch_offset = frame_parms->ofdm_symbol_size*2; - int N_RB_DL = dlsch->dlsch_config.number_rbs; - ue->measurements.nb_antennas_rx = frame_parms->nb_antennas_rx; allocCast3D(rx_spatial_power, @@ -85,7 +83,7 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, ue->measurements.rx_power[gNB_id][aarx] = 0; for (aatx = 0; aatx < frame_parms->nb_antenna_ports_gNB; aatx++){ - const int z=signal_energy_nodc((c16_t*)&dl_ch_estimates[gNB_id][ch_offset], N_RB_DL * NR_NB_SC_PER_RB); + const int z = signal_energy_nodc((c16_t*)&dl_ch_estimates[gNB_id][ch_offset], number_rbs * NR_NB_SC_PER_RB); rx_spatial_power[gNB_id][aatx][aarx] = z; if (rx_spatial_power[gNB_id][aatx][aarx] < 0) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index e281e1851d..7eff76e91f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -141,11 +141,11 @@ 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, + NR_DL_FRAME_PARMS *fp, uint16_t dlDmrsSymbPos, uint32_t csi_res_bitmap, int chest_time_type); @@ -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, @@ -314,12 +315,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, 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 matrixSz = ue->frame_parms.nb_antennas_rx * 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][ue->frame_parms.nb_antennas_rx][rx_size_symbol]; + __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]; @@ -328,7 +331,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, __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; - NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; PHY_NR_MEASUREMENTS *measurements = &ue->measurements; const int frame = proc->frame_rx; const int nr_slot_rx = proc->nr_slot_rx; @@ -347,7 +349,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, 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); + 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. @@ -393,13 +402,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); } @@ -408,12 +414,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, return(-1); } - if (!frame_parms) { - LOG_E(PHY, "dlsch_demodulation.c: Null frame_parms\n"); - return(-1); - } - - if(symbol > ue->frame_parms.symbols_per_slot >> 1) + if(symbol > fp->symbols_per_slot >> 1) slot = 1; uint8_t pilots = (dlsch_config->dlDmrsSymbPos >> symbol) & 1; @@ -421,9 +422,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, //---------------------------------------------------------- //--------------------- RBs extraction --------------------- //---------------------------------------------------------- - 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]; @@ -433,7 +433,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, LOG_D(PHY, "%d.%d symbol %d csi overlap bitmap %d\n", frame, nr_slot_rx, symbol, csi_res_bitmap); - nr_dlsch_extract_rbs(ue->frame_parms.samples_per_slot_wCP, + nr_dlsch_extract_rbs(fp->samples_per_slot_wCP, rxdataF, rx_size_symbol, pdsch_est_size, @@ -443,17 +443,17 @@ 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, + 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) * 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 +478,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", @@ -507,7 +508,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, //--------------------- Channel Scaling -------------------- //---------------------------------------------------------- start_meas_nr_ue_phy(ue, DLSCH_CHANNEL_SCALE_STATS); - nr_dlsch_scale_channel(rx_size_symbol, dl_ch_estimates_ext, frame_parms, nl, n_rx, symbol, pilots, nb_re_pdsch, nb_rb_pdsch); + nr_dlsch_scale_channel(rx_size_symbol, dl_ch_estimates_ext, fp, nl, n_rx, symbol, pilots, nb_re_pdsch, nb_rb_pdsch); stop_meas_nr_ue_phy(ue, DLSCH_CHANNEL_SCALE_STATS); if (meas_enabled) { LOG_D(PHY, @@ -578,7 +579,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dl_ch_magr, rxdataF_comp, NULL, - frame_parms, + fp, nl, symbol, nb_re_pdsch, @@ -603,10 +604,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, 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 * frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size, 1, 1); + 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 * frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size, 1, 1); + 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); @@ -682,13 +683,12 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, ptrs_re_per_slot, rx_size_symbol, rxdataF_comp, - frame_parms, + fp, dlsch0_harq, dlsch1_harq, gNB_id, nr_slot_rx, symbol, - (nb_rb_pdsch * 12), dlsch[0].rnti, dlsch); dl_valid_re[symbol] -= ptrs_re_per_slot[0][symbol]; @@ -759,9 +759,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, T_INT(frame % 1024), T_INT(nr_slot_rx), T_INT(nb_rb_pdsch), - T_INT(frame_parms->N_RB_UL), - T_INT(frame_parms->symbols_per_slot), - T_BUFFER(&rxdataF_comp[gNB_id][0], 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL * 12 * 2)); + T_INT(fp->N_RB_UL), + T_INT(fp->symbols_per_slot), + T_BUFFER(&rxdataF_comp[gNB_id][0], 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ fp->N_RB_UL * 12 * 2)); #endif if (ue->phy_sim_pdsch_rxdataF_comp) @@ -778,7 +778,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; } //============================================================================================== @@ -923,7 +923,7 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, void nr_dlsch_scale_channel(uint32_t rx_size_symbol, int32_t dl_ch_estimates_ext[][rx_size_symbol], - NR_DL_FRAME_PARMS *frame_parms, + NR_DL_FRAME_PARMS *fp, uint8_t n_tx, uint8_t n_rx, uint8_t symbol, @@ -932,30 +932,28 @@ void nr_dlsch_scale_channel(uint32_t rx_size_symbol, unsigned short nb_rb) { - - short rb, ch_amp; unsigned char aatx,aarx; simde__m128i *dl_ch128, ch_amp128; - uint32_t nb_rb_0 = len/12 + ((len%12)?1:0); // Determine scaling amplitude based the symbol - - ch_amp = 1024*8; //((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a)); - - LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n",symbol,ch_amp,pilots,nb_rb,frame_parms->Ncp,symbol); + ch_amp = 1024 * 8; //((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a)); + LOG_D(PHY, + "Scaling PDSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n", + symbol, + ch_amp, + pilots, + nb_rb, + fp->Ncp, + symbol); // printf("Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); ch_amp128 = simde_mm_set1_epi16(ch_amp); // Q3.13 - for (aatx=0; aatxfirst_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 = (fp->first_carrier_offset + start_rb * NR_NB_SC_PER_RB) % fp->ofdm_symbol_size; + for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) { + c16_t *rxF_ext = rxdataF_ext[aarx]; + c16_t *rxF = &rxdataF[aarx][symbol * fp->ofdm_symbol_size]; + for (int l = 0; l < Nl; l++) { + int32_t *dl_ch0 = &dl_ch_estimates[(l * fp->nb_antennas_rx) + aarx][validDmrsEst * fp->ofdm_symbol_size]; + int32_t *dl_ch0_ext = dl_ch_estimates_ext[(l * fp->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 <= fp->ofdm_symbol_size) { + memcpy(rxF_ext, &rxF[start_re], nb_rb * NR_NB_SC_PER_RB * sizeof(int32_t)); + } else { + int neg_length = fp->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 >= fp->ofdm_symbol_size) + k -= fp->ofdm_symbol_size; + } + dl_ch0 += 12; + } } } } } } + static void nr_dlsch_detection_mrc(uint32_t rx_size_symbol, short nl, short n_rx, @@ -1185,13 +1181,8 @@ void nr_a_sum_b(c16_t *input_x, c16_t *input_y, unsigned short nb_rb) } /* Zero Forcing Rx function: nr_element_sign() - * Compute b=sign*a - * - * */ -static inline void nr_element_sign(c16_t *a, // a - c16_t *b, // b - unsigned short nb_rb, - int32_t sign) + * Compute b=sign*a */ +static inline void nr_element_sign(c16_t *a, c16_t *b, unsigned short nb_rb, int32_t sign) { const int16_t nr_sign[8] __attribute__((aligned(16))) = {-1, -1, -1, -1, -1, -1, -1, -1}; simde__m128i *a_128,*b_128; 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 0c519451a5..41747a9ef1 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -67,7 +67,6 @@ typedef struct pdsch_scope_req_s { /** \brief This function initialises structures for DLSCH at UE */ void nr_ue_dlsch_init(NR_UE_DLSCH_t *dlsch_list, int num_dlsch, uint8_t max_ldpc_iterations); - void nr_conjch0_mult_ch1(c16_t *ch0, c16_t *ch1, c16_t *ch0conj_ch1, unsigned short nb_rb, unsigned char output_shift0); /** \brief This is the alternative top-level entry point for DLSCH decoding in UE. @@ -316,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 26f41b1fd3..596916f091 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -38,6 +38,15 @@ #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[MAX_FA_BLOCKS]; + int end[MAX_FA_BLOCKS]; + int num_rbs; + int num_blocks; + uint8_t bitmap[36]; +} freq_alloc_bitmap_t; + typedef struct { /// Index of current HARQ round for this ULSCH uint8_t round; diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 52d5033457..a8d628f473 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -287,26 +287,6 @@ static void configure_dlsch(NR_UE_DLSCH_t *dlsch0, NR_UE_MAC_INST_t *mac, int rnti) { - // Temporary code to process type0 as type1 when the RB allocation is contiguous - if (dlsch_config_pdu->resource_alloc == 0) { - dlsch_config_pdu->number_rbs = count_bits(dlsch_config_pdu->rb_bitmap, sizeofArray(dlsch_config_pdu->rb_bitmap)); - int state = 0; - for (int i = 0; i < sizeof(dlsch_config_pdu->rb_bitmap) * 8; i++) { - int allocated = dlsch_config_pdu->rb_bitmap[i / 8] & (1 << (i % 8)); - if (allocated) { - if (state == 0) { - dlsch_config_pdu->start_rb = i; - state = 1; - } else - AssertFatal(state == 1, "non-contiguous RB allocation in RB allocation type 0 not implemented"); - } else { - if (state == 1) { - state = 2; - } - } - } - } - const uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr; dlsch0->active = true; dlsch0->rnti = rnti; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 89b8ed91a7..f22d13c5fc 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -417,28 +417,25 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n stop_meas_nr_ue_phy(ue, PHY_PROC_TX); } -void nr_ue_measurement_procedures(uint16_t l, - PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, - NR_UE_DLSCH_t *dlsch, - uint32_t pdsch_est_size, - int32_t dl_ch_estimates[][pdsch_est_size]) +static void nr_ue_measurement_procedures(uint16_t l, + PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + int number_rbs, + uint32_t pdsch_est_size, + int32_t dl_ch_estimates[][pdsch_est_size]) { NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; int nr_slot_rx = proc->nr_slot_rx; int gNB_id = proc->gNB_id; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_IN); - if (l==2) { - + if (l == 2) { LOG_D(PHY,"Doing UE measurement procedures in symbol l %u Ncp %d nr_slot_rx %d, rxdata %p\n", - l, - ue->frame_parms.Ncp, - nr_slot_rx, - ue->common_vars.rxdata); - - nr_ue_measurements(ue, proc, dlsch, pdsch_est_size, dl_ch_estimates); - + l, + ue->frame_parms.Ncp, + nr_slot_rx, + ue->common_vars.rxdata); + nr_ue_measurements(ue, proc, number_rbs, pdsch_est_size, dl_ch_estimates); #if T_TRACER if(nr_slot_rx == 0) T(T_UE_PHY_MEAS, @@ -577,6 +574,51 @@ int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue, return (dci_ind.number_of_dcis); } +static freq_alloc_bitmap_t set_start_end_from_bitmap(int size, int alloc_size, const uint8_t bitmap[alloc_size]) +{ + freq_alloc_bitmap_t alloc = { + .num_rbs = 0, + .num_blocks = 0 + }; + + bool pos_bit = false; + for (int i = 0; i < size; i++) { + if ((bitmap[i / 8] >> i % 8) & 0x1) { + 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; + } + } + } + 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; +} + +static freq_alloc_bitmap_t set_bitmap_from_start_size(int start, int size) +{ + freq_alloc_bitmap_t alloc = { + .num_rbs = size, + .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++) + alloc.bitmap[i / 8] += 1 << (i % 8); + return alloc; +} + static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, NR_UE_DLSCH_t dlsch[2], @@ -595,8 +637,15 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, // 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); + LOG_D(PHY, - "[UE %d] frame_rx %d, nr_slot_rx %d, harq_pid %d (%d), BWP start %d, rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask " + "[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, @@ -604,8 +653,8 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, harq_pid, dlsch0_harq->status, dlschCfg->BWPStart, - dlschCfg->start_rb, - dlschCfg->number_rbs, + freq_alloc.start[0], + freq_alloc.end[freq_alloc.num_blocks - 1], dlschCfg->start_symbol, dlschCfg->number_symbols, dlschCfg->dlDmrsSymbPos, @@ -621,7 +670,7 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, 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 = (dlsch[0].dlsch_config.number_rbs * NR_NB_SC_PER_RB + 15) & ~15; + 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, @@ -641,17 +690,11 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, uint32_t nvar_tmp = 0; nr_pdsch_channel_estimation(ue, proc, + dlschCfg, + &freq_alloc, nl, get_dmrs_port(nl, dlschCfg->dmrs_ports), m, - dlschCfg->nscid, - dlschCfg->dlDmrsScramblingId, - dlschCfg->BWPStart, - dlschCfg->dmrsConfigType, - dlschCfg->n_dmrs_cdm_groups, - dlschCfg->rb_offset, - ue->frame_parms.first_carrier_offset + (dlschCfg->BWPStart + dlschCfg->start_rb) * 12, - dlschCfg->number_rbs, pdsch_est_size, pdsch_dl_ch_estimates, ue->frame_parms.samples_per_slot_wCP, @@ -671,10 +714,8 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, } } 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, &dlsch[0], pdsch_est_size, pdsch_dl_ch_estimates); + 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, @@ -682,7 +723,7 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, dlschCfg->number_symbols, dlschCfg->start_symbol, dlschCfg->dlDmrsSymbPos, - dlschCfg->number_rbs); + freq_alloc.num_rbs); } uint16_t first_symbol_with_data = dlschCfg->start_symbol; @@ -720,13 +761,13 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, pdschChanEstimates, sizeof(c16_t), 1, - dlschCfg->number_rbs * NR_NB_SC_PER_RB * dlschCfg->number_symbols, + 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, - dlschCfg->number_rbs * NR_NB_SC_PER_RB * dlschCfg->number_symbols, + 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++) { @@ -739,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, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 3d9d5fba43..7f8db35d9f 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -818,10 +818,7 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac, return -1; } - dlsch_pdu->rb_offset = dlsch_pdu->start_rb + dlsch_pdu->BWPStart; - - if (mac->get_sib1) - dlsch_pdu->rb_offset -= dlsch_pdu->BWPStart; + dlsch_pdu->refPoint = mac->get_sib1 ? 1 : 0; /* TIME_DOM_RESOURCE_ASSIGNMENT */ int dmrs_typeA_pos = mac->dmrs_TypeA_Position; @@ -1163,7 +1160,7 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac, LOG_W(MAC, "[%d.%d] Invalid frequency_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot); return -1; } - dlsch_pdu->rb_offset = dlsch_pdu->start_rb + dlsch_pdu->BWPStart; + dlsch_pdu->refPoint = 0; /* TIME_DOM_RESOURCE_ASSIGNMENT */ int dmrs_typeA_pos = mac->dmrs_TypeA_Position; int mux_pattern = 1;