mirror of https://github.com/PentHertz/srsLTE.git
move sched params and sched helper methods to sched_helpers.h/cc files. Removed place in the scheduler where the mcs is increased forcefully to avoid segmentation
This commit is contained in:
parent
920e15c1a5
commit
b4861bc59a
|
@ -26,28 +26,6 @@
|
|||
|
||||
namespace srsenb {
|
||||
|
||||
namespace sched_utils {
|
||||
|
||||
inline bool is_in_tti_interval(uint32_t tti, uint32_t tti1, uint32_t tti2)
|
||||
{
|
||||
tti %= 10240;
|
||||
tti1 %= 10240;
|
||||
tti2 %= 10240;
|
||||
if (tti1 <= tti2) {
|
||||
return tti >= tti1 and tti <= tti2;
|
||||
}
|
||||
return tti >= tti1 or tti <= tti2;
|
||||
}
|
||||
|
||||
} // namespace sched_utils
|
||||
|
||||
/* Caution: User addition (ue_cfg) and removal (ue_rem) are not thread-safe
|
||||
* Rest of operations are thread-safe
|
||||
*
|
||||
* The subclass sched_ue is thread-safe so that access to shared variables like buffer states
|
||||
* from scheduler thread and other threads is protected for each individual user.
|
||||
*/
|
||||
|
||||
class sched : public sched_interface
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -35,7 +35,7 @@ struct sched_dci_cce_t {
|
|||
uint32_t nof_loc[4]; ///< Number of possible CCE locations for each aggregation level index
|
||||
};
|
||||
|
||||
//! structs to bundle together all the sched arguments, and share them with all the sched sub-components
|
||||
/// structs to bundle together all the sched arguments, and share them with all the sched sub-components
|
||||
class sched_cell_params_t
|
||||
{
|
||||
struct regs_deleter {
|
||||
|
@ -86,47 +86,6 @@ struct prb_interval : public srslte::interval<uint32_t> {
|
|||
static prb_interval riv_to_prbs(uint32_t riv, uint32_t nof_prbs, int nof_vrbs = -1);
|
||||
};
|
||||
|
||||
/***********************
|
||||
* Helper Functions
|
||||
**********************/
|
||||
|
||||
namespace sched_utils {
|
||||
|
||||
inline uint32_t aggr_level(uint32_t aggr_idx)
|
||||
{
|
||||
return 1u << aggr_idx;
|
||||
}
|
||||
|
||||
//! Obtain rvidx from nof retxs. This value is stored in DCI
|
||||
inline uint32_t get_rvidx(uint32_t retx_idx)
|
||||
{
|
||||
const static uint32_t rv_idx[4] = {0, 2, 3, 1};
|
||||
return rv_idx[retx_idx % 4];
|
||||
}
|
||||
|
||||
//! Obtain nof retxs from rvidx.
|
||||
inline uint32_t get_nof_retx(uint32_t rv_idx)
|
||||
{
|
||||
const static uint32_t nof_retxs[4] = {0, 3, 1, 2};
|
||||
return nof_retxs[rv_idx % 4];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate possible CCE locations a user can use to allocate DCIs
|
||||
* @param regs Regs data for the given cell configuration
|
||||
* @param location Result of the CCE location computation.
|
||||
* @param cfi Number of control symbols used for the PDCCH
|
||||
* @param sf_idx subframe index specific to the tx TTI (relevant only for data and RAR transmissions)
|
||||
* @param rnti identity of the user (invalid RNTI for RAR and BC transmissions)
|
||||
*/
|
||||
void generate_cce_location(srslte_regs_t* regs,
|
||||
sched_dci_cce_t* location,
|
||||
uint32_t cfi,
|
||||
uint32_t sf_idx = 0,
|
||||
uint16_t rnti = SRSLTE_INVALID_RNTI);
|
||||
|
||||
} // namespace sched_utils
|
||||
|
||||
} // namespace srsenb
|
||||
|
||||
#endif // SRSLTE_SCHED_COMMON_H
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
*
|
||||
* \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_SCHED_HELPERS_H
|
||||
#define SRSLTE_SCHED_HELPERS_H
|
||||
|
||||
#include "srsenb/hdr/stack/mac/sched_common.h"
|
||||
#include "srslte/common/logmap.h"
|
||||
#include "srslte/interfaces/sched_interface.h"
|
||||
|
||||
namespace srsenb {
|
||||
|
||||
inline uint32_t aggr_level(uint32_t aggr_idx)
|
||||
{
|
||||
return 1u << aggr_idx;
|
||||
}
|
||||
|
||||
/// Obtain rvidx from nof retxs. This value is stored in DCI
|
||||
inline uint32_t get_rvidx(uint32_t retx_idx)
|
||||
{
|
||||
const static uint32_t rv_idx[4] = {0, 2, 3, 1};
|
||||
return rv_idx[retx_idx % 4];
|
||||
}
|
||||
|
||||
/// Obtain nof retxs from rvidx.
|
||||
inline uint32_t get_nof_retx(uint32_t rv_idx)
|
||||
{
|
||||
const static uint32_t nof_retxs[4] = {0, 3, 1, 2};
|
||||
return nof_retxs[rv_idx % 4];
|
||||
}
|
||||
|
||||
void log_dl_cc_results(srslte::log_ref log_h, uint32_t enb_cc_idx, const sched_interface::dl_sched_res_t& result);
|
||||
|
||||
/**
|
||||
* Generate possible CCE locations a user can use to allocate DCIs
|
||||
* @param regs Regs data for the given cell configuration
|
||||
* @param location Result of the CCE location computation.
|
||||
* @param cfi Number of control symbols used for the PDCCH
|
||||
* @param sf_idx subframe index specific to the tx TTI (relevant only for data and RAR transmissions)
|
||||
* @param rnti identity of the user (invalid RNTI for RAR and BC transmissions)
|
||||
*/
|
||||
void generate_cce_location(srslte_regs_t* regs,
|
||||
sched_dci_cce_t* location,
|
||||
uint32_t cfi,
|
||||
uint32_t sf_idx = 0,
|
||||
uint16_t rnti = SRSLTE_INVALID_RNTI);
|
||||
|
||||
} // namespace srsenb
|
||||
|
||||
#endif // SRSLTE_SCHED_HELPERS_H
|
|
@ -1,25 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* \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_SCHED_INTERFACE_HELPERS_H
|
||||
#define SRSLTE_SCHED_INTERFACE_HELPERS_H
|
||||
|
||||
#include "srslte/common/logmap.h"
|
||||
#include "srslte/interfaces/sched_interface.h"
|
||||
|
||||
namespace srsenb {
|
||||
|
||||
void log_dl_cc_results(srslte::log_ref log_h, uint32_t enb_cc_idx, const sched_interface::dl_sched_res_t& result);
|
||||
|
||||
}
|
||||
|
||||
#endif // SRSLTE_SCHED_INTERFACE_HELPERS_H
|
|
@ -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_ue_ctrl/sched_lch.cc sched_interface_helpers.cc)
|
||||
sched_ue_ctrl/sched_lch.cc sched_helpers.cc)
|
||||
add_library(srsenb_mac STATIC ${SOURCES} $<TARGET_OBJECTS:mac_schedulers>)
|
||||
|
||||
if(ENABLE_5GNR)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "srsenb/hdr/stack/mac/sched.h"
|
||||
#include "srsenb/hdr/stack/mac/sched_carrier.h"
|
||||
#include "srsenb/hdr/stack/mac/sched_helpers.h"
|
||||
#include "srslte/common/logmap.h"
|
||||
#include "srslte/srslte.h"
|
||||
|
||||
|
@ -25,103 +26,6 @@ using srslte::tti_point;
|
|||
|
||||
namespace srsenb {
|
||||
|
||||
namespace sched_utils {
|
||||
|
||||
uint32_t tti_subtract(uint32_t tti1, uint32_t tti2)
|
||||
{
|
||||
return TTI_SUB(tti1, tti2);
|
||||
}
|
||||
|
||||
uint32_t max_tti(uint32_t tti1, uint32_t tti2)
|
||||
{
|
||||
return ((tti1 - tti2) > 10240 / 2) ? SRSLTE_MIN(tti1, tti2) : SRSLTE_MAX(tti1, tti2);
|
||||
}
|
||||
|
||||
} // namespace sched_utils
|
||||
|
||||
/*******************************************************
|
||||
* Sched Params
|
||||
*******************************************************/
|
||||
|
||||
bool sched_cell_params_t::set_cfg(uint32_t enb_cc_idx_,
|
||||
const sched_interface::cell_cfg_t& cfg_,
|
||||
const sched_interface::sched_args_t& sched_args)
|
||||
{
|
||||
enb_cc_idx = enb_cc_idx_;
|
||||
cfg = cfg_;
|
||||
sched_cfg = &sched_args;
|
||||
|
||||
// Basic cell config checks
|
||||
if (cfg.si_window_ms == 0) {
|
||||
Error("SCHED: Invalid si-window length 0 ms\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool invalid_prach;
|
||||
if (cfg.cell.nof_prb == 6) {
|
||||
// PUCCH has to allow space for Msg3
|
||||
if (cfg.nrb_pucch > 1) {
|
||||
Console("Invalid PUCCH configuration: nrb_pucch=%d does not allow space for Msg3 transmission..\n",
|
||||
cfg.nrb_pucch);
|
||||
return false;
|
||||
}
|
||||
// PRACH has to fit within the PUSCH+PUCCH space
|
||||
invalid_prach = cfg.prach_freq_offset + 6 > cfg.cell.nof_prb;
|
||||
} else {
|
||||
// PRACH has to fit within the PUSCH space
|
||||
invalid_prach = (cfg.prach_freq_offset + 6) > (cfg.cell.nof_prb - cfg.nrb_pucch) or
|
||||
((int)cfg.prach_freq_offset < cfg.nrb_pucch);
|
||||
}
|
||||
if (invalid_prach) {
|
||||
Error("Invalid PRACH configuration: frequency offset=%d outside bandwidth limits\n", cfg.prach_freq_offset);
|
||||
Console("Invalid PRACH configuration: frequency offset=%d outside bandwidth limits\n", cfg.prach_freq_offset);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set derived sched parameters
|
||||
|
||||
// init regs
|
||||
regs.reset(new srslte_regs_t{});
|
||||
if (srslte_regs_init(regs.get(), cfg.cell) != SRSLTE_SUCCESS) {
|
||||
Error("Getting DCI locations\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compute Common locations for DCI for each CFI
|
||||
for (uint32_t cfix = 0; cfix < pdcch_grid_t::MAX_CFI; cfix++) {
|
||||
sched_utils::generate_cce_location(regs.get(), &common_locations[cfix], cfix + 1);
|
||||
}
|
||||
if (common_locations[sched_cfg->max_nof_ctrl_symbols - 1].nof_loc[2] == 0) {
|
||||
Error("SCHED: Current cfi=%d is not valid for broadcast (check scheduler.max_nof_ctrl_symbols in conf file).\n",
|
||||
sched_cfg->max_nof_ctrl_symbols);
|
||||
Console("SCHED: Current cfi=%d is not valid for broadcast (check scheduler.max_nof_ctrl_symbols in conf file).\n",
|
||||
sched_cfg->max_nof_ctrl_symbols);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compute UE locations for RA-RNTI
|
||||
for (uint32_t cfi = 0; cfi < 3; cfi++) {
|
||||
for (uint32_t sf_idx = 0; sf_idx < 10; sf_idx++) {
|
||||
sched_utils::generate_cce_location(regs.get(), &rar_locations[cfi][sf_idx], cfi + 1, sf_idx);
|
||||
}
|
||||
}
|
||||
|
||||
// precompute nof cces in PDCCH for each CFI
|
||||
for (uint32_t cfix = 0; cfix < nof_cce_table.size(); ++cfix) {
|
||||
int ret = srslte_regs_pdcch_ncce(regs.get(), cfix + 1);
|
||||
if (ret < 0) {
|
||||
Error("SCHED: Failed to calculate the number of CCEs in the PDCCH\n");
|
||||
return false;
|
||||
}
|
||||
nof_cce_table[cfix] = (uint32_t)ret;
|
||||
}
|
||||
|
||||
P = srslte_ra_type0_P(cfg.cell.nof_prb);
|
||||
nof_rbgs = srslte::ceil_div(cfg.cell.nof_prb, P);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*******************************************************
|
||||
*
|
||||
* Initialization and sched configuration functions
|
||||
|
@ -470,87 +374,4 @@ int sched::ue_db_access(uint16_t rnti, Func f, const char* func_name)
|
|||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************
|
||||
*
|
||||
* Helper functions and common data types
|
||||
*
|
||||
*******************************************************/
|
||||
|
||||
void sched_cell_params_t::regs_deleter::operator()(srslte_regs_t* p)
|
||||
{
|
||||
if (p != nullptr) {
|
||||
srslte_regs_free(p);
|
||||
delete p;
|
||||
}
|
||||
}
|
||||
|
||||
rbg_interval rbg_interval::prbs_to_rbgs(const prb_interval& prbs, uint32_t P)
|
||||
{
|
||||
return rbg_interval{srslte::ceil_div(prbs.start(), P), srslte::ceil_div(prbs.stop(), P)};
|
||||
}
|
||||
|
||||
prb_interval prb_interval::rbgs_to_prbs(const rbg_interval& rbgs, uint32_t P)
|
||||
{
|
||||
return prb_interval{rbgs.start() * P, rbgs.stop() * P};
|
||||
}
|
||||
|
||||
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;
|
||||
srslte_ra_type2_from_riv(riv, &l_crb, &rb_start, nof_prbs, (uint32_t)nof_vrbs);
|
||||
return {rb_start, rb_start + l_crb};
|
||||
}
|
||||
|
||||
namespace sched_utils {
|
||||
|
||||
void generate_cce_location(srslte_regs_t* regs_,
|
||||
sched_dci_cce_t* location,
|
||||
uint32_t cfi,
|
||||
uint32_t sf_idx,
|
||||
uint16_t rnti)
|
||||
{
|
||||
*location = {};
|
||||
|
||||
srslte_dci_location_t loc[64];
|
||||
uint32_t nloc = 0;
|
||||
if (rnti == 0) {
|
||||
nloc = srslte_pdcch_common_locations_ncce(srslte_regs_pdcch_ncce(regs_, cfi), loc, 64);
|
||||
} else {
|
||||
nloc = srslte_pdcch_ue_locations_ncce(srslte_regs_pdcch_ncce(regs_, cfi), loc, 64, sf_idx, rnti);
|
||||
}
|
||||
|
||||
// Save to different format
|
||||
for (uint32_t i = 0; i < nloc; i++) {
|
||||
uint32_t l = loc[i].L;
|
||||
location->cce_start[l][location->nof_loc[l]] = loc[i].ncce;
|
||||
location->nof_loc[l]++;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sched_utils
|
||||
|
||||
} // namespace srsenb
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
*/
|
||||
|
||||
#include "srsenb/hdr/stack/mac/sched_carrier.h"
|
||||
#include "srsenb/hdr/stack/mac/sched_interface_helpers.h"
|
||||
#include "srsenb/hdr/stack/mac/sched_helpers.h"
|
||||
#include "srsenb/hdr/stack/mac/schedulers/sched_time_pf.h"
|
||||
#include "srsenb/hdr/stack/mac/schedulers/sched_time_rr.h"
|
||||
#include "srslte/common/logmap.h"
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
|
||||
#include "srsenb/hdr/stack/mac/sched_grid.h"
|
||||
#include "srsenb/hdr/stack/mac/sched.h"
|
||||
#include "srsenb/hdr/stack/mac/sched_helpers.h"
|
||||
#include "srslte/common/log_helper.h"
|
||||
#include "srslte/common/logmap.h"
|
||||
#include <srslte/interfaces/sched_interface.h>
|
||||
|
||||
using srslte::tti_point;
|
||||
|
||||
|
@ -649,7 +649,7 @@ sf_sched::ctrl_code_t sf_sched::alloc_dl_ctrl(uint32_t aggr_lvl, uint32_t tbs_by
|
|||
alloc_outcome_t sf_sched::alloc_bc(uint32_t aggr_lvl, uint32_t sib_idx, uint32_t sib_ntx)
|
||||
{
|
||||
uint32_t sib_len = cc_cfg->cfg.sibs[sib_idx].len;
|
||||
uint32_t rv = sched_utils::get_rvidx(sib_ntx);
|
||||
uint32_t rv = get_rvidx(sib_ntx);
|
||||
ctrl_code_t ret = alloc_dl_ctrl(aggr_lvl, sib_len, SRSLTE_SIRNTI);
|
||||
if (not ret.first) {
|
||||
Warning("SCHED: Could not allocate SIB=%d, L=%d, len=%d, cause=%s\n",
|
||||
|
|
|
@ -0,0 +1,283 @@
|
|||
/**
|
||||
*
|
||||
* \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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "srsenb/hdr/stack/mac/sched_helpers.h"
|
||||
#include "srslte/mac/pdu.h"
|
||||
#include "srslte/srslog/bundled/fmt/format.h"
|
||||
#include <array>
|
||||
|
||||
#define Info(fmt, ...) srslte::logmap::get("MAC")->error(fmt, ##__VA_ARGS__)
|
||||
#define Error(fmt, ...) srslte::logmap::get("MAC")->error(fmt, ##__VA_ARGS__)
|
||||
|
||||
namespace srsenb {
|
||||
|
||||
using dl_sched_res_t = sched_interface::dl_sched_res_t;
|
||||
using dl_sched_data_t = sched_interface::dl_sched_data_t;
|
||||
using custom_mem_buffer = fmt::basic_memory_buffer<char, 1024>;
|
||||
|
||||
const char* to_string_short(srslte_dci_format_t dcifmt)
|
||||
{
|
||||
switch (dcifmt) {
|
||||
case SRSLTE_DCI_FORMAT0:
|
||||
return "0";
|
||||
case SRSLTE_DCI_FORMAT1:
|
||||
return "1";
|
||||
case SRSLTE_DCI_FORMAT1A:
|
||||
return "1A";
|
||||
case SRSLTE_DCI_FORMAT1B:
|
||||
return "1B";
|
||||
case SRSLTE_DCI_FORMAT2:
|
||||
return "2";
|
||||
case SRSLTE_DCI_FORMAT2A:
|
||||
return "2A";
|
||||
case SRSLTE_DCI_FORMAT2B:
|
||||
return "2B";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void fill_dl_cc_result_info(custom_mem_buffer& strbuf, const dl_sched_data_t& data)
|
||||
{
|
||||
uint32_t first_ce = sched_interface::MAX_RLC_PDU_LIST;
|
||||
for (uint32_t i = 0; i < data.nof_pdu_elems[0]; ++i) {
|
||||
if (srslte::is_mac_ce(static_cast<srslte::dl_sch_lcid>(data.pdu[i]->lcid))) {
|
||||
first_ce = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (first_ce == sched_interface::MAX_RLC_PDU_LIST) {
|
||||
return;
|
||||
}
|
||||
const char* prefix = strbuf.size() > 0 ? " | " : "";
|
||||
fmt::format_to(strbuf, "{}rnti={:0x}: [", prefix, data.dci.rnti);
|
||||
bool ces_found = false;
|
||||
for (uint32_t i = 0; i < data.nof_pdu_elems[0]; ++i) {
|
||||
const auto& pdu = data.pdu[0][i];
|
||||
prefix = (ces_found) ? " | " : "";
|
||||
srslte::dl_sch_lcid lcid = static_cast<srslte::dl_sch_lcid>(pdu.lcid);
|
||||
if (srslte::is_mac_ce(lcid)) {
|
||||
fmt::format_to(strbuf, "{}MAC CE \"{}\"", prefix, srslte::to_string_short(lcid));
|
||||
ces_found = true;
|
||||
}
|
||||
}
|
||||
fmt::format_to(strbuf, "]");
|
||||
}
|
||||
|
||||
void fill_dl_cc_result_debug(custom_mem_buffer& strbuf, const dl_sched_data_t& data)
|
||||
{
|
||||
if (data.nof_pdu_elems[0] == 0 and data.nof_pdu_elems[1] == 0) {
|
||||
return;
|
||||
}
|
||||
fmt::format_to(strbuf,
|
||||
" > rnti={:0x}, tbs={}, f={}, mcs={}: [",
|
||||
data.dci.rnti,
|
||||
data.tbs[0],
|
||||
to_string_short(data.dci.format),
|
||||
data.dci.tb[0].mcs_idx);
|
||||
for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; ++tb) {
|
||||
for (uint32_t i = 0; i < data.nof_pdu_elems[tb]; ++i) {
|
||||
const auto& pdu = data.pdu[tb][i];
|
||||
const char* prefix = (i == 0) ? "" : " | ";
|
||||
srslte::dl_sch_lcid lcid = static_cast<srslte::dl_sch_lcid>(pdu.lcid);
|
||||
if (srslte::is_mac_ce(lcid)) {
|
||||
fmt::format_to(strbuf, "{}MAC CE \"{}\"", prefix, srslte::to_string_short(lcid));
|
||||
} else {
|
||||
fmt::format_to(strbuf, "{}MAC SDU lcid={}, tb={}, len={} B", prefix, pdu.lcid, tb, pdu.nbytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt::format_to(strbuf, "]\n");
|
||||
}
|
||||
|
||||
void log_dl_cc_results(srslte::log_ref log_h, uint32_t enb_cc_idx, const sched_interface::dl_sched_res_t& result)
|
||||
{
|
||||
if (log_h->get_level() < srslte::LOG_LEVEL_INFO) {
|
||||
return;
|
||||
}
|
||||
custom_mem_buffer strbuf;
|
||||
for (uint32_t i = 0; i < result.nof_data_elems; ++i) {
|
||||
const dl_sched_data_t& data = result.data[i];
|
||||
if (log_h->get_level() == srslte::LOG_LEVEL_INFO) {
|
||||
fill_dl_cc_result_info(strbuf, data);
|
||||
} else if (log_h->get_level() == srslte::LOG_LEVEL_DEBUG) {
|
||||
fill_dl_cc_result_debug(strbuf, data);
|
||||
}
|
||||
}
|
||||
if (strbuf.size() != 0) {
|
||||
if (log_h->get_level() == srslte::LOG_LEVEL_DEBUG) {
|
||||
log_h->debug("SCHED: MAC LCID allocs cc=%d:\n%s", enb_cc_idx, fmt::to_string(strbuf).c_str());
|
||||
} else {
|
||||
log_h->info("SCHED: MAC CE allocs cc=%d: %s", enb_cc_idx, fmt::to_string(strbuf).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rbg_interval rbg_interval::prbs_to_rbgs(const prb_interval& prbs, uint32_t P)
|
||||
{
|
||||
return rbg_interval{srslte::ceil_div(prbs.start(), P), srslte::ceil_div(prbs.stop(), P)};
|
||||
}
|
||||
|
||||
prb_interval prb_interval::rbgs_to_prbs(const rbg_interval& rbgs, uint32_t P)
|
||||
{
|
||||
return prb_interval{rbgs.start() * P, rbgs.stop() * P};
|
||||
}
|
||||
|
||||
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;
|
||||
srslte_ra_type2_from_riv(riv, &l_crb, &rb_start, nof_prbs, (uint32_t)nof_vrbs);
|
||||
return {rb_start, rb_start + l_crb};
|
||||
}
|
||||
|
||||
/*******************************************************
|
||||
* Sched Params
|
||||
*******************************************************/
|
||||
|
||||
void sched_cell_params_t::regs_deleter::operator()(srslte_regs_t* p)
|
||||
{
|
||||
if (p != nullptr) {
|
||||
srslte_regs_free(p);
|
||||
delete p;
|
||||
}
|
||||
}
|
||||
|
||||
bool sched_cell_params_t::set_cfg(uint32_t enb_cc_idx_,
|
||||
const sched_interface::cell_cfg_t& cfg_,
|
||||
const sched_interface::sched_args_t& sched_args)
|
||||
{
|
||||
enb_cc_idx = enb_cc_idx_;
|
||||
cfg = cfg_;
|
||||
sched_cfg = &sched_args;
|
||||
|
||||
// Basic cell config checks
|
||||
if (cfg.si_window_ms == 0) {
|
||||
Error("SCHED: Invalid si-window length 0 ms\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool invalid_prach;
|
||||
if (cfg.cell.nof_prb == 6) {
|
||||
// PUCCH has to allow space for Msg3
|
||||
if (cfg.nrb_pucch > 1) {
|
||||
srslte::console("Invalid PUCCH configuration: nrb_pucch=%d does not allow space for Msg3 transmission..\n",
|
||||
cfg.nrb_pucch);
|
||||
return false;
|
||||
}
|
||||
// PRACH has to fit within the PUSCH+PUCCH space
|
||||
invalid_prach = cfg.prach_freq_offset + 6 > cfg.cell.nof_prb;
|
||||
} else {
|
||||
// PRACH has to fit within the PUSCH space
|
||||
invalid_prach = (cfg.prach_freq_offset + 6) > (cfg.cell.nof_prb - cfg.nrb_pucch) or
|
||||
((int)cfg.prach_freq_offset < cfg.nrb_pucch);
|
||||
}
|
||||
if (invalid_prach) {
|
||||
Error("Invalid PRACH configuration: frequency offset=%d outside bandwidth limits\n", cfg.prach_freq_offset);
|
||||
srslte::console("Invalid PRACH configuration: frequency offset=%d outside bandwidth limits\n",
|
||||
cfg.prach_freq_offset);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set derived sched parameters
|
||||
|
||||
// init regs
|
||||
regs.reset(new srslte_regs_t{});
|
||||
if (srslte_regs_init(regs.get(), cfg.cell) != SRSLTE_SUCCESS) {
|
||||
Error("Getting DCI locations\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compute Common locations for DCI for each CFI
|
||||
for (uint32_t cfix = 0; cfix < SRSLTE_NOF_CFI; cfix++) {
|
||||
generate_cce_location(regs.get(), &common_locations[cfix], cfix + 1);
|
||||
}
|
||||
if (common_locations[sched_cfg->max_nof_ctrl_symbols - 1].nof_loc[2] == 0) {
|
||||
Error("SCHED: Current cfi=%d is not valid for broadcast (check scheduler.max_nof_ctrl_symbols in conf file).\n",
|
||||
sched_cfg->max_nof_ctrl_symbols);
|
||||
srslte::console(
|
||||
"SCHED: Current cfi=%d is not valid for broadcast (check scheduler.max_nof_ctrl_symbols in conf file).\n",
|
||||
sched_cfg->max_nof_ctrl_symbols);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compute UE locations for RA-RNTI
|
||||
for (uint32_t cfi = 0; cfi < 3; cfi++) {
|
||||
for (uint32_t sf_idx = 0; sf_idx < 10; sf_idx++) {
|
||||
generate_cce_location(regs.get(), &rar_locations[cfi][sf_idx], cfi + 1, sf_idx);
|
||||
}
|
||||
}
|
||||
|
||||
// precompute nof cces in PDCCH for each CFI
|
||||
for (uint32_t cfix = 0; cfix < nof_cce_table.size(); ++cfix) {
|
||||
int ret = srslte_regs_pdcch_ncce(regs.get(), cfix + 1);
|
||||
if (ret < 0) {
|
||||
Error("SCHED: Failed to calculate the number of CCEs in the PDCCH\n");
|
||||
return false;
|
||||
}
|
||||
nof_cce_table[cfix] = (uint32_t)ret;
|
||||
}
|
||||
|
||||
P = srslte_ra_type0_P(cfg.cell.nof_prb);
|
||||
nof_rbgs = srslte::ceil_div(cfg.cell.nof_prb, P);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void generate_cce_location(srslte_regs_t* regs_,
|
||||
sched_dci_cce_t* location,
|
||||
uint32_t cfi,
|
||||
uint32_t sf_idx,
|
||||
uint16_t rnti)
|
||||
{
|
||||
*location = {};
|
||||
|
||||
srslte_dci_location_t loc[64];
|
||||
uint32_t nloc = 0;
|
||||
if (rnti == 0) {
|
||||
nloc = srslte_pdcch_common_locations_ncce(srslte_regs_pdcch_ncce(regs_, cfi), loc, 64);
|
||||
} else {
|
||||
nloc = srslte_pdcch_ue_locations_ncce(srslte_regs_pdcch_ncce(regs_, cfi), loc, 64, sf_idx, rnti);
|
||||
}
|
||||
|
||||
// Save to different format
|
||||
for (uint32_t i = 0; i < nloc; i++) {
|
||||
uint32_t l = loc[i].L;
|
||||
location->cce_start[l][location->nof_loc[l]] = loc[i].ncce;
|
||||
location->nof_loc[l]++;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace srsenb
|
|
@ -1,122 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* \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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "srsenb/hdr/stack/mac/sched_interface_helpers.h"
|
||||
#include "srslte/mac/pdu.h"
|
||||
#include "srslte/srslog/bundled/fmt/format.h"
|
||||
#include <array>
|
||||
|
||||
namespace srsenb {
|
||||
|
||||
using dl_sched_res_t = sched_interface::dl_sched_res_t;
|
||||
using dl_sched_data_t = sched_interface::dl_sched_data_t;
|
||||
using custom_mem_buffer = fmt::basic_memory_buffer<char, 1024>;
|
||||
|
||||
const char* to_string_short(srslte_dci_format_t dcifmt)
|
||||
{
|
||||
switch (dcifmt) {
|
||||
case SRSLTE_DCI_FORMAT0:
|
||||
return "0";
|
||||
case SRSLTE_DCI_FORMAT1:
|
||||
return "1";
|
||||
case SRSLTE_DCI_FORMAT1A:
|
||||
return "1A";
|
||||
case SRSLTE_DCI_FORMAT1B:
|
||||
return "1B";
|
||||
case SRSLTE_DCI_FORMAT2:
|
||||
return "2";
|
||||
case SRSLTE_DCI_FORMAT2A:
|
||||
return "2A";
|
||||
case SRSLTE_DCI_FORMAT2B:
|
||||
return "2B";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void fill_dl_cc_result_info(custom_mem_buffer& strbuf, const dl_sched_data_t& data)
|
||||
{
|
||||
uint32_t first_ce = sched_interface::MAX_RLC_PDU_LIST;
|
||||
for (uint32_t i = 0; i < data.nof_pdu_elems[0]; ++i) {
|
||||
if (srslte::is_mac_ce(static_cast<srslte::dl_sch_lcid>(data.pdu[i]->lcid))) {
|
||||
first_ce = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (first_ce == sched_interface::MAX_RLC_PDU_LIST) {
|
||||
return;
|
||||
}
|
||||
const char* prefix = strbuf.size() > 0 ? " | " : "";
|
||||
fmt::format_to(strbuf, "{}rnti={:0x}: [", prefix, data.dci.rnti);
|
||||
bool ces_found = false;
|
||||
for (uint32_t i = 0; i < data.nof_pdu_elems[0]; ++i) {
|
||||
const auto& pdu = data.pdu[0][i];
|
||||
prefix = (ces_found) ? " | " : "";
|
||||
srslte::dl_sch_lcid lcid = static_cast<srslte::dl_sch_lcid>(pdu.lcid);
|
||||
if (srslte::is_mac_ce(lcid)) {
|
||||
fmt::format_to(strbuf, "{}MAC CE \"{}\"", prefix, srslte::to_string_short(lcid));
|
||||
ces_found = true;
|
||||
}
|
||||
}
|
||||
fmt::format_to(strbuf, "]");
|
||||
}
|
||||
|
||||
void fill_dl_cc_result_debug(custom_mem_buffer& strbuf, const dl_sched_data_t& data)
|
||||
{
|
||||
if (data.nof_pdu_elems[0] == 0 and data.nof_pdu_elems[1] == 0) {
|
||||
return;
|
||||
}
|
||||
fmt::format_to(strbuf,
|
||||
" > rnti={:0x}, tbs={}, f={}, mcs={}: [",
|
||||
data.dci.rnti,
|
||||
data.tbs[0],
|
||||
to_string_short(data.dci.format),
|
||||
data.dci.tb[0].mcs_idx);
|
||||
for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; ++tb) {
|
||||
for (uint32_t i = 0; i < data.nof_pdu_elems[tb]; ++i) {
|
||||
const auto& pdu = data.pdu[tb][i];
|
||||
const char* prefix = (i == 0) ? "" : " | ";
|
||||
srslte::dl_sch_lcid lcid = static_cast<srslte::dl_sch_lcid>(pdu.lcid);
|
||||
if (srslte::is_mac_ce(lcid)) {
|
||||
fmt::format_to(strbuf, "{}MAC CE \"{}\"", prefix, srslte::to_string_short(lcid));
|
||||
} else {
|
||||
fmt::format_to(strbuf, "{}MAC SDU lcid={}, tb={}, len={} B", prefix, pdu.lcid, tb, pdu.nbytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt::format_to(strbuf, "]\n");
|
||||
}
|
||||
|
||||
void log_dl_cc_results(srslte::log_ref log_h, uint32_t enb_cc_idx, const sched_interface::dl_sched_res_t& result)
|
||||
{
|
||||
if (log_h->get_level() < srslte::LOG_LEVEL_INFO) {
|
||||
return;
|
||||
}
|
||||
custom_mem_buffer strbuf;
|
||||
for (uint32_t i = 0; i < result.nof_data_elems; ++i) {
|
||||
const dl_sched_data_t& data = result.data[i];
|
||||
if (log_h->get_level() == srslte::LOG_LEVEL_INFO) {
|
||||
fill_dl_cc_result_info(strbuf, data);
|
||||
} else if (log_h->get_level() == srslte::LOG_LEVEL_DEBUG) {
|
||||
fill_dl_cc_result_debug(strbuf, data);
|
||||
}
|
||||
}
|
||||
if (strbuf.size() != 0) {
|
||||
if (log_h->get_level() == srslte::LOG_LEVEL_DEBUG) {
|
||||
log_h->debug("SCHED: MAC LCID allocs cc=%d:\n%s", enb_cc_idx, fmt::to_string(strbuf).c_str());
|
||||
} else {
|
||||
log_h->info("SCHED: MAC CE allocs cc=%d: %s", enb_cc_idx, fmt::to_string(strbuf).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace srsenb
|
|
@ -13,6 +13,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "srsenb/hdr/stack/mac/sched.h"
|
||||
#include "srsenb/hdr/stack/mac/sched_helpers.h"
|
||||
#include "srsenb/hdr/stack/mac/sched_ue.h"
|
||||
#include "srslte/common/log_helper.h"
|
||||
#include "srslte/common/logmap.h"
|
||||
|
@ -31,7 +32,7 @@ namespace srsenb {
|
|||
|
||||
namespace sched_utils {
|
||||
|
||||
//! Obtains TB size *in bytes* for a given MCS and N_{PRB}
|
||||
/// Obtains TB size *in bytes* for a given MCS and nof allocated prbs
|
||||
uint32_t get_tbs_bytes(uint32_t mcs, uint32_t nof_alloc_prb, bool use_tbs_index_alt, bool is_ul)
|
||||
{
|
||||
int tbs_idx = srslte_ra_tbs_idx_from_mcs(mcs, use_tbs_index_alt, is_ul);
|
||||
|
@ -574,7 +575,7 @@ int sched_ue::generate_format1(uint32_t pid,
|
|||
SRSLTE_MIN(sched_utils::count_prb_per_tb(*carriers[ue_cc_idx].get_cell_cfg(), user_mask), cell.nof_prb);
|
||||
uint32_t RB_start = prb_int.start();
|
||||
dci->type2_alloc.riv = srslte_ra_type2_to_riv(L_crb, RB_start, cell.nof_prb);
|
||||
dci->format = SRSLTE_DCI_FORMAT1A;
|
||||
dci->format = SRSLTE_DCI_FORMAT1A;
|
||||
if (prb_int.length() != P * user_mask.count()) {
|
||||
// This happens if Type0 was using distributed allocation
|
||||
Warning("SCHED: Can't use distributed RA due to DCI size ambiguity\n");
|
||||
|
@ -599,7 +600,7 @@ int sched_ue::generate_format1(uint32_t pid,
|
|||
dci->pid = h->get_id();
|
||||
dci->ue_cc_idx = ue_cc_idx;
|
||||
dci->tb[0].mcs_idx = (uint32_t)mcs;
|
||||
dci->tb[0].rv = sched_utils::get_rvidx(h->nof_retx(0));
|
||||
dci->tb[0].rv = get_rvidx(h->nof_retx(0));
|
||||
dci->tb[0].ndi = h->get_ndi(0);
|
||||
|
||||
dci->tpc_pucch = carriers[ue_cc_idx].tpc_fsm.encode_pucch_tpc();
|
||||
|
@ -647,11 +648,8 @@ std::pair<int, int> sched_ue::compute_mcs_and_tbs(uint32_t ue_cc_i
|
|||
(uint32_t)carriers[ue_cc_idx].fixed_mcs_dl, nof_alloc_prbs, cfg.use_tbs_index_alt, false);
|
||||
}
|
||||
|
||||
// If the number of prbs is not sufficient to fit minimum required bytes, increase the mcs
|
||||
// NOTE: this may happen during ConRes CE tx when DL-CQI is still not available
|
||||
while (tbs_bytes > 0 and (uint32_t) tbs_bytes < req_bytes.start() and mcs < 28) {
|
||||
mcs++;
|
||||
tbs_bytes = sched_utils::get_tbs_bytes((uint32_t)mcs, nof_alloc_prbs, cfg.use_tbs_index_alt, false);
|
||||
if (tbs_bytes > 0 and (uint32_t) tbs_bytes < req_bytes.start() and mcs < 28) {
|
||||
log_h->warning("SCHED: Could not get PRB allocation that avoids MAC CE or RLC SBR0 PDU segmentation\n");
|
||||
}
|
||||
|
||||
return {mcs, tbs_bytes};
|
||||
|
@ -712,7 +710,7 @@ int sched_ue::generate_format2a(uint32_t pid,
|
|||
/* Fill DCI TB dedicated fields */
|
||||
if (tbs > 0 && tb_en[tb]) {
|
||||
dci->tb[tb].mcs_idx = (uint32_t)mcs;
|
||||
dci->tb[tb].rv = sched_utils::get_rvidx(h->nof_retx(tb));
|
||||
dci->tb[tb].rv = get_rvidx(h->nof_retx(tb));
|
||||
if (!SRSLTE_DCI_IS_TB_EN(dci->tb[tb])) {
|
||||
dci->tb[tb].rv = 2;
|
||||
}
|
||||
|
@ -855,7 +853,7 @@ int sched_ue::generate_format0(sched_interface::ul_sched_data_t* data,
|
|||
alloc.set(alloc.start(), alloc.start() + 4);
|
||||
}
|
||||
} else if (tbs > 0) {
|
||||
dci->tb.rv = sched_utils::get_rvidx(h->nof_retx(0));
|
||||
dci->tb.rv = get_rvidx(h->nof_retx(0));
|
||||
if (!is_newtx && data->needs_pdcch) {
|
||||
dci->tb.mcs_idx = 28 + dci->tb.rv;
|
||||
} else {
|
||||
|
@ -1330,7 +1328,7 @@ cc_sched_ue::cc_sched_ue(const sched_interface::ue_cfg_t& cfg_,
|
|||
// Generate allowed CCE locations
|
||||
for (int cfi = 0; cfi < 3; cfi++) {
|
||||
for (int sf_idx = 0; sf_idx < 10; sf_idx++) {
|
||||
sched_utils::generate_cce_location(cell_params->regs.get(), &dci_locations[cfi][sf_idx], cfi + 1, sf_idx, rnti);
|
||||
generate_cce_location(cell_params->regs.get(), &dci_locations[cfi][sf_idx], cfi + 1, sf_idx, rnti);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "sched_test_common.h"
|
||||
#include "srsenb/hdr/stack/mac/sched.h"
|
||||
#include "srsenb/hdr/stack/mac/sched_helpers.h"
|
||||
#include "srsenb/hdr/stack/upper/common_enb.h"
|
||||
#include "srslte/mac/pdu.h"
|
||||
|
||||
|
@ -211,7 +212,7 @@ int ue_ctxt_test::schedule_acks(cc_result result)
|
|||
ack_data.tb = 0;
|
||||
ack_data.pid = data.dci.pid;
|
||||
ack_data.ue_cc_idx = data.dci.ue_cc_idx;
|
||||
uint32_t nof_retx = sched_utils::get_nof_retx(data.dci.tb[0].rv); // 0..3
|
||||
uint32_t nof_retx = srsenb::get_nof_retx(data.dci.tb[0].rv); // 0..3
|
||||
ack_data.ack = randf() < sim_cfg.prob_dl_ack_mask[nof_retx % sim_cfg.prob_dl_ack_mask.size()];
|
||||
|
||||
pending_dl_acks.push(ack_data);
|
||||
|
@ -230,7 +231,7 @@ int ue_ctxt_test::schedule_acks(cc_result result)
|
|||
ack_data.ue_cc_idx = pusch.dci.ue_cc_idx;
|
||||
ack_data.tb = 0;
|
||||
ack_data.pid = to_tx_ul(current_tti_rx).to_uint() % (FDD_HARQ_DELAY_DL_MS + FDD_HARQ_DELAY_UL_MS);
|
||||
uint32_t nof_retx = sched_utils::get_nof_retx(pusch.dci.tb.rv); // 0..3
|
||||
uint32_t nof_retx = srsenb::get_nof_retx(pusch.dci.tb.rv); // 0..3
|
||||
ack_data.ack = randf() < sim_cfg.prob_ul_ack_mask[nof_retx % sim_cfg.prob_ul_ack_mask.size()];
|
||||
|
||||
pending_ul_acks.push(ack_data);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "sched_ue_ded_test_suite.h"
|
||||
#include "lib/include/srslte/mac/pdu.h"
|
||||
#include "srsenb/hdr/stack/mac/sched_helpers.h"
|
||||
#include "srslte/common/test_common.h"
|
||||
|
||||
namespace srsenb {
|
||||
|
@ -72,14 +73,14 @@ int test_pdsch_grant(const sim_enb_ctxt_t& enb_ctxt,
|
|||
|
||||
// TEST: DCI is consistent with current UE DL harq state
|
||||
auto& h = ue_ctxt.cc_list[pdsch.dci.ue_cc_idx].dl_harqs[pdsch.dci.pid];
|
||||
uint32_t nof_retx = sched_utils::get_nof_retx(pdsch.dci.tb[0].rv); // 0..3
|
||||
uint32_t nof_retx = get_nof_retx(pdsch.dci.tb[0].rv); // 0..3
|
||||
if (h.nof_txs == 0 or h.ndi != pdsch.dci.tb[0].ndi) {
|
||||
// It is newtx
|
||||
CONDERROR(nof_retx != 0, "Invalid rv index for new tx\n");
|
||||
CONDERROR(h.active, "DL newtx for already active DL harq pid=%d\n", h.pid);
|
||||
} else {
|
||||
// it is retx
|
||||
CONDERROR(sched_utils::get_rvidx(h.nof_retxs + 1) != (uint32_t)pdsch.dci.tb[0].rv, "Invalid rv index for retx\n");
|
||||
CONDERROR(get_rvidx(h.nof_retxs + 1) != (uint32_t)pdsch.dci.tb[0].rv, "Invalid rv index for retx\n");
|
||||
CONDERROR(not h.active, "retx for inactive dl harq pid=%d\n", h.pid);
|
||||
CONDERROR(to_tx_dl_ack(h.last_tti_rx) > tti_rx, "harq pid=%d reused too soon\n", h.pid);
|
||||
CONDERROR(h.nof_retxs + 1 > ue_ctxt.ue_cfg.maxharq_tx,
|
||||
|
@ -184,7 +185,7 @@ int test_ul_sched_result(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t&
|
|||
CONDERROR(pusch_ptr->dci.ue_cc_idx != (uint32_t)ue_cc_idx, "Inconsistent enb_cc_idx -> ue_cc_idx mapping\n");
|
||||
|
||||
// TEST: DCI is consistent with current UE UL harq state
|
||||
uint32_t nof_retx = sched_utils::get_nof_retx(pusch_ptr->dci.tb.rv); // 0..3
|
||||
uint32_t nof_retx = get_nof_retx(pusch_ptr->dci.tb.rv); // 0..3
|
||||
|
||||
if (h.nof_txs == 0 or h.ndi != pusch_ptr->dci.tb.ndi) {
|
||||
// newtx
|
||||
|
@ -204,8 +205,7 @@ int test_ul_sched_result(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t&
|
|||
CONDERROR(pusch_ptr->dci.type2_alloc.riv != h.riv, "Non-adaptive retx must keep the same riv\n");
|
||||
}
|
||||
}
|
||||
CONDERROR(sched_utils::get_rvidx(h.nof_retxs + 1) != (uint32_t)pusch_ptr->dci.tb.rv,
|
||||
"Invalid rv index for retx\n");
|
||||
CONDERROR(get_rvidx(h.nof_retxs + 1) != (uint32_t)pusch_ptr->dci.tb.rv, "Invalid rv index for retx\n");
|
||||
CONDERROR(h.tbs != pusch_ptr->tbs, "TBS changed during HARQ retx\n");
|
||||
CONDERROR(to_tx_ul(h.last_tti_rx) > sf_out.tti_rx, "UL harq pid=%d was reused too soon\n", h.pid);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue