Commit 830d619d authored by Sakthivel Velumani's avatar Sakthivel Velumani

mac: allocate PDSCH on beams in phytest

parent c288f846
......@@ -34,6 +34,15 @@ To this goal, we extended the virtual resource block (VRB) map by one dimension
It is important to note that in current implementation, there are several periodical channels, e.g. PRACH or PUCCH for CSI et cetera, that have the precendence in being assigned a beam, that is because the scheduling is automatic, set in RRC configuration, and not up to the scheduler. For these instances, we assume the beam is available (if not there are assertions to stop the process). For data channels, the currently implemented PF scheduler is used. The only modification is that a UE can be served only if there is a free beam available or the one of the beams already in use correspond to that UE beam.
## Beams in phy-test scheduler
In phy-test mode, beams are assigned to PDSCH slots in the same manner as SSB slots with the only addition that it repeats for every TDD period in a frame. For example if PDSCH is scheduled on all DL slot for TDD format DDDDDDDSUU, and with SSB bit map = `0b1010101` and the following beam parameters in config file,
- `beam_weights` = [10,11,12,13]
- `beam_duration` = 1
- `beams_per_period` = 1
The DL slots in every TDD period will have beams 10,11,12,13,0,0,0
# FAPI implementation
To be noted that in our implementation analog beamforming is only supported in non-split/monolithic mode because we don't support yet SCF P19 interface that would be needed to manage these procedure in a split scenario with SCF FAPI.
......
......@@ -136,10 +136,11 @@ static void schedule_one_ssb(gNB_MAC_INST *gNB,
uint8_t ssbSubcarrierOffset = gNB->ssb_SubcarrierOffset;
uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb);
int beam_index = get_fapi_beamforming_index(gNB, i_ssb);
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, slots_per_frame);
NR_beam_alloc_t beam =
beam_allocation_procedure(&gNB->beam_info, frameP, slotP, get_fapi_beamforming_index(gNB, i_ssb), slots_per_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate SSB %d in any available beam\n", i_ssb);
beam_index = convert_to_fapi_beam(beam_index, gNB->beam_info.beam_mode);
const uint16_t beam_index =
convert_to_fapi_beam(get_allocated_beam(&gNB->beam_info, frameP, slotP, slots_per_frame, beam.idx), gNB->beam_info.beam_mode);
const int prb_offset = (FR == FR2) ? offset_pointa >> (scs - 2) : offset_pointa >> scs;
schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, beam_index, ssbSubcarrierOffset, offset_pointa, mib_pdu);
fill_ssb_vrb_map(cc,
......
......@@ -92,14 +92,48 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
const int bwpSize = dl_bwp->BWPSize;
const int BWPStart = dl_bwp->BWPStart;
// TODO implement beam procedures for phy-test mode
int beam = 0;
/* This is a primitive beam allocation procedure for PDSCH in phytest mode which is
intended to be used to verify the beamformed signal in VSA. The beam allocation of PDSCH
slots follows the SSB slots even in slots that don't have SSB. */
int num_ssb = 0;
BIT_STRING_t *ssbBitmap = NULL;
switch (scc->ssb_PositionsInBurst->present) {
case 1:
num_ssb = 4;
ssbBitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap;
break;
case 2:
num_ssb = 8;
ssbBitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap;
break;
default:
AssertFatal(0, "SSB burst len in burst not supported\n");
}
int ssb_idx_beam = 0;
for (int i_ssb = 0; i_ssb < num_ssb; i_ssb++) {
if (IS_BIT_SET(ssbBitmap->buf[0], (7 - i_ssb))) {
NR_SubcarrierSpacing_t scs = *scc->ssbSubcarrierSpacing;
const long band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb);
// select beam for PDSCH in current slot based on SSB beam
if ((ssb_start_symbol / NR_NUMBER_OF_SYMBOLS_PER_SLOT) == (slot % mac->frame_structure.numb_slots_period)) {
ssb_idx_beam = i_ssb;
break;
}
}
}
int beam_idx = get_fapi_beamforming_index(mac, ssb_idx_beam);
NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info, frame, slot, beam_idx, mac->frame_structure.numb_slots_frame);
AssertFatal(beam.idx > -1, "Can't allocate beam %d in phytest scheduler\n", beam_idx);
UE->UE_beam_index = get_allocated_beam(&mac->beam_info, frame, slot, mac->frame_structure.numb_slots_frame, beam.idx);
int rbStart = 0;
int rbSize = 0;
if (target_dl_bw>bwpSize)
target_dl_bw = bwpSize;
uint16_t *vrb_map = mac->common_channels[CC_id].vrb_map[beam];
uint16_t *vrb_map = mac->common_channels[CC_id].vrb_map[beam.idx];
/* loop ensures that we allocate exactly target_dl_bw, or return */
while (true) {
/* advance to first free RB */
......@@ -132,9 +166,11 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer;
int CCEIndex = get_cce_index(mac,
CC_id, slot, UE->rnti,
CC_id,
slot,
UE->rnti,
&sched_ctrl->aggregation_level,
beam,
beam.idx,
sched_ctrl->search_space,
sched_ctrl->coreset,
&sched_ctrl->sched_pdcch,
......@@ -156,12 +192,7 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
sched_ctrl->cce_index = CCEIndex;
fill_pdcch_vrb_map(mac,
CC_id,
&sched_ctrl->sched_pdcch,
CCEIndex,
sched_ctrl->aggregation_level,
beam);
fill_pdcch_vrb_map(mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, beam.idx);
NR_sched_pdsch_t sched_pdsch = {
.rbSize = rbSize,
......
......@@ -3698,6 +3698,16 @@ uint16_t convert_to_fapi_beam(const uint16_t beam_idx, const nr_beam_mode_t mode
return (mode == LOPHY_BEAM_IDX) ? SET_BIT(beam_idx, 15) : beam_idx;
}
int16_t get_allocated_beam(const NR_beam_info_t *beam_info, int frame, int slot, int slots_per_frame, int beam_number_in_period)
{
int16_t beam_idx = 0;
if (beam_info->beam_mode != NO_BEAM_MODE) {
const int index = get_beam_index(beam_info, frame, slot, slots_per_frame);
beam_idx = beam_info->beam_allocation[beam_number_in_period][index];
}
return beam_idx;
}
void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame, bool new_beam)
{
if(!new_beam) // need to reset only if the beam was allocated specifically for this instance
......
......@@ -449,6 +449,7 @@ int ul_buffer_index(int frame, int slot, int slots_per_frame, int size);
void UL_tti_req_ahead_initialization(gNB_MAC_INST *gNB, int n, int CCid, frame_t frameP, int slotP);
void fapi_beam_index_allocation(NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *config, gNB_MAC_INST *mac);
int get_fapi_beamforming_index(gNB_MAC_INST *mac, int ssb_idx);
int16_t get_allocated_beam(const NR_beam_info_t *beam_info, int frame, int slot, int slots_per_frame, int beam_number_in_period);
uint16_t convert_to_fapi_beam(const uint16_t beam_idx, const nr_beam_mode_t mode);
NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame);
void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame, bool new_beam);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment