From c0f2d2447156d43fdd64641a8bedcbe9ff2c471f Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 11 Oct 2024 11:07:25 +0200 Subject: [PATCH 1/3] L1 beam allocation from symbol bitmap This is required because CSI-RS may not be allocated in consecutive symbols within a slot --- openair1/PHY/NR_TRANSPORT/nr_dci.c | 4 ++-- openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 4 ++-- openair1/PHY/NR_TRANSPORT/nr_prach.c | 8 ++------ openair1/PHY/NR_TRANSPORT/nr_ulsch.c | 8 ++------ openair1/PHY/NR_TRANSPORT/pucch_rx.c | 8 ++------ openair1/PHY/NR_TRANSPORT/srs_rx.c | 8 ++------ openair1/SCHED_NR/phy_procedures_nr_gNB.c | 21 ++++++++++----------- openair1/SCHED_NR/sched_nr.h | 7 +------ 8 files changed, 23 insertions(+), 45 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index 6cae31d465..54ca8665c3 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -80,12 +80,12 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB, uint32_t cset_nsymb = pdcch_pdu_rel15->DurationSymbols; int dci_idx = 0; // multi-beam number (for concurrent beams) + int bitmap = SL_to_bitmap(cset_start_symb, pdcch_pdu_rel15->DurationSymbols); int beam_nb = beam_index_allocation(dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx, &gNB->common_vars, slot, frame_parms->symbols_per_slot, - cset_start_symb, - pdcch_pdu_rel15->DurationSymbols); + bitmap); LOG_D(NR_PHY_DCI, "pdcch: Coreset rb_offset %d, nb_rb %d BWP Start %d\n", rb_offset, n_rb, pdcch_pdu_rel15->BWPStart); LOG_D(NR_PHY_DCI, diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 321ff3028b..e69e6b2f89 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -471,12 +471,12 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) start_meas(&gNB->dlsch_precoding_stats); nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming; // beam number in multi-beam scenario (concurrent beams) + int bitmap = SL_to_bitmap(rel15->StartSymbolIndex, rel15->NrOfSymbols); int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx, &gNB->common_vars, slot, frame_parms->symbols_per_slot, - rel15->StartSymbolIndex, - rel15->NrOfSymbols); + bitmap); c16_t **txdataF = gNB->common_vars.txdataF[beam_nb]; diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index a043d93500..3f41712f2c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -85,12 +85,8 @@ void nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *p int fapi_beam_idx = prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx; // TODO no idea how to compute final prach symbol here so for now we go til the end of the slot int temp_nb_symbols = NR_NUMBER_OF_SYMBOLS_PER_SLOT - prach_pdu->prach_start_symbol; - prach->beam_nb = beam_index_allocation(fapi_beam_idx, - &gNB->common_vars, - Slot, - NR_NUMBER_OF_SYMBOLS_PER_SLOT, - prach_pdu->prach_start_symbol, - temp_nb_symbols); + int bitmap = SL_to_bitmap(prach_pdu->prach_start_symbol, temp_nb_symbols); + prach->beam_nb = beam_index_allocation(fapi_beam_idx, &gNB->common_vars, Slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, bitmap); } LOG_D(NR_PHY,"Copying prach pdu %d bytes to index %d\n", (int)sizeof(*prach_pdu), prach_id); memcpy(&prach->pdu, prach_pdu, sizeof(*prach_pdu)); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c index 47a0afc625..982b236b70 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c @@ -75,12 +75,8 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pusch_pdu_t ulsch->beam_nb = 0; if (gNB->common_vars.beam_id) { int fapi_beam_idx = ulsch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx; - ulsch->beam_nb = beam_index_allocation(fapi_beam_idx, - &gNB->common_vars, - slot, - NR_NUMBER_OF_SYMBOLS_PER_SLOT, - ulsch_pdu->start_symbol_index, - ulsch_pdu->nr_of_symbols); + int bitmap = SL_to_bitmap(ulsch_pdu->start_symbol_index, ulsch_pdu->nr_of_symbols); + ulsch->beam_nb = beam_index_allocation(fapi_beam_idx, &gNB->common_vars, slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, bitmap); } ulsch->frame = frame; ulsch->slot = slot; diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 084046cc38..72cb374470 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -75,12 +75,8 @@ void nr_fill_pucch(PHY_VARS_gNB *gNB, pucch->beam_nb = 0; if (gNB->common_vars.beam_id) { int fapi_beam_idx = pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx; - pucch->beam_nb = beam_index_allocation(fapi_beam_idx, - &gNB->common_vars, - slot, - NR_NUMBER_OF_SYMBOLS_PER_SLOT, - pucch_pdu->start_symbol_index, - pucch_pdu->nr_of_symbols); + int bitmap = SL_to_bitmap(pucch_pdu->start_symbol_index, pucch_pdu->nr_of_symbols); + pucch->beam_nb = beam_index_allocation(fapi_beam_idx, &gNB->common_vars, slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, bitmap); } memcpy((void *)&pucch->pucch_pdu, (void *)pucch_pdu, sizeof(nfapi_nr_pucch_pdu_t)); LOG_D(PHY, diff --git a/openair1/PHY/NR_TRANSPORT/srs_rx.c b/openair1/PHY/NR_TRANSPORT/srs_rx.c index 931bfe21e7..49ae659a06 100644 --- a/openair1/PHY/NR_TRANSPORT/srs_rx.c +++ b/openair1/PHY/NR_TRANSPORT/srs_rx.c @@ -57,13 +57,9 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu srs->active = true; srs->beam_nb = 0; if (gNB->common_vars.beam_id) { + int bitmap = SL_to_bitmap(srs_pdu->time_start_position, 1 << srs_pdu->num_symbols); int fapi_beam_idx = srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx; - srs->beam_nb = beam_index_allocation(fapi_beam_idx, - &gNB->common_vars, - slot, - NR_NUMBER_OF_SYMBOLS_PER_SLOT, - srs_pdu->time_start_position, - 1 << srs_pdu->num_symbols); + srs->beam_nb = beam_index_allocation(fapi_beam_idx, &gNB->common_vars, slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, bitmap); } memcpy((void *)&srs->srs_pdu, (void *)srs_pdu, sizeof(nfapi_nr_srs_pdu_t)); break; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index a56c01ce99..3d35ab87e5 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -43,19 +43,16 @@ //#define DEBUG_RXDATA //#define SRS_IND_DEBUG -int beam_index_allocation(int fapi_beam_index, - NR_gNB_COMMON *common_vars, - int slot, - int symbols_per_slot, - int start_symbol, - int nb_symbols) +int beam_index_allocation(int fapi_beam_index, NR_gNB_COMMON *common_vars, int slot, int symbols_per_slot, int bitmap_symbols) { if (!common_vars->beam_id) return 0; int idx = -1; for (int j = 0; j < common_vars->num_beams_period; j++) { - for (int i = start_symbol; i < start_symbol + nb_symbols; i++) { + for (int i = 0; i < symbols_per_slot; i++) { + if (((bitmap_symbols >> i) & 0x01) == 0) + continue; int current_beam = common_vars->beam_id[j][slot * symbols_per_slot + i]; if (current_beam == -1 || current_beam == fapi_beam_index) idx = j; @@ -68,8 +65,10 @@ int beam_index_allocation(int fapi_beam_index, break; } AssertFatal(idx >= 0, "Couldn't allocate beam ID %d\n", fapi_beam_index); - for (int j = start_symbol; j < start_symbol + nb_symbols; j++) - common_vars->beam_id[idx][slot * symbols_per_slot + j] = fapi_beam_index; + for (int j = 0; j < symbols_per_slot; j++) { + if (((bitmap_symbols >> j) & 0x01)) + common_vars->beam_id[idx][slot * symbols_per_slot + j] = fapi_beam_index; + } LOG_D(PHY, "Allocating beam %d in slot %d\n", idx, slot); return idx; } @@ -129,12 +128,12 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_n c16_t ***txdataF = gNB->common_vars.txdataF; int txdataF_offset = slot * fp->samples_per_slot_wCP; // beam number in a scenario with multiple concurrent beams + int bitmap = SL_to_bitmap(ssb_start_symbol, 4); // 4 ssb symbols int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx, &gNB->common_vars, slot, fp->symbols_per_slot, - ssb_start_symbol, - 4); // 4 ssb symbols + bitmap); nr_generate_pss(&txdataF[beam_nb][0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp); nr_generate_sss(&txdataF[beam_nb][0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp); diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index 6cde0e8614..20028cea9f 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -47,10 +47,5 @@ void feptx_prec(RU_t *ru,int frame_tx,int tti_tx); int nr_phy_init_RU(RU_t *ru); void nr_phy_free_RU(RU_t *ru); void clear_slot_beamid(PHY_VARS_gNB *gNB, int slot); -int beam_index_allocation(int fapi_beam_index, - NR_gNB_COMMON *common_vars, - int slot, - int symbols_per_slot, - int start_symbol, - int nb_symbols); +int beam_index_allocation(int fapi_beam_index, NR_gNB_COMMON *common_vars, int slot, int symbols_per_slot, int bitmap_symbols); #endif From 0993eb4ed8c9aa48490b71314767d919f4d00004 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 19 Sep 2024 15:04:16 +0200 Subject: [PATCH 2/3] MAC beam allocation for CSI-RS --- .../nfapi/public_inc/nfapi_nr_interface_scf.h | 1 + openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 6 +---- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 22 ++++++++++--------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index dc2f8eef83..2476833d7c 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -979,6 +979,7 @@ typedef struct uint16_t scramb_id; // ScramblingID of the CSI-RS [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->1023 uint8_t power_control_offset; // Ratio of PDSCH EPRE to NZP CSI-RSEPRE [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->23 representing -8 to 15 dB in 1dB steps; 255: L1 is configured with ProfileSSS uint8_t power_control_offset_ss; // Ratio of NZP CSI-RS EPRE to SSB/PBCH block EPRE [3GPP TS 38.214, sec 5.2.2.3.1], Values: 0: -3dB; 1: 0dB; 2: 3dB; 3: 6dB; 255: L1 is configured with ProfileSSS + nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming; } nfapi_nr_dl_tti_csi_rs_pdu_rel15_t; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 0a51c9c803..4e591b6a7a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -778,11 +778,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, if (is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot)) { const int n_slots_frame = nr_slots_per_frame[mu]; - NR_beam_alloc_t beam_ul = beam_allocation_procedure(&nr_mac->beam_info, - sched_frame, - sched_slot, - ra->beam_id, - n_slots_frame); + NR_beam_alloc_t beam_ul = beam_allocation_procedure(&nr_mac->beam_info, sched_frame, sched_slot, ra->beam_id, n_slots_frame); if (beam_ul.idx < 0) return; NR_beam_alloc_t beam_dci = beam_allocation_procedure(&nr_mac->beam_info, frame, slot, ra->beam_id, n_slots_frame); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index dc442bedd0..a45dab00a4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2729,10 +2729,6 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo NR_SCHED_ENSURE_LOCKED(&gNB_mac->sched_lock); - // TODO implement beam procedures - int beam = 0; - uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map[beam]; - UE_info->sched_csirs = 0; UE_iterator(UE_info->list, UE) { @@ -2764,8 +2760,7 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo } } - if (csi_measconfig->nzp_CSI_RS_ResourceToAddModList != NULL && - nzp != NULL) { + if (csi_measconfig->nzp_CSI_RS_ResourceToAddModList != NULL && nzp != NULL) { NR_NZP_CSI_RS_Resource_t *nzpcsi; int period, offset; @@ -2779,12 +2774,14 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo continue; NR_CSI_RS_ResourceMapping_t resourceMapping = nzpcsi->resourceMapping; - csi_period_offset(NULL,nzpcsi->periodicityAndOffset,&period,&offset); + csi_period_offset(NULL, nzpcsi->periodicityAndOffset, &period, &offset); - if((frame*n_slots_frame+slot-offset)%period == 0) { + if((frame * n_slots_frame + slot - offset) % period == 0) { - LOG_D(NR_MAC,"Scheduling CSI-RS in frame %d slot %d Resource ID %ld\n", - frame, slot, nzpcsi->nzp_CSI_RS_ResourceId); + LOG_D(NR_MAC,"Scheduling CSI-RS in frame %d slot %d Resource ID %ld\n", frame, slot, nzpcsi->nzp_CSI_RS_ResourceId); + NR_beam_alloc_t beam_csi = beam_allocation_procedure(&gNB_mac->beam_info, frame, slot, UE->UE_beam_index, n_slots_frame); + AssertFatal(beam_csi.idx >= 0, "Cannot allocate CSI-RS in any available beam\n"); + uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map[beam_csi.idx]; UE_info->sched_csirs |= (1 << dl_bwp->bwp_id); nfapi_nr_dl_tti_request_pdu_t *dl_tti_csirs_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; @@ -2793,6 +2790,11 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo dl_tti_csirs_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_csi_rs_pdu)); nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csirs_pdu_rel15 = &dl_tti_csirs_pdu->csi_rs_pdu.csi_rs_pdu_rel15; + csirs_pdu_rel15->precodingAndBeamforming.num_prgs = 1; + csirs_pdu_rel15->precodingAndBeamforming.prg_size = resourceMapping.freqBand.nrofRBs; //1 PRG of max size + csirs_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces = 1; + csirs_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0; + csirs_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = UE->UE_beam_index; csirs_pdu_rel15->bwp_size = dl_bwp->BWPSize; csirs_pdu_rel15->bwp_start = dl_bwp->BWPStart; csirs_pdu_rel15->subcarrier_spacing = dl_bwp->scs; From f3bee8ed25d4651c729e86a8ced2f36b497c9cb0 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 11 Oct 2024 15:37:54 +0200 Subject: [PATCH 3/3] L1 beam allocation for CSI-RS --- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 3d35ab87e5..73eda60dcd 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -252,7 +252,6 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, for (int i = 0; i < NR_SYMBOLS_PER_SLOT; i++){ NR_gNB_CSIRS_t *csirs = &msgTx->csirs_pdu[i]; if (csirs->active == 1) { - AssertFatal(gNB->common_vars.beam_id == NULL, "Cannot handle CSI in the framework of beamforming yet\n"); LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot); nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csirs->csirs_pdu.csi_rs_pdu_rel15; if (csi_params->csi_type == 2) { // ZP-CSI @@ -263,8 +262,19 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, csi_params->freq_domain, csi_params->symb_l0, csi_params->symb_l1); + nfapi_nr_tx_precoding_and_beamforming_t *pb = &csi_params->precodingAndBeamforming; + int csi_bitmap = 0; + int lprime_num = mapping_parms.lprime + 1; + for (int j = 0; j < mapping_parms.size; j++) + csi_bitmap |= ((1 << lprime_num) - 1) << mapping_parms.loverline[j]; + int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx, + &gNB->common_vars, + slot, + fp->symbols_per_slot, + csi_bitmap); + nr_generate_csi_rs(&gNB->frame_parms, - (int32_t **)gNB->common_vars.txdataF[0], + (int32_t **)gNB->common_vars.txdataF[beam_nb], gNB->TX_AMP, csi_params, slot,