sched,nr: add function that schedule SSB

Notes:
- NOT YET TESTED
- Requires rebase on commit with PHY changes to work

Signed-off-by: Carlo Galiotto <carlo@srs.io>
master
Carlo Galiotto 3 years ago committed by Andre Puschmann
parent c9d7db7314
commit 9d864bbe55

@ -41,6 +41,8 @@ struct harq_ack_t {
}; };
using harq_ack_list_t = srsran::bounded_vector<harq_ack_t, MAX_GRANTS>; using harq_ack_list_t = srsran::bounded_vector<harq_ack_t, MAX_GRANTS>;
// save data for scheduler to keep track of previous allocations
// This only contains information about a given slot
struct bwp_slot_grid { struct bwp_slot_grid {
uint32_t slot_idx = 0; uint32_t slot_idx = 0;
const bwp_params* cfg = nullptr; const bwp_params* cfg = nullptr;
@ -79,6 +81,7 @@ struct bwp_res_grid {
const bwp_params* cfg = nullptr; const bwp_params* cfg = nullptr;
private: private:
// TTIMOD_SZ is the longest allocation in the future
srsran::bounded_vector<bwp_slot_grid, TTIMOD_SZ> slots; srsran::bounded_vector<bwp_slot_grid, TTIMOD_SZ> slots;
}; };

@ -24,6 +24,8 @@ void sched_nzp_csi_rs(srsran::const_span<srsran_csi_rs_nzp_set_t> nzp_csi_rs_set
const srsran_slot_cfg_t& slot_cfg, const srsran_slot_cfg_t& slot_cfg,
nzp_csi_rs_list& csi_rs_list); nzp_csi_rs_list& csi_rs_list);
void sched_ssb_basic(const slot_point& sl_point, uint32_t ssb_periodicity, ssb_list& ssb_list);
/// For a given BWP and slot, schedule SSB, NZP CSI RS and SIBs /// For a given BWP and slot, schedule SSB, NZP CSI RS and SIBs
void sched_dl_signalling(const bwp_params& bwp_params, void sched_dl_signalling(const bwp_params& bwp_params,
slot_point sl_pdcch, slot_point sl_pdcch,

@ -182,6 +182,8 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t
return alloc_result::success; return alloc_result::success;
} }
// ue is the UE (1 only) that will be allocated
// func computes the grant allocation for this UE
alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_grant) alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_grant)
{ {
if (ue.cfg->active_bwp().bwp_id != bwp_grid.cfg->bwp_id) { if (ue.cfg->active_bwp().bwp_id != bwp_grid.cfg->bwp_id) {
@ -195,12 +197,12 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr
} }
bwp_slot_grid& bwp_pdcch_slot = bwp_grid[ue.pdcch_slot]; bwp_slot_grid& bwp_pdcch_slot = bwp_grid[ue.pdcch_slot];
bwp_slot_grid& bwp_pdsch_slot = bwp_grid[ue.pdsch_slot]; bwp_slot_grid& bwp_pdsch_slot = bwp_grid[ue.pdsch_slot];
bwp_slot_grid& bwp_uci_slot = bwp_grid[ue.uci_slot]; bwp_slot_grid& bwp_uci_slot = bwp_grid[ue.uci_slot]; // UCI : UL control info
alloc_result result = verify_pdsch_space(bwp_pdsch_slot, bwp_pdcch_slot); alloc_result result = verify_pdsch_space(bwp_pdsch_slot, bwp_pdcch_slot);
if (result != alloc_result::success) { if (result != alloc_result::success) {
return result; return result;
} }
if (bwp_pdcch_slot.dl_prbs.collides(dl_grant)) { if (bwp_pdsch_slot.dl_prbs.collides(dl_grant)) {
return alloc_result::sch_collision; return alloc_result::sch_collision;
} }

@ -12,6 +12,11 @@
#include "srsenb/hdr/stack/mac/nr/sched_nr_signalling.h" #include "srsenb/hdr/stack/mac/nr/sched_nr_signalling.h"
#define POS_IN_BURST_FIRST_BIT_IDX 0
#define POS_IN_BURST_SECOND_BIT_IDX 1
#define POS_IN_BURST_THIRD_BIT_IDX 2
#define POS_IN_BURST_FOURTH_BIT_IDX 3
namespace srsenb { namespace srsenb {
namespace sched_nr_impl { namespace sched_nr_impl {
@ -33,6 +38,83 @@ void sched_nzp_csi_rs(srsran::const_span<srsran_csi_rs_nzp_set_t> nzp_csi_rs_set
} }
} }
void sched_ssb_basic(const slot_point& sl_point, uint32_t ssb_periodicity, ssb_list& ssb_list)
{
/* This function is extremely simplified.
* It works based on the following assumptions (hard-coded parameters)
* 1) 15kHz subcarrier spacing
* 2) Below 3GHz
* 3) Position in Burst 1000
* */
uint32_t sl_idx = sl_point.to_uint();
uint32_t ssb_sf_idx = sl_point.to_uint() % ssb_periodicity;
// code below is simplified
if (ssb_sf_idx == 0)
{
ssb_t ssb_msg = {};
srsran_mib_nr_t mib_msg = {};
mib_msg.sfn = sl_point.sfn();
mib_msg.hrf = (sl_idx % SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz) < SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz) / 2);
mib_msg.ssb_idx = 0; // This corresponds to "Position in Burst" = 1000
srsran_pbch_msg_nr_mib_pack(&mib_msg, &ssb_msg.pbch_msg);
ssb_list.push_back(ssb_msg);
}
}
#if 0
void sched_ssb(int slot_idx, int ssb_periodicity, srsran::bounded_bitset<4>& pos_in_burst)
{
/* Input needed:
* - slot_idx: slot index
* - ssb_periodicity: Periodicity of SSB in ms
* - pos_in_burst: position in Burst (bit map indicating in which SSB opportunities gNB needs to tx
*
* Parameters that could be passed but are currently hard-coded
* - Subcarrier spacing: 15kHz
* - Frequency (info on whether carrier is above or below 3GHz)
*
* NOTE: this function is hard coded for frequency < 3GHz,
* and SubCarrierSpacing 15kHz. Therefore, we assume
* 1 slot = 1ms
* */
// NOTE: This
// This function only implements SSB for frequency < 3GHz, and SubCarrierSpacing 15kHz
// In this case, 1 slot = 1ms
int ssb_sf_idx = slot_idx % ssb_periodicity;
// if slot falls into the correct periodicity, continue with further checks
// check if slot is
// code below will be simplified, depending on struct used
if (ssb_sf_idx == 0)
{
// check first two bit in bitmap (position in burst)
// and pack corresponding SSB for slot 0
if ( pos_in_burst.test(POS_IN_BURST_FIRST_BIT_IDX) )
printf("Pack first SSB in slot 0 ");
if ( pos_in_burst.test(POS_IN_BURST_SECOND_BIT_IDX) )
printf("Pack second SSB in slot 0 ");
}
else if (ssb_sf_idx == 1)
{
// check second two bit in bitmap (position in burst)
// and pack corresponding SSB for slot 1
if ( pos_in_burst.test(POS_IN_BURST_FIRST_BIT_IDX) )
printf("Pack first SSB in slot 1 ");
if ( pos_in_burst.test(POS_IN_BURST_SECOND_BIT_IDX) )
printf("Pack second SSB in slot 1 ");
}
else
// nothing to do here
return;
}
#endif
void sched_dl_signalling(const bwp_params& bwp_params, void sched_dl_signalling(const bwp_params& bwp_params,
slot_point sl_pdcch, slot_point sl_pdcch,
ssb_list& ssb_list, ssb_list& ssb_list,
@ -42,7 +124,7 @@ void sched_dl_signalling(const bwp_params& bwp_params,
cfg.idx = sl_pdcch.to_uint(); cfg.idx = sl_pdcch.to_uint();
// Schedule SSB // Schedule SSB
// TODO sched_ssb_basic(sl_pdcch, bwp_params.cell_cfg.ssb.periodicity_ms, ssb_list);
// Schedule NZP-CSI-RS // Schedule NZP-CSI-RS
sched_nzp_csi_rs(bwp_params.cfg.pdsch.nzp_csi_rs_sets, cfg, nzp_csi_rs); sched_nzp_csi_rs(bwp_params.cfg.pdsch.nzp_csi_rs_sets, cfg, nzp_csi_rs);

@ -68,10 +68,10 @@ void slot_cc_worker::run(slot_point pdcch_slot, ue_map_t& ue_db)
srsran_assert(not running(), "scheduler worker::start() called for active worker"); srsran_assert(not running(), "scheduler worker::start() called for active worker");
slot_rx = pdcch_slot - TX_ENB_DELAY; slot_rx = pdcch_slot - TX_ENB_DELAY;
// Run pending cell feedback // Run pending cell feedback (process feedback)
run_feedback(ue_db); run_feedback(ue_db);
// Reserve UEs for this worker slot // Reserve UEs for this worker slot (select candidate UEs)
for (auto& ue_pair : ue_db) { for (auto& ue_pair : ue_db) {
uint16_t rnti = ue_pair.first; uint16_t rnti = ue_pair.first;
ue& u = *ue_pair.second; ue& u = *ue_pair.second;
@ -79,6 +79,7 @@ void slot_cc_worker::run(slot_point pdcch_slot, ue_map_t& ue_db)
continue; continue;
} }
// info for a given UE on a slot to be process
slot_ues.insert(rnti, u.try_reserve(pdcch_slot, cfg.cc)); slot_ues.insert(rnti, u.try_reserve(pdcch_slot, cfg.cc));
if (slot_ues[rnti].empty()) { if (slot_ues[rnti].empty()) {
// Failed to generate slot UE because UE has no conditions for DL/UL tx // Failed to generate slot UE because UE has no conditions for DL/UL tx

Loading…
Cancel
Save