Commit 53eb43ba authored by Robert Schmidt's avatar Robert Schmidt

Rename FR1 preprocessor and update documentation

parent 2c7f59ed
...@@ -171,24 +171,31 @@ NR_sched_pusch_t (for values changing every TTI, e.g., frequency domain ...@@ -171,24 +171,31 @@ NR_sched_pusch_t (for values changing every TTI, e.g., frequency domain
allocation) and NR_sched_pusch_save_t (for values changing less frequently, at allocation) and NR_sched_pusch_save_t (for values changing less frequently, at
least in FR1 [to my understanding], e.g., DMRS fields when the time domain least in FR1 [to my understanding], e.g., DMRS fields when the time domain
allocation stays between TTIs) structures. Furthermore, the preprocessor is an allocation stays between TTIs) structures. Furthermore, the preprocessor is an
exchangeable module that might schedule differently, e.g., one user for exchangeable module that schedules differently based on a particular
phytest, multiple users in FR1, or maybe FR2: phytest is in use-case/deployment type, e.g., one user for phytest [in
nr_ul_preprocessor_phytest(), for FR1 is nr_simple_ulsch_preprocessor() [under nr_ul_preprocessor_phytest()], multiple users in FR1
development], for FR2 does not exist yet. [nr_fr1_ulsch_preprocessor()], or maybe FR2 [does not exist yet]:
* calls preprocessor via pre_processor_ul(): the preprocessor is responsible * calls preprocessor via pre_processor_ul(): the preprocessor is responsible
for allocating CCEs (using allocate_nr_CCEs()). Note that we do not yet have for allocating CCEs (using allocate_nr_CCEs()) and deciding on resource
scheduling requests or buffer status reports, and only one UE. E.g., allocation for the UEs including TB size. Note that we do not yet have
nr_simple_ulsch_preprocessor(): scheduling requests. What it typically does:
1) check whether the current frame/slot plus K2 is an UL slot, and return if 1) check whether the current frame/slot plus K2 is an UL slot, and return if
not. not.
2) Find first free start RB in vrb_map_UL, and as many free consecutive RBs 2) Find first free start RB in vrb_map_UL, and as many free consecutive RBs
as possible. as possible.
3) allocate a CCE for the UE (and return if it is not possible) 3) Either set up resource allocation directly (e.g., for a single UE,
4) Calculate DMRS stuff (nr_save_pusch_fields()) and the TBS. phytest), or call into a function to perform actual resource allocation.
5) Mark used resources in vrb_map_UL. Currently, this is done using pf_ul() which implements a basic
* loop through all users: get a free HARQ PID and proportional fair scheduler:
update statistics. Fill nFAPI structures directly for PUSCH, and call * for every UE, check for retransmission and allocate as necessary
config_uldci() and fill_dci_pdu_rel15() for DCI filling and PDCCH messages. * Calculate DMRS stuff (nr_save_pusch_fields())
* Calculate the PF coefficient and put eligible UEs into a list
* Allocate resources to the UE(s) with the highest coefficient
4) Mark used resources in vrb_map_UL.
* loop through all users: get a HARQ process as indicated through the
preprocessor, update statistics, fill nFAPI structures directly for PUSCH,
and call config_uldci() and fill_dci_pdu_rel15() for DCI filling and PDCCH
messages.
Calls nr_schedule_ue_spec(). It is divided into the "preprocessor" and the Calls nr_schedule_ue_spec(). It is divided into the "preprocessor" and the
"postprocessor": the first makes the scheduling decisions, the second fills "postprocessor": the first makes the scheduling decisions, the second fills
...@@ -196,29 +203,28 @@ nFAPI structures to indicate to the PHY what it is supposed to do. To signal ...@@ -196,29 +203,28 @@ nFAPI structures to indicate to the PHY what it is supposed to do. To signal
which users have how many resources, the preprocessor populates the which users have how many resources, the preprocessor populates the
NR_UE_sched_ctrl_t structure of affected users. In particular, the field rbSize NR_UE_sched_ctrl_t structure of affected users. In particular, the field rbSize
decides whether a user is to be allocated. Furthermore, the preprocessor is an decides whether a user is to be allocated. Furthermore, the preprocessor is an
exchangeable module that might schedule differently, e.g., one user for exchangeable module that schedules differently based on a particular
phytest, multiple users in FR1, or maybe FR2: phytest is in use-case/deployment type, e.g., one user for phytest [in
nr_preprocessor_phytest(), for FR1 is nr_simple_dlsch_preprocessor() [under nr_preprocessor_phytest()], multiple users in FR1
development], for FR2 does not exist yet. [nr_fr1_dlsch_preprocessor()], or maybe FR2 [does not exist yet].
* calls preprocessor via pre_processor_dl(): the preprocessor is responsible * calls preprocessor via pre_processor_dl(): the preprocessor is responsible
for allocating CCEs and PUCCH (using allocate_nr_CCEs() and for allocating CCEs and PUCCH (using allocate_nr_CCEs() and
nr_acknack_scheduling()) and deciding on the frequency/time domain nr_acknack_scheduling()) and deciding on the frequency/time domain
allocation. E.g., nr_simple_dlsch_preprocessor(): allocation including the TB size. What it typically does:
1) mac_rlc_status_ind() locks and checks directly inside rlc data the 1) Check available resources in the vrb_map
quantity of waiting data. 2) Checks the quantity of waiting data in RLC
2) return from the preprocessor if there is no data and no timing advance to 3) Either set up resource allocation directly (e.g., for a single UE,
send, phytest), or call into a function to perform actual resource allocation.
3) otherwise, allocate a CCE for the UE (and return if it is not possible) Currently, this is done using pf_dl() which implements a basic
4) find a PUCCH occasion for HARQ proportional fair scheduler:
5a) check if there is a retransmission: if yes, find free resources to * for every UE, check for retransmission and allocate as necessary
transmit using the same resources, else * Calculate the PF coefficient and put eligible UEs into a list
5b) calculate the necessary RBs needed to get a TBS large enough to hold all * Allocate resources to the UE(s) with the highest coefficient
data, or until no more resources are available 4) Mark taken resources in the vrb_map
6) Mark taken resources in the vrb_map
* loop through all users: check if a new TA is necessary. Then, if a user has * loop through all users: check if a new TA is necessary. Then, if a user has
allocated resources, compute its TBS, and fill nFAPI structures allocated resources, update statistics (round, sent bytes), update HARQ
(nr_fill_nfapi_dl_pdu() to populate what should be done by the lower layers process information, and fill nFAPI structures (allocate a DCI and PDCCH
to make the Tx subframe). Update statistics (round, sent bytes). messages, TX_req, ...)
# RRC # RRC
RRC is a regular thread with itti loop on queue: TASK_RRC_GNB RRC is a regular thread with itti loop on queue: TASK_RRC_GNB
......
...@@ -606,9 +606,8 @@ void pf_dl(module_id_t module_id, ...@@ -606,9 +606,8 @@ void pf_dl(module_id_t module_id,
} }
} }
void nr_simple_dlsch_preprocessor(module_id_t module_id, void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot)
frame_t frame, {
sub_frame_t slot) {
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
if (UE_info->num_UEs == 0) if (UE_info->num_UEs == 0)
...@@ -647,7 +646,7 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id, ...@@ -647,7 +646,7 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id,
nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id) nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id)
{ {
return nr_simple_dlsch_preprocessor; return nr_fr1_dlsch_preprocessor;
} }
void nr_schedule_ue_spec(module_id_t module_id, void nr_schedule_ue_spec(module_id_t module_id,
......
...@@ -815,10 +815,8 @@ void pf_ul(module_id_t module_id, ...@@ -815,10 +815,8 @@ void pf_ul(module_id_t module_id,
} }
} }
bool nr_simple_ulsch_preprocessor(module_id_t module_id, bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot, uint64_t ulsch_in_slot_bitmap)
frame_t frame, {
sub_frame_t slot,
uint64_t ulsch_in_slot_bitmap) {
gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
NR_COMMON_channels_t *cc = nr_mac->common_channels; NR_COMMON_channels_t *cc = nr_mac->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
...@@ -896,7 +894,7 @@ bool nr_simple_ulsch_preprocessor(module_id_t module_id, ...@@ -896,7 +894,7 @@ bool nr_simple_ulsch_preprocessor(module_id_t module_id,
nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(module_id_t module_id, int CC_id) nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(module_id_t module_id, int CC_id)
{ {
return nr_simple_ulsch_preprocessor; return nr_fr1_ulsch_preprocessor;
} }
void nr_schedule_ulsch(module_id_t module_id, void nr_schedule_ulsch(module_id_t module_id,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment