Allow collisions between PUCCH and Msg3 for 6 PRBs

- The UL Harq now stores the type of UL alloc (msg3 or data)
This commit is contained in:
Francisco 2021-02-19 14:42:02 +00:00 committed by Andre Puschmann
parent 39aea96c69
commit 8ae8b31ba2
7 changed files with 79 additions and 46 deletions

View File

@ -61,6 +61,7 @@ public:
uint32_t enb_cc_idx = 0; uint32_t enb_cc_idx = 0;
sched_interface::cell_cfg_t cfg = {}; sched_interface::cell_cfg_t cfg = {};
srslte_pucch_cfg_t pucch_cfg_common = {};
const sched_interface::sched_args_t* sched_cfg = nullptr; const sched_interface::sched_args_t* sched_cfg = nullptr;
std::unique_ptr<srslte_regs_t, regs_deleter> regs; std::unique_ptr<srslte_regs_t, regs_deleter> regs;
cce_sf_position_table common_locations = {}; cce_sf_position_table common_locations = {};

View File

@ -105,7 +105,8 @@ public:
alloc_outcome_t alloc_dl_data(sched_ue* user, const rbgmask_t& user_mask); alloc_outcome_t alloc_dl_data(sched_ue* user, const rbgmask_t& user_mask);
bool reserve_dl_rbgs(uint32_t start_rbg, uint32_t end_rbg); bool reserve_dl_rbgs(uint32_t start_rbg, uint32_t end_rbg);
alloc_outcome_t alloc_ul_data(sched_ue* user, prb_interval alloc, bool needs_pdcch); alloc_outcome_t alloc_ul_data(sched_ue* user, prb_interval alloc, bool needs_pdcch);
bool reserve_ul_prbs(const prbmask_t& prbmask, bool strict); alloc_outcome_t reserve_ul_prbs(const prbmask_t& prbmask, bool strict);
alloc_outcome_t reserve_ul_prbs(prb_interval alloc, bool strict);
bool find_ul_alloc(uint32_t L, prb_interval* alloc) const; bool find_ul_alloc(uint32_t L, prb_interval* alloc) const;
// getters // getters
@ -113,6 +114,7 @@ public:
const prbmask_t& get_ul_mask() const { return ul_mask; } const prbmask_t& get_ul_mask() const { return ul_mask; }
uint32_t get_cfi() const { return pdcch_alloc.get_cfi(); } uint32_t get_cfi() const { return pdcch_alloc.get_cfi(); }
const sf_cch_allocator& get_pdcch_grid() const { return pdcch_alloc; } const sf_cch_allocator& get_pdcch_grid() const { return pdcch_alloc; }
uint32_t get_pucch_width() const { return pucch_nrb; }
private: private:
alloc_outcome_t alloc_dl(uint32_t aggr_lvl, alloc_type_t alloc_type, rbgmask_t alloc_mask, sched_ue* user = nullptr); alloc_outcome_t alloc_dl(uint32_t aggr_lvl, alloc_type_t alloc_type, rbgmask_t alloc_mask, sched_ue* user = nullptr);
@ -122,6 +124,8 @@ private:
srslog::basic_logger& logger; srslog::basic_logger& logger;
uint32_t nof_rbgs = 0; uint32_t nof_rbgs = 0;
uint32_t si_n_rbg = 0, rar_n_rbg = 0; uint32_t si_n_rbg = 0, rar_n_rbg = 0;
uint32_t pucch_nrb = 0;
prbmask_t pucch_mask;
// derived // derived
sf_cch_allocator pdcch_alloc = {}; sf_cch_allocator pdcch_alloc = {};
@ -166,7 +170,7 @@ public:
uint32_t pid; uint32_t pid;
}; };
struct ul_alloc_t { struct ul_alloc_t {
enum type_t { NEWTX, NOADAPT_RETX, ADAPT_RETX, MSG3 }; enum type_t { NEWTX, NOADAPT_RETX, ADAPT_RETX, MSG3, MSG3_RETX };
size_t dci_idx; size_t dci_idx;
type_t type; type_t type;
uint16_t rnti; uint16_t rnti;
@ -243,7 +247,6 @@ private:
const sched_cell_params_t* cc_cfg = nullptr; const sched_cell_params_t* cc_cfg = nullptr;
srslog::basic_logger& logger; srslog::basic_logger& logger;
sf_sched_result* cc_results; ///< Results of other CCs for the same Subframe sf_sched_result* cc_results; ///< Results of other CCs for the same Subframe
prbmask_t pucch_mask;
// internal state // internal state
sf_grid_t tti_alloc; sf_grid_t tti_alloc;

View File

@ -85,13 +85,14 @@ private:
class ul_harq_proc : public harq_proc class ul_harq_proc : public harq_proc
{ {
public: public:
void new_tx(srslte::tti_point tti, int mcs, int tbs, prb_interval alloc, uint32_t max_retx_); void new_tx(srslte::tti_point tti, int mcs, int tbs, prb_interval alloc, uint32_t max_retx_, bool is_msg3);
void new_retx(srslte::tti_point tti_, int* mcs, int* tbs, prb_interval alloc); void new_retx(srslte::tti_point tti_, int* mcs, int* tbs, prb_interval alloc);
bool set_ack(uint32_t tb_idx, bool ack); bool set_ack(uint32_t tb_idx, bool ack);
bool retx_requires_pdcch(srslte::tti_point tti_, prb_interval alloc) const; bool retx_requires_pdcch(srslte::tti_point tti_, prb_interval alloc) const;
prb_interval get_alloc() const; prb_interval get_alloc() const;
bool has_pending_retx() const; bool has_pending_retx() const;
bool is_msg3() const { return is_msg3_; }
void reset_pending_data(); void reset_pending_data();
uint32_t get_pending_data() const; uint32_t get_pending_data() const;
@ -102,6 +103,7 @@ private:
prb_interval allocation; prb_interval allocation;
int pending_data; int pending_data;
bool pending_phich = false; bool pending_phich = false;
bool is_msg3_ = false;
}; };
class harq_entity class harq_entity

View File

@ -131,6 +131,14 @@ void sf_grid_t::init(const sched_cell_params_t& cell_params_)
ul_mask.resize(cc_cfg->nof_prb()); ul_mask.resize(cc_cfg->nof_prb());
pdcch_alloc.init(*cc_cfg); pdcch_alloc.init(*cc_cfg);
// Compute reserved PRBs for CQI, SR and HARQ-ACK, and store it in a bitmask
pucch_mask.resize(cc_cfg->nof_prb());
pucch_nrb = (cc_cfg->cfg.nrb_pucch > 0) ? (uint32_t)cc_cfg->cfg.nrb_pucch : 0;
if (pucch_nrb > 0) {
pucch_mask.fill(0, pucch_nrb);
pucch_mask.fill(cc_cfg->nof_prb() - pucch_nrb, cc_cfg->nof_prb());
}
} }
void sf_grid_t::new_tti(tti_point tti_rx_) void sf_grid_t::new_tti(tti_point tti_rx_)
@ -141,6 +149,19 @@ void sf_grid_t::new_tti(tti_point tti_rx_)
ul_mask.reset(); ul_mask.reset();
avail_rbg = nof_rbgs; avail_rbg = nof_rbgs;
// Reserve PRBs for PUCCH
ul_mask |= pucch_mask;
// Reserve PRBs for PRACH
if (srslte_prach_tti_opportunity_config_fdd(cc_cfg->cfg.prach_config, to_tx_ul(tti_rx).to_uint(), -1)) {
prbmask_t prach_mask{cc_cfg->nof_prb()};
prach_mask.fill(cc_cfg->cfg.prach_freq_offset, cc_cfg->cfg.prach_freq_offset + 6);
reserve_ul_prbs(prach_mask, cc_cfg->nof_prb() != 6);
logger.debug("SCHED: Allocated PRACH RBs for tti_tx_ul=%d. Mask: 0x%s",
to_tx_ul(tti_rx).to_uint(),
prach_mask.to_hex().c_str());
}
// internal state // internal state
pdcch_alloc.new_tti(tti_rx); pdcch_alloc.new_tti(tti_rx);
} }
@ -242,14 +263,25 @@ bool sf_grid_t::reserve_dl_rbgs(uint32_t start_rbg, uint32_t end_rbg)
return true; return true;
} }
bool sf_grid_t::reserve_ul_prbs(const prbmask_t& prbmask, bool strict) alloc_outcome_t sf_grid_t::reserve_ul_prbs(prb_interval alloc, bool strict)
{ {
bool ret = true; if (alloc.stop() > ul_mask.size()) {
return alloc_outcome_t::ERROR;
}
prbmask_t newmask(ul_mask.size());
newmask.fill(alloc.start(), alloc.stop());
return reserve_ul_prbs(newmask, strict);
}
alloc_outcome_t sf_grid_t::reserve_ul_prbs(const prbmask_t& prbmask, bool strict)
{
alloc_outcome_t ret = alloc_outcome_t::SUCCESS;
if (strict and (ul_mask & prbmask).any()) { if (strict and (ul_mask & prbmask).any()) {
logger.error("There was a collision in UL channel. current mask=0x%s, new alloc mask=0x%s", logger.error("There was a collision in UL channel. current mask=0x%s, new alloc mask=0x%s",
ul_mask.to_hex().c_str(), ul_mask.to_hex().c_str(),
prbmask.to_hex().c_str()); prbmask.to_hex().c_str());
ret = false; ret = alloc_outcome_t::ERROR;
} }
ul_mask |= prbmask; ul_mask |= prbmask;
return ret; return ret;
@ -300,13 +332,7 @@ void sf_sched::init(const sched_cell_params_t& cell_params_)
{ {
cc_cfg = &cell_params_; cc_cfg = &cell_params_;
tti_alloc.init(*cc_cfg); tti_alloc.init(*cc_cfg);
max_msg3_prb = std::max(6u, cc_cfg->cfg.cell.nof_prb - (uint32_t)cc_cfg->cfg.nrb_pucch); max_msg3_prb = std::max(6u, cc_cfg->cfg.cell.nof_prb - tti_alloc.get_pucch_width());
pucch_mask.resize(cc_cfg->nof_prb());
if (cc_cfg->cfg.nrb_pucch > 0) {
pucch_mask.fill(0, (uint32_t)cc_cfg->cfg.nrb_pucch);
pucch_mask.fill(cc_cfg->nof_prb() - cc_cfg->cfg.nrb_pucch, cc_cfg->nof_prb());
}
} }
void sf_sched::new_tti(tti_point tti_rx_, sf_sched_result* cc_results_) void sf_sched::new_tti(tti_point tti_rx_, sf_sched_result* cc_results_)
@ -321,21 +347,8 @@ void sf_sched::new_tti(tti_point tti_rx_, sf_sched_result* cc_results_)
tti_alloc.new_tti(tti_rx_); tti_alloc.new_tti(tti_rx_);
cc_results = cc_results_; cc_results = cc_results_;
// Reserve PRBs for PUCCH
reserve_ul_prbs(pucch_mask, true);
// Reserve PRBs for PRACH
if (srslte_prach_tti_opportunity_config_fdd(cc_cfg->cfg.prach_config, to_tx_ul(tti_rx).to_uint(), -1)) {
prbmask_t prach_mask{cc_cfg->nof_prb()};
prach_mask.fill(cc_cfg->cfg.prach_freq_offset, cc_cfg->cfg.prach_freq_offset + 6);
reserve_ul_prbs(prach_mask, cc_cfg->nof_prb() != 6);
logger.debug("SCHED: Allocated PRACH RBs for tti_tx_ul=%d. Mask: 0x%s",
to_tx_ul(tti_rx).to_uint(),
prach_mask.to_hex().c_str());
}
// setup first prb to be used for msg3 alloc. Account for potential PRACH alloc // setup first prb to be used for msg3 alloc. Account for potential PRACH alloc
last_msg3_prb = cc_cfg->cfg.nrb_pucch; last_msg3_prb = tti_alloc.get_pucch_width();
tti_point tti_msg3_alloc = to_tx_ul(tti_rx) + MSG3_DELAY_MS; tti_point tti_msg3_alloc = to_tx_ul(tti_rx) + MSG3_DELAY_MS;
if (srslte_prach_tti_opportunity_config_fdd(cc_cfg->cfg.prach_config, tti_msg3_alloc.to_uint(), -1)) { if (srslte_prach_tti_opportunity_config_fdd(cc_cfg->cfg.prach_config, tti_msg3_alloc.to_uint(), -1)) {
last_msg3_prb = std::max(last_msg3_prb, cc_cfg->cfg.prach_freq_offset + 6); last_msg3_prb = std::max(last_msg3_prb, cc_cfg->cfg.prach_freq_offset + 6);
@ -595,7 +608,13 @@ alloc_outcome_t sf_sched::alloc_ul(sched_ue* user, prb_interval alloc, ul_alloc_
} }
// Allocate RBGs and DCI space // Allocate RBGs and DCI space
alloc_outcome_t ret = tti_alloc.alloc_ul_data(user, alloc, needs_pdcch); alloc_outcome_t ret;
if (alloc_type != ul_alloc_t::MSG3 and alloc_type != ul_alloc_t::MSG3_RETX) {
ret = tti_alloc.alloc_ul_data(user, alloc, needs_pdcch);
} else {
// allow collisions between Msg3 and PUCCH for 6 PRBs
ret = tti_alloc.reserve_ul_prbs(alloc, cc_cfg->nof_prb() != 6);
}
if (ret != alloc_outcome_t::SUCCESS) { if (ret != alloc_outcome_t::SUCCESS) {
return ret; return ret;
} }
@ -617,15 +636,15 @@ alloc_outcome_t sf_sched::alloc_ul_user(sched_ue* user, prb_interval alloc)
ul_alloc_t::type_t alloc_type; ul_alloc_t::type_t alloc_type;
ul_harq_proc* h = user->get_ul_harq(get_tti_tx_ul(), cc_cfg->enb_cc_idx); ul_harq_proc* h = user->get_ul_harq(get_tti_tx_ul(), cc_cfg->enb_cc_idx);
bool has_retx = h->has_pending_retx(); bool has_retx = h->has_pending_retx();
if (has_retx) { if (not has_retx) {
if (h->retx_requires_pdcch(tti_point{get_tti_tx_ul()}, alloc)) { alloc_type = ul_alloc_t::NEWTX;
} else if (h->is_msg3()) {
alloc_type = ul_alloc_t::MSG3_RETX;
} else if (h->retx_requires_pdcch(tti_point{get_tti_tx_ul()}, alloc)) {
alloc_type = ul_alloc_t::ADAPT_RETX; alloc_type = ul_alloc_t::ADAPT_RETX;
} else { } else {
alloc_type = ul_alloc_t::NOADAPT_RETX; alloc_type = ul_alloc_t::NOADAPT_RETX;
} }
} else {
alloc_type = ul_alloc_t::NEWTX;
}
return alloc_ul(user, alloc, alloc_type); return alloc_ul(user, alloc, alloc_type);
} }

View File

@ -221,11 +221,14 @@ sched_cell_params_t::dl_lb_nof_re_table get_lb_nof_re_x_prb(const sched_cell_par
srslte::bounded_vector<uint32_t, SRSLTE_MAX_PRB> re_prb_vec(table.size()); srslte::bounded_vector<uint32_t, SRSLTE_MAX_PRB> re_prb_vec(table.size());
for (uint32_t p = 0; p < table.size(); ++p) { for (uint32_t p = 0; p < table.size(); ++p) {
for (uint32_t s = 0; s < SRSLTE_NOF_SLOTS_PER_SF; ++s) { for (uint32_t s = 0; s < SRSLTE_NOF_SLOTS_PER_SF; ++s) {
// assume max CFI to compute lower bound
re_prb_vec[p] += table[p][sf_idx][s][SRSLTE_NOF_CFI - 1]; re_prb_vec[p] += table[p][sf_idx][s][SRSLTE_NOF_CFI - 1];
} }
} }
srslte::bounded_vector<uint32_t, SRSLTE_MAX_PRB> re_prb_vec2(re_prb_vec.size()); srslte::bounded_vector<uint32_t, SRSLTE_MAX_PRB> re_prb_vec2(re_prb_vec.size());
std::copy(re_prb_vec.begin(), re_prb_vec.end(), re_prb_vec2.begin()); std::copy(re_prb_vec.begin(), re_prb_vec.end(), re_prb_vec2.begin());
// pick intervals of PRBs with the lowest sum of REs
ret[sf_idx][0] = *std::min_element(re_prb_vec2.begin(), re_prb_vec2.end()); ret[sf_idx][0] = *std::min_element(re_prb_vec2.begin(), re_prb_vec2.end());
for (uint32_t p = 1; p < table.size(); ++p) { for (uint32_t p = 1; p < table.size(); ++p) {
std::transform(re_prb_vec2.begin(), std::transform(re_prb_vec2.begin(),
@ -323,6 +326,13 @@ bool sched_cell_params_t::set_cfg(uint32_t enb_cc_id
nof_cce_table[cfix] = (uint32_t)ret; nof_cce_table[cfix] = (uint32_t)ret;
} }
// PUCCH config struct for PUCCH position derivation
pucch_cfg_common.format = SRSLTE_PUCCH_FORMAT_1;
pucch_cfg_common.delta_pucch_shift = cfg.delta_pucch_shift;
pucch_cfg_common.n_rb_2 = cfg.nrb_cqi;
pucch_cfg_common.N_cs = cfg.ncs_an;
pucch_cfg_common.N_pucch_1 = cfg.n1pucch_an;
P = srslte_ra_type0_P(cfg.cell.nof_prb); P = srslte_ra_type0_P(cfg.cell.nof_prb);
nof_rbgs = srslte::ceil_div(cfg.cell.nof_prb, P); nof_rbgs = srslte::ceil_div(cfg.cell.nof_prb, P);

View File

@ -616,11 +616,6 @@ int sched_ue::generate_format0(sched_interface::ul_sched_data_t* data,
bool is_newtx = h->is_empty(0); bool is_newtx = h->is_empty(0);
if (is_newtx) { if (is_newtx) {
uint32_t nof_retx;
// If Msg3 set different nof retx
nof_retx = (data->needs_pdcch) ? get_max_retx() : max_msg3retx;
if (tbinfo.mcs >= 0) { if (tbinfo.mcs >= 0) {
tbinfo.tbs_bytes = get_tbs_bytes(tbinfo.mcs, alloc.length(), false, true); tbinfo.tbs_bytes = get_tbs_bytes(tbinfo.mcs, alloc.length(), false, true);
} else { } else {
@ -653,7 +648,9 @@ int sched_ue::generate_format0(sched_interface::ul_sched_data_t* data,
// NOTE: if (nof_re < nof_uci_re) we should set TBS=0 // NOTE: if (nof_re < nof_uci_re) we should set TBS=0
} }
} }
h->new_tx(tti_tx_ul, tbinfo.mcs, tbinfo.tbs_bytes, alloc, nof_retx); // If Msg3 set different nof retx
uint32_t nof_retx = (data->needs_pdcch) ? get_max_retx() : max_msg3retx;
h->new_tx(tti_tx_ul, tbinfo.mcs, tbinfo.tbs_bytes, alloc, nof_retx, not data->needs_pdcch);
// Un-trigger the SR if data is allocated // Un-trigger the SR if data is allocated
if (tbinfo.tbs_bytes > 0) { if (tbinfo.tbs_bytes > 0) {
unset_sr(); unset_sr();

View File

@ -235,12 +235,13 @@ bool ul_harq_proc::has_pending_retx() const
return has_pending_retx_common(0); return has_pending_retx_common(0);
} }
void ul_harq_proc::new_tx(tti_point tti_, int mcs, int tbs, prb_interval alloc, uint32_t max_retx_) void ul_harq_proc::new_tx(tti_point tti_, int mcs, int tbs, prb_interval alloc, uint32_t max_retx_, bool is_msg3)
{ {
allocation = alloc; allocation = alloc;
new_tx_common(0, tti_point{tti_}, mcs, tbs, max_retx_); new_tx_common(0, tti_point{tti_}, mcs, tbs, max_retx_);
pending_data = tbs; pending_data = tbs;
pending_phich = true; pending_phich = true;
is_msg3_ = is_msg3;
} }
void ul_harq_proc::new_retx(tti_point tti_, int* mcs, int* tbs, prb_interval alloc) void ul_harq_proc::new_retx(tti_point tti_, int* mcs, int* tbs, prb_interval alloc)