mirror of https://github.com/pvnis/srsRAN_4G.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
238 lines
6.3 KiB
C
238 lines
6.3 KiB
C
3 years ago
|
/**
|
||
|
*
|
||
|
* \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_RB_H
|
||
|
#define SRSRAN_SCHED_NR_RB_H
|
||
|
|
||
|
#include "srsenb/hdr/stack/mac/nr/sched_nr_interface.h"
|
||
|
#include "srsran/adt/bounded_bitset.h"
|
||
|
#include "srsran/phy/common/phy_common_nr.h"
|
||
|
|
||
|
namespace srsenb {
|
||
|
namespace sched_nr_impl {
|
||
|
|
||
|
using prb_bitmap = srsran::bounded_bitset<SRSRAN_MAX_PRB_NR, true>;
|
||
|
using rbg_bitmap = srsran::bounded_bitset<SCHED_NR_MAX_NOF_RBGS, true>;
|
||
|
|
||
|
/// TS 38.214, Table 6.1.2.2.1-1 - Nominal RBG size P
|
||
|
uint32_t get_P(uint32_t bwp_nof_prb, bool config_1_or_2);
|
||
|
|
||
|
/// TS 38.214 - total number of RBGs for a uplink bandwidth part of size "bwp_nof_prb" PRBs
|
||
|
uint32_t get_nof_rbgs(uint32_t bwp_nof_prb, uint32_t bwp_start, bool config1_or_2);
|
||
|
|
||
|
/// Struct to express a {min,...,max} range of PRBs
|
||
|
struct prb_interval : public srsran::interval<uint32_t> {
|
||
|
using interval::interval;
|
||
|
};
|
||
|
|
||
|
struct prb_grant {
|
||
|
prb_grant() = default;
|
||
|
prb_grant(const prb_interval& other) noexcept : alloc_type_0(false), alloc(other) {}
|
||
|
prb_grant(const rbg_bitmap& other) noexcept : alloc_type_0(true), alloc(other) {}
|
||
|
prb_grant(const prb_grant& other) noexcept : alloc_type_0(other.alloc_type_0), alloc(other.alloc_type_0, other.alloc)
|
||
|
{}
|
||
|
prb_grant& operator=(const prb_grant& other) noexcept
|
||
|
{
|
||
|
if (this == &other) {
|
||
|
return *this;
|
||
|
}
|
||
|
if (other.alloc_type_0) {
|
||
|
*this = other.rbgs();
|
||
|
} else {
|
||
|
*this = other.prbs();
|
||
|
}
|
||
|
return *this;
|
||
|
}
|
||
|
prb_grant& operator=(const prb_interval& prbs)
|
||
|
{
|
||
|
if (alloc_type_0) {
|
||
|
alloc_type_0 = false;
|
||
|
alloc.rbgs.~rbg_bitmap();
|
||
|
new (&alloc.interv) prb_interval(prbs);
|
||
|
} else {
|
||
|
alloc.interv = alloc.interv;
|
||
|
}
|
||
|
return *this;
|
||
|
}
|
||
|
prb_grant& operator=(const rbg_bitmap& rbgs)
|
||
|
{
|
||
|
if (alloc_type_0) {
|
||
|
alloc.rbgs = rbgs;
|
||
|
} else {
|
||
|
alloc_type_0 = true;
|
||
|
alloc.interv.~prb_interval();
|
||
|
new (&alloc.rbgs) rbg_bitmap(rbgs);
|
||
|
}
|
||
|
return *this;
|
||
|
}
|
||
|
~prb_grant()
|
||
|
{
|
||
|
if (is_alloc_type0()) {
|
||
|
alloc.rbgs.~rbg_bitmap();
|
||
|
} else {
|
||
|
alloc.interv.~prb_interval();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool is_alloc_type0() const { return alloc_type_0; }
|
||
|
bool is_alloc_type1() const { return not is_alloc_type0(); }
|
||
|
const rbg_bitmap& rbgs() const
|
||
|
{
|
||
|
srsran_assert(is_alloc_type0(), "Invalid access to rbgs() field of grant with alloc type 1");
|
||
|
return alloc.rbgs;
|
||
|
}
|
||
|
const prb_interval& prbs() const
|
||
|
{
|
||
|
srsran_assert(is_alloc_type1(), "Invalid access to prbs() field of grant with alloc type 0");
|
||
|
return alloc.interv;
|
||
|
}
|
||
|
rbg_bitmap& rbgs()
|
||
|
{
|
||
|
srsran_assert(is_alloc_type0(), "Invalid access to rbgs() field of grant with alloc type 1");
|
||
|
return alloc.rbgs;
|
||
|
}
|
||
|
prb_interval& prbs()
|
||
|
{
|
||
|
srsran_assert(is_alloc_type1(), "Invalid access to prbs() field of grant with alloc type 0");
|
||
|
return alloc.interv;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
bool alloc_type_0 = false;
|
||
|
union alloc_t {
|
||
|
rbg_bitmap rbgs;
|
||
|
prb_interval interv;
|
||
|
|
||
|
alloc_t() : interv(0, 0) {}
|
||
|
explicit alloc_t(const prb_interval& prbs) : interv(prbs) {}
|
||
|
explicit alloc_t(const rbg_bitmap& rbgs_) : rbgs(rbgs_) {}
|
||
|
alloc_t(bool type0, const alloc_t& other)
|
||
|
{
|
||
|
if (type0) {
|
||
|
new (&rbgs) rbg_bitmap(other.rbgs);
|
||
|
} else {
|
||
|
new (&interv) prb_interval(other.interv);
|
||
|
}
|
||
|
}
|
||
|
} alloc;
|
||
|
};
|
||
|
|
||
|
struct bwp_rb_bitmap {
|
||
|
public:
|
||
|
bwp_rb_bitmap() = default;
|
||
|
bwp_rb_bitmap(uint32_t bwp_nof_prbs, uint32_t bwp_prb_start_, bool config1_or_2);
|
||
|
|
||
|
void reset()
|
||
|
{
|
||
|
prbs_.reset();
|
||
|
rbgs_.reset();
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
void operator|=(const T& grant)
|
||
|
{
|
||
|
add(grant);
|
||
|
}
|
||
|
|
||
|
void add(const prb_interval& prbs)
|
||
|
{
|
||
|
prbs_.fill(prbs.start(), prbs.stop());
|
||
|
add_prbs_to_rbgs(prbs);
|
||
|
}
|
||
|
void add(const prb_bitmap& grant)
|
||
|
{
|
||
|
prbs_ |= grant;
|
||
|
add_prbs_to_rbgs(grant);
|
||
|
}
|
||
|
void add(const rbg_bitmap& grant)
|
||
|
{
|
||
|
rbgs_ |= grant;
|
||
|
add_rbgs_to_prbs(grant);
|
||
|
}
|
||
|
void add(const prb_grant& grant)
|
||
|
{
|
||
|
if (grant.is_alloc_type0()) {
|
||
|
add(grant.rbgs());
|
||
|
} else {
|
||
|
add(grant.prbs());
|
||
|
}
|
||
|
}
|
||
|
bool collides(const prb_grant& grant) const
|
||
|
{
|
||
|
if (grant.is_alloc_type0()) {
|
||
|
return (rbgs() & grant.rbgs()).any();
|
||
|
}
|
||
|
return prbs().any(grant.prbs().start(), grant.prbs().stop());
|
||
|
}
|
||
|
bool test(uint32_t prb_idx) { return prbs().test(prb_idx); }
|
||
|
void set(uint32_t prb_idx)
|
||
|
{
|
||
|
prbs_.set(prb_idx);
|
||
|
rbgs_.set(prb_to_rbg_idx(prb_idx));
|
||
|
}
|
||
|
|
||
|
const prb_bitmap& prbs() const { return prbs_; }
|
||
|
const rbg_bitmap& rbgs() const { return rbgs_; }
|
||
|
uint32_t P() const { return P_; }
|
||
|
uint32_t nof_prbs() const { return prbs_.size(); }
|
||
|
uint32_t nof_rbgs() const { return rbgs_.size(); }
|
||
|
|
||
|
uint32_t prb_to_rbg_idx(uint32_t prb_idx) const;
|
||
|
|
||
|
private:
|
||
|
prb_bitmap prbs_;
|
||
|
rbg_bitmap rbgs_;
|
||
|
uint32_t P_ = 0;
|
||
|
uint32_t Pnofbits = 0;
|
||
|
uint32_t first_rbg_size = 0;
|
||
|
|
||
|
void add_prbs_to_rbgs(const prb_bitmap& grant);
|
||
|
void add_prbs_to_rbgs(const prb_interval& grant);
|
||
|
void add_rbgs_to_prbs(const rbg_bitmap& grant);
|
||
|
};
|
||
|
|
||
|
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)
|
||
|
{
|
||
|
int rb_start = mask.find_lowest(start_prb_idx, std::min(mask.size(), last_prb_idx), false);
|
||
|
if (rb_start != -1) {
|
||
|
int rb_end = mask.find_lowest(rb_start + 1, std::min(mask.size(), last_prb_idx), true);
|
||
|
return {(uint32_t)rb_start, (uint32_t)(rb_end < 0 ? mask.size() : rb_end)};
|
||
|
}
|
||
|
return {};
|
||
|
}
|
||
|
|
||
|
inline prb_interval find_empty_interval_of_length(const prb_bitmap& mask, size_t nof_prbs, uint32_t start_prb_idx = 0)
|
||
|
{
|
||
|
prb_interval max_interv;
|
||
|
do {
|
||
|
prb_interval interv = find_next_empty_interval(mask, start_prb_idx, mask.size());
|
||
|
if (interv.empty()) {
|
||
|
break;
|
||
|
}
|
||
|
if (interv.length() >= nof_prbs) {
|
||
|
max_interv.set(interv.start(), interv.start() + nof_prbs);
|
||
|
break;
|
||
|
}
|
||
|
if (interv.length() > max_interv.length()) {
|
||
|
max_interv = interv;
|
||
|
}
|
||
|
start_prb_idx = interv.stop() + 1;
|
||
|
} while (start_prb_idx < mask.size());
|
||
|
return max_interv;
|
||
|
}
|
||
|
|
||
|
} // namespace sched_nr_impl
|
||
|
} // namespace srsenb
|
||
|
|
||
|
#endif // SRSRAN_SCHED_NR_RB_H
|