mirror of https://github.com/PentHertz/srsLTE.git
nr,gnb,sched: implemented standalone PDSCH allocator class
This commit is contained in:
parent
20b327c320
commit
8ba08032b5
|
@ -33,6 +33,7 @@ using pusch_t = mac_interface_phy_nr::pusch_t;
|
|||
using pucch_t = mac_interface_phy_nr::pucch_t;
|
||||
using pdcch_dl_list_t = srsran::bounded_vector<pdcch_dl_t, MAX_GRANTS>;
|
||||
using pdcch_ul_list_t = srsran::bounded_vector<pdcch_ul_t, MAX_GRANTS>;
|
||||
using pdsch_list_t = srsran::bounded_vector<pdsch_t, MAX_GRANTS>;
|
||||
using pucch_list_t = srsran::bounded_vector<pucch_t, MAX_GRANTS>;
|
||||
using pusch_list_t = srsran::bounded_vector<pusch_t, MAX_GRANTS>;
|
||||
using nzp_csi_rs_list = srsran::bounded_vector<srsran_csi_rs_nzp_resource_t, mac_interface_phy_nr::MAX_NZP_CSI_RS>;
|
||||
|
@ -93,12 +94,12 @@ struct bwp_params_t {
|
|||
|
||||
bwp_params_t(const cell_cfg_t& cell, const sched_args_t& sched_cfg_, uint32_t cc, uint32_t bwp_id);
|
||||
|
||||
const prb_bitmap& used_prbs(uint32_t ss_id, srsran_dci_format_nr_t dci_fmt) const
|
||||
uint32_t coreset_bw(uint32_t cs_id) const { return coresets[cs_id].bw; }
|
||||
|
||||
const bwp_rb_bitmap& coreset_prb_limits(uint32_t ss_id, srsran_dci_format_nr_t dci_fmt) const
|
||||
{
|
||||
if (used_common_prb_masks.contains(ss_id)) {
|
||||
if (dci_fmt == srsran_dci_format_nr_1_0) {
|
||||
return used_common_prb_masks[ss_id];
|
||||
}
|
||||
if (used_common_prb_masks.contains(ss_id) and dci_fmt == srsran_dci_format_nr_1_0) {
|
||||
return used_common_prb_masks[ss_id];
|
||||
}
|
||||
return cached_empty_prb_mask;
|
||||
}
|
||||
|
@ -109,8 +110,12 @@ struct bwp_params_t {
|
|||
}
|
||||
|
||||
private:
|
||||
prb_bitmap cached_empty_prb_mask;
|
||||
srsran::optional_vector<prb_bitmap> used_common_prb_masks;
|
||||
bwp_rb_bitmap cached_empty_prb_mask;
|
||||
srsran::optional_vector<bwp_rb_bitmap> used_common_prb_masks;
|
||||
struct coreset_cached_params {
|
||||
uint32_t bw = 0;
|
||||
};
|
||||
srsran::optional_vector<coreset_cached_params> coresets;
|
||||
};
|
||||
|
||||
/// Structure packing a single cell config params, and sched args
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "sched_nr_helpers.h"
|
||||
#include "sched_nr_interface.h"
|
||||
#include "sched_nr_pdcch.h"
|
||||
#include "sched_nr_pdsch.h"
|
||||
#include "sched_nr_ue.h"
|
||||
#include "srsenb/hdr/stack/mac/sched_common.h"
|
||||
|
||||
|
@ -44,24 +45,20 @@ struct bwp_slot_grid {
|
|||
uint32_t slot_idx = 0;
|
||||
const bwp_params_t* cfg = nullptr;
|
||||
|
||||
bwp_rb_bitmap dl_prbs;
|
||||
bwp_rb_bitmap ul_prbs;
|
||||
dl_sched_res_t dl;
|
||||
ul_sched_t ul;
|
||||
harq_ack_list_t pending_acks;
|
||||
bwp_pdcch_allocator pdcchs; /// slot PDCCH resource allocator
|
||||
pdsch_allocator pdschs; /// slot PDSCH resource allocator
|
||||
|
||||
srsran::unique_pool_ptr<tx_harq_softbuffer> rar_softbuffer;
|
||||
|
||||
explicit bwp_slot_grid(const bwp_params_t& bwp_params, uint32_t slot_idx_);
|
||||
void reset();
|
||||
|
||||
bool is_dl() const { return cfg->slots[slot_idx].is_dl; }
|
||||
bool is_ul() const { return cfg->slots[slot_idx].is_ul; }
|
||||
prb_bitmap used_prbs(uint32_t ss_id, srsran_dci_format_nr_t dci_fmt) const
|
||||
{
|
||||
return dl_prbs.prbs() | cfg->used_prbs(ss_id, dci_fmt);
|
||||
}
|
||||
bool is_dl() const { return cfg->slots[slot_idx].is_dl; }
|
||||
bool is_ul() const { return cfg->slots[slot_idx].is_ul; }
|
||||
};
|
||||
|
||||
struct bwp_res_grid {
|
||||
|
|
|
@ -38,7 +38,7 @@ inline bool is_rnti_type_valid_in_search_space(srsran_rnti_type_t rnti_type, srs
|
|||
case srsran_search_space_type_common_2:
|
||||
return rnti_type == srsran_rnti_type_p;
|
||||
case srsran_search_space_type_common_3:
|
||||
return rnti_type == srsran_rnti_type_c or rnti_type == srsran_rnti_type_ra; // TODO: Fix
|
||||
return rnti_type == srsran_rnti_type_c; // TODO: Fix
|
||||
case srsran_search_space_type_ue:
|
||||
return rnti_type == srsran_rnti_type_c or rnti_type == srsran_rnti_type_cs or
|
||||
rnti_type == srsran_rnti_type_sp_csi;
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2021 Software Radio Systems Limited
|
||||
*
|
||||
* By using this file, you agree to the terms and conditions set
|
||||
* forth in the LICENSE file which can be found at the top level of
|
||||
* the distribution.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SRSRAN_SCHED_NR_PDSCH_H
|
||||
#define SRSRAN_SCHED_NR_PDSCH_H
|
||||
|
||||
#include "srsenb/hdr/stack/mac/sched_common.h"
|
||||
#include "srsgnb/hdr/stack/mac/sched_nr_cfg.h"
|
||||
|
||||
namespace srsenb {
|
||||
|
||||
namespace sched_nr_impl {
|
||||
|
||||
class pdsch_allocator
|
||||
{
|
||||
public:
|
||||
pdsch_allocator(const bwp_params_t& cfg_, uint32_t sl_index, pdsch_list_t& pdsch_lst);
|
||||
|
||||
/// Get available RBGs for allocation
|
||||
rbg_bitmap available_rbgs(uint32_t ss_id, srsran_dci_format_nr_t dci_fmt) const
|
||||
{
|
||||
return (dl_prbs | bwp_cfg.coreset_prb_limits(ss_id, dci_fmt)).rbgs();
|
||||
}
|
||||
/// Get available PRBs for allocation
|
||||
prb_bitmap available_prbs(uint32_t ss_id, srsran_dci_format_nr_t dci_fmt) const
|
||||
{
|
||||
return (dl_prbs | bwp_cfg.coreset_prb_limits(ss_id, dci_fmt)).prbs();
|
||||
}
|
||||
|
||||
/// Checks if provided PDSCH arguments produce a valid PDSCH that fits into cell PRBs and does not collide with other
|
||||
/// allocations
|
||||
alloc_result is_grant_valid(uint32_t ss_id,
|
||||
srsran_dci_format_nr_t dci_fmt,
|
||||
const prb_grant& grant,
|
||||
ue_carrier_params_t* ue = nullptr) const;
|
||||
|
||||
/**
|
||||
* @brief Tries to allocate PDSCH grant. Ensures that there are no collisions with other previous PDSCH allocations
|
||||
* @param dci_ctx[in] PDCCH DL DCI context information
|
||||
* @param ss_id[in] SearchSpaceId used for allocation
|
||||
* @param grant[in] PRBs used for the grant
|
||||
* @param pdcch[out] PDCCH where frequency_assignment and time_assignment get stored.
|
||||
* @return pdsch_t object pointer in case of success. alloc_result error code in case of failure
|
||||
*/
|
||||
srsran::expected<pdsch_t*, alloc_result>
|
||||
alloc_pdsch(const srsran_dci_ctx_t& dci_ctx, uint32_t ss_id, const prb_grant& grant, pdcch_dl_t& pdcch);
|
||||
|
||||
/**
|
||||
* @brief Allocates PDSCH grant without verifying for collisions. Useful to avoid redundant is_grant_valid(...) calls
|
||||
* @param dci_ctx[in] PDCCH DL DCI context information
|
||||
* @param grant[in] PRBs used for the grant
|
||||
* @param pdcch[out] PDCCH where frequency and time assignment get stored.
|
||||
*/
|
||||
pdsch_t& alloc_pdsch_unchecked(const srsran_dci_ctx_t& dci_ctx, const prb_grant& grant, pdcch_dl_t& pdcch);
|
||||
|
||||
void cancel_last_pdsch();
|
||||
|
||||
void reset();
|
||||
|
||||
private:
|
||||
const bwp_params_t& bwp_cfg;
|
||||
uint32_t slot_idx = 0;
|
||||
|
||||
pdsch_list_t& pdschs;
|
||||
bwp_rb_bitmap dl_prbs;
|
||||
};
|
||||
|
||||
} // namespace sched_nr_impl
|
||||
|
||||
} // namespace srsenb
|
||||
|
||||
#endif // SRSRAN_SCHED_NR_PDSCH_H
|
|
@ -198,6 +198,23 @@ public:
|
|||
|
||||
uint32_t prb_to_rbg_idx(uint32_t prb_idx) const;
|
||||
|
||||
bwp_rb_bitmap& operator|=(const bwp_rb_bitmap& other)
|
||||
{
|
||||
prbs_ |= other.prbs_;
|
||||
rbgs_ |= other.rbgs_;
|
||||
return *this;
|
||||
}
|
||||
bwp_rb_bitmap& operator|=(const rbg_bitmap& other)
|
||||
{
|
||||
add(other);
|
||||
return *this;
|
||||
}
|
||||
bwp_rb_bitmap& operator|=(const prb_bitmap& other)
|
||||
{
|
||||
add(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
prb_bitmap prbs_;
|
||||
rbg_bitmap rbgs_;
|
||||
|
@ -210,6 +227,12 @@ private:
|
|||
void add_rbgs_to_prbs(const rbg_bitmap& grant);
|
||||
};
|
||||
|
||||
template <typename Other>
|
||||
bwp_rb_bitmap operator|(const bwp_rb_bitmap& lhs, const Other& rhs)
|
||||
{
|
||||
return bwp_rb_bitmap(lhs) |= rhs;
|
||||
}
|
||||
|
||||
inline prb_interval
|
||||
find_next_empty_interval(const prb_bitmap& mask, size_t start_prb_idx = 0, size_t last_prb_idx = SRSRAN_MAX_PRB_NR)
|
||||
{
|
||||
|
|
|
@ -14,6 +14,7 @@ set(SOURCES mac_nr.cc
|
|||
sched_nr_grant_allocator.cc
|
||||
sched_nr_harq.cc
|
||||
sched_nr_pdcch.cc
|
||||
sched_nr_pdsch.cc
|
||||
sched_nr_cfg.cc
|
||||
sched_nr_helpers.cc
|
||||
sched_nr_bwp.cc
|
||||
|
|
|
@ -25,8 +25,8 @@ alloc_result
|
|||
ra_sched::allocate_pending_rar(bwp_slot_allocator& slot_grid, const pending_rar_t& rar, uint32_t& nof_grants_alloc)
|
||||
{
|
||||
const uint32_t rar_aggr_level = 2;
|
||||
prb_bitmap prbs = slot_grid.res_grid()[slot_grid.get_pdcch_tti()].used_prbs(bwp_cfg->cfg.pdcch.ra_search_space.id,
|
||||
srsran_dci_format_nr_1_0);
|
||||
prb_bitmap prbs = slot_grid.res_grid()[slot_grid.get_pdcch_tti()].pdschs.available_prbs(
|
||||
bwp_cfg->cfg.pdcch.ra_search_space.id, srsran_dci_format_nr_1_0);
|
||||
|
||||
alloc_result ret = alloc_result::other_cause;
|
||||
srsran::const_span<dl_sched_rar_info_t> msg3_grants{rar.msg3_grant};
|
||||
|
|
|
@ -44,14 +44,22 @@ bwp_params_t::bwp_params_t(const cell_cfg_t& cell, const sched_args_t& sched_cfg
|
|||
cc(cc_),
|
||||
bwp_id(bwp_id_),
|
||||
cfg(cell.bwps[bwp_id_]),
|
||||
logger(srslog::fetch_basic_logger(sched_cfg_.logger_name))
|
||||
logger(srslog::fetch_basic_logger(sched_cfg_.logger_name)),
|
||||
cached_empty_prb_mask(cell.bwps[bwp_id_].rb_width,
|
||||
cell.bwps[bwp_id_].start_rb,
|
||||
cell.bwps[bwp_id_].pdsch.rbg_size_cfg_1)
|
||||
{
|
||||
srsran_assert(cfg.pdcch.ra_search_space_present, "BWPs without RA search space not supported");
|
||||
const uint32_t ra_coreset_id = cfg.pdcch.ra_search_space.coreset_id;
|
||||
|
||||
P = get_P(cfg.rb_width, cfg.pdsch.rbg_size_cfg_1);
|
||||
N_rbg = get_nof_rbgs(cfg.rb_width, cfg.start_rb, cfg.pdsch.rbg_size_cfg_1);
|
||||
cached_empty_prb_mask.resize(cfg.rb_width);
|
||||
|
||||
for (const srsran_coreset_t& cs : view_active_coresets(cfg.pdcch)) {
|
||||
coresets.emplace(cs.id);
|
||||
auto& cached_coreset = coresets[cs.id];
|
||||
cached_coreset.bw = srsran_coreset_get_bw(&cs);
|
||||
}
|
||||
|
||||
// Derive params of individual slots
|
||||
uint32_t nof_slots = SRSRAN_NSLOTS_PER_FRAME_NR(cfg.numerology_idx);
|
||||
|
@ -112,10 +120,10 @@ bwp_params_t::bwp_params_t(const cell_cfg_t& cell, const sched_args_t& sched_cfg
|
|||
if (SRSRAN_SEARCH_SPACE_IS_COMMON(ss.type)) {
|
||||
used_common_prb_masks.emplace(ss_id, cached_empty_prb_mask);
|
||||
uint32_t coreset_start = srsran_coreset_start_rb(&cfg.pdcch.coreset[ss.coreset_id]);
|
||||
used_common_prb_masks[ss_id].fill(0, coreset_start, true);
|
||||
used_common_prb_masks[ss_id] |= prb_interval(0, coreset_start);
|
||||
if (ss.coreset_id == 0) {
|
||||
uint32_t coreset0_bw = srsran_coreset_get_bw(&cfg.pdcch.coreset[0]);
|
||||
used_common_prb_masks[ss_id].fill(coreset_start + coreset0_bw, cfg.rb_width, true);
|
||||
used_common_prb_masks[ss_id] |= prb_interval(coreset_start + coreset0_bw, cfg.rb_width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,24 +76,21 @@ candidate_ss_list_t find_ss(const srsran_pdcch_cfg_nr_t& pdcch,
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bwp_slot_grid::bwp_slot_grid(const bwp_params_t& bwp_cfg_, uint32_t slot_idx_) :
|
||||
dl_prbs(bwp_cfg_.cfg.rb_width, bwp_cfg_.cfg.start_rb, bwp_cfg_.cfg.pdsch.rbg_size_cfg_1),
|
||||
ul_prbs(bwp_cfg_.cfg.rb_width, bwp_cfg_.cfg.start_rb, bwp_cfg_.cfg.pdsch.rbg_size_cfg_1),
|
||||
slot_idx(slot_idx_),
|
||||
cfg(&bwp_cfg_),
|
||||
pdcchs(bwp_cfg_, slot_idx_, dl.phy.pdcch_dl, dl.phy.pdcch_ul),
|
||||
pdschs(bwp_cfg_, slot_idx_, dl.phy.pdsch),
|
||||
rar_softbuffer(harq_softbuffer_pool::get_instance().get_tx(bwp_cfg_.cfg.rb_width))
|
||||
{}
|
||||
|
||||
void bwp_slot_grid::reset()
|
||||
{
|
||||
pdcchs.reset();
|
||||
dl_prbs.reset();
|
||||
pdschs.reset();
|
||||
ul_prbs.reset();
|
||||
dl.phy.ssb.clear();
|
||||
dl.phy.nzp_csi_rs.clear();
|
||||
dl.phy.pdcch_dl.clear();
|
||||
dl.phy.pdcch_ul.clear();
|
||||
dl.phy.pdsch.clear();
|
||||
dl.data.clear();
|
||||
dl.rar.clear();
|
||||
dl.sib_idxs.clear();
|
||||
|
@ -121,25 +118,33 @@ alloc_result bwp_slot_allocator::alloc_si(uint32_t aggr_idx,
|
|||
const prb_interval& prbs,
|
||||
tx_harq_softbuffer& softbuffer)
|
||||
{
|
||||
static const uint32_t ss_id = 0;
|
||||
static const srsran_dci_format_nr_t dci_fmt = srsran_dci_format_nr_1_0;
|
||||
|
||||
bwp_slot_grid& bwp_pdcch_slot = bwp_grid[pdcch_slot];
|
||||
alloc_result ret = verify_pdsch_space(bwp_pdcch_slot, bwp_pdcch_slot);
|
||||
if (ret != alloc_result::success) {
|
||||
return ret;
|
||||
}
|
||||
if (bwp_pdcch_slot.dl_prbs.collides(prbs)) {
|
||||
return alloc_result::sch_collision;
|
||||
|
||||
// Verify there is space in PDSCH
|
||||
ret = bwp_pdcch_slot.pdschs.is_grant_valid(ss_id, dci_fmt, prbs);
|
||||
if (ret != alloc_result::success) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
const uint32_t ss_id = 0;
|
||||
auto pdcch_result = bwp_pdcch_slot.pdcchs.alloc_si_pdcch(ss_id, aggr_idx);
|
||||
auto pdcch_result = bwp_pdcch_slot.pdcchs.alloc_si_pdcch(ss_id, aggr_idx);
|
||||
if (pdcch_result.is_error()) {
|
||||
logger.warning("SCHED: Cannot allocate SIB1 due to lack of PDCCH space.");
|
||||
return pdcch_result.error();
|
||||
}
|
||||
pdcch_dl_t* pdcch = pdcch_result.value();
|
||||
|
||||
// RAR allocation successful.
|
||||
bwp_pdcch_slot.dl_prbs |= prbs;
|
||||
// SI allocation successful.
|
||||
|
||||
// Allocate PDSCH
|
||||
pdsch_t& pdsch = bwp_pdcch_slot.pdschs.alloc_pdsch_unchecked(pdcch->dci.ctx, prbs, *pdcch);
|
||||
|
||||
// Generate DCI for SIB
|
||||
pdcch->dci_cfg.coreset0_bw = srsran_coreset_get_bw(&cfg.cfg.pdcch.coreset[0]);
|
||||
if (not fill_dci_sib(prbs, si_idx, si_ntx, *bwp_grid.cfg, pdcch->dci)) {
|
||||
|
@ -149,8 +154,6 @@ alloc_result bwp_slot_allocator::alloc_si(uint32_t aggr_idx,
|
|||
}
|
||||
|
||||
// Generate PDSCH
|
||||
bwp_pdcch_slot.dl.phy.pdsch.emplace_back();
|
||||
pdsch_t& pdsch = bwp_pdcch_slot.dl.phy.pdsch.back();
|
||||
srsran_slot_cfg_t slot_cfg;
|
||||
slot_cfg.idx = pdcch_slot.to_uint();
|
||||
int code = srsran_ra_dl_dci_to_grant_nr(
|
||||
|
@ -174,12 +177,21 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t
|
|||
prb_interval interv,
|
||||
srsran::const_span<dl_sched_rar_info_t> pending_rachs)
|
||||
{
|
||||
static const uint32_t msg3_nof_prbs = 3, m = 0;
|
||||
static const uint32_t msg3_nof_prbs = 3, m = 0;
|
||||
static const srsran_dci_format_nr_t dci_fmt = srsran_dci_format_nr_1_0;
|
||||
|
||||
bwp_slot_grid& bwp_pdcch_slot = bwp_grid[pdcch_slot];
|
||||
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);
|
||||
|
||||
// Verify there is space in PDSCH
|
||||
alloc_result ret = bwp_pdcch_slot.pdschs.is_grant_valid(cfg.cfg.pdcch.ra_search_space.id, dci_fmt, interv);
|
||||
if (ret != alloc_result::success) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Verify there is space in PUSCH
|
||||
ret = verify_pusch_space(bwp_msg3_slot);
|
||||
if (ret != alloc_result::success) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -205,12 +217,6 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t
|
|||
}
|
||||
}
|
||||
|
||||
// Check DL RB collision
|
||||
if (bwp_pdcch_slot.dl_prbs.collides(interv)) {
|
||||
logger.debug("SCHED: Provided RBG mask collides with allocation previously made.");
|
||||
return alloc_result::sch_collision;
|
||||
}
|
||||
|
||||
// Check Msg3 RB collision
|
||||
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));
|
||||
|
@ -224,25 +230,25 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t
|
|||
auto pdcch_result = bwp_pdcch_slot.pdcchs.alloc_rar_pdcch(ra_rnti, aggr_idx);
|
||||
if (pdcch_result.is_error()) {
|
||||
// Could not find space in PDCCH
|
||||
logger.debug("SCHED: No space in PDCCH for DL tx.");
|
||||
return pdcch_result.error();
|
||||
}
|
||||
pdcch_dl_t* pdcch = pdcch_result.value();
|
||||
|
||||
// RAR allocation successful.
|
||||
bwp_pdcch_slot.dl_prbs |= interv;
|
||||
pdcch_dl_t* pdcch = pdcch_result.value();
|
||||
auto& phy_cfg = slot_ues[pending_rachs[0].temp_crnti]->phy();
|
||||
pdcch->dci_cfg = phy_cfg.get_dci_cfg();
|
||||
|
||||
// Allocate PDSCH
|
||||
pdsch_t& pdsch = bwp_pdcch_slot.pdschs.alloc_pdsch_unchecked(pdcch->dci.ctx, interv, *pdcch);
|
||||
|
||||
// Generate DCI for RAR with given RA-RNTI
|
||||
if (not fill_dci_rar(interv, ra_rnti, *bwp_grid.cfg, pdcch->dci)) {
|
||||
// Cancel on-going PDCCH allocation
|
||||
bwp_pdcch_slot.pdcchs.cancel_last_pdcch();
|
||||
return alloc_result::invalid_coderate;
|
||||
}
|
||||
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
|
||||
bwp_pdcch_slot.dl.phy.pdsch.emplace_back();
|
||||
pdsch_t& pdsch = bwp_pdcch_slot.dl.phy.pdsch.back();
|
||||
srsran_slot_cfg_t slot_cfg;
|
||||
slot_cfg.idx = pdcch_slot.to_uint();
|
||||
bool success = phy_cfg.get_pdsch_cfg(slot_cfg, pdcch->dci, pdsch.sch);
|
||||
|
@ -287,30 +293,12 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t
|
|||
alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, prb_grant dl_grant)
|
||||
{
|
||||
static const uint32_t aggr_idx = 2;
|
||||
static const std::array<srsran_dci_format_nr_t, 2> dci_fmt_list{srsran_dci_format_nr_1_1, srsran_dci_format_nr_1_0};
|
||||
static const srsran_dci_format_nr_t dci_fmt = srsran_dci_format_nr_1_0;
|
||||
static const std::array<srsran_dci_format_nr_t, 1> dci_fmt_list{srsran_dci_format_nr_1_0};
|
||||
|
||||
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, &bwp_uci_slot);
|
||||
if (result != alloc_result::success) {
|
||||
return result;
|
||||
}
|
||||
result = verify_ue_cfg(ue.cfg(), ue.h_dl);
|
||||
if (result != alloc_result::success) {
|
||||
return result;
|
||||
}
|
||||
if (not bwp_pdsch_slot.dl.phy.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;
|
||||
}
|
||||
if (bwp_pdsch_slot.dl_prbs.collides(dl_grant)) {
|
||||
return alloc_result::sch_collision;
|
||||
}
|
||||
|
||||
// Find space in PUCCH
|
||||
// TODO
|
||||
|
||||
// Choose SearchSpace + DCI format
|
||||
srsran_rnti_type_t rnti_type = srsran_rnti_type_c;
|
||||
|
@ -323,55 +311,75 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, prb_grant dl_grant)
|
|||
}
|
||||
const srsran_search_space_t& ss = *ss_candidates[0];
|
||||
|
||||
// Verify there is space in PDSCH
|
||||
alloc_result ret = bwp_pdcch_slot.pdschs.is_grant_valid(ss.id, dci_fmt, dl_grant);
|
||||
if (ret != alloc_result::success) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
alloc_result result = verify_pdsch_space(bwp_pdsch_slot, bwp_pdcch_slot, &bwp_uci_slot);
|
||||
if (result != alloc_result::success) {
|
||||
return result;
|
||||
}
|
||||
result = verify_ue_cfg(ue.cfg(), ue.h_dl);
|
||||
if (result != alloc_result::success) {
|
||||
return result;
|
||||
}
|
||||
if (not bwp_pdsch_slot.dl.phy.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;
|
||||
}
|
||||
|
||||
// Find space in PUCCH
|
||||
// TODO
|
||||
|
||||
// Find space and allocate PDCCH
|
||||
auto pdcch_result = bwp_pdcch_slot.pdcchs.alloc_dl_pdcch(rnti_type, ss.id, aggr_idx, ue.cfg());
|
||||
if (pdcch_result.is_error()) {
|
||||
// Could not find space in PDCCH
|
||||
return pdcch_result.error();
|
||||
}
|
||||
pdcch_dl_t* pdcch = pdcch_result.value();
|
||||
|
||||
// Update PRB grant based on the start and end of CORESET RBs
|
||||
reduce_to_dl_coreset_bw(cfg, ss.id, srsran_dci_format_nr_1_0, dl_grant);
|
||||
// DL allocation successful.
|
||||
pdcch_dl_t& pdcch = *pdcch_result.value();
|
||||
|
||||
// Allocate PDSCH
|
||||
pdsch_t& pdsch = bwp_pdcch_slot.pdschs.alloc_pdsch_unchecked(pdcch.dci.ctx, dl_grant, pdcch);
|
||||
|
||||
// Allocate HARQ
|
||||
int mcs = ue->fixed_pdsch_mcs();
|
||||
if (ue.h_dl->empty()) {
|
||||
bool ret = ue.h_dl->new_tx(ue.pdsch_slot, ue.uci_slot, dl_grant, mcs, 4);
|
||||
srsran_assert(ret, "Failed to allocate DL HARQ");
|
||||
bool success = ue.h_dl->new_tx(ue.pdsch_slot, ue.uci_slot, dl_grant, mcs, 4);
|
||||
srsran_assert(success, "Failed to allocate DL HARQ");
|
||||
} else {
|
||||
bool ret = ue.h_dl->new_retx(ue.pdsch_slot, ue.uci_slot, dl_grant);
|
||||
mcs = ue.h_dl->mcs();
|
||||
srsran_assert(ret, "Failed to allocate DL HARQ retx");
|
||||
bool success = ue.h_dl->new_retx(ue.pdsch_slot, ue.uci_slot, dl_grant);
|
||||
mcs = ue.h_dl->mcs();
|
||||
srsran_assert(success, "Failed to allocate DL HARQ retx");
|
||||
}
|
||||
|
||||
// Allocation Successful
|
||||
|
||||
const static float max_R = 0.93;
|
||||
while (true) {
|
||||
// Generate PDCCH
|
||||
fill_dl_dci_ue_fields(ue, *bwp_grid.cfg, ss.id, pdcch->dci.ctx.location, pdcch->dci);
|
||||
pdcch->dci.pucch_resource = 0;
|
||||
pdcch->dci.dai = std::count_if(bwp_uci_slot.pending_acks.begin(),
|
||||
bwp_uci_slot.pending_acks.end(),
|
||||
[&ue](const harq_ack_t& p) { return p.res.rnti == ue->rnti; });
|
||||
pdcch->dci.dai %= 4;
|
||||
pdcch->dci_cfg = ue->phy().get_dci_cfg();
|
||||
fill_dl_dci_ue_fields(ue, *bwp_grid.cfg, ss.id, pdcch.dci.ctx.location, pdcch.dci);
|
||||
pdcch.dci.pucch_resource = 0;
|
||||
pdcch.dci.dai = std::count_if(bwp_uci_slot.pending_acks.begin(),
|
||||
bwp_uci_slot.pending_acks.end(),
|
||||
[&ue](const harq_ack_t& p) { return p.res.rnti == ue->rnti; });
|
||||
pdcch.dci.dai %= 4;
|
||||
pdcch.dci_cfg = ue->phy().get_dci_cfg();
|
||||
|
||||
// Generate PUCCH
|
||||
bwp_uci_slot.pending_acks.emplace_back();
|
||||
bwp_uci_slot.pending_acks.back().phy_cfg = &ue->phy();
|
||||
srsran_assert(ue->phy().get_pdsch_ack_resource(pdcch->dci, bwp_uci_slot.pending_acks.back().res),
|
||||
srsran_assert(ue->phy().get_pdsch_ack_resource(pdcch.dci, bwp_uci_slot.pending_acks.back().res),
|
||||
"Error getting ack resource");
|
||||
|
||||
// Generate PDSCH
|
||||
bwp_pdsch_slot.dl_prbs |= dl_grant;
|
||||
bwp_pdsch_slot.dl.phy.pdsch.emplace_back();
|
||||
pdsch_t& pdsch = bwp_pdsch_slot.dl.phy.pdsch.back();
|
||||
srsran_slot_cfg_t slot_cfg;
|
||||
slot_cfg.idx = ue.pdsch_slot.to_uint();
|
||||
bool ret = ue->phy().get_pdsch_cfg(slot_cfg, pdcch->dci, pdsch.sch);
|
||||
srsran_assert(ret, "Error converting DCI to grant");
|
||||
bool success = ue->phy().get_pdsch_cfg(slot_cfg, pdcch.dci, pdsch.sch);
|
||||
srsran_assert(success, "Error converting DCI to grant");
|
||||
|
||||
pdsch.sch.grant.tb[0].softbuffer.tx = ue.h_dl->get_softbuffer().get();
|
||||
pdsch.data[0] = ue.h_dl->get_tx_pdu()->get();
|
||||
|
@ -386,7 +394,6 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, prb_grant dl_grant)
|
|||
// Decrease MCS if first tx and rate is too high
|
||||
mcs--;
|
||||
ue.h_dl->set_mcs(mcs);
|
||||
bwp_pdsch_slot.dl.phy.pdsch.pop_back();
|
||||
bwp_uci_slot.pending_acks.pop_back();
|
||||
}
|
||||
if (mcs == 0) {
|
||||
|
|
|
@ -70,26 +70,6 @@ void fill_dci_harq(const slot_ue& ue, DciDlOrUl& dci)
|
|||
dci.rv = rv_idx[h->nof_retx() % 4];
|
||||
}
|
||||
|
||||
void fill_dci_grant(const bwp_params_t& bwp_cfg, const prb_grant& grant, srsran_dci_dl_nr_t& dci)
|
||||
{
|
||||
dci.time_domain_assigment = 0;
|
||||
if (grant.is_alloc_type0()) {
|
||||
srsran_assert(not SRSRAN_SEARCH_SPACE_IS_COMMON(dci.ctx.ss_type), "AllocType0 for common search space");
|
||||
dci.freq_domain_assigment = grant.rbgs().to_uint64();
|
||||
} else {
|
||||
uint32_t rb_start = 0, nof_prb = bwp_cfg.nof_prb();
|
||||
if (dci.ctx.format == srsran_dci_format_nr_1_0 && SRSRAN_SEARCH_SPACE_IS_COMMON(dci.ctx.ss_type)) {
|
||||
rb_start = dci.ctx.coreset_start_rb;
|
||||
}
|
||||
if (dci.ctx.coreset_id == 0 and SRSRAN_SEARCH_SPACE_IS_COMMON(dci.ctx.ss_type)) {
|
||||
nof_prb = dci.coreset0_bw;
|
||||
}
|
||||
srsran_assert(grant.prbs().start() >= rb_start, "Invalid PRB index=%d < %d", grant.prbs().start(), rb_start);
|
||||
uint32_t grant_start = grant.prbs().start() - rb_start;
|
||||
dci.freq_domain_assigment = srsran_ra_nr_type1_riv(nof_prb, grant_start, grant.prbs().length());
|
||||
}
|
||||
}
|
||||
|
||||
void fill_dci_grant(const bwp_params_t& bwp_cfg, const prb_grant& grant, srsran_dci_ul_nr_t& dci)
|
||||
{
|
||||
dci.time_domain_assigment = 0;
|
||||
|
@ -101,25 +81,9 @@ void fill_dci_grant(const bwp_params_t& bwp_cfg, const prb_grant& grant, srsran_
|
|||
}
|
||||
}
|
||||
|
||||
void fill_rar_dci_context(const bwp_params_t& bwp_cfg, uint16_t ra_rnti, srsran_dci_ctx_t& dci_ctx)
|
||||
{
|
||||
uint32_t cs_id = bwp_cfg.cfg.pdcch.ra_search_space.coreset_id;
|
||||
|
||||
dci_ctx.format = srsran_dci_format_nr_1_0;
|
||||
dci_ctx.ss_type = srsran_search_space_type_common_1;
|
||||
dci_ctx.rnti_type = srsran_rnti_type_ra;
|
||||
dci_ctx.rnti = ra_rnti;
|
||||
dci_ctx.coreset_id = cs_id;
|
||||
dci_ctx.coreset_start_rb = srsran_coreset_start_rb(&bwp_cfg.cfg.pdcch.coreset[cs_id]);
|
||||
}
|
||||
|
||||
bool fill_dci_rar(prb_interval interv, uint16_t ra_rnti, const bwp_params_t& bwp_cfg, srsran_dci_dl_nr_t& dci)
|
||||
{
|
||||
fill_rar_dci_context(bwp_cfg, ra_rnti, dci.ctx);
|
||||
|
||||
dci.mcs = 5;
|
||||
fill_dci_common(bwp_cfg, dci);
|
||||
fill_dci_grant(bwp_cfg, interv, dci);
|
||||
// TODO: Fill
|
||||
|
||||
return true;
|
||||
|
@ -152,14 +116,7 @@ void fill_dl_dci_ue_fields(const slot_ue& ue,
|
|||
srsran_dci_location_t dci_pos,
|
||||
srsran_dci_dl_nr_t& dci)
|
||||
{
|
||||
// Note: DCI location may not be the final one, as scheduler may rellocate the UE PDCCH. However, the remaining DCI
|
||||
// params are independent of the exact DCI location
|
||||
bool ret = ue->phy().get_dci_ctx_pdsch_rnti_c(ss_id, dci_pos, ue->rnti, dci.ctx);
|
||||
srsran_assert(ret, "Invalid DL DCI format");
|
||||
|
||||
fill_dci_common(bwp_cfg, dci);
|
||||
fill_dci_harq(ue, dci);
|
||||
fill_dci_grant(bwp_cfg, ue.h_dl->prbs(), dci);
|
||||
if (dci.ctx.format == srsran_dci_format_nr_1_0) {
|
||||
dci.harq_feedback = (ue.uci_slot - ue.pdsch_slot) - 1;
|
||||
} else {
|
||||
|
|
|
@ -40,6 +40,23 @@ void log_pdcch_alloc_failure(srslog::log_channel& log_ch,
|
|||
log_ch("%s", srsran::to_c_str(fmtbuf));
|
||||
}
|
||||
|
||||
void fill_dci_from_cfg(const bwp_params_t& bwp_cfg, srsran_dci_dl_nr_t& dci)
|
||||
{
|
||||
dci.bwp_id = bwp_cfg.bwp_id;
|
||||
dci.cc_id = bwp_cfg.cc;
|
||||
dci.tpc = 1;
|
||||
dci.coreset0_bw = bwp_cfg.cfg.pdcch.coreset_present[0] ? bwp_cfg.coreset_bw(0) : 0;
|
||||
}
|
||||
|
||||
void fill_dci_from_cfg(const bwp_params_t& bwp_cfg, srsran_dci_ul_nr_t& dci)
|
||||
{
|
||||
dci.bwp_id = bwp_cfg.bwp_id;
|
||||
dci.cc_id = bwp_cfg.cc;
|
||||
dci.tpc = 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
coreset_region::coreset_region(const bwp_params_t& bwp_cfg_, uint32_t coreset_id_, uint32_t slot_idx_) :
|
||||
coreset_cfg(&bwp_cfg_.cfg.pdcch.coreset[coreset_id_]),
|
||||
coreset_id(coreset_id_),
|
||||
|
@ -226,6 +243,7 @@ void bwp_pdcch_allocator::fill_dci_ctx_common(srsran_dci_ctx_t& dci,
|
|||
srsran_dci_format_nr_t dci_fmt,
|
||||
const ue_carrier_params_t* ue)
|
||||
{
|
||||
// Note: Location is filled by coreset_region class.
|
||||
dci.ss_type = ss.type;
|
||||
dci.coreset_id = ss.coreset_id;
|
||||
const srsran_coreset_t* coreset =
|
||||
|
@ -271,7 +289,10 @@ pdcch_dl_alloc_result bwp_pdcch_allocator::alloc_dl_pdcch_common(srsran_rnti_typ
|
|||
if (r != alloc_result::success) {
|
||||
return {r};
|
||||
}
|
||||
const srsran_search_space_t& ss = (user == nullptr) ? *bwp_cfg.get_ss(ss_id) : *user->get_ss(ss_id);
|
||||
const srsran_search_space_t& ss =
|
||||
(user == nullptr)
|
||||
? (rnti_type == srsran_rnti_type_ra ? bwp_cfg.cfg.pdcch.ra_search_space : *bwp_cfg.get_ss(ss_id))
|
||||
: *user->get_ss(ss_id);
|
||||
|
||||
// Add new DL PDCCH to sched result
|
||||
pdcch_dl_list.emplace_back();
|
||||
|
@ -290,13 +311,19 @@ pdcch_dl_alloc_result bwp_pdcch_allocator::alloc_dl_pdcch_common(srsran_rnti_typ
|
|||
return {alloc_result::no_cch_space};
|
||||
}
|
||||
|
||||
// PDCCH allocation was successful
|
||||
pdcch_dl_t& pdcch = pdcch_dl_list.back();
|
||||
|
||||
// Fill DCI with semi-static config
|
||||
fill_dci_from_cfg(bwp_cfg, pdcch.dci);
|
||||
|
||||
// Fill DCI context information
|
||||
fill_dci_ctx_common(pdcch_dl_list.back().dci.ctx, rnti_type, rnti, ss, dci_fmt, user);
|
||||
fill_dci_ctx_common(pdcch.dci.ctx, rnti_type, rnti, ss, dci_fmt, user);
|
||||
|
||||
// register last PDCCH coreset, in case it needs to be aborted
|
||||
pending_dci = &pdcch_dl_list.back().dci.ctx;
|
||||
pending_dci = &pdcch.dci.ctx;
|
||||
|
||||
return {&pdcch_dl_list.back()};
|
||||
return {&pdcch};
|
||||
}
|
||||
|
||||
pdcch_ul_alloc_result
|
||||
|
@ -325,13 +352,19 @@ bwp_pdcch_allocator::alloc_ul_pdcch(uint32_t ss_id, uint32_t aggr_idx, const ue_
|
|||
return {alloc_result::no_cch_space};
|
||||
}
|
||||
|
||||
// PDCCH allocation was successful
|
||||
pdcch_ul_t& pdcch = pdcch_ul_list.back();
|
||||
|
||||
// Fill DCI with semi-static config
|
||||
fill_dci_from_cfg(bwp_cfg, pdcch.dci);
|
||||
|
||||
// Fill DCI context information
|
||||
fill_dci_ctx_common(pdcch_ul_list.back().dci.ctx, srsran_rnti_type_c, user.rnti, ss, dci_fmt, &user);
|
||||
fill_dci_ctx_common(pdcch.dci.ctx, srsran_rnti_type_c, user.rnti, ss, dci_fmt, &user);
|
||||
|
||||
// register last PDCCH coreset, in case it needs to be aborted
|
||||
pending_dci = &pdcch_ul_list.back().dci.ctx;
|
||||
pending_dci = &pdcch.dci.ctx;
|
||||
|
||||
return {&pdcch_ul_list.back()};
|
||||
return {&pdcch};
|
||||
}
|
||||
|
||||
void bwp_pdcch_allocator::cancel_last_pdcch()
|
||||
|
@ -394,7 +427,10 @@ alloc_result bwp_pdcch_allocator::check_args_valid(srsran_rnti_type_t rn
|
|||
}
|
||||
|
||||
// Verify SearchSpace validity
|
||||
const srsran_search_space_t* ss = (user == nullptr) ? bwp_cfg.get_ss(ss_id) : user->get_ss(ss_id);
|
||||
const srsran_search_space_t* ss =
|
||||
(user == nullptr)
|
||||
? (rnti_type == srsran_rnti_type_ra ? &bwp_cfg.cfg.pdcch.ra_search_space : bwp_cfg.get_ss(ss_id))
|
||||
: user->get_ss(ss_id);
|
||||
if (ss == nullptr) {
|
||||
// Couldn't find SearchSpace
|
||||
log_pdcch_alloc_failure(logger.error, rnti_type, ss_id, rnti, "SearchSpace has not been configured");
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2021 Software Radio Systems Limited
|
||||
*
|
||||
* By using this file, you agree to the terms and conditions set
|
||||
* forth in the LICENSE file which can be found at the top level of
|
||||
* the distribution.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "srsgnb/hdr/stack/mac/sched_nr_pdsch.h"
|
||||
#include "srsran/common/string_helpers.h"
|
||||
|
||||
namespace srsenb {
|
||||
namespace sched_nr_impl {
|
||||
|
||||
template <typename... Args>
|
||||
void log_alloc_failure(srslog::log_channel& log_ch, uint32_t ss_id, const char* cause_fmt, Args&&... args)
|
||||
{
|
||||
if (not log_ch.enabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Log allocation failure
|
||||
fmt::memory_buffer fmtbuf;
|
||||
fmt::format_to(fmtbuf, "SCHED: Failure to allocate PDSCH in SS#{}. Cause: ", ss_id);
|
||||
fmt::format_to(fmtbuf, cause_fmt, std::forward<Args>(args)...);
|
||||
log_ch("%s", srsran::to_c_str(fmtbuf));
|
||||
}
|
||||
|
||||
pdsch_allocator::pdsch_allocator(const bwp_params_t& cfg_, uint32_t slot_index, pdsch_list_t& pdsch_lst) :
|
||||
bwp_cfg(cfg_),
|
||||
slot_idx(slot_index),
|
||||
pdschs(pdsch_lst),
|
||||
dl_prbs(bwp_cfg.cfg.rb_width, bwp_cfg.cfg.start_rb, bwp_cfg.cfg.pdsch.rbg_size_cfg_1)
|
||||
{}
|
||||
|
||||
void pdsch_allocator::reset()
|
||||
{
|
||||
pdschs.clear();
|
||||
dl_prbs.reset();
|
||||
}
|
||||
|
||||
alloc_result pdsch_allocator::is_grant_valid(uint32_t ss_id,
|
||||
srsran_dci_format_nr_t dci_fmt,
|
||||
const prb_grant& grant,
|
||||
ue_carrier_params_t* ue) const
|
||||
{
|
||||
// DL must be active in given slot
|
||||
if (not bwp_cfg.slots[slot_idx].is_dl) {
|
||||
log_alloc_failure(bwp_cfg.logger.error, ss_id, "DL is disabled for slot={}", slot_idx);
|
||||
return alloc_result::no_sch_space;
|
||||
}
|
||||
|
||||
// No space in Scheduler PDSCH output list
|
||||
if (pdschs.full()) {
|
||||
log_alloc_failure(bwp_cfg.logger.warning, ss_id, "SearchSpace has not been configured.");
|
||||
return alloc_result::no_sch_space;
|
||||
}
|
||||
|
||||
// Verify SearchSpace validity
|
||||
const srsran_search_space_t* ss = (ue == nullptr) ? bwp_cfg.get_ss(ss_id) : ue->get_ss(ss_id);
|
||||
if (ss == nullptr) {
|
||||
// Couldn't find SearchSpace
|
||||
log_alloc_failure(bwp_cfg.logger.error, ss_id, "SearchSpace has not been configured.");
|
||||
return alloc_result::invalid_grant_params;
|
||||
}
|
||||
|
||||
if (SRSRAN_SEARCH_SPACE_IS_COMMON(ss_id)) {
|
||||
// In case of common SearchSpaces, the PRBs must be contiguous
|
||||
if (grant.is_alloc_type0()) {
|
||||
log_alloc_failure(bwp_cfg.logger.warning, ss_id, "AllocType0 not allowed in common SearchSpace.");
|
||||
return alloc_result::invalid_grant_params;
|
||||
}
|
||||
|
||||
// Grant PRBs do not collide with CORESET PRB limits (in case of common SearchSpace)
|
||||
if (bwp_cfg.coreset_prb_limits(ss_id, dci_fmt).collides(grant)) {
|
||||
bwp_cfg.logger.debug("SCHED: Provided RBG mask falls outside common CORESET PRB boundaries.");
|
||||
return alloc_result::sch_collision;
|
||||
}
|
||||
}
|
||||
|
||||
// Grant PRBs do not collide with previous PDSCH allocations
|
||||
if (dl_prbs.collides(grant)) {
|
||||
bwp_cfg.logger.debug("SCHED: Provided RBG mask collides with allocation previously made.");
|
||||
return alloc_result::sch_collision;
|
||||
}
|
||||
|
||||
return alloc_result::success;
|
||||
}
|
||||
|
||||
srsran::expected<pdsch_t*, alloc_result>
|
||||
pdsch_allocator::alloc_pdsch(const srsran_dci_ctx_t& dci_ctx, uint32_t ss_id, const prb_grant& grant, pdcch_dl_t& pdcch)
|
||||
{
|
||||
alloc_result code = is_grant_valid(ss_id, dci_ctx.format, grant);
|
||||
if (code != alloc_result::success) {
|
||||
return code;
|
||||
}
|
||||
|
||||
return {&alloc_pdsch_unchecked(dci_ctx, grant, pdcch)};
|
||||
}
|
||||
|
||||
pdsch_t&
|
||||
pdsch_allocator::alloc_pdsch_unchecked(const srsran_dci_ctx_t& dci_ctx, const prb_grant& grant, pdcch_dl_t& pdcch)
|
||||
{
|
||||
// Create new PDSCH entry in output PDSCH list
|
||||
pdschs.emplace_back();
|
||||
pdsch_t& pdsch = pdschs.back();
|
||||
|
||||
// Register allocated PRBs in accumulated bitmap
|
||||
dl_prbs |= grant;
|
||||
|
||||
// Fill DCI with PDSCH freq/time allocation information
|
||||
pdcch.dci.time_domain_assigment = 0;
|
||||
if (grant.is_alloc_type0()) {
|
||||
pdcch.dci.freq_domain_assigment = grant.rbgs().to_uint64();
|
||||
} else {
|
||||
uint32_t rb_start = grant.prbs().start(), nof_prb = bwp_cfg.nof_prb();
|
||||
if (SRSRAN_SEARCH_SPACE_IS_COMMON(dci_ctx.ss_type)) {
|
||||
if (dci_ctx.format == srsran_dci_format_nr_1_0) {
|
||||
rb_start -= dci_ctx.coreset_start_rb;
|
||||
}
|
||||
if (dci_ctx.coreset_id == 0) {
|
||||
nof_prb = bwp_cfg.coreset_bw(0);
|
||||
}
|
||||
}
|
||||
srsran_sanity_check(rb_start + grant.prbs().length() <= nof_prb, "Invalid PRB grant");
|
||||
pdcch.dci.freq_domain_assigment = srsran_ra_nr_type1_riv(nof_prb, rb_start, grant.prbs().length());
|
||||
}
|
||||
|
||||
return pdsch;
|
||||
}
|
||||
|
||||
void pdsch_allocator::cancel_last_pdsch()
|
||||
{
|
||||
srsran_assert(not pdschs.empty(), "Trying to abort PDSCH allocation that does not exist");
|
||||
pdschs.pop_back();
|
||||
}
|
||||
|
||||
} // namespace sched_nr_impl
|
||||
} // namespace srsenb
|
|
@ -108,14 +108,14 @@ bool fill_dci_sib(prb_interval interv,
|
|||
const bwp_params_t& bwp_cfg,
|
||||
srsran_dci_dl_nr_t& dci)
|
||||
{
|
||||
dci.mcs = 5;
|
||||
dci.ctx.format = srsran_dci_format_nr_1_0;
|
||||
dci.ctx.ss_type = srsran_search_space_type_common_0;
|
||||
dci.ctx.rnti_type = srsran_rnti_type_si;
|
||||
dci.ctx.rnti = SRSRAN_SIRNTI;
|
||||
dci.ctx.coreset_id = 0;
|
||||
dci.ctx.coreset_start_rb = bwp_cfg.cfg.pdcch.coreset[0].offset_rb;
|
||||
dci.coreset0_bw = srsran_coreset_get_bw(&bwp_cfg.cfg.pdcch.coreset[0]);
|
||||
dci.mcs = 5;
|
||||
dci.ctx.format = srsran_dci_format_nr_1_0;
|
||||
dci.ctx.ss_type = srsran_search_space_type_common_0;
|
||||
dci.ctx.rnti_type = srsran_rnti_type_si;
|
||||
dci.ctx.rnti = SRSRAN_SIRNTI;
|
||||
dci.ctx.coreset_id = 0;
|
||||
dci.ctx.coreset_start_rb = bwp_cfg.cfg.pdcch.coreset[0].offset_rb;
|
||||
dci.coreset0_bw = srsran_coreset_get_bw(&bwp_cfg.cfg.pdcch.coreset[0]);
|
||||
dci.freq_domain_assigment =
|
||||
srsran_ra_nr_type1_riv(srsran_coreset_get_bw(&bwp_cfg.cfg.pdcch.coreset[0]), interv.start(), interv.length());
|
||||
dci.time_domain_assigment = 0;
|
||||
|
@ -149,9 +149,10 @@ void si_sched::run_slot(bwp_slot_allocator& bwp_alloc)
|
|||
// TODO: provide proper config
|
||||
return;
|
||||
}
|
||||
const uint32_t si_aggr_level = 2;
|
||||
slot_point sl_pdcch = bwp_alloc.get_pdcch_tti();
|
||||
const prb_bitmap& prbs = bwp_alloc.res_grid()[sl_pdcch].dl_prbs.prbs();
|
||||
const uint32_t si_aggr_level = 2;
|
||||
const uint32_t ss_id = 0;
|
||||
slot_point sl_pdcch = bwp_alloc.get_pdcch_tti();
|
||||
prb_bitmap prbs = bwp_alloc.res_grid()[sl_pdcch].pdschs.available_prbs(ss_id, srsran_dci_format_nr_1_0);
|
||||
|
||||
// Update SI windows
|
||||
uint32_t N = bwp_cfg->slots.size();
|
||||
|
|
Loading…
Reference in New Issue