|
|
|
@ -89,20 +89,14 @@ alloc_result bwp_slot_allocator::alloc_si(uint32_t aggr_idx, uint32_t si_idx, ui
|
|
|
|
|
alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t ra_rnti,
|
|
|
|
|
uint32_t aggr_idx,
|
|
|
|
|
prb_interval interv,
|
|
|
|
|
srsran::const_span<dl_sched_rar_info_t> pending_rars)
|
|
|
|
|
srsran::const_span<dl_sched_rar_info_t> pending_rachs)
|
|
|
|
|
{
|
|
|
|
|
static const uint32_t msg3_nof_prbs = 3, m = 0;
|
|
|
|
|
|
|
|
|
|
bwp_slot_grid& bwp_pdcch_slot = bwp_grid[pdcch_slot];
|
|
|
|
|
if (not bwp_pdcch_slot.ssb.empty()) {
|
|
|
|
|
// TODO: support concurrent PDSCH and SSB
|
|
|
|
|
logger.info("SCHED: skipping ra-rnti=0x%x RAR allocation. Cause: concurrent PDSCH and SSB not yet supported",
|
|
|
|
|
ra_rnti);
|
|
|
|
|
return alloc_result::no_sch_space;
|
|
|
|
|
}
|
|
|
|
|
slot_point msg3_slot = pdcch_slot + cfg.pusch_ra_list[m].msg3_delay;
|
|
|
|
|
bwp_slot_grid& bwp_msg3_slot = bwp_grid[msg3_slot];
|
|
|
|
|
alloc_result ret = verify_pusch_space(bwp_msg3_slot, nullptr);
|
|
|
|
|
slot_point msg3_slot = pdcch_slot + cfg.pusch_ra_list[m].msg3_delay;
|
|
|
|
|
bwp_slot_grid& bwp_msg3_slot = bwp_grid[msg3_slot];
|
|
|
|
|
alloc_result ret = verify_pusch_space(bwp_msg3_slot, nullptr);
|
|
|
|
|
if (ret != alloc_result::success) {
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
@ -110,17 +104,15 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t
|
|
|
|
|
if (ret != alloc_result::success) {
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
if (bwp_pdcch_slot.rar.full()) {
|
|
|
|
|
return alloc_result::no_grant_space;
|
|
|
|
|
}
|
|
|
|
|
if (pending_rars.size() > MAX_GRANTS) {
|
|
|
|
|
logger.error("SCHED: Trying to allocate too many Msg3 grants in a single slot (%zd)", pending_rars.size());
|
|
|
|
|
if (pending_rachs.size() > bwp_pdcch_slot.rar.capacity() - bwp_pdcch_slot.rar.size()) {
|
|
|
|
|
logger.error("SCHED: Trying to allocate too many Msg3 grants in a single slot (%zd)", pending_rachs.size());
|
|
|
|
|
return alloc_result::invalid_grant_params;
|
|
|
|
|
}
|
|
|
|
|
for (auto& rar : pending_rars) {
|
|
|
|
|
if (not slot_ues.contains(rar.temp_crnti)) {
|
|
|
|
|
for (auto& rach : pending_rachs) {
|
|
|
|
|
auto ue_it = slot_ues.find(rach.temp_crnti);
|
|
|
|
|
if (ue_it == slot_ues.end()) {
|
|
|
|
|
logger.info("SCHED: Postponing rnti=0x%x RAR allocation. Cause: The ue object not yet fully created",
|
|
|
|
|
rar.temp_crnti);
|
|
|
|
|
rach.temp_crnti);
|
|
|
|
|
return alloc_result::no_rnti_opportunity;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -132,7 +124,7 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check Msg3 RB collision
|
|
|
|
|
uint32_t total_ul_nof_prbs = msg3_nof_prbs * pending_rars.size();
|
|
|
|
|
uint32_t total_ul_nof_prbs = msg3_nof_prbs * pending_rachs.size();
|
|
|
|
|
uint32_t total_ul_nof_rbgs = srsran::ceil_div(total_ul_nof_prbs, get_P(bwp_grid.nof_prbs(), false));
|
|
|
|
|
prb_interval msg3_rbs = find_empty_interval_of_length(bwp_msg3_slot.ul_prbs.prbs(), total_ul_nof_rbgs);
|
|
|
|
|
if (msg3_rbs.length() < total_ul_nof_rbgs) {
|
|
|
|
@ -158,7 +150,7 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t
|
|
|
|
|
bwp_pdcch_slot.coresets[coreset_id]->rem_last_dci();
|
|
|
|
|
return alloc_result::invalid_coderate;
|
|
|
|
|
}
|
|
|
|
|
auto& phy_cfg = slot_ues[pending_rars[0].temp_crnti]->phy();
|
|
|
|
|
auto& phy_cfg = slot_ues[pending_rachs[0].temp_crnti]->phy();
|
|
|
|
|
pdcch.dci_cfg = phy_cfg.get_dci_cfg();
|
|
|
|
|
// Generate RAR PDSCH
|
|
|
|
|
// TODO: Properly fill Msg3 grants
|
|
|
|
@ -176,7 +168,7 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t
|
|
|
|
|
slot_cfg.idx = msg3_slot.to_uint();
|
|
|
|
|
bwp_pdcch_slot.rar.emplace_back();
|
|
|
|
|
sched_nr_interface::rar_t& rar_out = bwp_pdcch_slot.rar.back();
|
|
|
|
|
for (const dl_sched_rar_info_t& grant : pending_rars) {
|
|
|
|
|
for (const dl_sched_rar_info_t& grant : pending_rachs) {
|
|
|
|
|
slot_ue& ue = slot_ues[grant.temp_crnti];
|
|
|
|
|
|
|
|
|
|
// Generate RAR grant
|
|
|
|
@ -207,35 +199,20 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t
|
|
|
|
|
// func computes the grant allocation for this UE
|
|
|
|
|
alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_grant)
|
|
|
|
|
{
|
|
|
|
|
if (ue->active_bwp().bwp_id != bwp_grid.cfg->bwp_id) {
|
|
|
|
|
logger.warning(
|
|
|
|
|
"SCHED: Trying to allocate PDSCH for rnti=0x%x in inactive BWP id=%d", ue->rnti, ue->active_bwp().bwp_id);
|
|
|
|
|
return alloc_result::no_rnti_opportunity;
|
|
|
|
|
}
|
|
|
|
|
if (ue.h_dl == nullptr) {
|
|
|
|
|
logger.warning("SCHED: Trying to allocate PDSCH for rnti=0x%x with no available HARQs", ue->rnti);
|
|
|
|
|
return alloc_result::no_rnti_opportunity;
|
|
|
|
|
}
|
|
|
|
|
bwp_slot_grid& bwp_pdcch_slot = bwp_grid[ue.pdcch_slot];
|
|
|
|
|
bwp_slot_grid& bwp_pdsch_slot = bwp_grid[ue.pdsch_slot];
|
|
|
|
|
bwp_slot_grid& bwp_uci_slot = bwp_grid[ue.uci_slot]; // UCI : UL control info
|
|
|
|
|
alloc_result result = verify_pdsch_space(bwp_pdsch_slot, bwp_pdcch_slot);
|
|
|
|
|
alloc_result result = verify_pdsch_space(bwp_pdsch_slot, bwp_pdcch_slot, &bwp_uci_slot);
|
|
|
|
|
if (result != alloc_result::success) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
if (bwp_uci_slot.pending_acks.full()) {
|
|
|
|
|
logger.warning("SCHED: PDSCH allocation for rnti=0x%x failed due to lack of space for respective ACK", ue->rnti);
|
|
|
|
|
return alloc_result::no_grant_space;
|
|
|
|
|
result = verify_ue_cfg(ue.cfg(), ue.h_dl);
|
|
|
|
|
if (result != alloc_result::success) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
if (bwp_pdsch_slot.dl_prbs.collides(dl_grant)) {
|
|
|
|
|
return alloc_result::sch_collision;
|
|
|
|
|
}
|
|
|
|
|
if (not bwp_pdcch_slot.ssb.empty()) {
|
|
|
|
|
// TODO: support concurrent PDSCH and SSB
|
|
|
|
|
logger.info("SCHED: skipping rnti=0x%x PDSCH allocation. Cause: concurrent PDSCH and SSB not yet supported",
|
|
|
|
|
ue->rnti);
|
|
|
|
|
return alloc_result::no_sch_space;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Find space in PUCCH
|
|
|
|
|
// TODO
|
|
|
|
@ -252,7 +229,7 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
uint32_t coreset_id = ue->phy().pdcch.search_space[ss_id].coreset_id;
|
|
|
|
|
if (not bwp_pdcch_slot.coresets[coreset_id]->alloc_dci(pdcch_grant_type_t::dl_data, aggr_idx, ss_id, &ue)) {
|
|
|
|
|
if (not bwp_pdcch_slot.coresets[coreset_id]->alloc_dci(pdcch_grant_type_t::dl_data, aggr_idx, ss_id, &ue.cfg())) {
|
|
|
|
|
// Could not find space in PDCCH
|
|
|
|
|
return alloc_result::no_cch_space;
|
|
|
|
|
}
|
|
|
|
@ -328,10 +305,9 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_pr
|
|
|
|
|
if (ret != alloc_result::success) {
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ue.h_ul == nullptr) {
|
|
|
|
|
logger.warning("SCHED: Trying to allocate PUSCH for rnti=0x%x with no available HARQs", ue->rnti);
|
|
|
|
|
return alloc_result::no_rnti_opportunity;
|
|
|
|
|
ret = verify_ue_cfg(ue.cfg(), ue.h_ul);
|
|
|
|
|
if (ret != alloc_result::success) {
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
pdcch_ul_list_t& pdcchs = bwp_pdcch_slot.ul_pdcchs;
|
|
|
|
|
if (bwp_pusch_slot.ul_prbs.collides(ul_prbs)) {
|
|
|
|
@ -348,14 +324,16 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_pr
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
uint32_t coreset_id = ue->phy().pdcch.search_space[ss_id].coreset_id;
|
|
|
|
|
if (not bwp_pdcch_slot.coresets[coreset_id].value().alloc_dci(pdcch_grant_type_t::ul_data, aggr_idx, ss_id, &ue)) {
|
|
|
|
|
if (not bwp_pdcch_slot.coresets[coreset_id].value().alloc_dci(
|
|
|
|
|
pdcch_grant_type_t::ul_data, aggr_idx, ss_id, &ue.cfg())) {
|
|
|
|
|
// Could not find space in PDCCH
|
|
|
|
|
return alloc_result::no_cch_space;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Allocation Successful
|
|
|
|
|
|
|
|
|
|
if (ue.h_ul->empty()) {
|
|
|
|
|
int mcs = ue->fixed_pusch_mcs();
|
|
|
|
|
int tbs = 100;
|
|
|
|
|
bool success = ue.h_ul->new_tx(ue.pusch_slot, ue.pusch_slot, ul_prbs, mcs, ue->ue_cfg().maxharq_tx);
|
|
|
|
|
srsran_assert(success, "Failed to allocate UL HARQ");
|
|
|
|
|
} else {
|
|
|
|
@ -363,7 +341,6 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_pr
|
|
|
|
|
srsran_assert(success, "Failed to allocate UL HARQ retx");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Allocation Successful
|
|
|
|
|
// Generate PDCCH
|
|
|
|
|
pdcch_ul_t& pdcch = pdcchs.back();
|
|
|
|
|
fill_ul_dci_ue_fields(ue, *bwp_grid.cfg, ss_id, pdcch.dci.ctx.location, pdcch.dci);
|
|
|
|
@ -387,20 +364,33 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_pr
|
|
|
|
|
return alloc_result::success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
alloc_result bwp_slot_allocator::verify_pdsch_space(bwp_slot_grid& bwp_pdsch, bwp_slot_grid& bwp_pdcch) const
|
|
|
|
|
alloc_result bwp_slot_allocator::verify_pdsch_space(bwp_slot_grid& pdsch_grid,
|
|
|
|
|
bwp_slot_grid& pdcch_grid,
|
|
|
|
|
bwp_slot_grid* uci_grid) const
|
|
|
|
|
{
|
|
|
|
|
if (not bwp_pdsch.is_dl() or not bwp_pdcch.is_dl()) {
|
|
|
|
|
logger.warning("SCHED: Trying to allocate PDSCH in TDD non-DL slot index=%d", bwp_pdsch.slot_idx);
|
|
|
|
|
if (not pdsch_grid.is_dl() or not pdcch_grid.is_dl()) {
|
|
|
|
|
logger.warning("SCHED: Trying to allocate PDSCH in TDD non-DL slot index=%d", pdsch_grid.slot_idx);
|
|
|
|
|
return alloc_result::no_sch_space;
|
|
|
|
|
}
|
|
|
|
|
if (bwp_pdcch.dl_pdcchs.full()) {
|
|
|
|
|
if (pdcch_grid.dl_pdcchs.full()) {
|
|
|
|
|
logger.warning("SCHED: Maximum number of DL PDCCH allocations reached");
|
|
|
|
|
return alloc_result::no_cch_space;
|
|
|
|
|
}
|
|
|
|
|
if (bwp_pdsch.pdschs.full()) {
|
|
|
|
|
if (pdsch_grid.pdschs.full()) {
|
|
|
|
|
logger.warning("SCHED: Maximum number of DL PDSCH grants reached");
|
|
|
|
|
return alloc_result::no_sch_space;
|
|
|
|
|
}
|
|
|
|
|
if (uci_grid != nullptr) {
|
|
|
|
|
if (uci_grid->pending_acks.full()) {
|
|
|
|
|
logger.warning("SCHED: No space for ACK.");
|
|
|
|
|
return alloc_result::no_grant_space;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (not pdsch_grid.ssb.empty()) {
|
|
|
|
|
// TODO: support concurrent PDSCH and SSB
|
|
|
|
|
logger.debug("SCHED: skipping PDSCH allocation. Cause: concurrent PDSCH and SSB not yet supported");
|
|
|
|
|
return alloc_result::no_sch_space;
|
|
|
|
|
}
|
|
|
|
|
return alloc_result::success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -428,5 +418,19 @@ alloc_result bwp_slot_allocator::verify_pusch_space(bwp_slot_grid& pusch_grid, b
|
|
|
|
|
return alloc_result::success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
alloc_result bwp_slot_allocator::verify_ue_cfg(const ue_carrier_params_t& ue_cfg, harq_proc* harq) const
|
|
|
|
|
{
|
|
|
|
|
if (ue_cfg.active_bwp().bwp_id != cfg.bwp_id) {
|
|
|
|
|
logger.warning(
|
|
|
|
|
"SCHED: Trying to allocate rnti=0x%x in inactive BWP id=%d", ue_cfg.rnti, ue_cfg.active_bwp().bwp_id);
|
|
|
|
|
return alloc_result::no_rnti_opportunity;
|
|
|
|
|
}
|
|
|
|
|
if (harq == nullptr) {
|
|
|
|
|
logger.warning("SCHED: Trying to allocate rnti=0x%x with no available HARQs", ue_cfg.rnti);
|
|
|
|
|
return alloc_result::no_rnti_opportunity;
|
|
|
|
|
}
|
|
|
|
|
return alloc_result::success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace sched_nr_impl
|
|
|
|
|
} // namespace srsenb
|