mirror of https://github.com/PentHertz/srsLTE.git
sched,nr: ensure PUCCH is generated for SR even if the UE doesn't have any pending ACK
This commit is contained in:
parent
3bbf173149
commit
00cc8fb8d8
|
@ -33,6 +33,7 @@ using slot_coreset_list = std::array<srsran::optional<coreset_re
|
||||||
using pdsch_t = mac_interface_phy_nr::pdsch_t;
|
using pdsch_t = mac_interface_phy_nr::pdsch_t;
|
||||||
using pdsch_list_t = srsran::bounded_vector<pdsch_t, MAX_GRANTS>;
|
using pdsch_list_t = srsran::bounded_vector<pdsch_t, MAX_GRANTS>;
|
||||||
using sched_rar_list_t = sched_nr_interface::sched_rar_list_t;
|
using sched_rar_list_t = sched_nr_interface::sched_rar_list_t;
|
||||||
|
using pucch_list_t = srsran::bounded_vector<pucch_t, MAX_GRANTS>;
|
||||||
|
|
||||||
struct harq_ack_t {
|
struct harq_ack_t {
|
||||||
const srsran::phy_cfg_nr_t* phy_cfg;
|
const srsran::phy_cfg_nr_t* phy_cfg;
|
||||||
|
@ -49,6 +50,7 @@ struct bwp_slot_grid {
|
||||||
pdcch_dl_list_t dl_pdcchs;
|
pdcch_dl_list_t dl_pdcchs;
|
||||||
pdcch_ul_list_t ul_pdcchs;
|
pdcch_ul_list_t ul_pdcchs;
|
||||||
pdsch_list_t pdschs;
|
pdsch_list_t pdschs;
|
||||||
|
pucch_list_t pucch;
|
||||||
sched_rar_list_t rar;
|
sched_rar_list_t rar;
|
||||||
slot_coreset_list coresets;
|
slot_coreset_list coresets;
|
||||||
pusch_list_t puschs;
|
pusch_list_t puschs;
|
||||||
|
|
|
@ -45,16 +45,17 @@ public:
|
||||||
int dl_pending_bytes = 0, ul_pending_bytes = 0;
|
int dl_pending_bytes = 0, ul_pending_bytes = 0;
|
||||||
|
|
||||||
// UE parameters that are sector specific
|
// UE parameters that are sector specific
|
||||||
const bwp_ue_cfg* cfg = nullptr;
|
const bwp_ue_cfg* cfg = nullptr;
|
||||||
harq_entity* harq_ent = nullptr;
|
harq_entity* harq_ent = nullptr;
|
||||||
slot_point pdcch_slot;
|
slot_point pdcch_slot;
|
||||||
slot_point pdsch_slot;
|
slot_point pdsch_slot;
|
||||||
slot_point pusch_slot;
|
slot_point pusch_slot;
|
||||||
slot_point uci_slot;
|
slot_point uci_slot;
|
||||||
uint32_t dl_cqi = 0;
|
uint32_t dl_cqi = 0;
|
||||||
uint32_t ul_cqi = 0;
|
uint32_t ul_cqi = 0;
|
||||||
dl_harq_proc* h_dl = nullptr;
|
dl_harq_proc* h_dl = nullptr;
|
||||||
ul_harq_proc* h_ul = nullptr;
|
ul_harq_proc* h_ul = nullptr;
|
||||||
|
srsran_uci_cfg_nr_t uci_cfg = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
class ue_carrier
|
class ue_carrier
|
||||||
|
|
|
@ -52,6 +52,7 @@ private:
|
||||||
|
|
||||||
void alloc_dl_ues();
|
void alloc_dl_ues();
|
||||||
void alloc_ul_ues();
|
void alloc_ul_ues();
|
||||||
|
void postprocess_decisions();
|
||||||
|
|
||||||
const sched_cell_params& cfg;
|
const sched_cell_params& cfg;
|
||||||
serv_cell_manager& cell;
|
serv_cell_manager& cell;
|
||||||
|
|
|
@ -94,6 +94,9 @@ void slot_cc_worker::run(slot_point pdcch_slot, ue_map_t& ue_db)
|
||||||
alloc_dl_ues();
|
alloc_dl_ues();
|
||||||
alloc_ul_ues();
|
alloc_ul_ues();
|
||||||
|
|
||||||
|
// Post-processing of scheduling decisions
|
||||||
|
postprocess_decisions();
|
||||||
|
|
||||||
// Log CC scheduler result
|
// Log CC scheduler result
|
||||||
log_sched_bwp_result(logger, bwp_alloc.get_pdcch_tti(), cell.bwps[0].grid, slot_ues);
|
log_sched_bwp_result(logger, bwp_alloc.get_pdcch_tti(), cell.bwps[0].grid, slot_ues);
|
||||||
|
|
||||||
|
@ -118,6 +121,82 @@ void slot_cc_worker::alloc_ul_ues()
|
||||||
cell.bwps[0].data_sched->sched_ul_users(slot_ues, bwp_alloc);
|
cell.bwps[0].data_sched->sched_ul_users(slot_ues, bwp_alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void slot_cc_worker::postprocess_decisions()
|
||||||
|
{
|
||||||
|
auto& bwp_slot = cell.bwps[0].grid[bwp_alloc.get_pdcch_tti()];
|
||||||
|
srsran_slot_cfg_t slot_cfg{};
|
||||||
|
slot_cfg.idx = bwp_alloc.get_pdcch_tti().slot_idx();
|
||||||
|
|
||||||
|
for (auto& ue_pair : slot_ues) {
|
||||||
|
auto& ue = ue_pair.second;
|
||||||
|
// Group pending HARQ ACKs
|
||||||
|
srsran_pdsch_ack_nr_t ack = {};
|
||||||
|
|
||||||
|
for (auto& h_ack : bwp_slot.pending_acks) {
|
||||||
|
if (h_ack.res.rnti == ue.rnti) {
|
||||||
|
ack.nof_cc = 1;
|
||||||
|
|
||||||
|
srsran_harq_ack_m_t ack_m = {};
|
||||||
|
ack_m.resource = h_ack.res;
|
||||||
|
ack_m.present = true;
|
||||||
|
srsran_harq_ack_insert_m(&ack, &ack_m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
srsran_uci_cfg_nr_t uci_cfg = {};
|
||||||
|
if (not ue.cfg->phy().get_uci_cfg(slot_cfg, ack, uci_cfg)) {
|
||||||
|
logger.error("Error getting UCI configuration");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ue.h_ul != nullptr and ue.h_ul->harq_slot_tx() == ue.pusch_slot) {
|
||||||
|
// PUSCH was allocated. Insert UCI in PUSCH
|
||||||
|
for (auto& pusch : bwp_slot.puschs) {
|
||||||
|
if (pusch.sch.grant.rnti == ue.rnti) {
|
||||||
|
// Put UCI configuration in PUSCH config
|
||||||
|
if (not ue.cfg->phy().get_pusch_uci_cfg(slot_cfg, uci_cfg, pusch.sch)) {
|
||||||
|
logger.error("Error setting UCI configuration in PUSCH");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If any UCI information is triggered, schedule PUCCH
|
||||||
|
if (uci_cfg.ack.count > 0 || uci_cfg.nof_csi > 0 || uci_cfg.o_sr > 0) {
|
||||||
|
bwp_slot.pucch.emplace_back();
|
||||||
|
mac_interface_phy_nr::pucch_t& pucch = bwp_slot.pucch.back();
|
||||||
|
|
||||||
|
uci_cfg.pucch.rnti = ue.rnti;
|
||||||
|
pucch.candidates.emplace_back();
|
||||||
|
pucch.candidates.back().uci_cfg = uci_cfg;
|
||||||
|
if (not ue.cfg->phy().get_pucch_uci_cfg(slot_cfg, uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource)) {
|
||||||
|
logger.error("Error getting UCI CFG");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this slot has a SR opportunity and the selected PUCCH format is 1, consider positive SR.
|
||||||
|
if (uci_cfg.o_sr > 0 and uci_cfg.ack.count > 0 and
|
||||||
|
pucch.candidates.back().resource.format == SRSRAN_PUCCH_NR_FORMAT_1) {
|
||||||
|
// Set SR negative
|
||||||
|
if (uci_cfg.o_sr > 0) {
|
||||||
|
uci_cfg.sr_positive_present = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append new resource
|
||||||
|
pucch.candidates.emplace_back();
|
||||||
|
pucch.candidates.back().uci_cfg = uci_cfg;
|
||||||
|
if (not ue.cfg->phy().get_pucch_uci_cfg(
|
||||||
|
slot_cfg, uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource)) {
|
||||||
|
logger.error("Error getting UCI CFG");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
sched_worker_manager::sched_worker_manager(ue_map_t& ue_db_,
|
sched_worker_manager::sched_worker_manager(ue_map_t& ue_db_,
|
||||||
|
@ -255,59 +334,7 @@ bool sched_worker_manager::save_sched_result(slot_point pdcch_slot,
|
||||||
dl_res.dl_sched.pdsch = bwp_slot.pdschs;
|
dl_res.dl_sched.pdsch = bwp_slot.pdschs;
|
||||||
dl_res.rar = bwp_slot.rar;
|
dl_res.rar = bwp_slot.rar;
|
||||||
ul_res.pusch = bwp_slot.puschs;
|
ul_res.pusch = bwp_slot.puschs;
|
||||||
|
ul_res.pucch = bwp_slot.pucch;
|
||||||
// Group pending HARQ ACKs
|
|
||||||
srsran_pdsch_ack_nr_t ack = {};
|
|
||||||
ack.nof_cc = not bwp_slot.pending_acks.empty();
|
|
||||||
const srsran::phy_cfg_nr_t* phy_cfg = nullptr;
|
|
||||||
for (const harq_ack_t& pending_ack : bwp_slot.pending_acks) {
|
|
||||||
srsran_harq_ack_m_t ack_m = {};
|
|
||||||
ack_m.resource = pending_ack.res;
|
|
||||||
ack_m.present = true;
|
|
||||||
srsran_harq_ack_insert_m(&ack, &ack_m);
|
|
||||||
phy_cfg = pending_ack.phy_cfg;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (phy_cfg != nullptr) {
|
|
||||||
srsran_slot_cfg_t slot_cfg{};
|
|
||||||
slot_cfg.idx = pdcch_slot.slot_idx();
|
|
||||||
srsran_uci_cfg_nr_t uci_cfg = {};
|
|
||||||
srsran_assert(phy_cfg->get_uci_cfg(slot_cfg, ack, uci_cfg), "Error getting UCI CFG");
|
|
||||||
|
|
||||||
if (uci_cfg.ack.count > 0 || uci_cfg.nof_csi > 0 || uci_cfg.o_sr > 0) {
|
|
||||||
if (not ul_res.pusch.empty()) {
|
|
||||||
// Put UCI configuration in PUSCH config
|
|
||||||
bool ret = phy_cfg->get_pusch_uci_cfg(slot_cfg, uci_cfg, ul_res.pusch[0].sch);
|
|
||||||
srsran_assert(ret, "Error setting UCI configuration in PUSCH");
|
|
||||||
} else {
|
|
||||||
// Put UCI configuration in PUCCH config
|
|
||||||
ul_res.pucch.emplace_back();
|
|
||||||
pucch_t& pucch = ul_res.pucch.back();
|
|
||||||
pucch.candidates.emplace_back();
|
|
||||||
pucch.candidates.back().uci_cfg = uci_cfg;
|
|
||||||
srsran_assert(phy_cfg->get_pucch_uci_cfg(
|
|
||||||
slot_cfg, pucch.candidates.back().uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource),
|
|
||||||
"Error getting PUCCH UCI cfg");
|
|
||||||
|
|
||||||
// If this slot has a SR opportunity and the selected PUCCH format is 1, consider positive SR.
|
|
||||||
if (uci_cfg.sr_positive_present and uci_cfg.ack.count > 0 and
|
|
||||||
pucch.candidates.back().resource.format == SRSRAN_PUCCH_NR_FORMAT_1) {
|
|
||||||
// Set SR negative
|
|
||||||
if (uci_cfg.o_sr > 0) {
|
|
||||||
uci_cfg.sr_positive_present = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append new resource
|
|
||||||
pucch.candidates.emplace_back();
|
|
||||||
pucch.candidates.back().uci_cfg = uci_cfg;
|
|
||||||
srsran_assert(
|
|
||||||
phy_cfg->get_pucch_uci_cfg(
|
|
||||||
slot_cfg, pucch.candidates.back().uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource),
|
|
||||||
"Error getting PUCCH UCI cfg");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear up BWP slot
|
// clear up BWP slot
|
||||||
bwp_slot.reset();
|
bwp_slot.reset();
|
||||||
|
|
Loading…
Reference in New Issue