nr,gnb,sched: refactor filling of dci harq fields

This commit is contained in:
Francisco 2021-12-10 20:42:04 +00:00 committed by Francisco Paisana
parent 632f2dbddd
commit 2a933ed8ad
7 changed files with 158 additions and 146 deletions

View File

@ -116,7 +116,6 @@ public:
private:
alloc_result verify_uci_space(const bwp_slot_grid& uci_grid) const;
alloc_result verify_ue_cfg(const ue_carrier_params_t& ue_cfg, harq_proc* harq) const;
bwp_res_grid& bwp_grid;

View File

@ -48,8 +48,6 @@ public:
bool clear_if_maxretx(slot_point slot_rx);
void reset();
bool new_tx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant, uint32_t mcs, uint32_t max_retx);
bool new_retx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant);
bool new_retx(slot_point slot_tx, slot_point slot_ack);
// NOTE: Has to be used before first tx is dispatched
@ -58,7 +56,10 @@ public:
const uint32_t pid;
private:
protected:
bool new_tx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant, uint32_t mcs, uint32_t max_retx);
bool new_retx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant);
struct tb_t {
bool active = false;
bool ack_state = false;
@ -83,9 +84,18 @@ public:
tx_harq_softbuffer& get_softbuffer() { return *softbuffer; }
srsran::unique_byte_buffer_t* get_tx_pdu() { return &pdu; }
bool new_tx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant, uint32_t mcs, uint32_t max_retx);
bool new_tx(slot_point slot_tx,
slot_point slot_ack,
const prb_grant& grant,
uint32_t mcs,
uint32_t max_retx,
srsran_dci_dl_nr_t& dci);
bool new_retx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant, srsran_dci_dl_nr_t& dci);
private:
void fill_dci(srsran_dci_dl_nr_t& dci);
srsran::unique_pool_ptr<tx_harq_softbuffer> softbuffer;
srsran::unique_byte_buffer_t pdu;
};
@ -97,6 +107,10 @@ public:
harq_proc(id_), softbuffer(harq_softbuffer_pool::get_instance().get_rx(nprb))
{}
bool new_tx(slot_point slot_tx, const prb_grant& grant, uint32_t mcs, uint32_t max_retx, srsran_dci_ul_nr_t& dci);
bool new_retx(slot_point slot_tx, const prb_grant& grant, srsran_dci_ul_nr_t& dci);
rx_harq_softbuffer& get_softbuffer() { return *softbuffer; }
bool set_tbs(uint32_t tbs)
@ -106,6 +120,8 @@ public:
}
private:
void fill_dci(srsran_dci_ul_nr_t& dci);
srsran::unique_pool_ptr<rx_harq_softbuffer> softbuffer;
};

View File

