mirror of https://github.com/PentHertz/srsLTE.git
created class that implements the scheduler transmit power control and PHR handling
This commit is contained in:
parent
788ed5ce70
commit
5865df39d1
|
@ -0,0 +1,134 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2020 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 SRSLTE_ACCUMULATORS_H
|
||||
#define SRSLTE_ACCUMULATORS_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
namespace srslte {
|
||||
|
||||
template <typename T>
|
||||
struct rolling_average {
|
||||
void push(T sample)
|
||||
{
|
||||
avg_ += (sample - avg_) / (count_ + 1);
|
||||
++count_;
|
||||
}
|
||||
T value() const { return count_ == 0 ? 0 : avg_; }
|
||||
uint32_t count() const { return count_; }
|
||||
|
||||
private:
|
||||
T avg_ = 0;
|
||||
uint32_t count_ = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct exp_average_fast_start {
|
||||
exp_average_fast_start(T alpha_, uint32_t start_size = 100) : alpha(alpha_), nof_left(start_size) {}
|
||||
void push(T sample)
|
||||
{
|
||||
if (nof_left-- > 0) {
|
||||
avg_ += (sample - avg_) / (count + 1);
|
||||
count++;
|
||||
} else {
|
||||
avg_ = (1 - alpha) * avg_ + alpha * sample;
|
||||
}
|
||||
}
|
||||
T value() const { return count == 0 ? 0 : avg_; }
|
||||
|
||||
private:
|
||||
T avg_ = 0;
|
||||
uint32_t count = 0;
|
||||
uint32_t nof_left;
|
||||
T alpha;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct sliding_window {
|
||||
sliding_window(uint32_t N, T val) : window(N, val) {}
|
||||
void push(T sample)
|
||||
{
|
||||
window[next_idx++] = sample;
|
||||
if (next_idx >= window.size()) {
|
||||
next_idx -= window.size();
|
||||
}
|
||||
}
|
||||
size_t size() const { return window.size(); }
|
||||
T& operator[](size_t i) { return window[i]; }
|
||||
const T& operator[](size_t i) const { return window[i]; }
|
||||
std::vector<T> window;
|
||||
size_t next_idx = 0;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T>
|
||||
struct sliding_sum {
|
||||
sliding_sum(uint32_t N) : window(N, 0) {}
|
||||
|
||||
void push(T sample) { window.push(sample); }
|
||||
T value() const
|
||||
{
|
||||
T ret = 0;
|
||||
for (size_t i = 0; i < window.size(); ++i) {
|
||||
ret += window[i];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
size_t size() const { return window.size(); }
|
||||
|
||||
private:
|
||||
detail::sliding_window<T> window;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct sliding_average {
|
||||
sliding_average(uint32_t N) : window(N, 0) {}
|
||||
void push(T sample) { window.push(sample); }
|
||||
T value() const { return window.value() / window.size(); }
|
||||
|
||||
private:
|
||||
sliding_sum<T> window;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct null_sliding_average {
|
||||
null_sliding_average(uint32_t N, T null_val = std::numeric_limits<T>::max()) :
|
||||
null_value_(null_val), window(N, null_val)
|
||||
{}
|
||||
void push(T sample) { window.push(sample); }
|
||||
void push_hole() { window.push(null_value_); }
|
||||
T value() const
|
||||
{
|
||||
T ret = 0;
|
||||
for (size_t i = 0; i < window.size(); ++i) {
|
||||
if (window[i] != null_value_) {
|
||||
ret += window[i];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
T null_value() const { return null_value_; }
|
||||
|
||||
private:
|
||||
T null_value_;
|
||||
detail::sliding_window<T> window;
|
||||
};
|
||||
|
||||
} // namespace srslte
|
||||
|
||||
#endif // SRSLTE_ACCUMULATORS_H
|
|
@ -65,6 +65,7 @@ public:
|
|||
|
||||
/* pusch configuration */
|
||||
srslte_pusch_hopping_cfg_t pusch_hopping_cfg;
|
||||
float target_ul_sinr;
|
||||
|
||||
/* prach configuration */
|
||||
uint32_t prach_config;
|
||||
|
@ -282,11 +283,11 @@ public:
|
|||
virtual int dl_cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi_value) = 0;
|
||||
|
||||
/* UL information */
|
||||
virtual int ul_crc_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, bool crc) = 0;
|
||||
virtual int ul_sr_info(uint32_t tti, uint16_t rnti) = 0;
|
||||
virtual int ul_bsr(uint16_t rnti, uint32_t lcg_id, uint32_t bsr) = 0;
|
||||
virtual int ul_phr(uint16_t rnti, int phr) = 0;
|
||||
virtual int ul_cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi, uint32_t ul_ch_code) = 0;
|
||||
virtual int ul_crc_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, bool crc) = 0;
|
||||
virtual int ul_sr_info(uint32_t tti, uint16_t rnti) = 0;
|
||||
virtual int ul_bsr(uint16_t rnti, uint32_t lcg_id, uint32_t bsr) = 0;
|
||||
virtual int ul_phr(uint16_t rnti, uint32_t enb_cc_idx, int phr) = 0;
|
||||
virtual int ul_snr_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, float snr, uint32_t ul_ch_code) = 0;
|
||||
|
||||
/* Run Scheduler for this tti */
|
||||
virtual int dl_sched(uint32_t tti, uint32_t enb_cc_idx, dl_sched_res_t& sched_result) = 0;
|
||||
|
|
|
@ -88,8 +88,8 @@ public:
|
|||
int ul_crc_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, bool crc) final;
|
||||
int ul_sr_info(uint32_t tti, uint16_t rnti) override;
|
||||
int ul_bsr(uint16_t rnti, uint32_t lcg_id, uint32_t bsr) final;
|
||||
int ul_phr(uint16_t rnti, int phr) final;
|
||||
int ul_cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi, uint32_t ul_ch_code) final;
|
||||
int ul_phr(uint16_t rnti, uint32_t enb_cc_idx, int phr) final;
|
||||
int ul_snr_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, float snr, uint32_t ul_ch_code) final;
|
||||
|
||||
int dl_sched(uint32_t tti, uint32_t enb_cc_idx, dl_sched_res_t& sched_result) final;
|
||||
int ul_sched(uint32_t tti, uint32_t enb_cc_idx, ul_sched_res_t& sched_result) final;
|
||||
|
@ -97,8 +97,6 @@ public:
|
|||
/* Custom functions
|
||||
*/
|
||||
void set_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) final;
|
||||
void tpc_inc(uint16_t rnti);
|
||||
void tpc_dec(uint16_t rnti);
|
||||
std::array<int, SRSLTE_MAX_CARRIERS> get_enb_ue_cc_map(uint16_t rnti) final;
|
||||
std::array<bool, SRSLTE_MAX_CARRIERS> get_scell_activation_mask(uint16_t rnti) final;
|
||||
int ul_buffer_add(uint16_t rnti, uint32_t lcid, uint32_t bytes) final;
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
#include <vector>
|
||||
|
||||
#include "sched_harq.h"
|
||||
#include "sched_lch.h"
|
||||
#include "sched_ue_ctrl/sched_lch.h"
|
||||
#include "sched_ue_ctrl/tpc.h"
|
||||
#include <bitset>
|
||||
#include <deque>
|
||||
|
||||
|
@ -67,6 +68,7 @@ struct cc_sched_ue {
|
|||
uint32_t max_mcs_dl = 28, max_mcs_ul = 28;
|
||||
uint32_t max_aggr_level = 3;
|
||||
int fixed_mcs_ul = 0, fixed_mcs_dl = 0;
|
||||
tpc tpc_fsm;
|
||||
|
||||
// Allowed DCI locations per per CFI and per subframe
|
||||
std::array<std::array<sched_dci_cce_t, 10>, 3> dci_locations = {};
|
||||
|
@ -115,10 +117,10 @@ public:
|
|||
|
||||
void dl_buffer_state(uint8_t lc_id, uint32_t tx_queue, uint32_t retx_queue);
|
||||
void ul_buffer_state(uint8_t lcg_id, uint32_t bsr);
|
||||
void ul_phr(int phr);
|
||||
void ul_phr(uint32_t enb_cc_idx, int phr);
|
||||
void mac_buffer_state(uint32_t ce_code, uint32_t nof_cmds);
|
||||
|
||||
void set_ul_cqi(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t cqi, uint32_t ul_ch_code);
|
||||
void set_ul_snr(tti_point tti_rx, uint32_t enb_cc_idx, float snr, uint32_t ul_ch_code);
|
||||
void set_dl_ri(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t ri);
|
||||
void set_dl_pmi(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t ri);
|
||||
void set_dl_cqi(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t cqi);
|
||||
|
@ -129,9 +131,6 @@ public:
|
|||
* Custom functions
|
||||
*******************************************************/
|
||||
|
||||
void tpc_inc();
|
||||
void tpc_dec();
|
||||
|
||||
const dl_harq_proc& get_dl_harq(uint32_t idx, uint32_t cc_idx) const;
|
||||
uint16_t get_rnti() const { return rnti; }
|
||||
std::pair<bool, uint32_t> get_active_cell_index(uint32_t enb_cc_idx) const;
|
||||
|
@ -252,15 +251,10 @@ private:
|
|||
bool sr = false;
|
||||
lch_ue_manager lch_handler;
|
||||
|
||||
int power_headroom = 0;
|
||||
uint32_t cqi_request_tti = 0;
|
||||
uint16_t rnti = 0;
|
||||
uint32_t max_msg3retx = 0;
|
||||
|
||||
/* User State */
|
||||
int next_tpc_pusch = 0;
|
||||
int next_tpc_pucch = 0;
|
||||
|
||||
bool phy_config_dedicated_enabled = false;
|
||||
|
||||
tti_point current_tti;
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2020 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 SRSLTE_TPC_H
|
||||
#define SRSLTE_TPC_H
|
||||
|
||||
#include "srslte/adt/accumulators.h"
|
||||
#include "srslte/common/common.h"
|
||||
|
||||
namespace srsenb {
|
||||
|
||||
/**
|
||||
* Class to handle TPC Commands sent to the UE.
|
||||
* The TPC value sent to the UE in each DCI is a result of:
|
||||
* - the difference between the target SINR and the windowed average of past UE UL SNR estimates
|
||||
* - subtracted by the sum of TPC values sent in the last TX_UL_DELAY milliseconds (i.e. 8ms), which the UE hasn't yet
|
||||
* applied
|
||||
*/
|
||||
class tpc
|
||||
{
|
||||
static constexpr size_t SNR_WINDOW_SIZE_MS = 8;
|
||||
|
||||
public:
|
||||
tpc(float target_snr_dB_ = -1.0) :
|
||||
target_snr_dB(target_snr_dB_),
|
||||
pusch_tpc_values(FDD_HARQ_DELAY_DL_MS + FDD_HARQ_DELAY_UL_MS),
|
||||
pucch_tpc_values(FDD_HARQ_DELAY_DL_MS + FDD_HARQ_DELAY_UL_MS),
|
||||
snr_avg(SNR_WINDOW_SIZE_MS)
|
||||
{
|
||||
pending_snr = snr_avg.null_value();
|
||||
}
|
||||
void set_cfg(float target_snr_dB_) { target_snr_dB = target_snr_dB_; }
|
||||
|
||||
void set_snr(float snr) { pending_snr = snr; }
|
||||
void set_phr(int phr_)
|
||||
{
|
||||
last_phr = phr_;
|
||||
|
||||
// compute and cache the max nof UL PRBs that avoids overflowing PHR
|
||||
max_prbs_cached = 1;
|
||||
for (int nof_prbs = 100; nof_prbs >= 0; --nof_prbs) {
|
||||
if (last_phr >= 10 * log10(nof_prbs)) {
|
||||
max_prbs_cached = last_phr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void new_tti()
|
||||
{
|
||||
if (target_snr_dB < 0) {
|
||||
return;
|
||||
}
|
||||
// Enqueue PUSCH/PUCCH TPC sent in last TTI (zero for both Delta_PUSCH/Delta_PUCCH=0 and TPC not sent)
|
||||
pusch_tpc_values.push(pending_pusch_tpc);
|
||||
pending_pusch_tpc = 0;
|
||||
pusch_tpc_values.push(pending_pucch_tpc);
|
||||
pending_pucch_tpc = 0;
|
||||
|
||||
// Enqueue pending SNR measurement
|
||||
snr_avg.push(pending_snr);
|
||||
pending_snr = snr_avg.null_value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called during DCI format0 encoding to set TPC command
|
||||
* @return accumulated TPC value {-3, -1, 0, 1, 3}
|
||||
*/
|
||||
int8_t encode_pusch_tpc()
|
||||
{
|
||||
if (target_snr_dB < 0) {
|
||||
return 0;
|
||||
}
|
||||
float diff = target_snr_dB - snr_avg.value();
|
||||
diff -= pusch_tpc_values.value();
|
||||
int8_t ret = 0;
|
||||
if (diff > 1) {
|
||||
ret = diff > 3 ? 3 : 1;
|
||||
} else if (diff <= -1) {
|
||||
ret = -1;
|
||||
}
|
||||
pending_pusch_tpc = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int8_t encode_pucch_tpc()
|
||||
{
|
||||
float diff = target_snr_dB - snr_avg.value();
|
||||
diff -= pucch_tpc_values.value();
|
||||
int8_t ret = 0;
|
||||
if (diff > 1) {
|
||||
ret = diff > 3 ? 3 : 1;
|
||||
} else if (diff <= -1) {
|
||||
ret = -1;
|
||||
}
|
||||
pending_pucch_tpc = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t max_ul_prbs() const { return max_prbs_cached; }
|
||||
|
||||
private:
|
||||
float target_snr_dB;
|
||||
srslte::null_sliding_average<float> snr_avg;
|
||||
srslte::sliding_sum<int> pusch_tpc_values, pucch_tpc_values;
|
||||
uint32_t max_prbs_cached = 100;
|
||||
int last_phr = 0;
|
||||
int pending_pusch_tpc = 0, pending_pucch_tpc = 0;
|
||||
float pending_snr = 0;
|
||||
};
|
||||
|
||||
} // namespace srsenb
|
||||
|
||||
#endif // SRSLTE_TPC_H
|
|
@ -54,7 +54,8 @@ public:
|
|||
|
||||
void start_ta() { ta_fsm.start(); };
|
||||
uint32_t set_ta_us(float ta_us) { return ta_fsm.push_value(ta_us); };
|
||||
uint32_t tick_ta_fsm() { return ta_fsm.tick(); };
|
||||
|
||||
void tic();
|
||||
|
||||
uint8_t* generate_pdu(uint32_t ue_cc_idx,
|
||||
uint32_t harq_pid,
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
add_subdirectory(schedulers)
|
||||
|
||||
set(SOURCES mac.cc ue.cc sched.cc sched_carrier.cc sched_grid.cc sched_harq.cc sched_ue.cc
|
||||
sched_lch.cc sched_interface_helpers.cc)
|
||||
sched_ue_ctrl/sched_lch.cc sched_interface_helpers.cc)
|
||||
add_library(srsenb_mac STATIC ${SOURCES} $<TARGET_OBJECTS:mac_schedulers>)
|
||||
|
||||
if(ENABLE_5GNR)
|
||||
|
|
|
@ -391,8 +391,7 @@ int mac::snr_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, float snr
|
|||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
uint32_t cqi = srslte_cqi_from_snr(snr);
|
||||
return scheduler.ul_cqi_info(tti_rx, rnti, enb_cc_idx, cqi, 0);
|
||||
return scheduler.ul_snr_info(tti_rx, rnti, enb_cc_idx, snr, 0);
|
||||
}
|
||||
|
||||
int mac::ta_info(uint32_t tti, uint16_t rnti, float ta_us)
|
||||
|
@ -843,12 +842,9 @@ int mac::get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res_list)
|
|||
|
||||
log_h->step(TTI_SUB(tti_tx_ul, FDD_HARQ_DELAY_UL_MS + FDD_HARQ_DELAY_DL_MS));
|
||||
|
||||
// Execute TA FSM
|
||||
// Execute UE FSMs (e.g. TA)
|
||||
for (auto& ue : ue_db) {
|
||||
uint32_t nof_ta_count = ue.second->tick_ta_fsm();
|
||||
if (nof_ta_count) {
|
||||
scheduler.dl_mac_buffer_state(ue.first, (uint32_t)srslte::dl_sch_lcid::TA_CMD, nof_ta_count);
|
||||
}
|
||||
ue.second->tic();
|
||||
}
|
||||
|
||||
for (uint32_t enb_cc_idx = 0; enb_cc_idx < cell_config.size(); enb_cc_idx++) {
|
||||
|
|
|
@ -313,9 +313,9 @@ int sched::dl_rach_info(uint32_t enb_cc_idx, dl_sched_rar_info_t rar_info)
|
|||
return carrier_schedulers[enb_cc_idx]->dl_rach_info(rar_info);
|
||||
}
|
||||
|
||||
int sched::ul_cqi_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi, uint32_t ul_ch_code)
|
||||
int sched::ul_snr_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, float snr, uint32_t ul_ch_code)
|
||||
{
|
||||
return ue_db_access(rnti, [&](sched_ue& ue) { ue.set_ul_cqi(tti_point{tti_rx}, enb_cc_idx, cqi, ul_ch_code); });
|
||||
return ue_db_access(rnti, [&](sched_ue& ue) { ue.set_ul_snr(tti_point{tti_rx}, enb_cc_idx, snr, ul_ch_code); });
|
||||
}
|
||||
|
||||
int sched::ul_bsr(uint16_t rnti, uint32_t lcg_id, uint32_t bsr)
|
||||
|
@ -328,10 +328,10 @@ int sched::ul_buffer_add(uint16_t rnti, uint32_t lcid, uint32_t bytes)
|
|||
return ue_db_access(rnti, [lcid, bytes](sched_ue& ue) { ue.ul_buffer_add(lcid, bytes); });
|
||||
}
|
||||
|
||||
int sched::ul_phr(uint16_t rnti, int phr)
|
||||
int sched::ul_phr(uint16_t rnti, uint32_t enb_cc_idx, int phr)
|
||||
{
|
||||
return ue_db_access(
|
||||
rnti, [phr](sched_ue& ue) { ue.ul_phr(phr); }, __PRETTY_FUNCTION__);
|
||||
rnti, [enb_cc_idx, phr](sched_ue& ue) { ue.ul_phr(enb_cc_idx, phr); }, __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
int sched::ul_sr_info(uint32_t tti, uint16_t rnti)
|
||||
|
@ -346,18 +346,6 @@ void sched::set_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs)
|
|||
carrier_schedulers[0]->set_dl_tti_mask(tti_mask, nof_sfs);
|
||||
}
|
||||
|
||||
void sched::tpc_inc(uint16_t rnti)
|
||||
{
|
||||
ue_db_access(
|
||||
rnti, [](sched_ue& ue) { ue.tpc_inc(); }, __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
void sched::tpc_dec(uint16_t rnti)
|
||||
{
|
||||
ue_db_access(
|
||||
rnti, [](sched_ue& ue) { ue.tpc_dec(); }, __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
std::array<int, SRSLTE_MAX_CARRIERS> sched::get_enb_ue_cc_map(uint16_t rnti)
|
||||
{
|
||||
std::array<int, SRSLTE_MAX_CARRIERS> ret{};
|
||||
|
|
|
@ -211,8 +211,6 @@ void sched_ue::reset()
|
|||
{
|
||||
cfg = {};
|
||||
sr = false;
|
||||
next_tpc_pusch = 1;
|
||||
next_tpc_pucch = 1;
|
||||
phy_config_dedicated_enabled = false;
|
||||
cqi_request_tti = 0;
|
||||
carriers.clear();
|
||||
|
@ -229,6 +227,7 @@ void sched_ue::new_subframe(tti_point tti_rx, uint32_t enb_cc_idx)
|
|||
current_tti = tti_rx;
|
||||
lch_handler.new_tti();
|
||||
}
|
||||
carriers.at(enb_ue_cc_idx_map[enb_cc_idx]).tpc_fsm.new_tti();
|
||||
}
|
||||
|
||||
/// sanity check the UE CC configuration
|
||||
|
@ -296,9 +295,9 @@ void sched_ue::ul_buffer_add(uint8_t lcid, uint32_t bytes)
|
|||
lch_handler.ul_buffer_add(lcid, bytes);
|
||||
}
|
||||
|
||||
void sched_ue::ul_phr(int phr)
|
||||
void sched_ue::ul_phr(uint32_t enb_cc_idx, int phr)
|
||||
{
|
||||
power_headroom = phr;
|
||||
carriers[enb_ue_cc_idx_map[enb_cc_idx]].tpc_fsm.set_phr(phr);
|
||||
}
|
||||
|
||||
void sched_ue::dl_buffer_state(uint8_t lc_id, uint32_t tx_queue, uint32_t retx_queue)
|
||||
|
@ -465,33 +464,18 @@ void sched_ue::set_dl_cqi(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t cqi)
|
|||
}
|
||||
}
|
||||
|
||||
void sched_ue::set_ul_cqi(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t cqi, uint32_t ul_ch_code)
|
||||
void sched_ue::set_ul_snr(tti_point tti_rx, uint32_t enb_cc_idx, float snr, uint32_t ul_ch_code)
|
||||
{
|
||||
cc_sched_ue* c = find_ue_carrier(enb_cc_idx);
|
||||
if (c != nullptr and c->cc_state() != cc_st::idle) {
|
||||
c->ul_cqi = cqi;
|
||||
c->tpc_fsm.set_snr(snr);
|
||||
c->ul_cqi = srslte_cqi_from_snr(snr);
|
||||
c->ul_cqi_tti_rx = tti_rx;
|
||||
} else {
|
||||
log_h->warning("Received SNR info for invalid cell index %d\n", enb_cc_idx);
|
||||
}
|
||||
}
|
||||
|
||||
void sched_ue::tpc_inc()
|
||||
{
|
||||
if (power_headroom > 0) {
|
||||
next_tpc_pusch = 3;
|
||||
next_tpc_pucch = 3;
|
||||
}
|
||||
log_h->info("SCHED: Set TCP=%d for rnti=0x%x\n", next_tpc_pucch, rnti);
|
||||
}
|
||||
|
||||
void sched_ue::tpc_dec()
|
||||
{
|
||||
next_tpc_pusch = 0;
|
||||
next_tpc_pucch = 0;
|
||||
log_h->info("SCHED: Set TCP=%d for rnti=0x%x\n", next_tpc_pucch, rnti);
|
||||
}
|
||||
|
||||
/*******************************************************
|
||||
*
|
||||
* Functions used to generate DCI grants
|
||||
|
@ -613,8 +597,7 @@ int sched_ue::generate_format1(uint32_t pid,
|
|||
dci->tb[0].rv = sched_utils::get_rvidx(h->nof_retx(0));
|
||||
dci->tb[0].ndi = h->get_ndi(0);
|
||||
|
||||
dci->tpc_pucch = (uint8_t)next_tpc_pucch;
|
||||
next_tpc_pucch = 1;
|
||||
dci->tpc_pucch = carriers[ue_cc_idx].tpc_fsm.encode_pucch_tpc();
|
||||
data->tbs[0] = (uint32_t)tbs;
|
||||
data->tbs[1] = 0;
|
||||
}
|
||||
|
@ -742,8 +725,7 @@ int sched_ue::generate_format2a(uint32_t pid,
|
|||
dci->rnti = rnti;
|
||||
dci->ue_cc_idx = ue_cc_idx;
|
||||
dci->pid = h->get_id();
|
||||
dci->tpc_pucch = (uint8_t)next_tpc_pucch;
|
||||
next_tpc_pucch = 1;
|
||||
dci->tpc_pucch = carriers[ue_cc_idx].tpc_fsm.encode_pucch_tpc();
|
||||
|
||||
int ret = data->tbs[0] + data->tbs[1];
|
||||
return ret;
|
||||
|
@ -850,8 +832,7 @@ int sched_ue::generate_format0(sched_interface::ul_sched_data_t* data,
|
|||
dci->tb.ndi = h->get_ndi(0);
|
||||
dci->cqi_request = cqi_request;
|
||||
dci->freq_hop_fl = srslte_dci_ul_t::SRSLTE_RA_PUSCH_HOP_DISABLED;
|
||||
dci->tpc_pusch = next_tpc_pusch;
|
||||
next_tpc_pusch = 1;
|
||||
dci->tpc_pusch = carriers[ue_cc_idx].tpc_fsm.encode_pusch_tpc();
|
||||
|
||||
dci->type2_alloc.riv = srslte_ra_type2_to_riv(alloc.length(), alloc.start(), cell.nof_prb);
|
||||
|
||||
|
@ -1328,7 +1309,8 @@ cc_sched_ue::cc_sched_ue(const sched_interface::ue_cfg_t& cfg_,
|
|||
log_h(srslte::logmap::get("MAC ")),
|
||||
ue_cc_idx(ue_cc_idx_),
|
||||
last_tti(current_tti),
|
||||
harq_ent(SCHED_MAX_HARQ_PROC, SCHED_MAX_HARQ_PROC)
|
||||
harq_ent(SCHED_MAX_HARQ_PROC, SCHED_MAX_HARQ_PROC),
|
||||
tpc_fsm(cell_cfg_.cfg.target_ul_sinr)
|
||||
{
|
||||
dl_cqi_rx = false;
|
||||
dl_cqi = (ue_cc_idx == 0) ? cell_params->cfg.initial_dl_cqi : 0;
|
||||
|
@ -1530,8 +1512,9 @@ uint32_t cc_sched_ue::get_required_prb_ul(uint32_t req_bytes)
|
|||
|
||||
// find nof prbs that lead to a tbs just above req_bytes
|
||||
int target_tbs = req_bytes + 4;
|
||||
std::tuple<uint32_t, int, uint32_t, int> ret = false_position_method(
|
||||
1u, cell_params->nof_prb(), target_tbs, compute_tbs_approx, [](int y) { return y == SRSLTE_ERROR; });
|
||||
uint32_t max_prbs = std::min(tpc_fsm.max_ul_prbs(), cell_params->nof_prb());
|
||||
std::tuple<uint32_t, int, uint32_t, int> ret =
|
||||
false_position_method(1u, max_prbs, target_tbs, compute_tbs_approx, [](int y) { return y == SRSLTE_ERROR; });
|
||||
uint32_t req_prbs = std::get<2>(ret);
|
||||
while (!srslte_dft_precoding_valid_prb(req_prbs) && req_prbs < cell_params->nof_prb()) {
|
||||
req_prbs++;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "srsenb/hdr/stack/mac/sched_lch.h"
|
||||
#include "srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h"
|
||||
#include "srsenb/hdr/stack/mac/sched_common.h"
|
||||
#include "srslte/common/log_helper.h"
|
||||
|
|
@ -347,7 +347,8 @@ bool ue::process_ce(srslte::sch_subh* subh)
|
|||
switch (subh->ul_sch_ce_type()) {
|
||||
case srslte::ul_sch_lcid::PHR_REPORT:
|
||||
phr = subh->get_phr();
|
||||
sched->ul_phr(rnti, (int)phr);
|
||||
// TODO: Add enb_cc_idx
|
||||
sched->ul_phr(rnti, 0, (int)phr);
|
||||
metrics_phr(phr);
|
||||
break;
|
||||
case srslte::ul_sch_lcid::CRNTI:
|
||||
|
@ -585,4 +586,13 @@ void ue::metrics_cnt()
|
|||
metrics.nof_tti++;
|
||||
}
|
||||
|
||||
void ue::tic()
|
||||
{
|
||||
// Check for pending TA commands
|
||||
uint32_t nof_ta_count = ta_fsm.tick();
|
||||
if (nof_ta_count) {
|
||||
sched->dl_mac_buffer_state(rnti, (uint32_t)srslte::dl_sch_lcid::TA_CMD, nof_ta_count);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace srsenb
|
||||
|
|
|
@ -91,8 +91,8 @@ int ue_ctxt_test::new_tti(sched* sched_ptr, srslte::tti_point tti_rx)
|
|||
for (auto& cc : active_ccs) {
|
||||
sched_ptr->dl_cqi_info(
|
||||
tti_rx.to_uint(), rnti, cc.enb_cc_idx, std::uniform_int_distribution<uint32_t>{5, 24}(get_rand_gen()));
|
||||
sched_ptr->ul_cqi_info(
|
||||
tti_rx.to_uint(), rnti, cc.enb_cc_idx, std::uniform_int_distribution<uint32_t>{5, 24}(get_rand_gen()), 0);
|
||||
sched_ptr->ul_snr_info(
|
||||
tti_rx.to_uint(), rnti, cc.enb_cc_idx, std::uniform_int_distribution<uint32_t>{5, 40}(get_rand_gen()), 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue