nr: slot value that handles wrapping around

master
Francisco Paisana 3 years ago
parent 5b31fa72d3
commit a0a1af9d0f

@ -0,0 +1,170 @@
/**
*
* \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_SLOT_POINT_H
#define SRSRAN_SLOT_POINT_H
#include "srsran/adt/interval.h"
#include "srsran/common/srsran_assert.h"
namespace srsran {
class slot_point
{
uint32_t numerology_ : 3;
uint32_t count_ : 29;
const static uint8_t NOF_NUMEROLOGIES = 5;
const static uint16_t NOF_SFNS = 1024;
const static uint8_t NOF_SUBFRAMES_PER_FRAME = 10;
uint32_t nof_slots_per_hf() const { return nof_slots_per_frame() * NOF_SFNS; }
public:
slot_point() : numerology_(NOF_NUMEROLOGIES), count_(0) {}
slot_point(uint8_t numerology, uint16_t sfn_val, uint8_t slot) :
numerology_(numerology), count_(slot + sfn_val * nof_slots_per_frame())
{
srsran_assert(numerology < NOF_NUMEROLOGIES, "Invalid numerology idx=%d passed", (int)numerology);
srsran_assert(sfn_val < NOF_SFNS, "Invalid SFN=%d provided", (int)sfn_val);
srsran_assert(slot < nof_slots_per_frame(),
"Slot index=%d exceeds maximum number of slots=%d",
(int)slot,
(int)nof_slots_per_frame());
}
bool valid() const { return numerology_ < NOF_NUMEROLOGIES; }
uint8_t nof_slots_per_subframe() const { return 1U << numerology_; }
uint8_t nof_slots_per_frame() const { return nof_slots_per_subframe() * NOF_SUBFRAMES_PER_FRAME; }
uint16_t sfn() const { return count_ / nof_slots_per_frame(); }
uint16_t sf_idx() const { return slot_idx() / nof_slots_per_subframe(); }
uint8_t slot_idx() const { return count_ % nof_slots_per_frame(); }
uint8_t numerology_idx() const { return numerology_; }
uint32_t to_uint() const { return count_; }
explicit operator uint32_t() const { return count_; }
void clear() { numerology_ = NOF_NUMEROLOGIES; }
// operators
bool operator==(const slot_point& other) const
{
srsran_assert(numerology_idx() == other.numerology_idx(), "Comparing slots of different numerologies");
return other.count_ == count_;
}
bool operator!=(const slot_point& other) const { return not(*this == other); }
bool operator<(const slot_point& other) const
{
srsran_assert(numerology_idx() == other.numerology_idx(), "Comparing slots of different numerologies");
int a = static_cast<int>(other.count_) - static_cast<int>(count_);
if (a > 0) {
return (a < (int)nof_slots_per_hf() / 2);
}
return (a < -(int)nof_slots_per_hf() / 2);
}
bool operator<=(const slot_point& other) const { return (*this == other) or (*this < other); }
bool operator>=(const slot_point& other) const { return not(*this < other); }
bool operator>(const slot_point& other) const { return (*this != other) and *this >= other; }
int32_t operator-(const slot_point& other) const
{
int a = static_cast<int>(count_) - static_cast<int>(other.count_);
if (a >= (int)nof_slots_per_hf() / 2) {
return a - nof_slots_per_hf();
}
if (a < -(int)nof_slots_per_hf() / 2) {
return a + nof_slots_per_hf();
}
return a;
}
slot_point& operator++()
{
count_++;
if (count_ == nof_slots_per_hf()) {
count_ = 0;
}
return *this;
}
slot_point operator++(int)
{
slot_point ret{*this};
this-> operator++();
return ret;
}
slot_point& operator+=(uint32_t jump)
{
count_ = (count_ + jump) % nof_slots_per_hf();
return *this;
}
slot_point& operator-=(uint32_t jump)
{
int a = (static_cast<int>(count_) - static_cast<int>(jump)) % static_cast<int>(nof_slots_per_hf());
if (a < 0) {
a += nof_slots_per_hf();
}
count_ = a;
return *this;
}
bool is_in_interval(slot_point begin, slot_point end) const { return (*this >= begin and *this < end); }
};
inline slot_point operator+(slot_point slot, uint32_t jump)
{
slot += jump;
return slot;
}
inline slot_point operator+(uint32_t jump, slot_point slot)
{
slot += jump;
return slot;
}
inline slot_point operator-(slot_point slot, uint32_t jump)
{
slot -= jump;
return slot;
}
inline slot_point max(slot_point s1, slot_point s2)
{
return s1 > s2 ? s1 : s2;
}
inline slot_point min(slot_point s1, slot_point s2)
{
return s1 < s2 ? s1 : s2;
}
using slot_interval = srsran::interval<slot_point>;
} // namespace srsran
namespace fmt {
template <>
struct formatter<srsran::slot_point> {
template <typename ParseContext>
auto parse(ParseContext& ctx) -> decltype(ctx.begin())
{
return ctx.begin();
}
template <typename FormatContext>
auto format(srsran::slot_point slot, FormatContext& ctx) -> decltype(std::declval<FormatContext>().out())
{
return format_to(ctx.out(), "{}/{}", slot.sfn(), slot.slot_idx());
}
};
} // namespace fmt
namespace srsenb {
using slot_point = srsran::slot_point;
}
#endif // SRSRAN_SLOT_POINT_H

@ -10,6 +10,7 @@
*
*/
#include "srsran/common/slot_point.h"
#include "srsran/common/test_common.h"
#include "srsran/common/tti_point.h"
@ -66,9 +67,53 @@ int test_tti_type()
return SRSRAN_SUCCESS;
}
void test_nr_slot_type()
{
// TEST: constructors
srsran::slot_point slot1;
TESTASSERT(not slot1.valid());
srsran::slot_point slot2{0, 1, 5};
TESTASSERT(slot2.valid() and slot2.numerology_idx() == 0 and slot2.slot_idx() == 5 and slot2.sf_idx() == 5 and
slot2.sfn() == 1);
srsran::slot_point slot3{slot2};
TESTASSERT(slot3 == slot2);
// TEST: comparison and difference operators
slot1 = srsran::slot_point{0, 1, 5};
slot2 = srsran::slot_point{0, 1, 5};
TESTASSERT(slot1 == slot2 and slot1 <= slot2 and slot1 >= slot2);
slot1++;
TESTASSERT(slot1 != slot2 and slot1 >= slot2 and slot1 > slot2 and slot2 < slot1 and slot2 <= slot1);
TESTASSERT(slot1 - slot2 == 1 and slot2 - slot1 == -1);
slot1 = srsran::slot_point{0, 2, 5};
TESTASSERT(slot1 != slot2 and slot1 >= slot2 and slot1 > slot2 and slot2 < slot1 and slot2 <= slot1);
TESTASSERT(slot1 - slot2 == 10 and slot2 - slot1 == -10);
slot1 = srsran::slot_point{0, 1023, 5};
TESTASSERT(slot1 != slot2 and slot1 <= slot2 and slot1 < slot2 and slot2 > slot1 and slot2 >= slot1);
TESTASSERT(slot1 - slot2 == -20 and slot2 - slot1 == 20);
// TEST: increment/decrement operators
slot1 = srsran::slot_point{0, 1, 5};
slot2 = srsran::slot_point{0, 1, 5};
TESTASSERT(slot1++ == slot2);
TESTASSERT(slot2 + 1 == slot1);
TESTASSERT(++slot2 == slot1);
slot1 = srsran::slot_point{0, 1, 5};
slot2 = srsran::slot_point{0, 1, 5};
TESTASSERT(slot1 - 100 == slot2 - 100);
TESTASSERT(((slot1 - 100000) + 100000) == slot1);
TESTASSERT((slot1 - 10240) == slot1);
TESTASSERT((slot1 - 100).slot_idx() == 5 and (slot1 - 100).sfn() == 1015);
TESTASSERT(((slot1 - 100) + 100) == slot1);
TESTASSERT(((slot1 - 1) + 1) == slot1);
fmt::print("[ {}]", slot1);
}
int main()
{
srslog::init();
TESTASSERT(test_tti_type() == SRSRAN_SUCCESS);
test_tti_type();
test_nr_slot_type();
return 0;
}

Loading…
Cancel
Save