1010
1111#include " slice_scheduler.h"
1212#include " ../policy/scheduler_policy_factory.h"
13+ #include " ../support/pusch/pusch_td_resource_indices.h"
1314#include " srsran/srslog/srslog.h"
1415
1516using namespace srsran ;
@@ -41,24 +42,48 @@ slice_scheduler::slice_scheduler(const cell_configuration& cell_cfg_, ue_reposit
4142 slices.back ().policy = create_scheduler_strategy (slice_scheduler_ue_expert_cfg);
4243 ++id_count;
4344 }
45+
46+ // NOTE: Below derivation assumes that only pusch-ConfigCommon includes pusch-TimeDomainAllocationList.
47+ // NOTE: [Implementation-defined] In case of FDD, we use only single value of k2.
48+ unsigned nof_slots = cell_cfg.is_tdd () ? nof_slots_per_tdd_period (*cell_cfg.tdd_cfg_common ) : 1 ;
49+ valid_pusch_td_list_per_slot.resize (nof_slots);
50+ for (unsigned slot_period_idx = 0 , e = nof_slots; slot_period_idx != e; ++slot_period_idx) {
51+ slot_point pdcch_slot{to_numerology_value (cell_cfg.dl_cfg_common .init_dl_bwp .generic_params .scs ), slot_period_idx};
52+ if (cell_cfg.is_dl_enabled (pdcch_slot)) {
53+ // TODO: Revisit when PUSCH time domain resource list is also defined in UE dedicated configuration.
54+ valid_pusch_td_list_per_slot[slot_period_idx] = get_pusch_td_resource_indices (cell_cfg, pdcch_slot);
55+ }
56+ }
4457}
4558
46- void slice_scheduler::slot_indication ()
59+ void slice_scheduler::slot_indication (slot_point slot_tx )
4760{
4861 slot_count++;
4962
5063 // Update the context of each slice.
5164 for (auto & slice : slices) {
52- slice.inst .slot_indication ();
65+ slice.inst .slot_indication (slot_tx );
5366 }
5467
68+ // TODO: Update slices (store_grant()) with already allocated grant in the previous slots.
69+
5570 // Recompute the priority queues.
5671 dl_prio_queue.clear ();
5772 ul_prio_queue.clear ();
5873 for (const auto & slice : slices) {
5974 unsigned max_rbs = slice.inst .cfg .min_prb > 0 ? slice.inst .cfg .min_prb : slice.inst .cfg .max_prb ;
60- dl_prio_queue.push (slice_candidate_context{slice.inst .id , slice.get_prio (true , slot_count, false ), {0 , max_rbs}});
61- ul_prio_queue.push (slice_candidate_context{slice.inst .id , slice.get_prio (false , slot_count, false ), {0 , max_rbs}});
75+ dl_prio_queue.push (slice_candidate_context{
76+ slice.inst .id , slice.get_prio (true , slot_count, false , slot_tx), {0 , max_rbs}, slot_tx});
77+
78+ // TODO: Revisit when PUSCH time domain resource list is also defined in UE dedicated configuration.
79+ span<const pusch_time_domain_resource_allocation> pusch_time_domain_list =
80+ cell_cfg.ul_cfg_common .init_ul_bwp .pusch_cfg_common .value ().pusch_td_alloc_list ;
81+ for (const unsigned pusch_td_res_idx :
82+ valid_pusch_td_list_per_slot[slot_tx.to_uint () % valid_pusch_td_list_per_slot.size ()]) {
83+ slot_point pusch_slot = slot_tx + pusch_time_domain_list[pusch_td_res_idx].k2 ;
84+ ul_prio_queue.push (slice_candidate_context{
85+ slice.inst .id , slice.get_prio (false , slot_count, false , pusch_slot), {0 , max_rbs}, pusch_slot});
86+ }
6287 }
6388}
6489
@@ -189,9 +214,11 @@ slice_scheduler::get_next_candidate()
189214 while (not prio_queue.empty ()) {
190215 ran_slice_sched_context& chosen_slice = slices[prio_queue.top ().id .value ()];
191216 interval<unsigned > rb_lims = prio_queue.top ().rb_lims ;
217+ slot_point slot_tx = prio_queue.top ().slot_tx ;
192218 prio_queue.pop ();
193219
194- unsigned rb_count = IsDownlink ? chosen_slice.inst .pdsch_rb_count : chosen_slice.inst .pusch_rb_count ;
220+ unsigned rb_count =
221+ IsDownlink ? chosen_slice.inst .pdsch_rb_count : chosen_slice.inst .pusch_rb_count_per_slot [slot_tx.to_uint ()];
195222 if (not rb_lims.contains (rb_count)) {
196223 // The slice has been scheduled in this slot with a number of RBs that is not within the limits for this
197224 // candidate. This could happen, for instance, if the scheduler could not schedule all RBs of a candidate
@@ -204,17 +231,17 @@ slice_scheduler::get_next_candidate()
204231 if (cfg.min_prb != cfg.max_prb and rb_lims.stop () == cfg.min_prb ) {
205232 // For the special case when minRB ratio>0, the first candidate for this slice was bounded between {0, minRB}.
206233 // We re-add the slice as a candidate, this time, with RB bounds {minRB, maxRB}.
207- priority_type prio = chosen_slice.get_prio (true , slot_count, true );
208- prio_queue.push (slice_candidate_context{chosen_slice.inst .id , prio, {cfg.min_prb , cfg.max_prb }});
234+ priority_type prio = chosen_slice.get_prio (IsDownlink , slot_count, true , slot_tx );
235+ prio_queue.push (slice_candidate_context{chosen_slice.inst .id , prio, {cfg.min_prb , cfg.max_prb }, slot_tx });
209236 }
210237
211238 // Save current slot count.
212239 unsigned & count_to_set = IsDownlink ? chosen_slice.last_dl_slot : chosen_slice.last_ul_slot ;
213240 count_to_set = slot_count;
214241
215242 // Return the candidate.
216- return std::conditional_t <IsDownlink, dl_ran_slice_candidate, ul_ran_slice_candidate>{chosen_slice. inst ,
217- rb_lims.stop ()};
243+ return std::conditional_t <IsDownlink, dl_ran_slice_candidate, ul_ran_slice_candidate>{
244+ chosen_slice. inst , slot_tx, rb_lims.stop ()};
218245 }
219246 return std::nullopt ;
220247}
@@ -231,7 +258,8 @@ std::optional<ul_ran_slice_candidate> slice_scheduler::get_next_ul_candidate()
231258
232259slice_scheduler::priority_type slice_scheduler::ran_slice_sched_context::get_prio (bool is_dl,
233260 slot_count_type current_slot_count,
234- bool slice_resched) const
261+ bool slice_resched,
262+ slot_point slot_tx) const
235263{
236264 // Note: The positive integer representing the priority of a slice consists of a concatenation of three priority
237265 // values:
@@ -248,7 +276,7 @@ slice_scheduler::priority_type slice_scheduler::ran_slice_sched_context::get_pri
248276 constexpr static priority_type delay_bitsize = 8U ;
249277 constexpr static priority_type rr_bitsize = 8U ;
250278
251- unsigned rb_count = is_dl ? inst.pdsch_rb_count : inst.pusch_rb_count ;
279+ unsigned rb_count = is_dl ? inst.pdsch_rb_count : inst.pusch_rb_count_per_slot [slot_tx. to_uint ()] ;
252280 if (not inst.active () or rb_count >= inst.cfg .max_prb ) {
253281 // If the slice is not in a state to be scheduled in this slot, return skip priority level.
254282 return skip_prio;
0 commit comments