mirror of https://github.com/PentHertz/srsLTE.git
move scheduler rbg/prb/cce mask and interval types and associated helper functions to a separate file
This commit is contained in:
parent
7c0649bc24
commit
0e0835a805
|
@ -25,7 +25,6 @@ namespace srsenb {
|
||||||
|
|
||||||
constexpr float tti_duration_ms = 1;
|
constexpr float tti_duration_ms = 1;
|
||||||
constexpr uint32_t NOF_AGGR_LEVEL = 4;
|
constexpr uint32_t NOF_AGGR_LEVEL = 4;
|
||||||
constexpr uint32_t MAX_NOF_RBGS = 25;
|
|
||||||
|
|
||||||
/***********************
|
/***********************
|
||||||
* Helper Types
|
* Helper Types
|
||||||
|
@ -82,30 +81,6 @@ public:
|
||||||
dl_lb_nof_re_table nof_re_lb_table;
|
dl_lb_nof_re_table nof_re_lb_table;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Bitmask used for CCE allocations
|
|
||||||
using pdcch_mask_t = srsran::bounded_bitset<sched_interface::max_cce, true>;
|
|
||||||
|
|
||||||
//! Bitmask that stores the allocared DL RBGs
|
|
||||||
using rbgmask_t = srsran::bounded_bitset<MAX_NOF_RBGS, true>;
|
|
||||||
|
|
||||||
//! Bitmask that stores the allocated UL PRBs
|
|
||||||
using prbmask_t = srsran::bounded_bitset<100, true>;
|
|
||||||
|
|
||||||
//! Struct to express a {min,...,max} range of RBGs
|
|
||||||
struct prb_interval;
|
|
||||||
struct rbg_interval : public srsran::interval<uint32_t> {
|
|
||||||
using interval::interval;
|
|
||||||
static rbg_interval rbgmask_to_rbgs(const rbgmask_t& mask);
|
|
||||||
static rbg_interval prbs_to_rbgs(const prb_interval& prbs, uint32_t cell_nof_prbs);
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Struct to express a {min,...,max} range of PRBs
|
|
||||||
struct prb_interval : public srsran::interval<uint32_t> {
|
|
||||||
using interval::interval;
|
|
||||||
static prb_interval rbgs_to_prbs(const rbg_interval& rbgs, uint32_t cell_nof_prb);
|
|
||||||
static prb_interval riv_to_prbs(uint32_t riv, uint32_t nof_prbs, int nof_vrbs = -1);
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Type of Allocation stored in PDSCH/PUSCH
|
/// Type of Allocation stored in PDSCH/PUSCH
|
||||||
enum class alloc_type_t { DL_BC, DL_PCCH, DL_RAR, DL_DATA, UL_DATA };
|
enum class alloc_type_t { DL_BC, DL_PCCH, DL_RAR, DL_DATA, UL_DATA };
|
||||||
inline bool is_dl_ctrl_alloc(alloc_type_t a)
|
inline bool is_dl_ctrl_alloc(alloc_type_t a)
|
||||||
|
@ -115,13 +90,4 @@ inline bool is_dl_ctrl_alloc(alloc_type_t a)
|
||||||
|
|
||||||
} // namespace srsenb
|
} // namespace srsenb
|
||||||
|
|
||||||
namespace fmt {
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct formatter<srsenb::rbg_interval> : public formatter<srsran::interval<uint32_t> > {};
|
|
||||||
template <>
|
|
||||||
struct formatter<srsenb::prb_interval> : public formatter<srsran::interval<uint32_t> > {};
|
|
||||||
|
|
||||||
} // namespace fmt
|
|
||||||
|
|
||||||
#endif // SRSRAN_SCHED_COMMON_H
|
#endif // SRSRAN_SCHED_COMMON_H
|
||||||
|
|
|
@ -38,74 +38,6 @@ inline uint32_t get_nof_retx(uint32_t rv_idx)
|
||||||
return nof_retxs[rv_idx % 4];
|
return nof_retxs[rv_idx % 4];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// convert cell nof PRBs to nof RBGs
|
|
||||||
inline uint32_t cell_nof_prb_to_rbg(uint32_t nof_prbs)
|
|
||||||
{
|
|
||||||
switch (nof_prbs) {
|
|
||||||
case 6:
|
|
||||||
return 6;
|
|
||||||
case 15:
|
|
||||||
return 8;
|
|
||||||
case 25:
|
|
||||||
return 13;
|
|
||||||
case 50:
|
|
||||||
return 17;
|
|
||||||
case 75:
|
|
||||||
return 19;
|
|
||||||
case 100:
|
|
||||||
return 25;
|
|
||||||
default:
|
|
||||||
srslog::fetch_basic_logger("MAC").error("Provided nof PRBs not valid");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// convert cell nof RBGs to nof PRBs
|
|
||||||
inline uint32_t cell_nof_rbg_to_prb(uint32_t nof_rbgs)
|
|
||||||
{
|
|
||||||
switch (nof_rbgs) {
|
|
||||||
case 6:
|
|
||||||
return 6;
|
|
||||||
case 8:
|
|
||||||
return 15;
|
|
||||||
case 13:
|
|
||||||
return 25;
|
|
||||||
case 17:
|
|
||||||
return 50;
|
|
||||||
case 19:
|
|
||||||
return 75;
|
|
||||||
case 25:
|
|
||||||
return 100;
|
|
||||||
default:
|
|
||||||
srslog::fetch_basic_logger("MAC").error("Provided nof PRBs not valid");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Count number of PRBs present in a DL RBG mask
|
|
||||||
* @param cell_nof_prb cell nof prbs
|
|
||||||
* @param P cell ratio prb/rbg
|
|
||||||
* @param bitmask DL RBG mask
|
|
||||||
* @return number of prbs
|
|
||||||
*/
|
|
||||||
inline uint32_t count_prb_per_tb(const rbgmask_t& bitmask)
|
|
||||||
{
|
|
||||||
uint32_t Nprb = cell_nof_rbg_to_prb(bitmask.size());
|
|
||||||
uint32_t P = srsran_ra_type0_P(Nprb);
|
|
||||||
uint32_t nof_prb = P * bitmask.count();
|
|
||||||
if (bitmask.test(bitmask.size() - 1)) {
|
|
||||||
nof_prb -= bitmask.size() * P - Nprb;
|
|
||||||
}
|
|
||||||
return nof_prb;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint32_t count_prb_per_tb_approx(uint32_t nof_rbgs, uint32_t cell_nof_prb)
|
|
||||||
{
|
|
||||||
uint32_t P = srsran_ra_type0_P(cell_nof_prb);
|
|
||||||
return std::min(nof_rbgs * P, cell_nof_prb);
|
|
||||||
}
|
|
||||||
|
|
||||||
cce_frame_position_table generate_cce_location_table(uint16_t rnti, const sched_cell_params_t& cell_cfg);
|
cce_frame_position_table generate_cce_location_table(uint16_t rnti, const sched_cell_params_t& cell_cfg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,12 +73,6 @@ uint32_t get_aggr_level(uint32_t nof_bits,
|
||||||
uint32_t cell_nof_prb,
|
uint32_t cell_nof_prb,
|
||||||
bool use_tbs_index_alt);
|
bool use_tbs_index_alt);
|
||||||
|
|
||||||
/*******************************************************
|
|
||||||
* RB mask helper functions
|
|
||||||
*******************************************************/
|
|
||||||
|
|
||||||
bool is_contiguous(const rbgmask_t& mask);
|
|
||||||
|
|
||||||
/*******************************************************
|
/*******************************************************
|
||||||
* sched_interface helper functions
|
* sched_interface helper functions
|
||||||
*******************************************************/
|
*******************************************************/
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#define SRSRAN_SCHED_DCI_H
|
#define SRSRAN_SCHED_DCI_H
|
||||||
|
|
||||||
#include "../sched_common.h"
|
#include "../sched_common.h"
|
||||||
|
#include "srsenb/hdr/stack/mac/sched_phy_ch/sched_phy_resource.h"
|
||||||
#include "srsran/adt/bounded_vector.h"
|
#include "srsran/adt/bounded_vector.h"
|
||||||
|
|
||||||
namespace srsenb {
|
namespace srsenb {
|
||||||
|
|
|
@ -0,0 +1,174 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* \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_PHY_RESOURCE_H
|
||||||
|
#define SRSRAN_SCHED_PHY_RESOURCE_H
|
||||||
|
|
||||||
|
#include "srsran/adt/bounded_bitset.h"
|
||||||
|
#include "srsran/adt/interval.h"
|
||||||
|
#include "srsran/common/srsran_assert.h"
|
||||||
|
extern "C" {
|
||||||
|
#include "srsran/phy/phch/ra.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Description: This file defines the types associated with representing the allocation masks/intervals for RBGs, PRBs
|
||||||
|
// and PDCCH CCEs, and provides some function helpers and algorithms to handle these types.
|
||||||
|
|
||||||
|
constexpr uint32_t MAX_NOF_RBGS = 25;
|
||||||
|
constexpr uint32_t MAX_NOF_PRBS = 100;
|
||||||
|
constexpr uint32_t MAX_NOF_CCES = 128;
|
||||||
|
|
||||||
|
namespace srsenb {
|
||||||
|
|
||||||
|
/// convert cell nof PRBs to nof RBGs
|
||||||
|
inline uint32_t cell_nof_prb_to_rbg(uint32_t nof_prbs)
|
||||||
|
{
|
||||||
|
switch (nof_prbs) {
|
||||||
|
case 6:
|
||||||
|
return 6;
|
||||||
|
case 15:
|
||||||
|
return 8;
|
||||||
|
case 25:
|
||||||
|
return 13;
|
||||||
|
case 50:
|
||||||
|
return 17;
|
||||||
|
case 75:
|
||||||
|
return 19;
|
||||||
|
case 100:
|
||||||
|
return 25;
|
||||||
|
default:
|
||||||
|
srsran_terminate("Provided nof PRBs not valid");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// convert cell nof RBGs to nof PRBs
|
||||||
|
inline uint32_t cell_nof_rbg_to_prb(uint32_t nof_rbgs)
|
||||||
|
{
|
||||||
|
switch (nof_rbgs) {
|
||||||
|
case 6:
|
||||||
|
return 6;
|
||||||
|
case 8:
|
||||||
|
return 15;
|
||||||
|
case 13:
|
||||||
|
return 25;
|
||||||
|
case 17:
|
||||||
|
return 50;
|
||||||
|
case 19:
|
||||||
|
return 75;
|
||||||
|
case 25:
|
||||||
|
return 100;
|
||||||
|
default:
|
||||||
|
srsran_terminate("Provided nof PRBs not valid");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Bitmask used for CCE allocations
|
||||||
|
using pdcch_mask_t = srsran::bounded_bitset<MAX_NOF_CCES, true>;
|
||||||
|
|
||||||
|
/// Bitmask that stores the allocared DL RBGs
|
||||||
|
using rbgmask_t = srsran::bounded_bitset<MAX_NOF_RBGS, true>;
|
||||||
|
|
||||||
|
/// Bitmask that stores the allocated UL PRBs
|
||||||
|
using prbmask_t = srsran::bounded_bitset<MAX_NOF_PRBS, true>;
|
||||||
|
|
||||||
|
/// Struct to express a {min,...,max} range of RBGs
|
||||||
|
struct prb_interval;
|
||||||
|
struct rbg_interval : public srsran::interval<uint32_t> {
|
||||||
|
using interval::interval;
|
||||||
|
static rbg_interval find_first_interval(const rbgmask_t& mask);
|
||||||
|
static rbg_interval prbs_to_rbgs(const prb_interval& prbs, uint32_t cell_nof_prb);
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Struct to express a {min,...,max} range of PRBs
|
||||||
|
struct prb_interval : public srsran::interval<uint32_t> {
|
||||||
|
using interval::interval;
|
||||||
|
static prb_interval rbgs_to_prbs(const rbg_interval& rbgs, uint32_t cell_nof_prb)
|
||||||
|
{
|
||||||
|
uint32_t P = srsran_ra_type0_P(cell_nof_prb);
|
||||||
|
return prb_interval{rbgs.start() * P, std::min(rbgs.stop() * P, cell_nof_prb)};
|
||||||
|
}
|
||||||
|
static prb_interval riv_to_prbs(uint32_t riv, uint32_t nof_prbs, int nof_vrbs = -1);
|
||||||
|
};
|
||||||
|
|
||||||
|
inline rbg_interval rbg_interval::prbs_to_rbgs(const prb_interval& prbs, uint32_t cell_nof_prb)
|
||||||
|
{
|
||||||
|
uint32_t P = srsran_ra_type0_P(cell_nof_prb);
|
||||||
|
return rbg_interval{prbs.start() / P, srsran::ceil_div(prbs.stop(), P)};
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************
|
||||||
|
* helper functions
|
||||||
|
*******************************************************/
|
||||||
|
|
||||||
|
/// If the RBG mask one bits are all contiguous
|
||||||
|
inline bool is_contiguous(const rbgmask_t& mask)
|
||||||
|
{
|
||||||
|
return rbg_interval::find_first_interval(mask).length() == mask.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Count number of PRBs present in a DL RBG mask
|
||||||
|
inline uint32_t count_prb_per_tb(const rbgmask_t& bitmask)
|
||||||
|
{
|
||||||
|
uint32_t Nprb = cell_nof_rbg_to_prb(bitmask.size());
|
||||||
|
uint32_t P = srsran_ra_type0_P(Nprb);
|
||||||
|
uint32_t nof_prb = P * bitmask.count();
|
||||||
|
if (bitmask.test(bitmask.size() - 1)) {
|
||||||
|
nof_prb -= bitmask.size() * P - Nprb;
|
||||||
|
}
|
||||||
|
return nof_prb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Estimate of number of PRBs in DL grant given Nof RBGs
|
||||||
|
inline uint32_t count_prb_per_tb_approx(uint32_t nof_rbgs, uint32_t cell_nof_prb)
|
||||||
|
{
|
||||||
|
uint32_t P = srsran_ra_type0_P(cell_nof_prb);
|
||||||
|
return std::min(nof_rbgs * P, cell_nof_prb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a contiguous interval of "zeroed"/available RBG resources
|
||||||
|
* @param max_nof_rbgs maximum number of RBGs
|
||||||
|
* @param current_mask bitmask of occupied RBGs, used to search for available RBGs
|
||||||
|
* @return interval with found RBGs. If a valid interval wasn't found, interval.length() == 0
|
||||||
|
*/
|
||||||
|
rbg_interval find_empty_rbg_interval(uint32_t max_nof_rbgs, const rbgmask_t& current_mask);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a bitmask of "zeroed"/available RBG resources
|
||||||
|
* @param max_nof_rbgs maximum number of RBGs
|
||||||
|
* @param current_mask bitmask of occupied RBGs, used to search for available RBGs
|
||||||
|
* @return bitmask of found RBGs. If a valid mask wasn't found, bitmask::size() == 0
|
||||||
|
*/
|
||||||
|
rbgmask_t find_available_rbgmask(uint32_t max_nof_rbgs, bool is_contiguous, const rbgmask_t& current_mask);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a range of L contiguous PRBs that are empty
|
||||||
|
* @param L Max length of the requested UL PRBs
|
||||||
|
* @param current_mask input PRB mask where to search for available PRBs
|
||||||
|
* @return found interval of PRBs
|
||||||
|
*/
|
||||||
|
prb_interval find_contiguous_ul_prbs(uint32_t L, const prbmask_t& current_mask);
|
||||||
|
|
||||||
|
} // namespace srsenb
|
||||||
|
|
||||||
|
namespace fmt {
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct formatter<srsenb::rbg_interval> : public formatter<srsran::interval<uint32_t> > {};
|
||||||
|
template <>
|
||||||
|
struct formatter<srsenb::prb_interval> : public formatter<srsran::interval<uint32_t> > {};
|
||||||
|
|
||||||
|
} // namespace fmt
|
||||||
|
|
||||||
|
#endif // SRSRAN_SCHED_PHY_RESOURCE_H
|
|
@ -14,6 +14,7 @@
|
||||||
#define SRSRAN_SCHED_RESULT_H
|
#define SRSRAN_SCHED_RESULT_H
|
||||||
|
|
||||||
#include "../sched_common.h"
|
#include "../sched_common.h"
|
||||||
|
#include "srsenb/hdr/stack/mac/sched_phy_ch/sched_phy_resource.h"
|
||||||
|
|
||||||
namespace srsenb {
|
namespace srsenb {
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include "srsenb/hdr/stack/mac/sched_common.h"
|
#include "srsenb/hdr/stack/mac/sched_common.h"
|
||||||
#include "srsenb/hdr/stack/mac/sched_helpers.h"
|
#include "srsenb/hdr/stack/mac/sched_helpers.h"
|
||||||
|
#include "srsenb/hdr/stack/mac/sched_phy_ch/sched_phy_resource.h"
|
||||||
#include "srsran/adt/accumulators.h"
|
#include "srsran/adt/accumulators.h"
|
||||||
#include "srsran/common/common_lte.h"
|
#include "srsran/common/common_lte.h"
|
||||||
#include "srsran/phy/phch/cqi.h"
|
#include "srsran/phy/phch/cqi.h"
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#define SRSRAN_SCHED_BASE_H
|
#define SRSRAN_SCHED_BASE_H
|
||||||
|
|
||||||
#include "srsenb/hdr/stack/mac/sched_grid.h"
|
#include "srsenb/hdr/stack/mac/sched_grid.h"
|
||||||
|
#include "srsenb/hdr/stack/mac/sched_phy_ch/sched_phy_resource.h"
|
||||||
|
|
||||||
namespace srsenb {
|
namespace srsenb {
|
||||||
|
|
||||||
|
@ -34,25 +35,6 @@ protected:
|
||||||
|
|
||||||
/**************** Helper methods ****************/
|
/**************** Helper methods ****************/
|
||||||
|
|
||||||
rbg_interval find_empty_rbg_interval(uint32_t max_nof_rbgs, const rbgmask_t& current_mask);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds a bitmask of available RBG resources for a given UE in a greedy fashion
|
|
||||||
* @param ue UE being allocated
|
|
||||||
* @param is_contiguous whether to find a contiguous range of RBGs
|
|
||||||
* @param current_mask bitmask of occupied RBGs, where to search for available RBGs
|
|
||||||
* @return bitmask of found RBGs. If a valid mask wasn't found, bitmask::size() == 0
|
|
||||||
*/
|
|
||||||
rbgmask_t find_available_rbgmask(uint32_t max_nof_rbgs, bool is_contiguous, const rbgmask_t& current_mask);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds a range of L contiguous PRBs that are empty
|
|
||||||
* @param L Size of the requested UL PRBs
|
|
||||||
* @param current_mask input prb mask where to search for available PRBs
|
|
||||||
* @return found interval of PRBs
|
|
||||||
*/
|
|
||||||
prb_interval find_contiguous_ul_prbs(uint32_t L, const prbmask_t& current_mask);
|
|
||||||
|
|
||||||
const dl_harq_proc* get_dl_retx_harq(sched_ue& user, sf_sched* tti_sched);
|
const dl_harq_proc* get_dl_retx_harq(sched_ue& user, sf_sched* tti_sched);
|
||||||
const dl_harq_proc* get_dl_newtx_harq(sched_ue& user, sf_sched* tti_sched);
|
const dl_harq_proc* get_dl_newtx_harq(sched_ue& user, sf_sched* tti_sched);
|
||||||
const ul_harq_proc* get_ul_retx_harq(sched_ue& user, sf_sched* tti_sched);
|
const ul_harq_proc* get_ul_retx_harq(sched_ue& user, sf_sched* tti_sched);
|
||||||
|
|
|
@ -10,7 +10,8 @@ add_subdirectory(schedulers)
|
||||||
|
|
||||||
set(SOURCES mac.cc ue.cc sched.cc sched_carrier.cc sched_grid.cc sched_ue_ctrl/sched_harq.cc sched_ue.cc
|
set(SOURCES mac.cc ue.cc sched.cc sched_carrier.cc sched_grid.cc sched_ue_ctrl/sched_harq.cc sched_ue.cc
|
||||||
sched_ue_ctrl/sched_lch.cc sched_ue_ctrl/sched_ue_cell.cc sched_ue_ctrl/sched_dl_cqi.cc
|
sched_ue_ctrl/sched_lch.cc sched_ue_ctrl/sched_ue_cell.cc sched_ue_ctrl/sched_dl_cqi.cc
|
||||||
sched_phy_ch/sf_cch_allocator.cc sched_phy_ch/sched_dci.cc sched_helpers.cc)
|
sched_phy_ch/sf_cch_allocator.cc sched_phy_ch/sched_dci.cc sched_phy_ch/sched_phy_resource.cc
|
||||||
|
sched_helpers.cc)
|
||||||
add_library(srsenb_mac STATIC ${SOURCES} $<TARGET_OBJECTS:mac_schedulers>)
|
add_library(srsenb_mac STATIC ${SOURCES} $<TARGET_OBJECTS:mac_schedulers>)
|
||||||
|
|
||||||
set(SOURCES mac_nr.cc)
|
set(SOURCES mac_nr.cc)
|
||||||
|
|
|
@ -152,54 +152,6 @@ void log_phich_cc_results(srslog::basic_logger& logger,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rbg_interval rbg_interval::prbs_to_rbgs(const prb_interval& prbs, uint32_t cell_nof_prb)
|
|
||||||
{
|
|
||||||
uint32_t P = srsran_ra_type0_P(cell_nof_prb);
|
|
||||||
return rbg_interval{prbs.start() / P, (prbs.stop() + P - 1) / P};
|
|
||||||
}
|
|
||||||
|
|
||||||
prb_interval prb_interval::rbgs_to_prbs(const rbg_interval& rbgs, uint32_t cell_nof_prb)
|
|
||||||
{
|
|
||||||
uint32_t P = srsran_ra_type0_P(cell_nof_prb);
|
|
||||||
return prb_interval{rbgs.start() * P, std::min(rbgs.stop() * P, cell_nof_prb)};
|
|
||||||
}
|
|
||||||
|
|
||||||
rbg_interval rbg_interval::rbgmask_to_rbgs(const rbgmask_t& mask)
|
|
||||||
{
|
|
||||||
int rb_start = -1;
|
|
||||||
for (uint32_t i = 0; i < mask.size(); i++) {
|
|
||||||
if (rb_start == -1) {
|
|
||||||
if (mask.test(i)) {
|
|
||||||
rb_start = i;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!mask.test(i)) {
|
|
||||||
return rbg_interval(rb_start, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rb_start != -1) {
|
|
||||||
return rbg_interval(rb_start, mask.size());
|
|
||||||
} else {
|
|
||||||
return rbg_interval();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
prb_interval prb_interval::riv_to_prbs(uint32_t riv, uint32_t nof_prbs, int nof_vrbs)
|
|
||||||
{
|
|
||||||
if (nof_vrbs < 0) {
|
|
||||||
nof_vrbs = nof_prbs;
|
|
||||||
}
|
|
||||||
uint32_t rb_start, l_crb;
|
|
||||||
srsran_ra_type2_from_riv(riv, &l_crb, &rb_start, nof_prbs, (uint32_t)nof_vrbs);
|
|
||||||
return {rb_start, rb_start + l_crb};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_contiguous(const rbgmask_t& mask)
|
|
||||||
{
|
|
||||||
return rbg_interval::rbgmask_to_rbgs(mask).length() == mask.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************
|
/*******************************************************
|
||||||
* Sched Params
|
* Sched Params
|
||||||
*******************************************************/
|
*******************************************************/
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* \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 "srsenb/hdr/stack/mac/sched_phy_ch/sched_phy_resource.h"
|
||||||
|
extern "C" {
|
||||||
|
#include "lib/include/srsran/phy/dft/dft_precoding.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace srsenb {
|
||||||
|
|
||||||
|
rbg_interval rbg_interval::find_first_interval(const rbgmask_t& mask)
|
||||||
|
{
|
||||||
|
int rb_start = -1;
|
||||||
|
for (uint32_t i = 0; i < mask.size(); i++) {
|
||||||
|
if (rb_start == -1) {
|
||||||
|
if (mask.test(i)) {
|
||||||
|
rb_start = i;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!mask.test(i)) {
|
||||||
|
return rbg_interval(rb_start, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rb_start != -1) {
|
||||||
|
return rbg_interval(rb_start, mask.size());
|
||||||
|
}
|
||||||
|
return rbg_interval();
|
||||||
|
}
|
||||||
|
|
||||||
|
prb_interval prb_interval::riv_to_prbs(uint32_t riv, uint32_t nof_prbs, int nof_vrbs)
|
||||||
|
{
|
||||||
|
if (nof_vrbs < 0) {
|
||||||
|
nof_vrbs = nof_prbs;
|
||||||
|
}
|
||||||
|
uint32_t rb_start, l_crb;
|
||||||
|
srsran_ra_type2_from_riv(riv, &l_crb, &rb_start, nof_prbs, (uint32_t)nof_vrbs);
|
||||||
|
return {rb_start, rb_start + l_crb};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename RBMask,
|
||||||
|
typename RBInterval =
|
||||||
|
typename std::conditional<std::is_same<RBMask, prbmask_t>::value, prb_interval, rbg_interval>::type>
|
||||||
|
RBInterval find_contiguous_interval(const RBMask& in_mask, uint32_t max_size)
|
||||||
|
{
|
||||||
|
RBInterval max_interv;
|
||||||
|
|
||||||
|
for (size_t n = 0; n < in_mask.size();) {
|
||||||
|
int pos = in_mask.find_lowest(n, in_mask.size(), false);
|
||||||
|
if (pos < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t max_pos = std::min(in_mask.size(), (size_t)pos + max_size);
|
||||||
|
int pos2 = in_mask.find_lowest(pos, max_pos, true);
|
||||||
|
RBInterval interv(pos, pos2 < 0 ? max_pos : pos2);
|
||||||
|
if (interv.length() >= max_size) {
|
||||||
|
return interv;
|
||||||
|
}
|
||||||
|
if (interv.length() > max_interv.length()) {
|
||||||
|
max_interv = interv;
|
||||||
|
}
|
||||||
|
n = interv.stop();
|
||||||
|
}
|
||||||
|
return max_interv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rbgmask_t find_available_rbgmask(const rbgmask_t& in_mask, uint32_t max_size)
|
||||||
|
{
|
||||||
|
// 1's for free RBs
|
||||||
|
rbgmask_t localmask = ~(in_mask);
|
||||||
|
|
||||||
|
if (max_size >= localmask.size() or max_size >= localmask.count()) {
|
||||||
|
// shortcut in case rbg count < max_size
|
||||||
|
return localmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t i = 0, nof_alloc = 0;
|
||||||
|
for (; i < localmask.size() and nof_alloc < max_size; ++i) {
|
||||||
|
if (localmask.test(i)) {
|
||||||
|
nof_alloc++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
localmask.fill(i, localmask.size(), false);
|
||||||
|
return localmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
rbg_interval find_empty_rbg_interval(uint32_t max_nof_rbgs, const rbgmask_t& current_mask)
|
||||||
|
{
|
||||||
|
return find_contiguous_interval(current_mask, max_nof_rbgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
rbgmask_t find_available_rbgmask(uint32_t max_nof_rbgs, bool is_contiguous, const rbgmask_t& current_mask)
|
||||||
|
{
|
||||||
|
// Allocate enough RBs that accommodate pending data
|
||||||
|
rbgmask_t newtx_mask(current_mask.size());
|
||||||
|
if (is_contiguous) {
|
||||||
|
rbg_interval interv = find_contiguous_interval(current_mask, max_nof_rbgs);
|
||||||
|
newtx_mask.fill(interv.start(), interv.stop());
|
||||||
|
} else {
|
||||||
|
newtx_mask = find_available_rbgmask(current_mask, max_nof_rbgs);
|
||||||
|
}
|
||||||
|
return newtx_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
prb_interval find_contiguous_ul_prbs(uint32_t L, const prbmask_t& current_mask)
|
||||||
|
{
|
||||||
|
prb_interval prb_interv = find_contiguous_interval(current_mask, L);
|
||||||
|
if (prb_interv.empty()) {
|
||||||
|
return prb_interv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure L is allowed by SC-FDMA modulation
|
||||||
|
prb_interval prb_interv2 = prb_interv;
|
||||||
|
while (not srsran_dft_precoding_valid_prb(prb_interv.length()) and prb_interv.stop() < current_mask.size() and
|
||||||
|
not current_mask.test(prb_interv.stop())) {
|
||||||
|
prb_interv.resize_by(1);
|
||||||
|
}
|
||||||
|
if (not srsran_dft_precoding_valid_prb(prb_interv.length())) {
|
||||||
|
// if length increase failed, try to decrease
|
||||||
|
prb_interv = prb_interv2;
|
||||||
|
prb_interv.resize_by(-1);
|
||||||
|
while (not srsran_dft_precoding_valid_prb(prb_interv.length()) and not prb_interv.empty()) {
|
||||||
|
prb_interv.resize_by(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prb_interv;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace srsenb
|
|
@ -408,7 +408,7 @@ int sched_ue::generate_format1a(uint32_t pid,
|
||||||
|
|
||||||
dci->alloc_type = SRSRAN_RA_ALLOC_TYPE2;
|
dci->alloc_type = SRSRAN_RA_ALLOC_TYPE2;
|
||||||
dci->type2_alloc.mode = srsran_ra_type2_t::SRSRAN_RA_TYPE2_LOC;
|
dci->type2_alloc.mode = srsran_ra_type2_t::SRSRAN_RA_TYPE2_LOC;
|
||||||
rbg_interval rbg_int = rbg_interval::rbgmask_to_rbgs(user_mask);
|
rbg_interval rbg_int = rbg_interval::find_first_interval(user_mask);
|
||||||
prb_interval prb_int = prb_interval::rbgs_to_prbs(rbg_int, cell.nof_prb);
|
prb_interval prb_int = prb_interval::rbgs_to_prbs(rbg_int, cell.nof_prb);
|
||||||
uint32_t L_crb = prb_int.length();
|
uint32_t L_crb = prb_int.length();
|
||||||
uint32_t RB_start = prb_int.start();
|
uint32_t RB_start = prb_int.start();
|
||||||
|
|
|
@ -14,79 +14,6 @@
|
||||||
|
|
||||||
namespace srsenb {
|
namespace srsenb {
|
||||||
|
|
||||||
/*********************************
|
|
||||||
* Common UL/DL Helper methods
|
|
||||||
********************************/
|
|
||||||
|
|
||||||
template <typename RBMask,
|
|
||||||
typename RBInterval =
|
|
||||||
typename std::conditional<std::is_same<RBMask, prbmask_t>::value, prb_interval, rbg_interval>::type>
|
|
||||||
RBInterval find_contiguous_interval(const RBMask& in_mask, uint32_t max_size)
|
|
||||||
{
|
|
||||||
RBInterval max_interv;
|
|
||||||
|
|
||||||
for (size_t n = 0; n < in_mask.size();) {
|
|
||||||
int pos = in_mask.find_lowest(n, in_mask.size(), false);
|
|
||||||
if (pos < 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t max_pos = std::min(in_mask.size(), (size_t)pos + max_size);
|
|
||||||
int pos2 = in_mask.find_lowest(pos, max_pos, true);
|
|
||||||
RBInterval interv(pos, pos2 < 0 ? max_pos : pos2);
|
|
||||||
if (interv.length() >= max_size) {
|
|
||||||
return interv;
|
|
||||||
}
|
|
||||||
if (interv.length() > max_interv.length()) {
|
|
||||||
max_interv = interv;
|
|
||||||
}
|
|
||||||
n = interv.stop();
|
|
||||||
}
|
|
||||||
return max_interv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************
|
|
||||||
* DL Helper methods
|
|
||||||
***************************/
|
|
||||||
|
|
||||||
rbgmask_t find_available_rbgmask(const rbgmask_t& in_mask, uint32_t max_size)
|
|
||||||
{
|
|
||||||
// 1's for free RBs
|
|
||||||
rbgmask_t localmask = ~(in_mask);
|
|
||||||
|
|
||||||
if (max_size >= localmask.size() or max_size >= localmask.count()) {
|
|
||||||
// shortcut in case rbg count < max_size
|
|
||||||
return localmask;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t i = 0, nof_alloc = 0;
|
|
||||||
for (; i < localmask.size() and nof_alloc < max_size; ++i) {
|
|
||||||
if (localmask.test(i)) {
|
|
||||||
nof_alloc++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
localmask.fill(i, localmask.size(), false);
|
|
||||||
return localmask;
|
|
||||||
}
|
|
||||||
|
|
||||||
rbg_interval find_empty_rbg_interval(uint32_t max_nof_rbgs, const rbgmask_t& current_mask)
|
|
||||||
{
|
|
||||||
return find_contiguous_interval(current_mask, max_nof_rbgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
rbgmask_t find_available_rbgmask(uint32_t max_nof_rbgs, bool is_contiguous, const rbgmask_t& current_mask)
|
|
||||||
{
|
|
||||||
// Allocate enough RBs that accommodate pending data
|
|
||||||
rbgmask_t newtx_mask(current_mask.size());
|
|
||||||
if (is_contiguous) {
|
|
||||||
rbg_interval interv = find_contiguous_interval(current_mask, max_nof_rbgs);
|
|
||||||
newtx_mask.fill(interv.start(), interv.stop());
|
|
||||||
} else {
|
|
||||||
newtx_mask = find_available_rbgmask(current_mask, max_nof_rbgs);
|
|
||||||
}
|
|
||||||
return newtx_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_ue_cc_idx_if_pdsch_enabled(const sched_ue& user, sf_sched* tti_sched)
|
int get_ue_cc_idx_if_pdsch_enabled(const sched_ue& user, sf_sched* tti_sched)
|
||||||
{
|
{
|
||||||
// Do not allocate a user multiple times in the same tti
|
// Do not allocate a user multiple times in the same tti
|
||||||
|
@ -180,30 +107,6 @@ alloc_result try_dl_newtx_alloc_greedy(sf_sched& tti_sched, sched_ue& ue, const
|
||||||
* UL Helpers
|
* UL Helpers
|
||||||
****************/
|
****************/
|
||||||
|
|
||||||
prb_interval find_contiguous_ul_prbs(uint32_t L, const prbmask_t& current_mask)
|
|
||||||
{
|
|
||||||
prb_interval prb_interv = find_contiguous_interval(current_mask, L);
|
|
||||||
if (prb_interv.empty()) {
|
|
||||||
return prb_interv;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure L is allowed by SC-FDMA modulation
|
|
||||||
prb_interval prb_interv2 = prb_interv;
|
|
||||||
while (not srsran_dft_precoding_valid_prb(prb_interv.length()) and prb_interv.stop() < current_mask.size() and
|
|
||||||
not current_mask.test(prb_interv.stop())) {
|
|
||||||
prb_interv.resize_by(1);
|
|
||||||
}
|
|
||||||
if (not srsran_dft_precoding_valid_prb(prb_interv.length())) {
|
|
||||||
// if length increase failed, try to decrease
|
|
||||||
prb_interv = prb_interv2;
|
|
||||||
prb_interv.resize_by(-1);
|
|
||||||
while (not srsran_dft_precoding_valid_prb(prb_interv.length()) and not prb_interv.empty()) {
|
|
||||||
prb_interv.resize_by(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return prb_interv;
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_ue_cc_idx_if_pusch_enabled(const sched_ue& user, sf_sched* tti_sched, bool needs_pdcch)
|
int get_ue_cc_idx_if_pusch_enabled(const sched_ue& user, sf_sched* tti_sched, bool needs_pdcch)
|
||||||
{
|
{
|
||||||
// Do not allocate a user multiple times in the same tti
|
// Do not allocate a user multiple times in the same tti
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#define SRSRAN_SCHED_COMMON_TEST_SUITE_H
|
#define SRSRAN_SCHED_COMMON_TEST_SUITE_H
|
||||||
|
|
||||||
#include "srsenb/hdr/stack/mac/sched_common.h"
|
#include "srsenb/hdr/stack/mac/sched_common.h"
|
||||||
#include "srsran/adt/bounded_bitset.h"
|
#include "srsenb/hdr/stack/mac/sched_phy_ch/sched_phy_resource.h"
|
||||||
#include "srsran/adt/span.h"
|
#include "srsran/adt/span.h"
|
||||||
#include "srsran/common/tti_point.h"
|
#include "srsran/common/tti_point.h"
|
||||||
#include "srsran/interfaces/sched_interface.h"
|
#include "srsran/interfaces/sched_interface.h"
|
||||||
|
|
Loading…
Reference in New Issue