simplified tbs/mcs computation in scheduler

master
Francisco 4 years ago committed by Francisco Paisana
parent 9c67a029b5
commit 9748c0be84

@ -181,15 +181,15 @@ srslte_mod_t srslte_ra_ul_mod_from_mcs(uint32_t mcs)
static int srslte_ra_dl_mcs_from_tbs_idx(uint32_t tbs_idx, bool use_tbs_index_alt)
{
if (use_tbs_index_alt) {
for (int i = 0; i < 28; i++) {
if (tbs_idx == dl_mcs_tbs_idx_table2[i]) {
return i;
for (int mcs = 27; mcs >= 0; mcs--) {
if (tbs_idx == dl_mcs_tbs_idx_table2[mcs]) {
return mcs;
}
}
} else {
for (int i = 0; i < 29; i++) {
if (tbs_idx == dl_mcs_tbs_idx_table[i]) {
return i;
for (int mcs = 28; mcs >= 0; mcs--) {
if (tbs_idx == dl_mcs_tbs_idx_table[mcs]) {
return mcs;
}
}
}
@ -198,9 +198,10 @@ static int srslte_ra_dl_mcs_from_tbs_idx(uint32_t tbs_idx, bool use_tbs_index_al
static int srslte_ra_ul_mcs_from_tbs_idx(uint32_t tbs_idx)
{
for (int i = 0; i < 29; i++) {
if (tbs_idx == ul_mcs_tbs_idx_table[i]) {
return i;
// Note: go in descent order to find max mcs possible
for (int mcs = 28; mcs >= 0; mcs--) {
if (tbs_idx == ul_mcs_tbs_idx_table[mcs]) {
return mcs;
}
}
return SRSLTE_ERROR;
@ -224,21 +225,22 @@ int srslte_ra_tbs_from_idx(uint32_t tbs_idx, uint32_t n_prb)
/* Returns lowest nearest index of TBS value in table 7.1.7.2 on 36.213
* or -1 if the TBS value is not within the valid TBS values
*/
/*
* Returns upper bound (exclusive) of TBS index interval whose TBS value encompasses the provided TBS
* \remark taken from table 7.1.7.2 on 36.213
* @return upper bound of TBS index (0..27), -2 if bad arguments
*/
int srslte_ra_tbs_to_table_idx(uint32_t tbs, uint32_t n_prb)
{
uint32_t idx;
if (n_prb > 0 && n_prb <= SRSLTE_MAX_PRB) {
if (tbs <= tbs_table[0][n_prb - 1]) {
return 0;
}
if (tbs >= tbs_table[26][n_prb - 1]) {
return 27;
}
for (idx = 0; idx < 26; idx++) {
if (tbs_table[idx][n_prb - 1] <= tbs && tbs_table[idx + 1][n_prb - 1] >= tbs) {
return idx + 1;
}
if (n_prb == 0 || n_prb > SRSLTE_MAX_PRB) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
if (tbs < tbs_table[0][n_prb - 1]) {
return 0;
}
for (int mcs = 26; mcs >= 0; mcs--) {
if (tbs_table[mcs][n_prb - 1] <= tbs) {
return mcs + 1;
}
}
return SRSLTE_ERROR;

@ -0,0 +1,35 @@
/**
*
* \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_DCI_H
#define SRSLTE_SCHED_DCI_H
#include <cstdint>
namespace srsenb {
struct tbs_info {
int tbs_bytes = -1;
int mcs = 0;
};
tbs_info compute_mcs_and_tbs(uint32_t nof_prb,
uint32_t nof_re,
uint32_t cqi,
uint32_t max_mcs,
bool is_ul,
bool ulqam64_enabled,
bool use_tbs_index_alt);
} // namespace srsenb
#endif // SRSLTE_SCHED_DCI_H

@ -15,17 +15,13 @@
#include "../sched_common.h"
#include "sched_harq.h"
#include "srsenb/hdr/stack/mac/sched_phy_ch/sched_dci.h"
#include "tpc.h"
namespace srsenb {
enum class cc_st { active, idle, activating, deactivating };
struct tbs_info {
int tbs_bytes = -1;
int mcs = 0;
};
struct sched_ue_cell {
using ue_cc_cfg = sched_interface::ue_cfg_t::cc_cfg_t;
const static int SCHED_MAX_HARQ_PROC = FDD_HARQ_DELAY_UL_MS + FDD_HARQ_DELAY_DL_MS;

@ -9,7 +9,7 @@
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
sched_ue_ctrl/sched_lch.cc sched_ue_ctrl/sched_ue_cell.cc sched_phy_ch/sf_cch_allocator.cc sched_helpers.cc)
sched_ue_ctrl/sched_lch.cc sched_ue_ctrl/sched_ue_cell.cc sched_phy_ch/sf_cch_allocator.cc sched_phy_ch/sched_dci.cc sched_helpers.cc)
add_library(srsenb_mac STATIC ${SOURCES} $<TARGET_OBJECTS:mac_schedulers>)
set(SOURCES mac_nr.cc)

@ -0,0 +1,87 @@
/**
*
* \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_phy_ch/sched_dci.h"
#include "srsenb/hdr/stack/mac/sched_common.h"
#include <cmath>
#include <cstdint>
namespace srsenb {
/// Compute max TBS based on max coderate
int coderate_to_tbs(float max_coderate, uint32_t nof_re)
{
return floorf(nof_re * max_coderate - 24);
}
tbs_info compute_mcs_and_tbs_recursive(uint32_t nof_prb,
uint32_t nof_re,
uint32_t max_mcs,
bool is_ul,
bool use_tbs_index_alt,
float max_coderate)
{
// compute max MCS based on max coderate
int max_tbs = coderate_to_tbs(max_coderate, nof_re);
if (max_tbs <= 0) {
return tbs_info{};
}
int tbs_idx = srslte_ra_tbs_to_table_idx(max_tbs, nof_prb);
if (tbs_idx <= 0) {
return tbs_info{};
}
tbs_idx -= 1; // get TBS index lower bound
uint32_t mcs = srslte_ra_mcs_from_tbs_idx(tbs_idx, use_tbs_index_alt, is_ul);
if (mcs > max_mcs) {
// bound mcs
mcs = max_mcs;
tbs_idx = srslte_ra_tbs_idx_from_mcs(mcs, use_tbs_index_alt, is_ul);
}
// compute real TBS based on max MCS
int tbs = srslte_ra_tbs_from_idx(tbs_idx, nof_prb);
float coderate = srslte_coderate(tbs, nof_re);
srslte_mod_t mod = (is_ul) ? srslte_ra_ul_mod_from_mcs(mcs) : srslte_ra_dl_mod_from_mcs(mcs, use_tbs_index_alt);
float new_maxcoderate = std::min(0.930f * srslte_mod_bits_x_symbol(mod), max_coderate);
if (new_maxcoderate > coderate) {
tbs_info tb;
tb.tbs_bytes = tbs / 8u;
tb.mcs = mcs;
return tb;
}
if (mcs == 0) {
// solution not found
return tbs_info{};
}
return compute_mcs_and_tbs_recursive(nof_prb, nof_re, mcs - 1, is_ul, use_tbs_index_alt, new_maxcoderate);
}
tbs_info compute_mcs_and_tbs(uint32_t nof_prb,
uint32_t nof_re,
uint32_t cqi,
uint32_t max_mcs,
bool is_ul,
bool ulqam64_enabled,
bool use_tbs_index_alt)
{
assert((not is_ul or not use_tbs_index_alt) && "UL cannot use Alt CQI Table");
assert((is_ul or not ulqam64_enabled) && "DL cannot use UL-QAM64 enable flag");
float max_coderate = srslte_cqi_to_coderate(std::min(cqi + 1u, 15u), use_tbs_index_alt);
uint32_t max_Qm = (is_ul) ? (ulqam64_enabled ? 6 : 4) : (use_tbs_index_alt ? 8 : 6);
max_coderate = std::min(max_coderate, 0.930f * max_Qm);
return compute_mcs_and_tbs_recursive(nof_prb, nof_re, max_mcs, is_ul, use_tbs_index_alt, max_coderate);
}
} // namespace srsenb

@ -12,6 +12,7 @@
#include "srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h"
#include "srsenb/hdr/stack/mac/sched_helpers.h"
#include "srsenb/hdr/stack/mac/sched_phy_ch/sched_dci.h"
#include <numeric>
namespace srsenb {
@ -273,6 +274,15 @@ tbs_info cqi_to_tbs(const sched_ue_cell& cell, uint32_t nof_prb, uint32_t nof_re
ret2.mcs = std::get<0>(ret);
ret2.tbs_bytes = get_tbs_bytes(ret2.mcs, nof_prb, cell.get_ue_cfg()->use_tbs_index_alt, is_ul);
tbs_info ret3 = compute_mcs_and_tbs(nof_prb,
nof_re,
(is_ul) ? cell.ul_cqi : cell.dl_cqi,
max_mcs,
is_ul,
is_ul and cell.get_ue_cfg()->support_ul64qam == ul64qam_cap::enabled,
not is_ul and cell.get_ue_cfg()->use_tbs_index_alt);
assert((ret3.mcs == ret2.mcs and ret3.tbs_bytes == ret2.tbs_bytes) or (std::get<0>(ret) == std::get<2>(ret)));
// If coderate > SRSLTE_MIN(max_coderate, 0.930 * Qm) we should set TBS=0. We don't because it's not correctly
// handled by the scheduler, but we might be scheduling undecodable codewords at very low SNR

Loading…
Cancel
Save