diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 80e4643e14..0a4dc1b44b 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -153,6 +153,7 @@ void nr_dlsim_preprocessor(module_id_t module_id, /* CC_id = */ 0, sched_ctrl->aggregation_level, nr_of_candidates, + 0, &sched_ctrl->sched_pdcch, sched_ctrl->coreset, Y); diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 2d69caf9ba..389304dd87 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -625,11 +625,16 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c const int NTN_gNB_Koffset = get_NTN_Koffset(scc); const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; const int size = n << (int)ceil(log2((NTN_gNB_Koffset + 13) / n + 1)); // 13 is upper limit for max_fb_time - nrmac->vrb_map_UL_size = size; - nrmac->common_channels[0].vrb_map_UL = calloc(size * MAX_BWP_SIZE, sizeof(uint16_t)); - AssertFatal(nrmac->common_channels[0].vrb_map_UL, - "could not allocate memory for RC.nrmac[]->common_channels[0].vrb_map_UL\n"); + + int num_beams = 1; + if(nrmac->beam_info.beam_allocation) + num_beams = nrmac->beam_info.beams_per_period; + for (int i = 0; i < num_beams; i++) { + nrmac->common_channels[0].vrb_map_UL[i] = calloc(size * MAX_BWP_SIZE, sizeof(uint16_t)); + AssertFatal(nrmac->common_channels[0].vrb_map_UL[i], + "could not allocate memory for RC.nrmac[]->common_channels[0].vrb_map_UL[%d]\n", i); + } nrmac->UL_tti_req_ahead_size = size; nrmac->UL_tti_req_ahead[0] = calloc(size, sizeof(nfapi_nr_ul_tti_request_t)); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 9d1ad65315..ad18ead1f4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -234,17 +234,20 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_ } for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - //mbsfn_status[CC_id] = 0; - + int num_beams = 1; + if(gNB->beam_info.beam_allocation) + num_beams = gNB->beam_info.beams_per_period; // clear vrb_maps - memset(cc[CC_id].vrb_map, 0, sizeof(uint16_t) * MAX_BWP_SIZE); + for (int i = 0; i < num_beams; i++) + memset(cc[CC_id].vrb_map[i], 0, sizeof(uint16_t) * MAX_BWP_SIZE); // clear last scheduled slot's content (only)! const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; const int size = gNB->vrb_map_UL_size; const int prev_slot = frame * num_slots + slot + size - 1; - uint16_t *vrb_map_UL = cc[CC_id].vrb_map_UL; - memcpy(&vrb_map_UL[prev_slot % size * MAX_BWP_SIZE], &gNB->ulprbbl, sizeof(uint16_t) * MAX_BWP_SIZE); - + for (int i = 0; i < num_beams; i++) { + uint16_t *vrb_map_UL = cc[CC_id].vrb_map_UL[i]; + memcpy(&vrb_map_UL[prev_slot % size * MAX_BWP_SIZE], &gNB->ulprbbl, sizeof(uint16_t) * MAX_BWP_SIZE); + } clear_nr_nfapi_information(gNB, CC_id, frame, slot, &sched_info->DL_req, &sched_info->TX_req, &sched_info->UL_dci_req); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index b89c566794..e55be8974e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -414,11 +414,13 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP } // block resources in vrb_map_UL + // TODO properly allocate beam index for PRACH + int beam_idx = 0; const uint8_t mu_pusch = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; const int16_t n_ra_rb = get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value, mu_pusch); index = ul_buffer_index(frameP, slotP, mu, gNB->vrb_map_UL_size); - uint16_t *vrb_map_UL = &cc->vrb_map_UL[index * MAX_BWP_SIZE]; + uint16_t *vrb_map_UL = &cc->vrb_map_UL[beam_idx][index * MAX_BWP_SIZE]; for (int i = 0; i < n_ra_rb * fdm; ++i) vrb_map_UL[bwp_start + rach_ConfigGeneric->msg1_FrequencyStart + i] |= SL_to_bitmap(start_symbol, N_t_slot * N_dur); } @@ -591,7 +593,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, int mappingtype = pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType; int buffer_index = ul_buffer_index(sched_frame, sched_slot, mu, nr_mac->vrb_map_UL_size); - uint16_t *vrb_map_UL = &nr_mac->common_channels[CC_id].vrb_map_UL[buffer_index * MAX_BWP_SIZE]; + uint16_t *vrb_map_UL = &nr_mac->common_channels[CC_id].vrb_map_UL[beam_ul.idx][buffer_index * MAX_BWP_SIZE]; const int BWPSize = sc_info->initial_ul_BWPSize; const int BWPStart = sc_info->initial_ul_BWPStart; @@ -665,6 +667,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, int CCEIndex = get_cce_index(nr_mac, CC_id, slot, 0, &aggregation_level, + beam_dci.idx, ss, coreset, &ra->sched_pdcch, @@ -715,7 +718,8 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, CC_id, &ra->sched_pdcch, CCEIndex, - aggregation_level); + aggregation_level, + beam_dci.idx); for (int rb = 0; rb < ra->msg3_nb_rb; rb++) { vrb_map_UL[rbStart + BWPStart + rb] |= SL_to_bitmap(StartSymbolIndex, NrOfSymbols); @@ -737,42 +741,38 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, } } -static int get_feasible_msg3_tda(frame_type_t frame_type, - const NR_ServingCellConfigCommon_t *scc, - int mu_delta, - uint64_t ulsch_slot_bitmap[3], - const NR_PUSCH_TimeDomainResourceAllocationList_t *tda_list, - int slots_per_frame, - int frame, - int slot, - NR_RA_t *ra, - NR_beam_info_t *beam_info, - const NR_TDD_UL_DL_Pattern_t *tdd) +static bool get_feasible_msg3_tda(frame_type_t frame_type, + const NR_ServingCellConfigCommon_t *scc, + int mu_delta, + uint64_t ulsch_slot_bitmap[3], + const NR_PUSCH_TimeDomainResourceAllocationList_t *tda_list, + int slots_per_frame, + int frame, + int slot, + NR_RA_t *ra, + NR_beam_info_t *beam_info, + const NR_TDD_UL_DL_Pattern_t *tdd) { DevAssert(tda_list != NULL); - if (frame_type == FDD) { - int tda = 0; // the first occasion is good enough - return tda; - } - const int NTN_gNB_Koffset = get_NTN_Koffset(scc); - // TDD - DevAssert(tdd != NULL); - uint8_t tdd_period_slot = slots_per_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity); + int tdd_period_slot = tdd ? slots_per_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : slots_per_frame; for (int i = 0; i < tda_list->list.count; i++) { // check if it is UL long k2 = *tda_list->list.array[i]->k2 + NTN_gNB_Koffset; int abs_slot = slot + k2 + mu_delta; int temp_frame = (frame + (abs_slot / slots_per_frame)) & 1023; int temp_slot = abs_slot % slots_per_frame; // msg3 slot according to 8.3 in 38.213 - if (!is_xlsch_in_slot(ulsch_slot_bitmap[temp_slot / 64], temp_slot)) + if ((frame_type == TDD) && !is_xlsch_in_slot(ulsch_slot_bitmap[temp_slot / 64], temp_slot)) continue; // check if enough symbols in case of mixed slot - bool has_mixed = tdd->nrofUplinkSymbols != 0 || tdd->nrofDownlinkSymbols != 0; - bool is_mixed = has_mixed && ((temp_slot % tdd_period_slot) == tdd->nrofDownlinkSlots); + bool is_mixed = false; + if (frame_type == TDD) { + bool has_mixed = tdd->nrofUplinkSymbols != 0 || tdd->nrofDownlinkSymbols != 0; + is_mixed = has_mixed && ((temp_slot % tdd_period_slot) == tdd->nrofDownlinkSlots); + } // if the mixed slot has not enough symbols, skip if (is_mixed && tdd->nrofUplinkSymbols < 3) continue; @@ -800,7 +800,7 @@ static int get_feasible_msg3_tda(frame_type_t frame_type, return true; } - return -1; // invalid + return false; } static void nr_get_Msg3alloc(module_id_t module_id, @@ -834,7 +834,7 @@ static void nr_get_Msg3alloc(module_id_t module_id, current_slot, ra->Msg3_tda_id); const int buffer_index = ul_buffer_index(ra->Msg3_frame, ra->Msg3_slot, mu, mac->vrb_map_UL_size); - uint16_t *vrb_map_UL = &mac->common_channels[CC_id].vrb_map_UL[buffer_index * MAX_BWP_SIZE]; + uint16_t *vrb_map_UL = &mac->common_channels[CC_id].vrb_map_UL[ra->Msg3_beam.idx][buffer_index * MAX_BWP_SIZE]; int bwpSize = sc_info->initial_ul_BWPSize; int bwpStart = sc_info->initial_ul_BWPStart; @@ -989,7 +989,7 @@ static void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_f const int scs = ul_bwp->scs; const uint16_t mask = SL_to_bitmap(ra->msg3_startsymb, ra->msg3_nbSymb); int buffer_index = ul_buffer_index(ra->Msg3_frame, ra->Msg3_slot, scs, mac->vrb_map_UL_size); - uint16_t *vrb_map_UL = &RC.nrmac[module_idP]->common_channels[CC_id].vrb_map_UL[buffer_index * MAX_BWP_SIZE]; + uint16_t *vrb_map_UL = &RC.nrmac[module_idP]->common_channels[CC_id].vrb_map_UL[ra->Msg3_beam.idx][buffer_index * MAX_BWP_SIZE]; for (int i = 0; i < ra->msg3_nb_rb; ++i) { AssertFatal(!(vrb_map_UL[i + ra->msg3_first_rb + ra->msg3_bwp_start] & mask), "RB %d in %4d.%2d is already taken, cannot allocate Msg3!\n", @@ -1216,28 +1216,27 @@ static void nr_generate_Msg2(module_id_t module_idP, return; } - const NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP; - const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; - ra->Msg3_tda_id = get_feasible_msg3_tda(cc->frame_type, - scc, - DELTA[ul_bwp->scs], - nr_mac->ulsch_slot_bitmap, - ul_bwp->tdaList_Common, - nr_slots_per_frame[ul_bwp->scs], - frameP, - slotP, - ra, - &nr_mac->beam_info, - tdd); - if (ra->Msg3_tda_id < 0 || ra->Msg3_tda_id > 15) { - LOG_D(NR_MAC, "UE RNTI %04x %d.%d: infeasible Msg3 TDA\n", ra->rnti, frameP, slotP); - return; - } - const int n_slots_frame = nr_slots_per_frame[dl_bwp->scs]; NR_beam_alloc_t beam = beam_allocation_procedure(&nr_mac->beam_info, frameP, slotP, ra->beam_id, n_slots_frame); - if (beam.idx < 0) { - reset_beam_status(&nr_mac->beam_info, ra->Msg3_frame, ra->Msg3_slot, ra->beam_id, n_slots_frame, ra->Msg3_beam.new_beam); + if (beam.idx < 0) + return; + + const NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP; + const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; + bool ret = get_feasible_msg3_tda(cc->frame_type, + scc, + DELTA[ul_bwp->scs], + nr_mac->ulsch_slot_bitmap, + ul_bwp->tdaList_Common, + nr_slots_per_frame[ul_bwp->scs], + frameP, + slotP, + ra, + &nr_mac->beam_info, + tdd); + if (!ret || ra->Msg3_tda_id > 15) { + LOG_D(NR_MAC, "UE RNTI %04x %d.%d: infeasible Msg3 TDA\n", ra->rnti, frameP, slotP); + reset_beam_status(&nr_mac->beam_info, frameP, slotP, ra->beam_id, n_slots_frame, beam.new_beam); return; } @@ -1276,7 +1275,7 @@ static void nr_generate_Msg2(module_id_t module_idP, if (!tda_info.valid_tda) return; - uint16_t *vrb_map = cc[CC_id].vrb_map; + uint16_t *vrb_map = cc[CC_id].vrb_map[beam.idx]; for (int i = 0; (i < rbSize) && (rbStart <= (BWPSize - rbSize)); i++) { if (vrb_map[BWPStart + rbStart + i] & SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)) { rbStart += i; @@ -1285,7 +1284,7 @@ static void nr_generate_Msg2(module_id_t module_idP, } if (rbStart > (BWPSize - rbSize)) { - LOG_W(NR_MAC, "%s(): cannot find free vrb_map for RA RNTI %04x!\n", __func__, ra->RA_rnti); + LOG_W(NR_MAC, "Cannot find free vrb_map for RA RNTI %04x!\n", ra->RA_rnti); reset_beam_status(&nr_mac->beam_info, ra->Msg3_frame, ra->Msg3_slot, ra->beam_id, n_slots_frame, ra->Msg3_beam.new_beam); reset_beam_status(&nr_mac->beam_info, frameP, slotP, ra->beam_id, n_slots_frame, beam.new_beam); return; @@ -1301,7 +1300,7 @@ static void nr_generate_Msg2(module_id_t module_idP, } uint8_t aggregation_level; - int CCEIndex = get_cce_index(nr_mac, CC_id, slotP, 0, &aggregation_level, ss, coreset, &ra->sched_pdcch, true); + int CCEIndex = get_cce_index(nr_mac, CC_id, slotP, 0, &aggregation_level, beam.idx, ss, coreset, &ra->sched_pdcch, true); if (CCEIndex < 0) { LOG_W(NR_MAC, "UE %04x: %d.%d cannot find free CCE for Msg2!\n", ra->rnti, frameP, slotP); @@ -1520,7 +1519,7 @@ static void nr_generate_Msg2(module_id_t module_idP, TX_req->Slot = slotP; // Mark the corresponding symbols RBs as used - fill_pdcch_vrb_map(nr_mac, CC_id, &ra->sched_pdcch, CCEIndex, aggregation_level); + fill_pdcch_vrb_map(nr_mac, CC_id, &ra->sched_pdcch, CCEIndex, aggregation_level, beam.idx); for (int rb = 0; rb < rbSize; rb++) { vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); } @@ -1792,6 +1791,7 @@ static void nr_generate_Msg4(module_id_t module_idP, int CCEIndex = get_cce_index(nr_mac, CC_id, slotP, 0, &aggregation_level, + beam.idx, ss, coreset, &ra->sched_pdcch, @@ -1824,10 +1824,7 @@ static void nr_generate_Msg4(module_id_t module_idP, if (!msg4_tda.valid_tda) return; - NR_pdsch_dmrs_t dmrs_info = get_dl_dmrs_params(scc, - dl_bwp, - &msg4_tda, - 1); + NR_pdsch_dmrs_t dmrs_info = get_dl_dmrs_params(scc, dl_bwp, &msg4_tda, 1); uint8_t mcsTableIdx = dl_bwp->mcsTableIdx; uint8_t mcsIndex = 0; @@ -1861,7 +1858,7 @@ static void nr_generate_Msg4(module_id_t module_idP, AssertFatal(tb_size >= pdu_length,"Cannot allocate Msg4\n"); int i = 0; - uint16_t *vrb_map = cc[CC_id].vrb_map; + uint16_t *vrb_map = cc[CC_id].vrb_map[beam.idx]; while ((i < rbSize) && (rbStart + rbSize <= BWPSize)) { if (vrb_map[BWPStart + rbStart + i]&SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols)) { rbStart += i+1; @@ -1989,7 +1986,8 @@ static void nr_generate_Msg4(module_id_t module_idP, CC_id, &ra->sched_pdcch, CCEIndex, - aggregation_level); + aggregation_level, + beam.idx); for (int rb = 0; rb < rbSize; rb++) { vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 2353745c36..4e3133aff3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -89,13 +89,18 @@ static void schedule_ssb(frame_t frame, LOG_D(MAC,"Scheduling ssb %d at frame %d and slot %d\n",i_ssb,frame,slot); } -static void fill_ssb_vrb_map(NR_COMMON_channels_t *cc, int rbStart, int ssb_subcarrier_offset, uint16_t symStart, int CC_id) +static void fill_ssb_vrb_map(NR_COMMON_channels_t *cc, + int rbStart, + int ssb_subcarrier_offset, + uint16_t symStart, + int CC_id, + int beam) { AssertFatal(*cc->ServingCellConfigCommon->ssbSubcarrierSpacing != NR_SubcarrierSpacing_kHz240, "240kHZ subcarrier won't work with current VRB map because a single SSB might be across 2 slots\n"); - uint16_t *vrb_map = cc[CC_id].vrb_map; + uint16_t *vrb_map = cc[CC_id].vrb_map[beam]; const int extra_prb = ssb_subcarrier_offset > 0; for (int rb = 0; rb < 20 + extra_prb; rb++) vrb_map[rbStart + rb] = SL_to_bitmap(symStart % NR_NUMBER_OF_SYMBOLS_PER_SLOT, 4); @@ -181,7 +186,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, AssertFatal(beam.idx >= 0, "Cannot allocate SSB %d in any available beam\n", i_ssb); const int prb_offset = offset_pointa >> scs; schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, mib_pdu); - fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset, ssb_start_symbol, CC_id); + fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset, ssb_start_symbol, CC_id, beam.idx); if (get_softmodem_params()->sa == 1) { get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb], frameP, @@ -212,7 +217,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, AssertFatal(beam.idx >= 0, "Cannot allocate SSB %d in any available beam\n", i_ssb); const int prb_offset = offset_pointa >> scs; schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, mib_pdu); - fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset, ssb_start_symbol, CC_id); + fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset, ssb_start_symbol, CC_id, beam.idx); if (get_softmodem_params()->sa == 1) { get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb], frameP, @@ -243,7 +248,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, AssertFatal(beam.idx >= 0, "Cannot allocate SSB %d in any available beam\n", i_ssb); const int prb_offset = offset_pointa >> (scs-2); // reference 60kHz schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, mib_pdu); - fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset >> (scs - 2), ssb_start_symbol, CC_id); + fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset >> (scs - 2), ssb_start_symbol, CC_id, beam.idx); if (get_softmodem_params()->sa == 1) { get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb], frameP, @@ -278,12 +283,13 @@ static uint32_t schedule_control_sib1(module_id_t module_id, NR_pdsch_dmrs_t *dmrs_parms, NR_tda_info_t *tda_info, uint8_t candidate_idx, + int beam, uint16_t num_total_bytes) { gNB_MAC_INST *gNB_mac = RC.nrmac[module_id]; NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - uint16_t *vrb_map = cc->vrb_map; + uint16_t *vrb_map = cc->vrb_map[beam]; if (gNB_mac->sched_ctrlCommon == NULL){ LOG_D(NR_MAC,"schedule_control_common: Filling nr_mac->sched_ctrlCommon\n"); @@ -322,6 +328,7 @@ static uint32_t schedule_control_sib1(module_id_t module_id, CC_id, gNB_mac->sched_ctrlCommon->aggregation_level, nr_of_candidates, + beam, &gNB_mac->sched_ctrlCommon->sched_pdcch, gNB_mac->sched_ctrlCommon->coreset, 0); @@ -383,7 +390,8 @@ static uint32_t schedule_control_sib1(module_id_t module_id, CC_id, &gNB_mac->sched_ctrlCommon->sched_pdcch, gNB_mac->sched_ctrlCommon->cce_index, - gNB_mac->sched_ctrlCommon->aggregation_level); + gNB_mac->sched_ctrlCommon->aggregation_level, + beam); for (int rb = 0; rb < pdsch->rbSize; rb++) { vrb_map[rb + rbStart] |= SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); } @@ -601,6 +609,7 @@ void schedule_nr_sib1(module_id_t module_idP, &dmrs_parms, &tda_info, candidate_idx, + beam.idx, cc->sib1_bcch_length); nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index b608c4c5f0..334c263501 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -543,10 +543,14 @@ static bool allocate_dl_retransmission(module_id_t module_id, retInfo->tda_info = temp_tda; } + // TODO properly set the beam index (currently only done for RA) + int beam = 0; + /* Find a free CCE */ int CCEIndex = get_cce_index(nr_mac, CC_id, slot, UE->rnti, &sched_ctrl->aggregation_level, + beam, sched_ctrl->search_space, sched_ctrl->coreset, &sched_ctrl->sched_pdcch, @@ -565,8 +569,7 @@ static bool allocate_dl_retransmission(module_id_t module_id, int alloc = -1; if (!get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, current_harq_pid)) { int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex); - // TODO properly set the beam index (currently only done for RA) - alloc = nr_acknack_scheduling(nr_mac, UE, frame, slot, 0, r_pucch, 0); + alloc = nr_acknack_scheduling(nr_mac, UE, frame, slot, beam, r_pucch, 0); if (alloc < 0) { LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI retransmission\n", UE->rnti, @@ -581,7 +584,8 @@ static bool allocate_dl_retransmission(module_id_t module_id, /* CC_id = */ 0, &sched_ctrl->sched_pdcch, CCEIndex, - sched_ctrl->aggregation_level); + sched_ctrl->aggregation_level, + beam); /* just reuse from previous scheduling opportunity, set new start RB */ sched_ctrl->sched_pdsch = *retInfo; sched_ctrl->sched_pdsch.rbStart = rbStart; @@ -737,9 +741,13 @@ static void pf_dl(module_id_t module_id, NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; sched_pdsch->dl_harq_pid = sched_ctrl->available_dl_harq.head; + // TODO properly set the beam index (currently only done for RA) + int beam = 0; + int CCEIndex = get_cce_index(mac, CC_id, slot, iterator->UE->rnti, &sched_ctrl->aggregation_level, + beam, sched_ctrl->search_space, sched_ctrl->coreset, &sched_ctrl->sched_pdcch, @@ -759,8 +767,7 @@ static void pf_dl(module_id_t module_id, int alloc = -1; if (!get_FeedbackDisabled(iterator->UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, sched_pdsch->dl_harq_pid)) { int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex); - // TODO properly set the beam index (currently only done for RA) - alloc = nr_acknack_scheduling(mac, iterator->UE, frame, slot, 0, r_pucch, 0); + alloc = nr_acknack_scheduling(mac, iterator->UE, frame, slot, beam, r_pucch, 0); if (alloc < 0) { LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI\n", rnti, @@ -776,7 +783,8 @@ static void pf_dl(module_id_t module_id, /* CC_id = */ 0, &sched_ctrl->sched_pdcch, CCEIndex, - sched_ctrl->aggregation_level); + sched_ctrl->aggregation_level, + beam); /* MCS has been set above */ sched_pdsch->time_domain_allocation = get_dl_tda(mac, scc, slot); @@ -876,7 +884,8 @@ static void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_ const uint16_t BWPStart = current_BWP->BWPStart; const uint16_t slbitmap = SL_to_bitmap(startSymbolIndex, nrOfSymbols); - uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map; + // TODO improve handling of beam in vrb_map (for now just using 0) + uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map[0]; uint16_t rballoc_mask[bwpSize]; int n_rb_sched = 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 56c9ff6221..26cffef6ac 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -85,11 +85,14 @@ void nr_preprocessor_phytest(module_id_t module_id, const int bwpSize = dl_bwp->BWPSize; const int BWPStart = dl_bwp->BWPStart; + // TODO implement beam procedures for phy-test mode + int beam = 0; + int rbStart = 0; int rbSize = 0; if (target_dl_bw>bwpSize) target_dl_bw = bwpSize; - uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map; + uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map[beam]; /* loop ensures that we allocate exactly target_dl_bw, or return */ while (true) { /* advance to first free RB */ @@ -133,6 +136,7 @@ void nr_preprocessor_phytest(module_id_t module_id, int CCEIndex = get_cce_index(RC.nrmac[module_id], CC_id, slot, UE->rnti, &sched_ctrl->aggregation_level, + beam, sched_ctrl->search_space, sched_ctrl->coreset, &sched_ctrl->sched_pdcch, @@ -166,7 +170,8 @@ void nr_preprocessor_phytest(module_id_t module_id, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, - sched_ctrl->aggregation_level); + sched_ctrl->aggregation_level, + beam); //AssertFatal(alloc, // "could not find uplink slot for PUCCH (RNTI %04x@%d.%d)!\n", @@ -282,8 +287,12 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ return false; sched_ctrl->sched_pusch.tda_info = tda_info; sched_ctrl->sched_pusch.time_domain_allocation = tda; + + // TODO implement beam procedures for phy-test mode + int beam = 0; + const int buffer_index = ul_buffer_index(sched_frame, sched_slot, mu, nr_mac->vrb_map_UL_size); - uint16_t *vrb_map_UL = &nr_mac->common_channels[CC_id].vrb_map_UL[buffer_index * MAX_BWP_SIZE]; + uint16_t *vrb_map_UL = &nr_mac->common_channels[CC_id].vrb_map_UL[beam][buffer_index * MAX_BWP_SIZE]; for (int i = rbStart; i < rbStart + rbSize; ++i) { if ((vrb_map_UL[i+BWPStart] & SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)) != 0) { LOG_E(MAC, "%4d.%2d RB %d is already reserved, cannot schedule UE\n", frame, slot, i); @@ -297,6 +306,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ int CCEIndex = get_cce_index(nr_mac, CC_id, slot, UE->rnti, &sched_ctrl->aggregation_level, + beam, sched_ctrl->search_space, sched_ctrl->coreset, &sched_ctrl->sched_pdcch, @@ -348,7 +358,8 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ CC_id, &sched_ctrl->sched_pdcch, CCEIndex, - sched_ctrl->aggregation_level); + sched_ctrl->aggregation_level, + beam); for (int rb = rbStart; rb < rbStart + rbSize; rb++) vrb_map_UL[rb+BWPStart] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 3f1519e1da..5bc2a97fd7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -501,11 +501,12 @@ int find_pdcch_candidate(const gNB_MAC_INST *mac, int cc_id, int aggregation, int nr_of_candidates, + int beam_idx, const NR_sched_pdcch_t *pdcch, const NR_ControlResourceSet_t *coreset, uint32_t Y) { - const uint16_t *vrb_map = mac->common_channels[cc_id].vrb_map; + const uint16_t *vrb_map = mac->common_channels[cc_id].vrb_map[beam_idx]; const int N_ci = 0; const int N_rb = pdcch->n_rb; // nb of rbs of coreset per symbol @@ -546,6 +547,7 @@ int get_cce_index(const gNB_MAC_INST *nrmac, const int slot, const rnti_t rnti, uint8_t *aggregation_level, + int beam_idx, const NR_SearchSpace_t *ss, const NR_ControlResourceSet_t *coreset, NR_sched_pdcch_t *sched_pdcch, @@ -567,6 +569,7 @@ int get_cce_index(const gNB_MAC_INST *nrmac, CC_id, *aggregation_level, nr_of_candidates, + beam_idx, sched_pdcch, coreset, Y); @@ -577,9 +580,10 @@ void fill_pdcch_vrb_map(gNB_MAC_INST *mac, int CC_id, NR_sched_pdcch_t *pdcch, int first_cce, - int aggregation){ - - uint16_t *vrb_map = mac->common_channels[CC_id].vrb_map; + int aggregation, + int beam) +{ + uint16_t *vrb_map = mac->common_channels[CC_id].vrb_map[beam]; int N_rb = pdcch->n_rb; // nb of rbs of coreset per symbol int L = pdcch->RegBundleSize; @@ -2725,7 +2729,9 @@ 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); - uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map; + // 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; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c index b4492ffa44..20bf3c0cf2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c @@ -470,7 +470,8 @@ static void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, srs_pdu->beamforming.prg_size = 1; } - uint16_t *vrb_map_UL = &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[buffer_index * MAX_BWP_SIZE]; + // TODO properly use beam allocation + uint16_t *vrb_map_UL = &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[0][buffer_index * MAX_BWP_SIZE]; uint64_t mask = SL_to_bitmap(13 - srs_pdu->time_start_position, srs_pdu->num_symbols); for (int i = 0; i < srs_pdu->bwp_size; ++i) vrb_map_UL[i + srs_pdu->bwp_start] |= mask; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index d61b6f0a49..d7fb5611ac 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -279,8 +279,9 @@ void nr_csi_meas_reporting(int Mod_idP, int bwp_start = ul_bwp->BWPStart; // going through the list of PUCCH resources to find the one indexed by resource_id + int beam_idx = 0; // TODO proper beam allocation const int index = ul_buffer_index(sched_frame, sched_slot, ul_bwp->scs, nrmac->vrb_map_UL_size); - uint16_t *vrb_map_UL = &nrmac->common_channels[0].vrb_map_UL[index * MAX_BWP_SIZE]; + uint16_t *vrb_map_UL = &nrmac->common_channels[0].vrb_map_UL[beam_idx][index * MAX_BWP_SIZE]; const int m = pucch_Config->resourceToAddModList->list.count; for (int j = 0; j < m; j++) { NR_PUCCH_Resource_t *pucchres = pucch_Config->resourceToAddModList->list.array[j]; @@ -1329,24 +1330,27 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac, else { // unoccupied occasion // checking if in ul_slot the resources potentially to be assigned to this PUCCH are available set_pucch_allocation(ul_bwp, r_pucch, bwp_size, curr_pucch); - const int index = ul_buffer_index(pucch_frame, pucch_slot, ul_bwp->scs, mac->vrb_map_UL_size); - uint16_t *vrb_map_UL = &mac->common_channels[CC_id].vrb_map_UL[index * MAX_BWP_SIZE]; - bool ret = test_pucch0_vrb_occupation(curr_pucch, - vrb_map_UL, - bwp_start, - bwp_size); - if(!ret) { - LOG_D(NR_MAC, - "DL %4d.%2d, UL_ACK %4d.%2d PRB resources for this occasion are already occupied, move to the following occasion\n", - frame, slot, pucch_frame, pucch_slot); - continue; - } NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info, pucch_frame, pucch_slot, beam_index, n_slots_frame); if (beam.idx < 0) { LOG_D(NR_MAC, "DL %4d.%2d, UL_ACK %4d.%2d beam resources for this occasion are already occupied, move to the following occasion\n", - frame, slot, pucch_frame, pucch_slot); - // TODO add reset beam status + frame, + slot, + pucch_frame, + pucch_slot); + continue; + } + const int index = ul_buffer_index(pucch_frame, pucch_slot, ul_bwp->scs, mac->vrb_map_UL_size); + uint16_t *vrb_map_UL = &mac->common_channels[CC_id].vrb_map_UL[beam.idx][index * MAX_BWP_SIZE]; + bool ret = test_pucch0_vrb_occupation(curr_pucch, vrb_map_UL, bwp_start, bwp_size); + if(!ret) { + LOG_D(NR_MAC, + "DL %4d.%2d, UL_ACK %4d.%2d PRB resources for this occasion are already occupied, move to the following occasion\n", + frame, + slot, + pucch_frame, + pucch_slot); + reset_beam_status(&mac->beam_info, pucch_frame, pucch_slot, beam_index, n_slots_frame, beam.new_beam); continue; } // allocating a new PUCCH structure for this occasion @@ -1438,8 +1442,9 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot) continue; } else { + int beam_idx = 0; // TODO proper beam allocation const int index = ul_buffer_index(SFN, slot, ul_bwp->scs, nrmac->vrb_map_UL_size); - uint16_t *vrb_map_UL = &nrmac->common_channels[CC_id].vrb_map_UL[index * MAX_BWP_SIZE]; + uint16_t *vrb_map_UL = &nrmac->common_channels[CC_id].vrb_map_UL[beam_idx][index * MAX_BWP_SIZE]; const int bwp_start = ul_bwp->BWPStart; const int bwp_size = ul_bwp->BWPSize; set_pucch_allocation(ul_bwp, -1, bwp_size, curr_pucch); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 144d7ef1b4..d0b36a4603 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1708,6 +1708,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, int CCEIndex = get_cce_index(nrmac, CC_id, slot, UE->rnti, &sched_ctrl->aggregation_level, + 0, // TODO use beam index sched_ctrl->search_space, sched_ctrl->coreset, &sched_ctrl->sched_pdcch, @@ -1725,7 +1726,8 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, - sched_ctrl->aggregation_level); + sched_ctrl->aggregation_level, + 0); // TODO use beam index when implemented /* frame/slot in sched_pusch has been set previously. In the following, we * overwrite the information in the retransmission information before storing @@ -1866,6 +1868,7 @@ static void pf_ul(module_id_t module_id, int CCEIndex = get_cce_index(nrmac, CC_id, slot, UE->rnti, &sched_ctrl->aggregation_level, + 0, // TODO use beam index sched_ctrl->search_space, sched_ctrl->coreset, &sched_ctrl->sched_pdcch, @@ -1912,7 +1915,8 @@ static void pf_ul(module_id_t module_id, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, - sched_ctrl->aggregation_level); + sched_ctrl->aggregation_level, + 0); // TODO use beam index); NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; sched_pusch->mcs = min(nrmac->min_grant_mcs, sched_pusch->mcs); @@ -1983,6 +1987,7 @@ static void pf_ul(module_id_t module_id, int CCEIndex = get_cce_index(nrmac, CC_id, slot, iterator->UE->rnti, &sched_ctrl->aggregation_level, + 0, // TODO use beam index sched_ctrl->search_space, sched_ctrl->coreset, &sched_ctrl->sched_pdcch, @@ -2089,7 +2094,8 @@ static void pf_ul(module_id_t module_id, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, - sched_ctrl->aggregation_level); + sched_ctrl->aggregation_level, + 0); // TODO use beam index); n_rb_sched -= sched_pusch->rbSize; for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++) @@ -2155,7 +2161,8 @@ static bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_ * vrb_map_UL) overlap with the "default" tda and exclude those RBs. * Calculate largest contiguous RBs */ const int index = ul_buffer_index(sched_frame, sched_slot, mu, nr_mac->vrb_map_UL_size); - uint16_t *vrb_map_UL = &nr_mac->common_channels[CC_id].vrb_map_UL[index * MAX_BWP_SIZE]; + // TODO improve handling of beam in vrb_map (for now just using 0) + uint16_t *vrb_map_UL = &nr_mac->common_channels[CC_id].vrb_map_UL[0][index * MAX_BWP_SIZE]; const uint16_t bwpSize = current_BWP->BWPSize; const uint16_t bwpStart = current_BWP->BWPStart; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index f262887e8f..9011e13f75 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -215,6 +215,7 @@ int find_pdcch_candidate(const gNB_MAC_INST *mac, int cc_id, int aggregation, int nr_of_candidates, + int beam_idx, const NR_sched_pdcch_t *pdcch, const NR_ControlResourceSet_t *coreset, uint32_t Y); @@ -223,7 +224,8 @@ void fill_pdcch_vrb_map(gNB_MAC_INST *mac, int CC_id, NR_sched_pdcch_t *pdcch, int first_cce, - int aggregation); + int aggregation, + int beam); void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo, const NR_UE_DL_BWP_t *current_DL_BWP, @@ -397,6 +399,7 @@ int get_cce_index(const gNB_MAC_INST *nrmac, const int slot, const rnti_t rnti, uint8_t *aggregation_level, + int beam_idx, const NR_SearchSpace_t *ss, const NR_ControlResourceSet_t *coreset, NR_sched_pdcch_t *sched_pdcch, diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 3815660ff6..ea696faa71 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -100,6 +100,7 @@ #define MAX_NUM_OF_SSB 64 #define MAX_NUM_NR_PRACH_PREAMBLES 64 #define MIN_NUM_PRBS_TO_SCHEDULE 5 +#define MAX_NUM_BEAM_PERIODS 4 extern const uint8_t nr_rv_round_map[4]; @@ -270,10 +271,10 @@ typedef struct { /// Template for RA computations NR_RA_t ra[NR_NB_RA_PROC_MAX]; /// VRB map for common channels - uint16_t vrb_map[275]; + uint16_t vrb_map[MAX_NUM_BEAM_PERIODS][275]; /// VRB map for common channels and PUSCH, dynamically allocated because /// length depends on number of slots and RBs - uint16_t *vrb_map_UL; + uint16_t *vrb_map_UL[MAX_NUM_BEAM_PERIODS]; ///Number of active SSBs int num_active_ssb; //Total available prach occasions per configuration period