@ -48,14 +48,6 @@ inline bool is_rnti_type_valid_in_search_space(srsran_rnti_type_t rnti_type, srs
return false;
}
bool fill_dci_msg3(const slot_ue& ue, const bwp_params_t& bwp_cfg, srsran_dci_ul_nr_t& dci);
/// Generate PDCCH DL DCI fields
void fill_dl_dci_ue_fields(const slot_ue& ue, srsran_dci_dl_nr_t& dci);
/// Generate PDCCH UL DCI fields
void fill_ul_dci_ue_fields(const slot_ue& ue, srsran_dci_ul_nr_t& dci);
/// Log UE state for slot being scheduled
void log_sched_slot_ues(srslog::basic_logger& logger,
slot_point pdcch_slot,

View File

@ -136,7 +136,7 @@ alloc_result bwp_slot_allocator::alloc_si(uint32_t aggr_idx,
}
pdcch_dl_t& pdcch = *pdcch_result.value();
// Allocate PDSCH
// Allocate PDSCH (no need to verify again if there is space in PDSCH)
pdsch_t& pdsch = bwp_pdcch_slot.pdschs.alloc_si_pdsch_unchecked(ss_id, prbs, pdcch.dci);
// Generate DCI for SIB
@ -176,7 +176,7 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t
slot_point msg3_slot = pdcch_slot + cfg.pusch_ra_list[m].msg3_delay;
bwp_slot_grid& bwp_msg3_slot = bwp_grid[msg3_slot];
// Verify there is space in PDSCH
// Verify there is space in PDSCH for RAR
alloc_result ret = bwp_pdcch_slot.pdschs.is_rar_grant_valid(interv);
if (ret != alloc_result::success) {
return ret;
@ -210,22 +210,20 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t
return alloc_result::sch_collision;
}
// Allocate PDCCH position
// Allocate PDCCH position for RAR
auto pdcch_result = bwp_pdcch_slot.pdcchs.alloc_rar_pdcch(ra_rnti, aggr_idx);
if (pdcch_result.is_error()) {
// Could not find space in PDCCH
return pdcch_result.error();
}
pdcch_dl_t& pdcch = *pdcch_result.value();
// Allocate PDSCH
pdsch_t& pdsch = bwp_pdcch_slot.pdschs.alloc_rar_pdsch_unchecked(interv, pdcch.dci);
// Generate DCI for RAR with given RA-RNTI
pdcch.dci_cfg = slot_ues[pending_rachs[0].temp_crnti]->get_dci_cfg();
pdcch.dci.mcs = 5;
// Generate RAR PDSCH
// Allocate RAR PDSCH
pdsch_t& pdsch = bwp_pdcch_slot.pdschs.alloc_rar_pdsch_unchecked(interv, pdcch.dci);
// Fill RAR PDSCH content
// TODO: Properly fill Msg3 grants
srsran_slot_cfg_t slot_cfg;
slot_cfg.idx = pdcch_slot.to_uint();
@ -247,15 +245,26 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t
rar_out.grants.emplace_back();
auto& rar_grant = rar_out.grants.back();
rar_grant.data = grant;
fill_dci_from_cfg(cfg, rar_grant.msg3_dci);
// Fill Msg3 DCI context
rar_grant.msg3_dci.ctx.coreset_id = pdcch.dci.ctx.coreset_id;
rar_grant.msg3_dci.ctx.rnti_type = srsran_rnti_type_tc;
rar_grant.msg3_dci.ctx.rnti = ue->rnti;
rar_grant.msg3_dci.ctx.ss_type = srsran_search_space_type_rar;
rar_grant.msg3_dci.ctx.format = srsran_dci_format_nr_rar;
// Allocate Msg3 PUSCH allocation
prb_interval msg3_interv{last_msg3, last_msg3 + msg3_nof_prbs};
last_msg3 += msg3_nof_prbs;
ue.h_ul = ue.find_empty_ul_harq();
bool success = ue.h_ul->new_tx(msg3_slot, msg3_slot, msg3_interv, mcs, max_harq_msg3_retx);
srsran_assert(success, "Failed to allocate Msg3");
fill_dci_msg3(ue, *bwp_grid.cfg, rar_grant.msg3_dci);
// Generate PUSCH
pusch_t& pusch = bwp_msg3_slot.puschs.alloc_pusch_unchecked(msg3_interv, rar_grant.msg3_dci);
// Allocate UL HARQ
ue.h_ul = ue.find_empty_ul_harq();
srsran_sanity_check(ue.h_ul != nullptr, "Failed to allocate Msg3");
bool success = ue.h_ul->new_tx(msg3_slot, msg3_interv, mcs, max_harq_msg3_retx, rar_grant.msg3_dci);
srsran_sanity_check(success, "Failed to allocate Msg3");
// Generate PUSCH content
success = ue->phy().get_pusch_cfg(slot_cfg, rar_grant.msg3_dci, pusch.sch);
srsran_assert(success, "Error converting DCI to PUSCH grant");
pusch.sch.grant.tb[0].softbuffer.rx = ue.h_ul->get_softbuffer().get();
@ -287,8 +296,8 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, uint32_t ss_id, const
if (result != alloc_result::success) {
return result;
}
result = verify_ue_cfg(ue.cfg(), ue.h_dl);
if (result != alloc_result::success) {
if (ue.h_dl == nullptr) {
logger.warning("SCHED: Trying to allocate rnti=0x%x with no available DL HARQs", ue->rnti);
return result;
}
if (not bwp_pdsch_slot.dl.phy.ssb.empty()) {
@ -297,7 +306,7 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, uint32_t ss_id, const
return alloc_result::no_sch_space;
}
// Find space in PUCCH
// Check space in PUCCH/PUSCH for UCI
// TODO
// Find space and allocate PDCCH
@ -307,6 +316,12 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, uint32_t ss_id, const
return pdcch_result.error();
}
pdcch_dl_t& pdcch = *pdcch_result.value();
pdcch.dci_cfg = ue->get_dci_cfg();
pdcch.dci.pucch_resource = 0;
pdcch.dci.dai = std::count_if(bwp_uci_slot.pending_acks.begin(),
bwp_uci_slot.pending_acks.end(),
[&ue](const harq_ack_t& p) { return p.res.rnti == ue->rnti; });
pdcch.dci.dai %= 4;
// Allocate PDSCH
pdsch_t& pdsch = bwp_pdcch_slot.pdschs.alloc_ue_pdsch_unchecked(ss_id, dci_fmt, dl_grant, ue.cfg(), pdcch.dci);
@ -314,42 +329,22 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, uint32_t ss_id, const
// Allocate HARQ
int mcs = ue->fixed_pdsch_mcs();
if (ue.h_dl->empty()) {
bool success = ue.h_dl->new_tx(ue.pdsch_slot, ue.uci_slot, dl_grant, mcs, 4);
bool success = ue.h_dl->new_tx(ue.pdsch_slot, ue.uci_slot, dl_grant, mcs, 4, pdcch.dci);
srsran_assert(success, "Failed to allocate DL HARQ");
} else {
bool success = ue.h_dl->new_retx(ue.pdsch_slot, ue.uci_slot, dl_grant);
bool success = ue.h_dl->new_retx(ue.pdsch_slot, ue.uci_slot, dl_grant, pdcch.dci);
mcs = ue.h_dl->mcs();
srsran_assert(success, "Failed to allocate DL HARQ retx");
}
const static float max_R = 0.93;
while (true) {
// Generate PDCCH
fill_dl_dci_ue_fields(ue, pdcch.dci);
pdcch.dci.pucch_resource = 0;
pdcch.dci.dai = std::count_if(bwp_uci_slot.pending_acks.begin(),
bwp_uci_slot.pending_acks.end(),
[&ue](const harq_ack_t& p) { return p.res.rnti == ue->rnti; });
pdcch.dci.dai %= 4;
pdcch.dci_cfg = ue->get_dci_cfg();
// Generate PUCCH
bwp_uci_slot.pending_acks.emplace_back();
bwp_uci_slot.pending_acks.back().phy_cfg = &ue->phy();
srsran_assert(ue->phy().get_pdsch_ack_resource(pdcch.dci, bwp_uci_slot.pending_acks.back().res),
"Error getting ack resource");
// Generate PDSCH
srsran_slot_cfg_t slot_cfg;
slot_cfg.idx = ue.pdsch_slot.to_uint();
const static float max_R = 0.95;
while (true) {
// Generate PDSCH
bool success = ue->phy().get_pdsch_cfg(slot_cfg, pdcch.dci, pdsch.sch);
srsran_assert(success, "Error converting DCI to grant");
pdsch.sch.grant.tb[0].softbuffer.tx = ue.h_dl->get_softbuffer().get();
pdsch.data[0] = ue.h_dl->get_tx_pdu()->get();
if (ue.h_dl->nof_retx() == 0) {
ue.h_dl->set_tbs(pdsch.sch.grant.tb[0].tbs); // update HARQ with correct TBS
} else {
if (ue.h_dl->nof_retx() != 0) {
srsran_assert(pdsch.sch.grant.tb[0].tbs == (int)ue.h_dl->tbs(), "The TBS did not remain constant in retx");
}
if (ue.h_dl->nof_retx() > 0 or bwp_pdsch_slot.dl.phy.pdsch.back().sch.grant.tb[0].R_prime < max_R or mcs <= 0) {
@ -358,16 +353,24 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, uint32_t ss_id, const
// Decrease MCS if first tx and rate is too high
mcs--;
ue.h_dl->set_mcs(mcs);
bwp_uci_slot.pending_acks.pop_back();
}
if (mcs == 0) {
logger.warning("Couldn't find mcs that leads to R<0.9");
logger.warning("Couldn't find mcs that leads to R<0.95");
}
ue.h_dl->set_tbs(pdsch.sch.grant.tb[0].tbs); // set HARQ TBS
pdsch.sch.grant.tb[0].softbuffer.tx = ue.h_dl->get_softbuffer().get();
pdsch.data[0] = ue.h_dl->get_tx_pdu()->get();
// Select scheduled LCIDs and update UE buffer state
bwp_pdsch_slot.dl.data.emplace_back();
ue.build_pdu(ue.h_dl->tbs(), bwp_pdsch_slot.dl.data.back());
// Generate PUCCH
bwp_uci_slot.pending_acks.emplace_back();
bwp_uci_slot.pending_acks.back().phy_cfg = &ue->phy();
srsran_assert(ue->phy().get_pdsch_ack_resource(pdcch.dci, bwp_uci_slot.pending_acks.back().res),
"Error getting ack resource");
return alloc_result::success;
}
@ -380,9 +383,9 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_gr
auto& bwp_pdcch_slot = bwp_grid[ue.pdcch_slot];
auto& bwp_pusch_slot = bwp_grid[ue.pusch_slot];
alloc_result ret = verify_ue_cfg(ue.cfg(), ue.h_ul);
if (ret != alloc_result::success) {
return ret;
if (ue.h_ul == nullptr) {
logger.warning("SCHED: Trying to allocate rnti=0x%x with no available UL HARQs", ue->rnti);
return alloc_result::no_rnti_opportunity;
}
// Choose SearchSpace + DCI format
@ -395,7 +398,7 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_gr
const srsran_search_space_t& ss = *ss_candidates[0];
// Verify if PUSCH allocation is valid
ret = bwp_pusch_slot.puschs.is_grant_valid(ss.type, ul_grant);
alloc_result ret = bwp_pusch_slot.puschs.is_grant_valid(ss.type, ul_grant);
if (ret != alloc_result::success) {
return ret;
}
@ -408,23 +411,20 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_gr
// Allocation Successful
pdcch_ul_t& pdcch = *pdcch_result.value();
pdcch.dci_cfg = ue->get_dci_cfg();
// Allocate PUSCH
pusch_t& pusch = bwp_pusch_slot.puschs.alloc_pusch_unchecked(ul_grant, pdcch.dci);
if (ue.h_ul->empty()) {
int mcs = ue->fixed_pusch_mcs();
bool success = ue.h_ul->new_tx(ue.pusch_slot, ue.pusch_slot, ul_grant, mcs, ue->ue_cfg().maxharq_tx);
bool success = ue.h_ul->new_tx(ue.pusch_slot, ul_grant, mcs, ue->ue_cfg().maxharq_tx, pdcch.dci);
srsran_assert(success, "Failed to allocate UL HARQ");
} else {
bool success = ue.h_ul->new_retx(ue.pusch_slot, ue.pusch_slot, ul_grant);
bool success = ue.h_ul->new_retx(ue.pusch_slot, ul_grant, pdcch.dci);
srsran_assert(success, "Failed to allocate UL HARQ retx");
}
// Generate PDCCH content
fill_ul_dci_ue_fields(ue, pdcch.dci);
pdcch.dci_cfg = ue->get_dci_cfg();
// Generate PUSCH content
srsran_slot_cfg_t slot_cfg;
slot_cfg.idx = ue.pusch_slot.to_uint();
@ -450,20 +450,6 @@ alloc_result bwp_slot_allocator::verify_uci_space(const bwp_slot_grid& uci_grid)
return alloc_result::success;
}
alloc_result bwp_slot_allocator::verify_ue_cfg(const ue_carrier_params_t& ue_cfg, harq_proc* harq) const
{
if (ue_cfg.active_bwp().bwp_id != cfg.bwp_id) {
logger.warning(
"SCHED: Trying to allocate rnti=0x%x in inactive BWP id=%d", ue_cfg.rnti, ue_cfg.active_bwp().bwp_id);
return alloc_result::no_rnti_opportunity;
}
if (harq == nullptr) {
logger.warning("SCHED: Trying to allocate rnti=0x%x with no available HARQs", ue_cfg.rnti);
return alloc_result::no_rnti_opportunity;
}
return alloc_result::success;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
prb_grant find_optimal_dl_grant(bwp_slot_allocator& slot_alloc, const slot_ue& ue, uint32_t ss_id)

View File

@ -115,14 +115,76 @@ dl_harq_proc::dl_harq_proc(uint32_t id_, uint32_t nprb) :
harq_proc(id_), softbuffer(harq_softbuffer_pool::get_instance().get_tx(nprb)), pdu(srsran::make_byte_buffer())
{}
void dl_harq_proc::fill_dci(srsran_dci_dl_nr_t& dci)
{
const static uint32_t rv_idx[4] = {0, 2, 3, 1};
dci.pid = pid;
dci.ndi = ndi();
dci.mcs = mcs();
dci.rv = rv_idx[nof_retx() % 4];
if (dci.ctx.format == srsran_dci_format_nr_1_0) {
dci.harq_feedback = (slot_ack - slot_tx) - 1;
} else {
dci.harq_feedback = slot_tx.to_uint();
}
}
bool dl_harq_proc::new_tx(slot_point slot_tx,
slot_point slot_ack,
const prb_grant& grant,
uint32_t mcs,
uint32_t max_retx)
uint32_t mcs_,
uint32_t max_retx,
srsran_dci_dl_nr_t& dci)
{
if (harq_proc::new_tx(slot_tx, slot_ack, grant, mcs, max_retx)) {
const static uint32_t rv_idx[4] = {0, 2, 3, 1};
if (harq_proc::new_tx(slot_tx, slot_ack, grant, mcs_, max_retx)) {
pdu->clear();
fill_dci(dci);
return true;
}
return false;
}
bool dl_harq_proc::new_retx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant, srsran_dci_dl_nr_t& dci)
{
if (harq_proc::new_retx(slot_tx, slot_ack, grant)) {
fill_dci(dci);
return true;
}
return false;
}
void ul_harq_proc::fill_dci(srsran_dci_ul_nr_t& dci)
{
const static uint32_t rv_idx[4] = {0, 2, 3, 1};
dci.pid = pid;
dci.ndi = ndi();
dci.mcs = mcs();
dci.rv = rv_idx[nof_retx() % 4];
}
bool ul_harq_proc::new_tx(slot_point slot_tx,
const prb_grant& grant,
uint32_t mcs_,
uint32_t max_retx,
srsran_dci_ul_nr_t& dci)
{
const static uint32_t rv_idx[4] = {0, 2, 3, 1};
if (harq_proc::new_tx(slot_tx, slot_tx, grant, mcs_, max_retx)) {
fill_dci(dci);
return true;
}
return false;
}
bool ul_harq_proc::new_retx(slot_point slot_tx, const prb_grant& grant, srsran_dci_ul_nr_t& dci)
{
if (harq_proc::new_retx(slot_tx, slot_tx, grant)) {
fill_dci(dci);
return true;
}
return false;

View File

@ -19,61 +19,6 @@
namespace srsenb {
namespace sched_nr_impl {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename DciDlOrUl>
void fill_dci_harq(const slot_ue& ue, DciDlOrUl& dci)
{
const static uint32_t rv_idx[4] = {0, 2, 3, 1};
harq_proc* h = std::is_same<DciDlOrUl, srsran_dci_dl_nr_t>::value ? static_cast<harq_proc*>(ue.h_dl)
: static_cast<harq_proc*>(ue.h_ul);
dci.pid = h->pid;
dci.ndi = h->ndi();
dci.mcs = h->mcs();
dci.rv = rv_idx[h->nof_retx() % 4];
}
bool fill_dci_msg3(const slot_ue& ue, const bwp_params_t& bwp_cfg, srsran_dci_ul_nr_t& msg3_dci)
{
// Fill DCI context
msg3_dci.ctx.coreset_id = ue->phy().pdcch.ra_search_space.coreset_id;
msg3_dci.ctx.rnti_type = srsran_rnti_type_tc;
msg3_dci.ctx.rnti = ue->rnti;
msg3_dci.ctx.ss_type = srsran_search_space_type_rar;
if (ue.h_ul->nof_retx() == 0) {
msg3_dci.ctx.format = srsran_dci_format_nr_rar;
} else {
msg3_dci.ctx.format = srsran_dci_format_nr_0_0;
}
// Fill DCI content
fill_dci_from_cfg(bwp_cfg, msg3_dci);
msg3_dci.time_domain_assigment = 0;
uint32_t nof_prb = bwp_cfg.nof_prb();
msg3_dci.freq_domain_assigment =
srsran_ra_nr_type1_riv(nof_prb, ue.h_ul->prbs().prbs().start(), ue.h_ul->prbs().prbs().length());
fill_dci_harq(ue, msg3_dci);
return true;
}
void fill_dl_dci_ue_fields(const slot_ue& ue, srsran_dci_dl_nr_t& dci)
{
fill_dci_harq(ue, dci);
if (dci.ctx.format == srsran_dci_format_nr_1_0) {
dci.harq_feedback = (ue.uci_slot - ue.pdsch_slot) - 1;
} else {
dci.harq_feedback = ue.pdsch_slot.slot_idx();
}
}
void fill_ul_dci_ue_fields(const slot_ue& ue, srsran_dci_ul_nr_t& dci)
{
fill_dci_harq(ue, dci);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void log_sched_slot_ues(srslog::basic_logger& logger, slot_point pdcch_slot, uint32_t cc, const slot_ue_map_t& slot_ues)

View File

@ -475,6 +475,18 @@ alloc_result bwp_pdcch_allocator::check_args_valid(srsran_rnti_type_t rn
return alloc_result::no_cch_space;
}
if (user != nullptr) {
if (user->active_bwp().bwp_id != bwp_cfg.bwp_id) {
log_pdcch_alloc_failure(logger.warning,
rnti_type,
ss_id,
rnti,
"Trying to allocate BWP#{} which is inactive for the UE.",
user->active_bwp().bwp_id);
return alloc_result::no_rnti_opportunity;
}
}
srsran_sanity_check(pdcch_dl_list.size() + pdcch_ul_list.size() == nof_allocations(), "Invalid PDCCH state");
return alloc_result::success;
}