diff --git a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf index 32de0aa4f57d6ea6d05d8625fc93b547056db0dc..5c004e67e448dba388f4ed103238faf7dda1fb9c 100644 --- a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf @@ -55,27 +55,14 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=1,L=13 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; - - initialDLBWPk0_3 = 0; - initialDLBWPmappingType_3 = 0; - #this is SS=1,L=4 - initialDLBWPstartSymbolAndLength_3 = 57; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_3 = 0; #for mixed slot + initialDLBWPmappingType_3 = 0; + initialDLBWPstartSymbolAndLength_3 = 57; #this is SS=1,L=5 + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 66; @@ -131,20 +118,18 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 6; + initialULBWPk2_0 = 6; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 - initialULBWPk2_1 = 6; + initialULBWPk2_1 = 6; # used for mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 - initialULBWPk2_2 = 7; + initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; - # this is SS=10 L=4 - initialULBWPstartSymbolAndLength_2 = 52; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 + msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf index a11509a3f021afde65da345cb0de036e661c193a..e2fdbc8448b8e916829a85ae7a57bbf71f323281 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -56,27 +56,13 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=1,L=13 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; - - initialDLBWPk0_3 = 0; - initialDLBWPmappingType_3 = 0; - #this is SS=1,L=5 - initialDLBWPstartSymbolAndLength_3 = 57; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 #uplinkConfigCommon #frequencyInfoUL @@ -132,20 +118,17 @@ gNBs = restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 6; + initialULBWPk2_0 = 6; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 - initialULBWPk2_1 = 6; + initialULBWPk2_1 = 6; # used for mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 - initialULBWPk2_2 = 7; + initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; - # this is SS=10 L=4 - initialULBWPstartSymbolAndLength_2 = 52; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf index daee5486c1d9fab9734563b5d998a8255992263a..8d2f490dc39aba770d3d57f9e8d75d6227c9e3cd 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf @@ -57,27 +57,14 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=1,L=13 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; - - initialDLBWPk0_3 = 0; - initialDLBWPmappingType_3 = 0; - #this is SS=1,L=4 //5 (4 is for 43, 5 is for 57) - initialDLBWPstartSymbolAndLength_3 = 57; //43; //57; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 78; @@ -132,20 +119,17 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 2; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 2; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 + + initialULBWPk2_1 = 2; # used for mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 - initialULBWPk2_2 = 7; + initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; - # this is SS=10 L=4 - initialULBWPstartSymbolAndLength_2 = 52; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/doc/SW_archi.md b/doc/SW_archi.md index d92f8021488fb30b6a2b3fb7d209fc733b92347d..a82043fd10cbaf3babc510f4ed27d02598012923 100644 --- a/doc/SW_archi.md +++ b/doc/SW_archi.md @@ -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 least in FR1 [to my understanding], e.g., DMRS fields when the time domain allocation stays between TTIs) structures. Furthermore, the preprocessor is an -exchangeable module that might schedule differently, e.g., one user for -phytest, multiple users in FR1, or maybe FR2: phytest is in -nr_ul_preprocessor_phytest(), for FR1 is nr_simple_ulsch_preprocessor() [under -development], for FR2 does not exist yet. +exchangeable module that schedules differently based on a particular +use-case/deployment type, e.g., one user for phytest [in +nr_ul_preprocessor_phytest()], multiple users in FR1 +[nr_fr1_ulsch_preprocessor()], or maybe FR2 [does not exist yet]: * calls preprocessor via pre_processor_ul(): the preprocessor is responsible - for allocating CCEs (using allocate_nr_CCEs()). Note that we do not yet have - scheduling requests or buffer status reports, and only one UE. E.g., - nr_simple_ulsch_preprocessor(): + for allocating CCEs (using allocate_nr_CCEs()) and deciding on resource + allocation for the UEs including TB size. Note that we do not yet have + scheduling requests. What it typically does: 1) check whether the current frame/slot plus K2 is an UL slot, and return if not. 2) Find first free start RB in vrb_map_UL, and as many free consecutive RBs as possible. - 3) allocate a CCE for the UE (and return if it is not possible) - 4) Calculate DMRS stuff (nr_save_pusch_fields()) and the TBS. - 5) Mark used resources in vrb_map_UL. -* loop through all users: get a free HARQ PID and - update statistics. Fill nFAPI structures directly for PUSCH, and call - config_uldci() and fill_dci_pdu_rel15() for DCI filling and PDCCH messages. + 3) Either set up resource allocation directly (e.g., for a single UE, + phytest), or call into a function to perform actual resource allocation. + Currently, this is done using pf_ul() which implements a basic + proportional fair scheduler: + * for every UE, check for retransmission and allocate as necessary + * Calculate DMRS stuff (nr_set_pusch_semi_static()) + * 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 "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 which users have how many resources, the preprocessor populates the 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 -exchangeable module that might schedule differently, e.g., one user for -phytest, multiple users in FR1, or maybe FR2: phytest is in -nr_preprocessor_phytest(), for FR1 is nr_simple_dlsch_preprocessor() [under -development], for FR2 does not exist yet. +exchangeable module that schedules differently based on a particular +use-case/deployment type, e.g., one user for phytest [in +nr_preprocessor_phytest()], multiple users in FR1 +[nr_fr1_dlsch_preprocessor()], or maybe FR2 [does not exist yet]. * calls preprocessor via pre_processor_dl(): the preprocessor is responsible for allocating CCEs and PUCCH (using allocate_nr_CCEs() and nr_acknack_scheduling()) and deciding on the frequency/time domain - allocation. E.g., nr_simple_dlsch_preprocessor(): - 1) mac_rlc_status_ind() locks and checks directly inside rlc data the - quantity of waiting data. - 2) return from the preprocessor if there is no data and no timing advance to - send, - 3) otherwise, allocate a CCE for the UE (and return if it is not possible) - 4) find a PUCCH occasion for HARQ - 5a) check if there is a retransmission: if yes, find free resources to - transmit using the same resources, else - 5b) calculate the necessary RBs needed to get a TBS large enough to hold all - data, or until no more resources are available - 6) Mark taken resources in the vrb_map + allocation including the TB size. What it typically does: + 1) Check available resources in the vrb_map + 2) Checks the quantity of waiting data in RLC + 3) Either set up resource allocation directly (e.g., for a single UE, + phytest), or call into a function to perform actual resource allocation. + Currently, this is done using pf_dl() which implements a basic + proportional fair scheduler: + * for every UE, check for retransmission and allocate as necessary + * Calculate the PF coefficient and put eligible UEs into a list + * Allocate resources to the UE(s) with the highest coefficient + 4) Mark taken resources in the vrb_map * 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 - (nr_fill_nfapi_dl_pdu() to populate what should be done by the lower layers - to make the Tx subframe). Update statistics (round, sent bytes). + allocated resources, update statistics (round, sent bytes), update HARQ + process information, and fill nFAPI structures (allocate a DCI and PDCCH + messages, TX_req, ...) # RRC RRC is a regular thread with itti loop on queue: TASK_RRC_GNB diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h index 500819e6844016ea2829d7b0472a8358fff9f70b..813ffcf8fac29f3060f72dbe74057fb8cb03755a 100644 --- a/executables/nr-softmodem-common.h +++ b/executables/nr-softmodem-common.h @@ -68,11 +68,15 @@ #define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n" #define CONFIG_HLP_EXMCAL "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n" #define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n" -#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n" +#define CONFIG_HLP_DLMCS_PHYTEST "Set the downlink MCS for PHYTEST mode\n" #define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n" #define CONFIG_HLP_PRB "Set the PRB, valid values: 6, 25, 50, 100 \n" #define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n" -#define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n" +#define CONFIG_HLP_ULMCS_PHYTEST "Set the uplink MCS for PHYTEST mode\n" +#define CONFIG_HLP_DLBW_PHYTEST "Set the number of PRBs used for DLSCH in PHYTEST mode\n" +#define CONFIG_HLP_ULBW_PHYTEST "Set the number of PRBs used for ULSCH in PHYTEST mode\n" +#define CONFIG_HLP_DLBM_PHYTEST "Bitmap for DLSCH slots (slot 0 starts at LSB)\n" +#define CONFIG_HLP_ULBM_PHYTEST "Bitmap for ULSCH slots (slot 0 starts at LSB)\n" #define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n" #define CONFIG_HLP_UE "Set the lte softmodem as a UE\n" #define CONFIG_HLP_L2MONW "Enable L2 wireshark messages on localhost \n" diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 63c06563d288666ad25e86905b4b89a4abb85049..a29295ff52a8d00e0b9596cfb8d9e59a0cbed1cd 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -160,8 +160,6 @@ int otg_enabled; //static NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; //static nfapi_nr_config_request_t *config[MAX_NUM_CCs]; -uint32_t target_dl_mcs = 28; //maximum allowed mcs -uint32_t target_ul_mcs = 20; uint32_t timing_advance = 0; uint64_t num_missed_slots=0; // counter for the number of missed slots diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h index d6cfe6b906acef4026dcf08d7b03433b32fd1986..62c7328144b590b7668826af21d96ae5da46b275 100644 --- a/executables/nr-softmodem.h +++ b/executables/nr-softmodem.h @@ -23,14 +23,24 @@ {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \ {"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 0}, \ - {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ - {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ + {"m" , CONFIG_HLP_DLMCS_PHYTEST,0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ + {"t" , CONFIG_HLP_ULMCS_PHYTEST,0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ + {"M" , CONFIG_HLP_DLBW_PHYTEST,0, uptr:&target_dl_bw, defintval:0, TYPE_UINT, 0}, \ + {"T" , CONFIG_HLP_ULBW_PHYTEST,0, uptr:&target_ul_bw, defintval:0, TYPE_UINT, 0}, \ + {"D" , CONFIG_HLP_DLBM_PHYTEST,0, u64ptr:&dlsch_slot_bitmap, defintval:0, TYPE_UINT64, 0}, \ + {"U" , CONFIG_HLP_ULBM_PHYTEST,0, u64ptr:&ulsch_slot_bitmap, defintval:0, TYPE_UINT64, 0}, \ {"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \ {"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \ } #include "threads_t.h" extern threads_t threads; +extern uint32_t target_dl_mcs; +extern uint32_t target_ul_mcs; +extern uint32_t target_dl_bw; +extern uint32_t target_ul_bw; +extern uint64_t dlsch_slot_bitmap; +extern uint64_t ulsch_slot_bitmap; // In nr-gnb.c extern void init_gNB(int single_thread_flag,int wait_for_sync); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 674ae82cc392fdf2fa0cb910fcb1e5fbf203a8ed..f49bd114c9ad56fc946a4bb2037ab4635e35f2b6 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -666,7 +666,7 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) start_meas(&gNB->rx_pusch_stats); for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) { no_sig = nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid); - if (no_sig) { + if (no_sig && (get_softmodem_params()->phy_test == 0)) { LOG_I(PHY, "PUSCH not detected in symbol %d\n",symbol); nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1); return; diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 9614b4b649abf46b0e59e5a391213ef70606d768..a2ece67f318363779b618b8319e9dcee09533646 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -228,13 +228,38 @@ void nr_dlsim_preprocessor(module_id_t module_id, sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */); sched_ctrl->cce_index = 0; - sched_ctrl->rbStart = g_rbStart; - sched_ctrl->rbSize = g_rbSize; - sched_ctrl->mcs = g_mcsIndex; - sched_ctrl->time_domain_allocation = 2; - sched_ctrl->mcsTableIdx = g_mcsTableIdx; + NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; + const NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon; + nr_set_pdsch_semi_static(scc, + UE_info->secondaryCellGroup[0], + sched_ctrl->active_bwp, + /* tda = */ 2, + /* num_dmrs_cdm_grps_no_data = */ 1, + ps); + + NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; + sched_pdsch->rbStart = g_rbStart; + sched_pdsch->rbSize = g_rbSize; + sched_pdsch->mcs = g_mcsIndex; + /* the following might override the table that is mandated by RRC + * configuration */ + ps->mcsTableIdx = g_mcsTableIdx; + + sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx); + sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx); + sched_pdsch->tb_size = nr_compute_tbs(sched_pdsch->Qm, + sched_pdsch->R, + sched_pdsch->rbSize, + ps->nrOfSymbols, + ps->N_PRB_DMRS * ps->N_DMRS_SLOT, + 0 /* N_PRB_oh, 0 for initialBWP */, + 0 /* tb_scaling */, + 1 /* nrOfLayers */) + >> 3; + /* the simulator assumes the HARQ PID is equal to the slot number */ - sched_ctrl->dl_harq_pid = slot; + sched_pdsch->dl_harq_pid = slot; + /* The scheduler uses lists to track whether a HARQ process is * free/busy/awaiting retransmission, and updates the HARQ process states. * However, in the simulation, we never get ack or nack for any HARQ process, @@ -247,11 +272,10 @@ void nr_dlsim_preprocessor(module_id_t module_id, else add_front_nr_list(&sched_ctrl->retrans_dl_harq, slot); // ... make PID retransmission sched_ctrl->harq_processes[slot].is_waiting = false; - AssertFatal(sched_ctrl->rbStart >= 0, "invalid rbStart %d\n", sched_ctrl->rbStart); - AssertFatal(sched_ctrl->rbSize > 0, "invalid rbSize %d\n", sched_ctrl->rbSize); - AssertFatal(sched_ctrl->mcs >= 0, "invalid sched_ctrl->mcs %d\n", sched_ctrl->mcs); - AssertFatal(sched_ctrl->mcsTableIdx >= 0 && sched_ctrl->mcsTableIdx <= 2, "invalid sched_ctrl->mcsTableIdx %d\n", sched_ctrl->mcsTableIdx); - sched_ctrl->numDmrsCdmGrpsNoData = 1; + AssertFatal(sched_pdsch->rbStart >= 0, "invalid rbStart %d\n", sched_pdsch->rbStart); + AssertFatal(sched_pdsch->rbSize > 0, "invalid rbSize %d\n", sched_pdsch->rbSize); + AssertFatal(sched_pdsch->mcs >= 0, "invalid mcs %d\n", sched_pdsch->mcs); + AssertFatal(ps->mcsTableIdx >= 0 && ps->mcsTableIdx <= 2, "invalid mcsTableIdx %d\n", ps->mcsTableIdx); } @@ -626,7 +650,6 @@ int main(int argc, char **argv) RC.nb_nr_mac_CC[i] = 1; mac_top_init_gNB(); gNB_mac = RC.nrmac[0]; - gNB_mac->pre_processor_dl = nr_dlsim_preprocessor; gNB_RRC_INST rrc; memset((void*)&rrc,0,sizeof(rrc)); @@ -714,6 +737,9 @@ int main(int argc, char **argv) rrc_mac_config_req_gNB(0,0,n_tx,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL); // UE dedicated configuration rrc_mac_config_req_gNB(0,0,n_tx,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); + // reset preprocessor to the one of DLSIM after it has been set during + // rrc_mac_config_req_gNB + gNB_mac->pre_processor_dl = nr_dlsim_preprocessor; phy_init_nr_gNB(gNB,0,0); N_RB_DL = gNB->frame_parms.N_RB_DL; NR_UE_info_t *UE_info = &RC.nrmac[0]->UE_info; diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index a3c25011970097f68483b98f2f24e96ff54de5a0..276daee337dab99fd7bc68e96f77937e4c5b33a1 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -66,6 +66,7 @@ uint8_t const nr_rv_round_map[4] = {0, 2, 1, 3}; uint8_t const nr_rv_round_map_ue[4] = {0, 2, 1, 3}; uint64_t get_softmodem_optmask(void) {return 0;} +softmodem_params_t *get_softmodem_params(void) {return 0;} void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {} diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 381dce11b2cddce03c9633c17add5dc24d3ad7e6..37bf8fdcb6b7f39544f15dede15129d732794364 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -148,10 +148,10 @@ typedef struct { // single Entry PHR MAC CE // TS 38.321 ch. 6.1.3.8 typedef struct { - uint8_t PH: 6; - uint8_t R1: 2; - uint8_t PCMAX: 6; - uint8_t R2: 6; + uint8_t PH: 6; // octet 1 [5:0] + uint8_t R1: 2; // octet 1 [7:6] + uint8_t PCMAX: 6; // octet 2 [5:0] + uint8_t R2: 2; // octet 2 [7:6] } __attribute__ ((__packed__)) NR_SINGLE_ENTRY_PHR_MAC_CE; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 3e299d291e012f2c7f94efcfda47ac13b2058003..df2fdb3e3fb953e69ebadf3eada10fcfb4221b58 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -374,6 +374,8 @@ typedef struct { NR_SearchSpace_t *search_space_zero; NR_ControlResourceSet_t *coreset0; + dci_pdu_rel15_t def_dci_pdu_rel15[8]; + } NR_UE_MAC_INST_t; typedef enum seach_space_mask_e { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 11edc6c20d26ef544dbc7e8bef284505dd88dfcb..64c8978ed02784eeb48ff450c6324925834e0d2c 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -49,8 +49,6 @@ // #define DEBUG_DCI -dci_pdu_rel15_t *def_dci_pdu_rel15; - void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) { LOG_D(MAC,"Filling search candidates for DCI\n"); @@ -72,7 +70,6 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t uint16_t monitoringSymbolsWithinSlot = 0; uint8_t coreset_id = 1; int sps = 0; - def_dci_pdu_rel15 = calloc(1,2*sizeof(dci_pdu_rel15_t)); AssertFatal(mac->scc != NULL, "scc is null\n"); NR_BWP_Id_t bwp_id = mac->DL_BWP_Id; NR_ServingCellConfigCommon_t *scc = mac->scc; @@ -135,7 +132,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); rel15->SubcarrierSpacing = bwp_Common->genericParameters.subcarrierSpacing; for (int i = 0; i < rel15->num_dci_options; i++) { - rel15->dci_length_options[i] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15+i, rel15->dci_format_options[i], NR_RNTI_C, rel15->BWPSize, bwp_id); + rel15->dci_length_options[i] = nr_dci_size(scc, mac->scg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_C, rel15->BWPSize, bwp_id); } break; case NR_RNTI_RA: @@ -146,7 +143,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); //NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing; - rel15->dci_length_options[0] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format_options[0], NR_RNTI_RA, rel15->BWPSize, bwp_id); + rel15->dci_length_options[0] = nr_dci_size(scc, mac->scg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[0]], rel15->dci_format_options[0], NR_RNTI_RA, rel15->BWPSize, bwp_id); break; case NR_RNTI_P: break; @@ -169,7 +166,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t rel15->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon; for (int i = 0; i < rel15->num_dci_options; i++) { - rel15->dci_length_options[i] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format_options[i], NR_RNTI_SI, rel15->BWPSize, 0); + rel15->dci_length_options[i] = nr_dci_size(scc, mac->scg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_SI, rel15->BWPSize, 0); } break; case NR_RNTI_SFI: diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index cfcaac6c4bd90044b924b521f4c8d846ee2d8103..4d9a6731a2ba14b51590addb170138bdb66e9500 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -449,9 +449,9 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in LOG_D(MAC,"Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n", dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long*)dci->payloadBits); - if (nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, (uint64_t *)dci->payloadBits, def_dci_pdu_rel15)) + if (nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, (uint64_t *)dci->payloadBits, &mac->def_dci_pdu_rel15[dci->dci_format])) return -1; - return (nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci->rnti, dci->dci_format)); + return (nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, &mac->def_dci_pdu_rel15[dci->dci_format], dci->rnti, dci->dci_format)); } int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, uint16_t rnti, uint8_t dci_format){ diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 844ee95d3249583e38906c7d107452d85760d657..cbf14a89adb6a1e9fdcbed75383677ebe75c1e3e 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -913,10 +913,9 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in //and block this traffic from being forwarded to the upper layers at the gNB LOG_D(PHY, "In %s: Random data to be transmitted: TBS_bytes %d \n", __FUNCTION__, TBS_bytes); - //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2) - //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should - //have a valid LCID (nr_process_mac_pdu function) - ulsch_input_buffer[0] = 0x31; + // Make the first byte padding so that gNB ignores the PHY random + // data in the TB for the PHY at the MAC layer + ulsch_input_buffer[0] = UL_SCH_LCID_PADDING; for (int i = 1; i < TBS_bytes; i++) { ulsch_input_buffer[i] = (unsigned char) rand(); diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index caa56bdff9118ea1c93e4542e0253a906782c610..a67a71d0be0fa2c19a3979ad2622d17171af8564 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -405,12 +405,53 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, find_SSB_and_RO_available(Mod_idP); + const NR_TDD_UL_DL_Pattern_t *tdd = &scc->tdd_UL_DL_ConfigurationCommon->pattern1; + const int nr_mix_slots = tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0; + const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + nr_mix_slots; + const int nr_dlmix_slots = tdd->nrofDownlinkSlots + (tdd->nrofDownlinkSymbols != 0); + const int nr_ulstart_slot = tdd->nrofDownlinkSlots + (tdd->nrofUplinkSymbols == 0); + for (int slot = 0; slot < n; ++slot) { + /* FIXME: it seems there is a problem with slot 0/10/slots right after UL: + * we just get retransmissions. Thus, do not schedule such slots in DL */ + if (slot % nr_slots_period != 0) + RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] |= ((slot % nr_slots_period) < nr_dlmix_slots) << (slot % 64); + RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] |= ((slot % nr_slots_period) >= nr_ulstart_slot) << (slot % 64); + LOG_D(MAC, + "slot %d DL %d UL %d\n", + slot, + (RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] & (1 << (slot % 64))) != 0, + (RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] & (1 << (slot % 64))) != 0); + } + + if (get_softmodem_params()->phy_test) { + RC.nrmac[Mod_idP]->pre_processor_dl = nr_preprocessor_phytest; + RC.nrmac[Mod_idP]->pre_processor_ul = nr_ul_preprocessor_phytest; + } else { + RC.nrmac[Mod_idP]->pre_processor_dl = nr_init_fr1_dlsch_preprocessor(Mod_idP, 0); + RC.nrmac[Mod_idP]->pre_processor_ul = nr_init_fr1_ulsch_preprocessor(Mod_idP, 0); + } } if (secondaryCellGroup) { RC.nrmac[Mod_idP]->secondaryCellGroupCommon = secondaryCellGroup; + const NR_ServingCellConfig_t *servingCellConfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated; + const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList; + AssertFatal(bwpList->list.count > 0, "downlinkBWP_ToAddModList has no BWPs!\n"); + for (int i = 0; i < bwpList->list.count; ++i) { + const NR_BWP_Downlink_t *bwp = bwpList->list.array[i]; + calculate_preferred_dl_tda(Mod_idP, bwp); + } + + const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = + servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList; + AssertFatal(ubwpList->list.count > 0, "downlinkBWP_ToAddModList no BWPs!\n"); + for (int i = 0; i < ubwpList->list.count; ++i) { + const NR_BWP_Uplink_t *ubwp = ubwpList->list.array[i]; + calculate_preferred_ul_tda(Mod_idP, ubwp); + } + NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; if (add_ue == 1 && get_softmodem_params()->phy_test) { const int UE_id = add_new_nr_ue(Mod_idP, rnti, secondaryCellGroup); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 584648c67f84e81d954c94ed4213b67759df4ba4..8d1e899fcb03696b41082900f831e917ab1acf98 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -53,6 +53,7 @@ #include "executables/softmodem-common.h" #include "nfapi/oai_integration/vendor_ext.h" +#include "executables/nr-softmodem.h" uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; @@ -65,7 +66,13 @@ void dump_mac_stats(gNB_MAC_INST *gNB) NR_UE_info_t *UE_info = &gNB->UE_info; int num = 1; for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { - LOG_I(MAC, "UE ID %d RNTI %04x (%d/%d)\n", UE_id, UE_info->rnti[UE_id], num++, UE_info->num_UEs); + LOG_I(MAC, "UE ID %d RNTI %04x (%d/%d) PH %d dB PCMAX %d dBm\n", + UE_id, + UE_info->rnti[UE_id], + num++, + UE_info->num_UEs, + UE_info->UE_sched_ctrl[UE_id].ph, + UE_info->UE_sched_ctrl[UE_id].pcmax); NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id]; const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0; LOG_I(MAC, "UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, average RSRP %d (%d meas)\n", @@ -76,10 +83,15 @@ void dump_mac_stats(gNB_MAC_INST *gNB) stats->num_rsrp_meas = 0; stats->cumul_rsrp = 0 ; LOG_I(MAC, "UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes); - LOG_I(MAC, "UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_errors %d\n", + const NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + LOG_I(MAC, "UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_errors %d, PUSCH SNR %2.1f dB, PUCCH SNR %2.1f dB, noise rssi %2.1f dB\n", UE_id, stats->ulsch_rounds[0], stats->ulsch_rounds[1], - stats->ulsch_rounds[2], stats->ulsch_rounds[3], stats->ulsch_errors); + stats->ulsch_rounds[2], stats->ulsch_rounds[3], + stats->ulsch_errors, + (float) sched_ctrl->pusch_snrx10 / 10, + (float) sched_ctrl->pucch_snrx10 / 10, + (float) (sched_ctrl->raw_rssi - 1280) / 10); LOG_I(MAC, "UE %d: ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n", UE_id, @@ -312,51 +324,11 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, protocol_ctxt_t ctxt; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP); - int nb_periods_per_frame; - const int bwp_id = 1; gNB_MAC_INST *gNB = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = gNB->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - NR_TDD_UL_DL_Pattern_t *tdd_pattern = &scc->tdd_UL_DL_ConfigurationCommon->pattern1; - - switch(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity) { - case 0: - nb_periods_per_frame = 20; // 10ms/0p5ms - break; - - case 1: - nb_periods_per_frame = 16; // 10ms/0p625ms - break; - - case 2: - nb_periods_per_frame = 10; // 10ms/1ms - break; - - case 3: - nb_periods_per_frame = 8; // 10ms/1p25ms - break; - - case 4: - nb_periods_per_frame = 5; // 10ms/2ms - break; - - case 5: - nb_periods_per_frame = 4; // 10ms/2p5ms - break; - - case 6: - nb_periods_per_frame = 2; // 10ms/5ms - break; - - case 7: - nb_periods_per_frame = 1; // 10ms/10ms - break; - - default: - AssertFatal(1==0,"Undefined tdd period %ld\n", scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity); - } if (slot==0 && (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]>=257)) { // re-initialization of tdd_beam_association at beginning of frame (only for FR2) @@ -364,10 +336,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, gNB->tdd_beam_association[i] = -1; } - int num_slots_per_tdd = (nr_slots_per_frame[*scc->ssbSubcarrierSpacing])/nb_periods_per_frame; - - const int nr_ulmix_slots = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0); - start_meas(&RC.nrmac[module_idP]->eNB_scheduler); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN); @@ -381,17 +349,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing); } -#define BIT(x) (1 << (x)) - const uint64_t dlsch_in_slot_bitmap = BIT( 1) | BIT( 2) | BIT( 3) | BIT( 4) | BIT( 5) | BIT( 6) - | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16); - - uint8_t prach_config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; - uint64_t ulsch_in_slot_bitmap; - if (prach_config_index==4) //this is the PRACH config used in the Benetel RRU. TODO: make this generic for any PRACH config. - ulsch_in_slot_bitmap = BIT( 8) | BIT( 9); - else - ulsch_in_slot_bitmap = BIT( 8) | BIT(18); - memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0 memset(RC.nrmac[module_idP]->cce_list[bwp_id][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid 1 NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info; @@ -452,14 +409,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, } // This schedules the DCI for Uplink and subsequently PUSCH - { - nr_schedule_ulsch(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, ulsch_in_slot_bitmap); - } + nr_schedule_ulsch(module_idP, frame, slot); // This schedules the DCI for Downlink and PDSCH - if (is_xlsch_in_slot(dlsch_in_slot_bitmap, slot)) - nr_schedule_ue_spec(module_idP, frame, slot); - + nr_schedule_ue_spec(module_idP, frame, slot); nr_schedule_pucch(module_idP, frame, slot); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index bc297225aff6f95e56e04d95fcde11bcd44528aa..bc25279783d93630082a1d91dfe59d8e954db71e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -377,6 +377,16 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP } } } + + // block resources in vrb_map_UL + const NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = + &scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric; + const uint8_t mu_pusch = + scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + const int16_t N_RA_RB = get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value, mu_pusch); + uint16_t *vrb_map_UL = &cc->vrb_map_UL[slotP * MAX_BWP_SIZE]; + for (int i = 0; i < N_RA_RB * fdm; ++i) + vrb_map_UL[rach_ConfigGeneric->msg1_FrequencyStart + i] = 0xff; // all symbols } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 0ceff015e718625af5edda6562366c82d327d6e8..3c90bf709b0334fb6288068415e57aea67ec981b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -295,9 +295,9 @@ void schedule_control_sib1(module_id_t module_id, } gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL; - gNB_mac->sched_ctrlCommon->time_domain_allocation = time_domain_allocation; - gNB_mac->sched_ctrlCommon->mcsTableIdx = mcsTableIdx; - gNB_mac->sched_ctrlCommon->mcs = mcs; + gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation = time_domain_allocation; + gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx = mcsTableIdx; + gNB_mac->sched_ctrlCommon->sched_pdsch.mcs = mcs; gNB_mac->sched_ctrlCommon->num_total_bytes = num_total_bytes; uint8_t nr_of_candidates; @@ -318,18 +318,19 @@ void schedule_control_sib1(module_id_t module_id, // Calculate number of symbols struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - const int startSymbolAndLength = tdaList->list.array[gNB_mac->sched_ctrlCommon->time_domain_allocation]->startSymbolAndLength; + const int startSymbolAndLength = + tdaList->list.array[gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation]->startSymbolAndLength; int startSymbolIndex, nrOfSymbols; SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); if (nrOfSymbols == 2) { - gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData = 1; + gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData = 1; } else { - gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData = 2; + gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData = 2; } // Calculate number of PRB_DMRS - uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6; + uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData * 6; uint16_t dlDmrsSymbPos = fill_dmrs_mask(gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, startSymbolIndex+nrOfSymbols); uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos); @@ -337,22 +338,24 @@ void schedule_control_sib1(module_id_t module_id, uint32_t TBS = 0; do { rbSize++; - TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx), - nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx), + TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, + gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx), + nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, + gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx), rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0, 0,1) >> 3; } while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && TBS < gNB_mac->sched_ctrlCommon->num_total_bytes); - gNB_mac->sched_ctrlCommon->rbSize = rbSize; - gNB_mac->sched_ctrlCommon->rbStart = 0; + gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize = rbSize; + gNB_mac->sched_ctrlCommon->sched_pdsch.rbStart = 0; LOG_D(MAC,"SLIV = %i\n", startSymbolAndLength); LOG_D(MAC,"startSymbolIndex = %i\n", startSymbolIndex); LOG_D(MAC,"nrOfSymbols = %i\n", nrOfSymbols); - LOG_D(MAC,"rbSize = %i\n", gNB_mac->sched_ctrlCommon->rbSize); + LOG_D(MAC, "rbSize = %i\n", gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize); LOG_D(MAC,"TBS = %i\n", TBS); // Mark the corresponding RBs as used - for (int rb = 0; rb < gNB_mac->sched_ctrlCommon->rbSize; rb++) { + for (int rb = 0; rb < gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize; rb++) { vrb_map[rb + rbStart] = 1; } } @@ -405,9 +408,9 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, } pdsch_pdu_rel15->NrOfCodewords = 1; - pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs,0); + pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, 0); pdsch_pdu_rel15->qamModOrder[0] = 2; - pdsch_pdu_rel15->mcsIndex[0] = gNB_mac->sched_ctrlCommon->mcs; + pdsch_pdu_rel15->mcsIndex[0] = gNB_mac->sched_ctrlCommon->sched_pdsch.mcs; pdsch_pdu_rel15->mcsTable[0] = 0; pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[0]; pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; @@ -417,15 +420,16 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, pdsch_pdu_rel15->dmrsConfigType = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1; pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu_rel15->SCID = 0; - pdsch_pdu_rel15->numDmrsCdmGrpsNoData = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData; + pdsch_pdu_rel15->numDmrsCdmGrpsNoData = gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData; pdsch_pdu_rel15->dmrsPorts = 1; pdsch_pdu_rel15->resourceAlloc = 1; - pdsch_pdu_rel15->rbStart = gNB_mac->sched_ctrlCommon->rbStart; - pdsch_pdu_rel15->rbSize = gNB_mac->sched_ctrlCommon->rbSize; + pdsch_pdu_rel15->rbStart = gNB_mac->sched_ctrlCommon->sched_pdsch.rbStart; + pdsch_pdu_rel15->rbSize = gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize; pdsch_pdu_rel15->VRBtoPRBMapping = 0; - pdsch_pdu_rel15->qamModOrder[0] = nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx); + pdsch_pdu_rel15->qamModOrder[0] = nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, + gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx); pdsch_pdu_rel15->TBSize[0] = TBS; - pdsch_pdu_rel15->mcsTable[0] = gNB_mac->sched_ctrlCommon->mcsTableIdx; + pdsch_pdu_rel15->mcsTable[0] = gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx; pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex; pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols; @@ -454,8 +458,8 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0( pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, gNB_mac->type0_PDCCH_CSS_config.num_rbs); - dci_payload.time_domain_assignment.val = gNB_mac->sched_ctrlCommon->time_domain_allocation; - dci_payload.mcs = gNB_mac->sched_ctrlCommon->mcs; + dci_payload.time_domain_assignment.val = gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation; + dci_payload.mcs = gNB_mac->sched_ctrlCommon->sched_pdsch.mcs; dci_payload.rv = pdsch_pdu_rel15->rvIndex[0]; dci_payload.harq_pid = 0; dci_payload.ndi = 0; @@ -525,17 +529,26 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) // Calculate number of symbols int startSymbolIndex, nrOfSymbols; struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - const int startSymbolAndLength = tdaList->list.array[gNB_mac->sched_ctrlCommon->time_domain_allocation]->startSymbolAndLength; + const int startSymbolAndLength = + tdaList->list.array[gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation]->startSymbolAndLength; SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); // Calculate number of PRB_DMRS - uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6; + uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData * 6; uint16_t dlDmrsSymbPos = fill_dmrs_mask(gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, startSymbolIndex+nrOfSymbols); uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos); - const uint32_t TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx), - nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx), - gNB_mac->sched_ctrlCommon->rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0 ,0 ,1 ) >> 3; + const uint32_t TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, + gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx), + nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, + gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx), + gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize, + nrOfSymbols, + N_PRB_DMRS * dmrs_length, + 0, + 0, + 1) + >> 3; nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, TBS, startSymbolIndex, nrOfSymbols); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 30a89cce77cf219bde280151b122ce0beddf4ef3..9cb07255b8d125da53e7903d42cc3e52caa5db74 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -56,6 +56,82 @@ #define WORD 32 //#define SIZE_OF_POINTER sizeof (void *) +void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *bwp) +{ + gNB_MAC_INST *nrmac = RC.nrmac[module_id]; + const int bwp_id = bwp->bwp_Id; + if (nrmac->preferred_dl_tda[bwp_id]) + return; + + /* there is a mixed slot only when in TDD */ + NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon; + const NR_TDD_UL_DL_Pattern_t *tdd = + scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; + const int symb_dlMixed = tdd ? (1 << tdd->nrofDownlinkSymbols) - 1 : 0; + + const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + const NR_SearchSpace_t *search_space = get_searchspace(bwp, target_ss); + const NR_ControlResourceSet_t *coreset = get_coreset(bwp, search_space, 1 /* dedicated */); + // get coreset symbol "map" + const uint16_t symb_coreset = (1 << coreset->duration) - 1; + + /* check that TDA index 0 fits into DL and does not overlap CORESET */ + const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = + bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; + AssertFatal(tdaList->list.count >= 1, "need to have at least one TDA for DL slots\n"); + const NR_PDSCH_TimeDomainResourceAllocation_t *tdaP_DL = tdaList->list.array[0]; + AssertFatal(!tdaP_DL->k0 || *tdaP_DL->k0 == 0, + "TimeDomainAllocation at index 1: non-null k0 (%ld) is not supported by the scheduler\n", + *tdaP_DL->k0); + int start, len; + SLIV2SL(tdaP_DL->startSymbolAndLength, &start, &len); + const uint16_t symb_tda = ((1 << len) - 1) << start; + // check whether coreset and TDA overlap: then we cannot use it. Note that + // here we assume that the coreset is scheduled every slot (which it + // currently is) and starting at symbol 0 + AssertFatal((symb_coreset & symb_tda) == 0, "TDA index 0 for DL overlaps with CORESET\n"); + + /* check that TDA index 1 fits into DL part of mixed slot, if it exists */ + int tdaMi = -1; + if (tdaList->list.count > 1) { + const NR_PDSCH_TimeDomainResourceAllocation_t *tdaP_Mi = tdaList->list.array[1]; + AssertFatal(!tdaP_Mi->k0 || *tdaP_Mi->k0 == 0, + "TimeDomainAllocation at index 1: non-null k0 (%ld) is not supported by the scheduler\n", + *tdaP_Mi->k0); + int start, len; + SLIV2SL(tdaP_Mi->startSymbolAndLength, &start, &len); + const uint16_t symb_tda = ((1 << start) - 1) << start; + // check whether coreset and TDA overlap: then, we cannot use it. Also, + // check whether TDA is entirely within mixed slot DL. Note that + // here we assume that the coreset is scheduled every slot (which it + // currently is) + if ((symb_coreset & symb_tda) == 0 && (symb_dlMixed & symb_tda) == symb_tda) { + tdaMi = 1; + } else { + LOG_E(MAC, + "TDA index 1 DL overlaps with CORESET or is not entirely in mixed slot (symb_coreset %x symb_dlMixed %x symb_tda %x), won't schedule DL mixed slot\n", + symb_coreset, + symb_dlMixed, + symb_tda); + } + } + + const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160}; + const int n = slots_per_frame[*scc->ssbSubcarrierSpacing]; + nrmac->preferred_dl_tda[bwp_id] = malloc(n * sizeof(*nrmac->preferred_dl_tda[bwp_id])); + + const int nr_mix_slots = tdd ? tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0 : 0; + const int nr_slots_period = tdd ? tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + nr_mix_slots : n; + for (int i = 0; i < n; ++i) { + nrmac->preferred_dl_tda[bwp_id][i] = -1; + if (!tdd || i % nr_slots_period < tdd->nrofDownlinkSlots) + nrmac->preferred_dl_tda[bwp_id][i] = 0; + else if (tdd && nr_mix_slots && i % nr_slots_period == tdd->nrofDownlinkSlots) + nrmac->preferred_dl_tda[bwp_id][i] = tdaMi; + LOG_I(MAC, "slot %d preferred_dl_tda %d\n", i, nrmac->preferred_dl_tda[bwp_id][i]); + } +} + // Compute and write all MAC CEs and subheaders, and return number of written // bytes int nr_write_ce_dlsch_pdu(module_id_t module_idP, @@ -302,35 +378,6 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP, return offset; } -int getNrOfSymbols(NR_BWP_Downlink_t *bwp, int tda) { - struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = - bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - AssertFatal(tda < tdaList->list.count, - "time_domain_allocation %d>=%d\n", - tda, - tdaList->list.count); - - const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength; - int startSymbolIndex, nrOfSymbols; - SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); - return nrOfSymbols; -} - -nfapi_nr_dmrs_type_e getDmrsConfigType(NR_BWP_Downlink_t *bwp) { - return bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1; -} - -uint8_t getN_PRB_DMRS(NR_BWP_Downlink_t *bwp, int numDmrsCdmGrpsNoData) { - const nfapi_nr_dmrs_type_e dmrsConfigType = getDmrsConfigType(bwp); - if (dmrsConfigType == NFAPI_NR_DMRS_TYPE1) { - // if no data in dmrs cdm group is 1 only even REs have no data - // if no data in dmrs cdm group is 2 both odd and even REs have no data - return numDmrsCdmGrpsNoData * 6; - } else { - return numDmrsCdmGrpsNoData * 4; - } -} - void nr_store_dlsch_buffer(module_id_t module_id, frame_t frame, sub_frame_t slot) { @@ -365,61 +412,125 @@ void nr_store_dlsch_buffer(module_id_t module_id, } } -bool allocate_retransmission(module_id_t module_id, - uint8_t *rballoc_mask, - int *n_rb_sched, - int UE_id, - int current_harq_pid){ - NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[module_id]->UE_info.UE_sched_ctrl[UE_id]; - NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid]; +bool allocate_dl_retransmission(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + uint8_t *rballoc_mask, + int *n_rb_sched, + int UE_id, + int current_harq_pid) +{ + const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels->ServingCellConfigCommon; + NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + NR_sched_pdsch_t *retInfo = &sched_ctrl->harq_processes[current_harq_pid].sched_pdsch; const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + const uint8_t num_dmrs_cdm_grps_no_data = 1; - sched_ctrl->time_domain_allocation = retInfo->time_domain_allocation; - - /* ensure that there is a free place for RB allocation */ int rbSize = 0; - while (rbSize < retInfo->rbSize) { - rbStart += rbSize; /* last iteration rbSize was not enough, skip it */ - rbSize = 0; - while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++; - if (rbStart >= bwpSize) { - LOG_D(MAC, - "cannot allocate retransmission for UE %d/RNTI %04x: no resources\n", - UE_id, - RC.nrmac[module_id]->UE_info.rnti[UE_id]); - return false; + const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot]; + if (tda == retInfo->time_domain_allocation) { + /* Check that there are enough resources for retransmission */ + while (rbSize < retInfo->rbSize) { + rbStart += rbSize; /* last iteration rbSize was not enough, skip it */ + rbSize = 0; + while (rbStart < bwpSize && !rballoc_mask[rbStart]) + rbStart++; + if (rbStart >= bwpSize) { + LOG_D(MAC, "cannot allocate retransmission for UE %d/RNTI %04x: no resources\n", UE_id, UE_info->rnti[UE_id]); + return false; + } + while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart + rbSize] && rbSize < retInfo->rbSize) + rbSize++; } - while (rbStart + rbSize < bwpSize - && rballoc_mask[rbStart + rbSize] - && rbSize < retInfo->rbSize) + /* check whether we need to switch the TDA allocation since the last + * (re-)transmission */ + NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; + if (ps->time_domain_allocation != tda || ps->numDmrsCdmGrpsNoData != num_dmrs_cdm_grps_no_data) + nr_set_pdsch_semi_static( + scc, UE_info->secondaryCellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, ps); + } else { + /* the retransmission will use a different time domain allocation, check + * that we have enough resources */ + while (rbStart < bwpSize && !rballoc_mask[rbStart]) + rbStart++; + while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart + rbSize]) rbSize++; + NR_pdsch_semi_static_t temp_ps; + nr_set_pdsch_semi_static( + scc, UE_info->secondaryCellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, &temp_ps); + uint32_t new_tbs; + uint16_t new_rbSize; + bool success = nr_find_nb_rb(retInfo->Qm, + retInfo->R, + temp_ps.nrOfSymbols, + temp_ps.N_PRB_DMRS * temp_ps.N_DMRS_SLOT, + retInfo->tb_size, + rbSize, + &new_tbs, + &new_rbSize); + if (!success || new_tbs != retInfo->tb_size) { + LOG_D(MAC, "%s(): new TBsize %d of new TDA does not match old TBS %d\n", __func__, new_tbs, retInfo->tb_size); + return false; /* the maximum TBsize we might have is smaller than what we need */ + } + /* we can allocate it. Overwrite the time_domain_allocation, the number + * of RBs, and the new TB size. The rest is done below */ + retInfo->tb_size = new_tbs; + retInfo->rbSize = new_rbSize; + retInfo->time_domain_allocation = tda; + sched_ctrl->pdsch_semi_static = temp_ps; } - sched_ctrl->rbSize = retInfo->rbSize; - sched_ctrl->rbStart = rbStart; - /* MCS etc: just reuse from previous scheduling opportunity */ - sched_ctrl->mcsTableIdx = retInfo->mcsTableIdx; - sched_ctrl->mcs = retInfo->mcs; - sched_ctrl->numDmrsCdmGrpsNoData = retInfo->numDmrsCdmGrpsNoData; + /* Find a free CCE */ + bool freeCCE = find_free_CCE(module_id, slot, UE_id); + if (!freeCCE) { + LOG_D(MAC, "%4d.%2d could not find CCE for DL DCI retransmission UE %d/RNTI %04x\n", + frame, slot, UE_id, UE_info->rnti[UE_id]); + return false; + } + + /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH + * allocation after CCE alloc fail would be more complex) */ + const bool alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot); + if (!alloc) { + LOG_D(MAC, + "%s(): could not find PUCCH for UE %d/%04x@%d.%d\n", + __func__, + UE_id, + UE_info->rnti[UE_id], + frame, + slot); + int cid = sched_ctrl->coreset->controlResourceSetId; + UE_info->num_pdcch_cand[UE_id][cid]--; + int *cce_list = RC.nrmac[module_id]->cce_list[sched_ctrl->active_bwp->bwp_Id][cid]; + for (int i = 0; i < sched_ctrl->aggregation_level; i++) + cce_list[sched_ctrl->cce_index + i] = 0; + return false; + } + + /* just reuse from previous scheduling opportunity, set new start RB */ + sched_ctrl->sched_pdsch = *retInfo; + sched_ctrl->sched_pdsch.rbStart = rbStart; /* retransmissions: directly allocate */ - *n_rb_sched -= sched_ctrl->rbSize; - for (int rb = 0; rb < sched_ctrl->rbSize; rb++) - rballoc_mask[rb+sched_ctrl->rbStart] = 0; + *n_rb_sched -= sched_ctrl->sched_pdsch.rbSize; + for (int rb = 0; rb < sched_ctrl->sched_pdsch.rbSize; rb++) + rballoc_mask[rb + sched_ctrl->sched_pdsch.rbStart] = 0; return true; } float thr_ue[MAX_MOBILES_PER_GNB]; +uint32_t pf_tbs[3][28]; // pre-computed, approximate TBS values for PF coefficient void pf_dl(module_id_t module_id, frame_t frame, sub_frame_t slot, NR_list_t *UE_list, + int max_num_ue, int n_rb_sched, - uint8_t *rballoc_mask, - int max_num_ue) { - + uint8_t *rballoc_mask) { + const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels->ServingCellConfigCommon; NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; float coeff_ue[MAX_MOBILES_PER_GNB]; // UEs that could be scheduled @@ -429,11 +540,10 @@ void pf_dl(module_id_t module_id, /* Loop UE_info->list to check retransmission */ for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; - sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, NR_SearchSpace__searchSpaceType_PR_ue_Specific); - sched_ctrl->coreset = get_coreset(sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */); + NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; + NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; /* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */ - sched_ctrl->dl_harq_pid = sched_ctrl->retrans_dl_harq.head; - const rnti_t rnti = UE_info->rnti[UE_id]; + sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head; /* Calculate Throughput */ const float a = 0.0005f; // corresponds to 200ms window @@ -441,33 +551,10 @@ void pf_dl(module_id_t module_id, thr_ue[UE_id] = (1 - a) * thr_ue[UE_id] + a * b; /* retransmission */ - if (sched_ctrl->dl_harq_pid >= 0) { - /* Find a free CCE */ - bool freeCCE = find_free_CCE(module_id, slot, UE_id); - if (!freeCCE){ - LOG_D(MAC, "%4d.%2d could not find CCE for DL DCI retransmission UE %d/RNTI %04x\n", frame, slot, UE_id, rnti); - continue; - } - /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH - * allocation after CCE alloc fail would be more complex) */ - const bool alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot); - if (!alloc) { - LOG_W(MAC, - "%s(): could not find PUCCH for UE %d/%04x@%d.%d\n", - __func__, - UE_id, - rnti, - frame, - slot); - int cid = sched_ctrl->coreset->controlResourceSetId; - UE_info->num_pdcch_cand[UE_id][cid]--; - int *cce_list = RC.nrmac[module_id]->cce_list[sched_ctrl->active_bwp->bwp_Id][cid]; - for (int i = 0; i < sched_ctrl->aggregation_level; i++) - cce_list[sched_ctrl->cce_index + i] = 0; - return; - } + if (sched_pdsch->dl_harq_pid >= 0) { /* Allocate retransmission */ - bool r = allocate_retransmission(module_id, rballoc_mask, &n_rb_sched, UE_id, sched_ctrl->dl_harq_pid); + bool r = allocate_dl_retransmission( + module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pdsch->dl_harq_pid); if (!r) { LOG_D(MAC, "%4d.%2d retransmission can NOT be allocated\n", frame, slot); continue; @@ -481,23 +568,8 @@ void pf_dl(module_id_t module_id, continue; /* Calculate coeff */ - sched_ctrl->time_domain_allocation = 2; - sched_ctrl->mcsTableIdx = 0; - sched_ctrl->mcs = 9; - sched_ctrl->numDmrsCdmGrpsNoData = 1; - uint8_t N_PRB_DMRS = - getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData); - int nrOfSymbols = getNrOfSymbols(sched_ctrl->active_bwp, - sched_ctrl->time_domain_allocation); - uint32_t tbs = nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), - nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), - 1, // rbSize - nrOfSymbols, - N_PRB_DMRS, // FIXME // This should be multiplied by the - // number of dmrs symbols - 0 /* N_PRB_oh, 0 for initialBWP */, 0 /* tb_scaling */, - 1 /* nrOfLayers */) - >> 3; + sched_pdsch->mcs = 9; + uint32_t tbs = pf_tbs[ps->mcsTableIdx][sched_pdsch->mcs]; coeff_ue[UE_id] = (float) tbs / thr_ue[UE_id]; LOG_D(MAC,"b %d, thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n", b, UE_id, thr_ue[UE_id], tbs, UE_id, coeff_ue[UE_id]); @@ -545,7 +617,7 @@ void pf_dl(module_id_t module_id, * allocation after CCE alloc fail would be more complex) */ const bool alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot); if (!alloc) { - LOG_W(MAC, + LOG_D(MAC, "%s(): could not find PUCCH for UE %d/%04x@%d.%d\n", __func__, UE_id, @@ -560,57 +632,48 @@ void pf_dl(module_id_t module_id, return; } - /* Allocate transmission */ - // Time-domain allocation - sched_ctrl->time_domain_allocation = 2; - - // modulation scheme - sched_ctrl->mcsTableIdx = 0; - sched_ctrl->mcs = 9; - sched_ctrl->numDmrsCdmGrpsNoData = 1; - // Freq-demain allocation while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++; + uint16_t max_rbSize = 1; + while (rbStart + max_rbSize < bwpSize && rballoc_mask[rbStart + max_rbSize]) + max_rbSize++; + + /* MCS has been set above */ + const uint8_t num_dmrs_cdm_grps_no_data = 1; + const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot]; + NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; + NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; + if (ps->time_domain_allocation != tda || ps->numDmrsCdmGrpsNoData != num_dmrs_cdm_grps_no_data) + nr_set_pdsch_semi_static( + scc, UE_info->secondaryCellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, ps); + sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx); + sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx); - const uint8_t N_PRB_DMRS = - getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData); - const int nrOfSymbols = getNrOfSymbols(sched_ctrl->active_bwp, - sched_ctrl->time_domain_allocation); - const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels->ServingCellConfigCommon; - const uint8_t N_DMRS_SLOT = get_num_dmrs_symbols( - sched_ctrl->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, - scc->dmrs_TypeA_Position, - nrOfSymbols); - - int rbSize = 0; uint32_t TBS = 0; + uint16_t rbSize; const int oh = 2 + (sched_ctrl->num_total_bytes >= 256) + 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024); - do { - rbSize++; - TBS = nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), - nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), - rbSize, - nrOfSymbols, - N_PRB_DMRS * N_DMRS_SLOT, - 0 /* N_PRB_oh, 0 for initialBWP */, - 0 /* tb_scaling */, - 1 /* nrOfLayers */) - >> 3; - } while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart + rbSize] && TBS < sched_ctrl->num_total_bytes + oh); - sched_ctrl->rbSize = rbSize; - sched_ctrl->rbStart = rbStart; + nr_find_nb_rb(sched_pdsch->Qm, + sched_pdsch->R, + ps->nrOfSymbols, + ps->N_PRB_DMRS * ps->N_DMRS_SLOT, + sched_ctrl->num_total_bytes + oh, + max_rbSize, + &TBS, + &rbSize); + sched_pdsch->rbSize = rbSize; + sched_pdsch->rbStart = rbStart; + sched_pdsch->tb_size = TBS; /* transmissions: directly allocate */ - n_rb_sched -= sched_ctrl->rbSize; - for (int rb = 0; rb < sched_ctrl->rbSize; rb++) - rballoc_mask[rb+sched_ctrl->rbStart] = 0; + n_rb_sched -= sched_pdsch->rbSize; + for (int rb = 0; rb < sched_pdsch->rbSize; rb++) + rballoc_mask[rb + sched_pdsch->rbStart] = 0; } } -void nr_simple_dlsch_preprocessor(module_id_t module_id, - frame_t frame, - sub_frame_t slot) { +void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot) +{ NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; if (UE_info->num_UEs == 0) @@ -642,15 +705,45 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id, frame, slot, &UE_info->list, + 2, n_rb_sched, - rballoc_mask, - 2); + rballoc_mask); +} + +nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id) +{ + /* in the PF algorithm, we have to use the TBsize to compute the coefficient. + * This would include the number of DMRS symbols, which in turn depends on + * the time domain allocation. In case we are in a mixed slot, we do not want + * to recalculate all these values just, and therefore we provide a look-up + * table which should approximately give us the TBsize */ + for (int mcsTableIdx = 0; mcsTableIdx < 3; ++mcsTableIdx) { + for (int mcs = 0; mcs < 29; ++mcs) { + if (mcs > 27 && mcsTableIdx == 1) + continue; + const uint8_t Qm = nr_get_Qm_dl(mcs, mcsTableIdx); + const uint16_t R = nr_get_code_rate_dl(mcs, mcsTableIdx); + pf_tbs[mcsTableIdx][mcs] = nr_compute_tbs(Qm, + R, + 1, /* rbSize */ + 10, /* hypothetical number of slots */ + 0, /* N_PRB_DMRS * N_DMRS_SLOT */ + 0 /* N_PRB_oh, 0 for initialBWP */, + 0 /* tb_scaling */, + 1 /* nrOfLayers */) + >> 3; + } + } + + return nr_fr1_dlsch_preprocessor; } void nr_schedule_ue_spec(module_id_t module_id, frame_t frame, sub_frame_t slot) { gNB_MAC_INST *gNB_mac = RC.nrmac[module_id]; + if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot)) + return; /* PREPROCESSOR */ gNB_mac->pre_processor_dl(module_id, frame, slot); @@ -664,6 +757,7 @@ void nr_schedule_ue_spec(module_id_t module_id, NR_list_t *UE_list = &UE_info->list; for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; UE_info->mac_stats[UE_id].dlsch_current_bytes = 0; /* update TA and set ta_apply every 10 frames. @@ -675,45 +769,23 @@ void nr_schedule_ue_spec(module_id_t module_id, LOG_D(MAC, "[UE %d][%d.%d] UL timing alignment procedures: setting flag for Timing Advance command\n", UE_id, frame, slot); } - if (sched_ctrl->rbSize <= 0) + if (sched_pdsch->rbSize <= 0) continue; const rnti_t rnti = UE_info->rnti[UE_id]; /* POST processing */ - struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = - sched_ctrl->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - AssertFatal(sched_ctrl->time_domain_allocation < tdaList->list.count, - "time_domain_allocation %d>=%d\n", - sched_ctrl->time_domain_allocation, - tdaList->list.count); - - const int startSymbolAndLength = - tdaList->list.array[sched_ctrl->time_domain_allocation]->startSymbolAndLength; - int startSymbolIndex, nrOfSymbols; - SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); - - uint8_t N_PRB_DMRS = - getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData); - uint8_t N_DMRS_SLOT = get_num_dmrs_symbols(sched_ctrl->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, - RC.nrmac[module_id]->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position , - nrOfSymbols); - const nfapi_nr_dmrs_type_e dmrsConfigType = getDmrsConfigType(sched_ctrl->active_bwp); const int nrOfLayers = 1; - const uint16_t R = nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx); - const uint8_t Qm = nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx); - const uint32_t TBS = - nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), - nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), - sched_ctrl->rbSize, - nrOfSymbols, - N_PRB_DMRS * N_DMRS_SLOT, - 0 /* N_PRB_oh, 0 for initialBWP */, - 0 /* tb_scaling */, - nrOfLayers) - >> 3; - - int8_t current_harq_pid = sched_ctrl->dl_harq_pid; + const uint16_t R = sched_pdsch->R; + const uint8_t Qm = sched_pdsch->Qm; + const uint32_t TBS = sched_pdsch->tb_size; + + /* pre-computed PDSCH values that only change if time domain + * allocation/DMRS parameters change. Updated in the preprocessor through + * nr_set_pdsch_semi_static() */ + NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; + + int8_t current_harq_pid = sched_pdsch->dl_harq_pid; if (current_harq_pid < 0) { /* PP has not selected a specific HARQ Process, get a new one */ current_harq_pid = sched_ctrl->available_dl_harq.head; @@ -721,7 +793,7 @@ void nr_schedule_ue_spec(module_id_t module_id, "no free HARQ process available for UE %d\n", UE_id); remove_front_nr_list(&sched_ctrl->available_dl_harq); - sched_ctrl->dl_harq_pid = current_harq_pid; + sched_pdsch->dl_harq_pid = current_harq_pid; } else { /* PP selected a specific HARQ process. Check whether it will be a new * transmission or a retransmission, and remove from the corresponding @@ -735,20 +807,21 @@ void nr_schedule_ue_spec(module_id_t module_id, DevAssert(!harq->is_waiting); add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[0]; + harq->feedback_frame = pucch->frame; harq->feedback_slot = pucch->ul_slot; harq->is_waiting = true; UE_info->mac_stats[UE_id].dlsch_rounds[harq->round]++; LOG_D(MAC, - "%4d.%2d RNTI %04x start %d RBs %d startSymbol %d nb_symbsol %d MCS %d TBS %d HARQ PID %d round %d NDI %d\n", + "%4d.%2d RNTI %04x start %3d RBs %3d startSymbol %2d nb_symbol %2d MCS %2d TBS %4d HARQ PID %2d round %d NDI %d\n", frame, slot, rnti, - sched_ctrl->rbStart, - sched_ctrl->rbSize, - startSymbolIndex, - nrOfSymbols, - sched_ctrl->mcs, + sched_pdsch->rbStart, + sched_pdsch->rbSize, + ps->startSymbolIndex, + ps->nrOfSymbols, + sched_pdsch->mcs, TBS, current_harq_pid, harq->round, @@ -804,8 +877,8 @@ void nr_schedule_ue_spec(module_id_t module_id, pdsch_pdu->NrOfCodewords = 1; pdsch_pdu->targetCodeRate[0] = R; pdsch_pdu->qamModOrder[0] = Qm; - pdsch_pdu->mcsIndex[0] = sched_ctrl->mcs; - pdsch_pdu->mcsTable[0] = sched_ctrl->mcsTableIdx; + pdsch_pdu->mcsIndex[0] = sched_pdsch->mcs; + pdsch_pdu->mcsTable[0] = ps->mcsTableIdx; pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round]; pdsch_pdu->TBSize[0] = TBS; @@ -815,25 +888,22 @@ void nr_schedule_ue_spec(module_id_t module_id, pdsch_pdu->refPoint = 0; // Point A // DMRS - pdsch_pdu->dlDmrsSymbPos = - fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup, - scc->dmrs_TypeA_Position, - nrOfSymbols); - pdsch_pdu->dmrsConfigType = dmrsConfigType; + pdsch_pdu->dlDmrsSymbPos = ps->dl_dmrs_symb_pos; + pdsch_pdu->dmrsConfigType = ps->dmrsConfigType; pdsch_pdu->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu->SCID = 0; - pdsch_pdu->numDmrsCdmGrpsNoData = sched_ctrl->numDmrsCdmGrpsNoData; + pdsch_pdu->numDmrsCdmGrpsNoData = ps->numDmrsCdmGrpsNoData; pdsch_pdu->dmrsPorts = 1; // Pdsch Allocation in frequency domain pdsch_pdu->resourceAlloc = 1; - pdsch_pdu->rbStart = sched_ctrl->rbStart; - pdsch_pdu->rbSize = sched_ctrl->rbSize; + pdsch_pdu->rbStart = sched_pdsch->rbStart; + pdsch_pdu->rbSize = sched_pdsch->rbSize; pdsch_pdu->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP // Resource Allocation in time domain - pdsch_pdu->StartSymbolIndex = startSymbolIndex; - pdsch_pdu->NrOfSymbols = nrOfSymbols; + pdsch_pdu->StartSymbolIndex = ps->startSymbolIndex; + pdsch_pdu->NrOfSymbols = ps->nrOfSymbols; /* Check and validate PTRS values */ struct NR_SetupRelease_PTRS_DownlinkConfig *phaseTrackingRS = @@ -887,8 +957,8 @@ void nr_schedule_ue_spec(module_id_t module_id, pdsch_pdu->rbSize, pdsch_pdu->rbStart, pdsch_pdu->BWPSize); - dci_payload.time_domain_assignment.val = sched_ctrl->time_domain_allocation; - dci_payload.mcs = sched_ctrl->mcs; + dci_payload.time_domain_assignment.val = ps->time_domain_allocation; + dci_payload.mcs = sched_pdsch->mcs; dci_payload.rv = pdsch_pdu->rvIndex[0]; dci_payload.harq_pid = current_harq_pid; dci_payload.ndi = harq->ndi; @@ -933,29 +1003,7 @@ void nr_schedule_ue_spec(module_id_t module_id, pdcch_pdu->StartSymbolIndex, pdcch_pdu->DurationSymbols); - NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid]; if (harq->round != 0) { /* retransmission */ - if (sched_ctrl->rbSize != retInfo->rbSize) - LOG_W(MAC, - "retransmission uses different rbSize (%d vs. orig %d)\n", - sched_ctrl->rbSize, - retInfo->rbSize); - if (sched_ctrl->time_domain_allocation != retInfo->time_domain_allocation) - LOG_W(MAC, - "retransmission uses different time_domain_allocation (%d vs. orig %d)\n", - sched_ctrl->time_domain_allocation, - retInfo->time_domain_allocation); - if (sched_ctrl->mcs != retInfo->mcs - || sched_ctrl->mcsTableIdx != retInfo->mcsTableIdx - || sched_ctrl->numDmrsCdmGrpsNoData != retInfo->numDmrsCdmGrpsNoData) - LOG_W(MAC, - "retransmission uses different table/MCS/numDmrsCdmGrpsNoData (%d/%d/%d vs. orig %d/%d/%d)\n", - sched_ctrl->mcsTableIdx, - sched_ctrl->mcs, - sched_ctrl->numDmrsCdmGrpsNoData, - retInfo->mcsTableIdx, - retInfo->mcs, - retInfo->numDmrsCdmGrpsNoData); /* we do not have to do anything, since we do not require to get data * from RLC or encode MAC CEs. The TX_req structure is filled below * or copy data to FAPI structures */ @@ -968,7 +1016,7 @@ void nr_schedule_ue_spec(module_id_t module_id, current_harq_pid, harq->round, harq->ndi); - AssertFatal(harq->tb_size == TBS, + AssertFatal(harq->sched_pdsch.tb_size == TBS, "UE %d mismatch between scheduled TBS and buffered TB for HARQ PID %d\n", UE_id, current_harq_pid); @@ -976,7 +1024,6 @@ void nr_schedule_ue_spec(module_id_t module_id, LOG_D(MAC, "[%s] Initial HARQ transmission in %d.%d\n", __FUNCTION__, frame, slot); - harq->tb_size = TBS; uint8_t *buf = (uint8_t *) harq->tb; /* first, write all CEs that might be there */ @@ -1084,11 +1131,11 @@ void nr_schedule_ue_spec(module_id_t module_id, UE_info->mac_stats[UE_id].dlsch_current_bytes = TBS; UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += dlsch_total_bytes; - retInfo->rbSize = sched_ctrl->rbSize; - retInfo->time_domain_allocation = sched_ctrl->time_domain_allocation; - retInfo->mcsTableIdx = sched_ctrl->mcsTableIdx; - retInfo->mcs = sched_ctrl->mcs; - retInfo->numDmrsCdmGrpsNoData = sched_ctrl->numDmrsCdmGrpsNoData; + /* save retransmission information */ + harq->sched_pdsch = *sched_pdsch; + /* save which time allocation has been used, to be used on + * retransmissions */ + harq->sched_pdsch.time_domain_allocation = ps->time_domain_allocation; // ta command is sent, values are reset if (sched_ctrl->ta_apply) { @@ -1117,6 +1164,6 @@ void nr_schedule_ue_spec(module_id_t module_id, gNB_mac->TX_req[CC_id].Slot = slot; /* mark UE as scheduled */ - sched_ctrl->rbSize = 0; + memset(sched_pdsch, 0, sizeof(*sched_pdsch)); } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 6487f391b9198bfb489dba0471ba670f53e3fa84..6c4e3398f10fdd254cc06192cf89829d863050b4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -254,16 +254,22 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, } } +extern int getNrOfSymbols(NR_BWP_Downlink_t *bwp, int tda); +extern uint8_t getN_PRB_DMRS(NR_BWP_Downlink_t *bwp, int numDmrsCdmGrpsNoData); +uint32_t target_dl_mcs = 9; +uint32_t target_dl_bw = 50; +uint64_t dlsch_slot_bitmap = (1<<1); /* schedules whole bandwidth for first user, all the time */ void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_t slot) { - if (slot != 1) + if (!is_xlsch_in_slot(dlsch_slot_bitmap, slot)) return; + const int CC_id = 0; + const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[CC_id].ServingCellConfigCommon; NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; const int UE_id = 0; - const int CC_id = 0; AssertFatal(UE_info->active[UE_id], "%s(): expected UE %d to be active\n", __func__, @@ -272,24 +278,25 @@ void nr_preprocessor_phytest(module_id_t module_id, /* find largest unallocated chunk */ const int bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); int rbStart = 0; - int tStart = 0; int rbSize = 0; uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map; - /* find largest unallocated RB region */ - do { + /* loop ensures that we allocate exactly target_dl_bw, or return */ + while (true) { /* advance to first free RB */ - while (tStart < bwpSize && vrb_map[tStart]) - tStart++; - /* find maximum rbSize at current rbStart */ - int tSize = 1; - while (tStart + tSize < bwpSize && !vrb_map[tStart + tSize]) - tSize++; - if (tSize > rbSize) { - rbStart = tStart; - rbSize = tSize; - } - tStart += tSize; - } while (tStart < bwpSize); + while (rbStart < bwpSize && vrb_map[rbStart]) + rbStart++; + rbSize = 1; + /* iterate until we are at target_dl_bw or no available RBs */ + while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && rbSize < target_dl_bw) + rbSize++; + /* found target_dl_bw? */ + if (rbSize == target_dl_bw) + break; + /* at end and below target_dl_bw? */ + if (rbStart + rbSize >= bwpSize) + return; + rbStart += rbSize; + } sched_ctrl->num_total_bytes = 0; const int lcid = DL_SCH_LCID_DTCH; @@ -308,14 +315,10 @@ void nr_preprocessor_phytest(module_id_t module_id, 0); sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer; - const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss); uint8_t nr_of_candidates; find_aggregation_candidates(&sched_ctrl->aggregation_level, &nr_of_candidates, sched_ctrl->search_space); - sched_ctrl->coreset = get_coreset( - sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */); const int cid = sched_ctrl->coreset->controlResourceSetId; const uint16_t Y = UE_info->Y[UE_id][cid][slot]; const int m = UE_info->num_pdcch_cand[UE_id][cid]; @@ -351,32 +354,42 @@ void nr_preprocessor_phytest(module_id_t module_id, "could not find uplink slot for PUCCH (RNTI %04x@%d.%d)!\n", rnti, frame, slot); - sched_ctrl->rbStart = rbStart; - sched_ctrl->rbSize = rbSize; - sched_ctrl->time_domain_allocation = 2; - if (!UE_info->secondaryCellGroup[UE_id]->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table) - sched_ctrl->mcsTableIdx = 0; - else { - if (*UE_info->secondaryCellGroup[UE_id]->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table == 0) - sched_ctrl->mcsTableIdx = 1; - else - sched_ctrl->mcsTableIdx = 2; - } - sched_ctrl->mcs = 9; - sched_ctrl->numDmrsCdmGrpsNoData = 1; + NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; + NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; + sched_pdsch->rbStart = rbStart; + sched_pdsch->rbSize = rbSize; + const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot]; + const uint8_t num_dmrs_cdm_grps_no_data = 1; + if (ps->time_domain_allocation != tda || ps->numDmrsCdmGrpsNoData != num_dmrs_cdm_grps_no_data) + nr_set_pdsch_semi_static( + scc, UE_info->secondaryCellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, ps); + + sched_pdsch->mcs = target_dl_mcs; + sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx); + sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx); + sched_pdsch->tb_size = nr_compute_tbs(sched_pdsch->Qm, + sched_pdsch->R, + sched_pdsch->rbSize, + ps->nrOfSymbols, + ps->N_PRB_DMRS * ps->N_DMRS_SLOT, + 0 /* N_PRB_oh, 0 for initialBWP */, + 0 /* tb_scaling */, + 1 /* nrOfLayers */) + >> 3; + /* get the PID of a HARQ process awaiting retransmission, or -1 otherwise */ - sched_ctrl->dl_harq_pid = sched_ctrl->retrans_dl_harq.head; + sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head; /* mark the corresponding RBs as used */ - for (int rb = 0; rb < sched_ctrl->rbSize; rb++) - vrb_map[rb + sched_ctrl->rbStart] = 1; + for (int rb = 0; rb < sched_pdsch->rbSize; rb++) + vrb_map[rb + sched_pdsch->rbStart] = 1; } -bool nr_ul_preprocessor_phytest(module_id_t module_id, - frame_t frame, - sub_frame_t slot, - int num_slots_per_tdd, - uint64_t ulsch_in_slot_bitmap) { +uint32_t target_ul_mcs = 9; +uint32_t target_ul_bw = 50; +uint64_t ulsch_slot_bitmap = (1 << 8) | (1 << 18); +bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_t slot) +{ gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; NR_COMMON_channels_t *cc = nr_mac->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; @@ -395,7 +408,9 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; - const int tda = 1; + const int tda = RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot]; + if (tda < 0) + return false; const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; AssertFatal(tda < tdaList->list.count, @@ -408,14 +423,11 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, /* check if slot is UL, and that slot is 8 (assuming K2=6 because of UE * limitations). Note that if K2 or the TDD configuration is changed, below * conditions might exclude each other and never be true */ - if (!(is_xlsch_in_slot(ulsch_in_slot_bitmap, sched_slot) && sched_slot == 8)) + if (!is_xlsch_in_slot(ulsch_slot_bitmap, sched_slot)) return false; - const int bw = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); uint16_t rbStart = 0; - uint16_t rbSize = 50; /* due to OAI UE limitations */ - if (rbSize>bw) - rbSize = bw; + uint16_t rbSize = target_ul_bw; uint16_t *vrb_map_UL = &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE]; @@ -434,14 +446,10 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, sched_ctrl->sched_pusch.slot = sched_slot; sched_ctrl->sched_pusch.frame = sched_frame; - const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss); uint8_t nr_of_candidates; find_aggregation_candidates(&sched_ctrl->aggregation_level, &nr_of_candidates, sched_ctrl->search_space); - sched_ctrl->coreset = get_coreset( - sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */); const int cid = sched_ctrl->coreset->controlResourceSetId; const uint16_t Y = UE_info->Y[UE_id][cid][slot]; const int m = UE_info->num_pdcch_cand[UE_id][cid]; @@ -458,25 +466,19 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, } UE_info->num_pdcch_cand[UE_id][cid]++; - sched_ctrl->sched_pusch.time_domain_allocation = tda; const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats; const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0; const uint8_t num_dmrs_cdm_grps_no_data = 1; /* we want to avoid a lengthy deduction of DMRS and other parameters in * every TTI if we can save it, so check whether dci_format, TDA, or * num_dmrs_cdm_grps_no_data has changed and only then recompute */ - NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save; + NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; if (ps->time_domain_allocation != tda || ps->dci_format != dci_format || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) - nr_save_pusch_fields(scc, - sched_ctrl->active_ubwp, - dci_format, - tda, - num_dmrs_cdm_grps_no_data, - ps); - - const int mcs = 9; + nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps); + + const int mcs = target_ul_mcs; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; sched_pusch->mcs = mcs; sched_pusch->rbStart = rbStart; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 94524795f3264b13a0129035696ededc7d062f68..0717cc568e6f3ecf33282e533f9fb19a2d438deb 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -120,11 +120,10 @@ static inline uint8_t get_max_candidates(uint8_t scs) { static inline uint8_t get_max_cces(uint8_t scs) { AssertFatal(scs<4, "Invalid PDCCH subcarrier spacing %d\n", scs); return (nr_max_number_of_cces_per_slot[scs]); -} +} -NR_ControlResourceSet_t *get_coreset(NR_BWP_Downlink_t *bwp, - NR_SearchSpace_t *ss, - int ss_type) { +NR_ControlResourceSet_t *get_coreset(const NR_BWP_Downlink_t *bwp, const NR_SearchSpace_t *ss, int ss_type) +{ NR_ControlResourceSetId_t coreset_id = *ss->controlResourceSetId; if (ss_type == 0) { // common search space AssertFatal(coreset_id != 0, "coreset0 currently not supported\n"); @@ -146,9 +145,8 @@ NR_ControlResourceSet_t *get_coreset(NR_BWP_Downlink_t *bwp, } } -NR_SearchSpace_t *get_searchspace( - NR_BWP_Downlink_t *bwp, - NR_SearchSpace__searchSpaceType_PR target_ss) { +NR_SearchSpace_t *get_searchspace(const NR_BWP_Downlink_t *bwp, NR_SearchSpace__searchSpaceType_PR target_ss) +{ DevAssert(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList); DevAssert(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count > 0); @@ -212,12 +210,98 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, } -void nr_save_pusch_fields(const NR_ServingCellConfigCommon_t *scc, - const NR_BWP_Uplink_t *ubwp, - long dci_format, - int tda, - uint8_t num_dmrs_cdm_grps_no_data, - NR_sched_pusch_save_t *ps) +bool nr_find_nb_rb(uint16_t Qm, + uint16_t R, + uint16_t nb_symb_sch, + uint16_t nb_dmrs_prb, + uint32_t bytes, + uint16_t nb_rb_max, + uint32_t *tbs, + uint16_t *nb_rb) +{ + /* is the maximum (not even) enough? */ + *nb_rb = nb_rb_max; + *tbs = nr_compute_tbs(Qm, R, *nb_rb, nb_symb_sch, nb_dmrs_prb, 0, 0, 1) >> 3; + /* check whether it does not fit, or whether it exactly fits. Some algorithms + * might depend on the return value! */ + if (bytes > *tbs) + return false; + if (bytes == *tbs) + return true; + + /* is the minimum enough? */ + *nb_rb = 1; + *tbs = nr_compute_tbs(Qm, R, *nb_rb, nb_symb_sch, nb_dmrs_prb, 0, 0, 1) >> 3; + if (bytes <= *tbs) + return true; + + /* perform binary search to allocate all bytes within a TBS up to nb_rb_max + * RBs */ + int hi = nb_rb_max; + int lo = 1; + for (int p = (hi + lo) / 2; lo + 1 < hi; p = (hi + lo) / 2) { + const uint32_t TBS = nr_compute_tbs(Qm, R, p, nb_symb_sch, nb_dmrs_prb, 0, 0, 1) >> 3; + if (bytes == TBS) { + hi = p; + break; + } else if (bytes < TBS) { + hi = p; + } else { + lo = p; + } + } + *nb_rb = hi; + *tbs = nr_compute_tbs(Qm, R, *nb_rb, nb_symb_sch, nb_dmrs_prb, 0, 0, 1) >> 3; + /* return whether we could allocate all bytes and stay below nb_rb_max */ + return *tbs >= bytes && *nb_rb <= nb_rb_max; +} + +void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc, + const NR_CellGroupConfig_t *secondaryCellGroup, + const NR_BWP_Downlink_t *bwp, + int tda, + uint8_t num_dmrs_cdm_grps_no_data, + NR_pdsch_semi_static_t *ps) +{ + ps->time_domain_allocation = tda; + + const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = + bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; + AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count); + const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength; + SLIV2SL(startSymbolAndLength, &ps->startSymbolIndex, &ps->nrOfSymbols); + + if (!secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup + ->mcs_Table) + ps->mcsTableIdx = 0; + else if (*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup + ->mcs_Table + == 0) + ps->mcsTableIdx = 1; + else + ps->mcsTableIdx = 2; + + ps->numDmrsCdmGrpsNoData = num_dmrs_cdm_grps_no_data; + ps->dmrsConfigType = + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type + == NULL + ? 0 + : 1; + // if no data in dmrs cdm group is 1 only even REs have no data + // if no data in dmrs cdm group is 2 both odd and even REs have no data + ps->N_PRB_DMRS = num_dmrs_cdm_grps_no_data * (ps->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4); + ps->N_DMRS_SLOT = + get_num_dmrs_symbols(bwp->bwp_Dedicated->pdsch_Config->choice.setup, scc->dmrs_TypeA_Position, ps->nrOfSymbols); + ps->dl_dmrs_symb_pos = + fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup, scc->dmrs_TypeA_Position, ps->nrOfSymbols); +} + +void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc, + const NR_BWP_Uplink_t *ubwp, + long dci_format, + int tda, + uint8_t num_dmrs_cdm_grps_no_data, + NR_pusch_semi_static_t *ps) { ps->dci_format = dci_format; ps->time_domain_allocation = tda; @@ -1616,6 +1700,24 @@ int get_nrofHARQ_ProcessesForPDSCH(e_NR_PDSCH_ServingCellConfig__nrofHARQ_Proces } } +int get_dl_bwp_id(const NR_ServingCellConfig_t *servingCellConfig) +{ + if (servingCellConfig->firstActiveDownlinkBWP_Id) + return *servingCellConfig->firstActiveDownlinkBWP_Id; + else if (servingCellConfig->defaultDownlinkBWP_Id) + return *servingCellConfig->defaultDownlinkBWP_Id; + else + return 1; +} + +int get_ul_bwp_id(const NR_ServingCellConfig_t *servingCellConfig) +{ + if (servingCellConfig->uplinkConfig && servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id) + return *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id; + else + return 1; +} + //------------------------------------------------------------------------------ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *secondaryCellGroup) { @@ -1644,23 +1746,32 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *secon sched_ctrl->ta_frame = 0; sched_ctrl->ta_update = 31; sched_ctrl->ta_apply = false; - sched_ctrl->ul_rssi = 0; /* set illegal time domain allocation to force recomputation of all fields */ - sched_ctrl->pusch_save.time_domain_allocation = -1; + sched_ctrl->pdsch_semi_static.time_domain_allocation = -1; + sched_ctrl->pusch_semi_static.time_domain_allocation = -1; const NR_ServingCellConfig_t *servingCellConfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated; /* Set default BWPs */ const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList; - AssertFatal(bwpList->list.count == 1, - "downlinkBWP_ToAddModList has %d BWP!\n", + const int bwp_id = get_dl_bwp_id(servingCellConfig); + AssertFatal(bwp_id > 0 && bwp_id <= bwpList->list.count, + "%s(): illegal bwp_id %d (max %d)!\n", + __func__, + bwp_id, bwpList->list.count); - const int bwp_id = 1; sched_ctrl->active_bwp = bwpList->list.array[bwp_id - 1]; + const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss); + sched_ctrl->coreset = get_coreset(sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */); + const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList; - AssertFatal(ubwpList->list.count == 1, - "uplinkBWP_ToAddModList has %d BWP!\n", + const int ubwp_id = get_ul_bwp_id(servingCellConfig); + AssertFatal(ubwp_id > 0 && ubwp_id <= ubwpList->list.count, + "%s(): illegal ubwp_id %d (max %d)!\n", + __func__, + ubwp_id, ubwpList->list.count); - sched_ctrl->active_ubwp = ubwpList->list.array[bwp_id - 1]; + sched_ctrl->active_ubwp = ubwpList->list.array[ubwp_id - 1]; /* get Number of HARQ processes for this UE */ AssertFatal(servingCellConfig->pdsch_ServingCellConfig->present == NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 247a7e2c459292c3ef59d2aea863400fd5412ce0..bdd6cf0c1dba241b5369d75c9555847b5baa9424 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -948,7 +948,50 @@ void extract_pucch_csi_report (NR_CSI_MeasConfig_t *csi_MeasConfig, if ( !(reportQuantity_type)) AssertFatal(reportQuantity_type, "reportQuantity is not configured"); +} +static NR_UE_harq_t *find_harq(module_id_t mod_id, frame_t frame, sub_frame_t slot, int UE_id) +{ + /* In case of realtime problems: we can only identify a HARQ process by + * timing. If the HARQ process's feedback_frame/feedback_slot is not the one we + * expected, we assume that processing has been aborted and we need to + * skip this HARQ process, which is what happens in the loop below. + * Similarly, we might be "in advance", in which case we need to skip + * this result. */ + NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[mod_id]->UE_info.UE_sched_ctrl[UE_id]; + int8_t pid = sched_ctrl->feedback_dl_harq.head; + if (pid < 0) + return NULL; + NR_UE_harq_t *harq = &sched_ctrl->harq_processes[pid]; + /* old feedbacks we missed: mark for retransmission */ + while (harq->feedback_frame != frame + || (harq->feedback_frame == frame && harq->feedback_slot < slot)) { + LOG_W(MAC, + "expected HARQ pid %d feedback at %d.%d, but is at %d.%d instead (HARQ feedback is in the past)\n", + pid, + harq->feedback_frame, + harq->feedback_slot, + frame, + slot); + remove_front_nr_list(&sched_ctrl->feedback_dl_harq); + handle_dl_harq(mod_id, UE_id, pid, 0); + pid = sched_ctrl->feedback_dl_harq.head; + if (pid < 0) + return NULL; + harq = &sched_ctrl->harq_processes[pid]; + } + /* feedbacks that we wait for in the future: don't do anything */ + if (harq->feedback_slot > slot) { + LOG_W(MAC, + "expected HARQ pid %d feedback at %d.%d, but is at %d.%d instead (HARQ feedback is in the future)\n", + pid, + harq->feedback_frame, + harq->feedback_slot, + frame, + slot); + return NULL; + } + return harq; } void handle_nr_uci_pucch_0_1(module_id_t mod_id, @@ -968,6 +1011,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10, uci_01->ul_cqi, 30); + sched_ctrl->pucch_snrx10 = uci_01->ul_cqi * 5 - 640; NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon; const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; @@ -976,28 +1020,14 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) { const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value; const uint8_t harq_confidence = uci_01->harq->harq_confidence_level; + const int feedback_frame = slot == 0 ? (frame - 1 + 1024) % 1024 : frame; const int feedback_slot = (slot - 1 + num_slots) % num_slots; - /* In case of realtime problems: we can only identify a HARQ process by - * timing. If the HARQ process's feedback_slot is not the one we - * expected, we assume that processing has been aborted and we need to - * skip this HARQ process, which is what happens in the loop below. If - * you don't experience real-time problems, you might simply revert the - * commit that introduced these changes. */ - int8_t pid = sched_ctrl->feedback_dl_harq.head; - DevAssert(pid >= 0); - while (sched_ctrl->harq_processes[pid].feedback_slot != feedback_slot) { - LOG_W(MAC, - "expected feedback slot %d, but found %d instead\n", - sched_ctrl->harq_processes[pid].feedback_slot, - feedback_slot); - remove_front_nr_list(&sched_ctrl->feedback_dl_harq); - handle_dl_harq(mod_id, UE_id, pid, 0); - pid = sched_ctrl->feedback_dl_harq.head; - DevAssert(pid >= 0); - } - remove_front_nr_list(&sched_ctrl->feedback_dl_harq); - NR_UE_harq_t *harq = &sched_ctrl->harq_processes[pid]; + NR_UE_harq_t *harq = find_harq(mod_id, feedback_frame, feedback_slot, UE_id); + if (!harq) + break; DevAssert(harq->is_waiting); + const int8_t pid = sched_ctrl->feedback_dl_harq.head; + remove_front_nr_list(&sched_ctrl->feedback_dl_harq); handle_dl_harq(mod_id, UE_id, pid, harq_value == 1 && harq_confidence == 0); } } @@ -1021,6 +1051,7 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10, uci_234->ul_cqi, 30); + sched_ctrl->pucch_snrx10 = uci_234->ul_cqi * 5 - 640; NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon; const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; @@ -1028,28 +1059,14 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, // iterate over received harq bits for (int harq_bit = 0; harq_bit < uci_234->harq.harq_bit_len; harq_bit++) { const int acknack = ((uci_234->harq.harq_payload[harq_bit >> 3]) >> harq_bit) & 0x01; + const int feedback_frame = slot == 0 ? (frame - 1 + 1024) % 1024 : frame; const int feedback_slot = (slot - 1 + num_slots) % num_slots; - /* In case of realtime problems: we can only identify a HARQ process by - * timing. If the HARQ process's feedback_slot is not the one we - * expected, we assume that processing has been aborted and we need to - * skip this HARQ process, which is what happens in the loop below. If - * you don't experience real-time problems, you might simply revert the - * commit that introduced these changes. */ - int8_t pid = sched_ctrl->feedback_dl_harq.head; - DevAssert(pid >= 0); - while (sched_ctrl->harq_processes[pid].feedback_slot != feedback_slot) { - LOG_W(MAC, - "expected feedback slot %d, but found %d instead\n", - sched_ctrl->harq_processes[pid].feedback_slot, - feedback_slot); - remove_front_nr_list(&sched_ctrl->feedback_dl_harq); - handle_dl_harq(mod_id, UE_id, pid, 0); - pid = sched_ctrl->feedback_dl_harq.head; - DevAssert(pid >= 0); - } - remove_front_nr_list(&sched_ctrl->feedback_dl_harq); - NR_UE_harq_t *harq = &sched_ctrl->harq_processes[pid]; + NR_UE_harq_t *harq = find_harq(mod_id, feedback_frame, feedback_slot, UE_id); + if (!harq) + break; DevAssert(harq->is_waiting); + const int8_t pid = sched_ctrl->feedback_dl_harq.head; + remove_front_nr_list(&sched_ctrl->feedback_dl_harq); handle_dl_harq(mod_id, UE_id, pid, uci_234->harq.harq_crc != 1 && acknack); } } @@ -1218,6 +1235,29 @@ bool nr_acknack_scheduling(int mod_id, // advance ul_slot if it is not reachable by UE pucch->ul_slot = max(pucch->ul_slot, slot + pdsch_to_harq_feedback[0]); + // is there already CSI in this slot? + const NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[2]; + // skip the CSI PUCCH if it is present and if in the next frame/slot + if (csi_pucch->csi_bits > 0 + && csi_pucch->frame == pucch->frame + && csi_pucch->ul_slot == pucch->ul_slot) { + AssertFatal(!csi_pucch->simultaneous_harqcsi, + "%s(): %d.%d cannot handle simultaneous_harqcsi, but found for UE %d\n", + __func__, + pucch->frame, + pucch->ul_slot, + UE_id); + nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id); + /* advance the UL slot information in PUCCH by one so we won't schedule in + * the same slot again */ + const int f = pucch->frame; + const int s = pucch->ul_slot; + memset(pucch, 0, sizeof(*pucch)); + pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f; + pucch->ul_slot = (s + 1) % n_slots_frame; + return nr_acknack_scheduling(mod_id, UE_id, frame, slot); + } + // Find the right timing_indicator value. int i = 0; while (i < 8) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 9784b6b79e9f391392fdf7684d353ba6bf44ac6b..db4e26ae85ded329da854f40bd56b5b65dee522f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -61,13 +61,124 @@ const uint32_t NR_LONG_BSR_TABLE[256] ={ 35910462, 38241455, 40723756, 43367187, 46182206, 49179951, 52372284, 55771835, 59392055, 63247269, 67352729, 71724679, 76380419, 81338368, 162676736, 4294967295 }; -void nr_process_mac_pdu( - module_id_t module_idP, - rnti_t rnti, - uint8_t CC_id, - frame_t frameP, - uint8_t *pduP, - uint16_t mac_pdu_len) +void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ubwp) +{ + gNB_MAC_INST *nrmac = RC.nrmac[module_id]; + const int bwp_id = ubwp->bwp_Id; + if (nrmac->preferred_ul_tda[bwp_id]) + return; + + /* there is a mixed slot only when in TDD */ + const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon; + const int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; + const NR_TDD_UL_DL_Pattern_t *tdd = + scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; + /* Uplink symbols are at the end of the slot */ + const int symb_ulMixed = tdd ? ((1 << tdd->nrofUplinkSymbols) - 1) << (14 - tdd->nrofUplinkSymbols) : 0; + + const struct NR_PUCCH_Config__resourceToAddModList *resList = ubwp->bwp_Dedicated->pucch_Config->choice.setup->resourceToAddModList; + // for the moment, just block any symbol that might hold a PUCCH, regardless + // of the RB. This is a big simplification, as most RBs will NOT have a PUCCH + // in the respective symbols, but it simplifies scheduling + uint16_t symb_pucch = 0; + for (int i = 0; i < resList->list.count; ++i) { + const NR_PUCCH_Resource_t *resource = resList->list.array[i]; + int nrofSymbols = 0; + int startingSymbolIndex = 0; + switch (resource->format.present) { + case NR_PUCCH_Resource__format_PR_format0: + nrofSymbols = resource->format.choice.format0->nrofSymbols; + startingSymbolIndex = resource->format.choice.format0->startingSymbolIndex; + break; + case NR_PUCCH_Resource__format_PR_format1: + nrofSymbols = resource->format.choice.format1->nrofSymbols; + startingSymbolIndex = resource->format.choice.format1->startingSymbolIndex; + break; + case NR_PUCCH_Resource__format_PR_format2: + nrofSymbols = resource->format.choice.format2->nrofSymbols; + startingSymbolIndex = resource->format.choice.format2->startingSymbolIndex; + break; + case NR_PUCCH_Resource__format_PR_format3: + nrofSymbols = resource->format.choice.format3->nrofSymbols; + startingSymbolIndex = resource->format.choice.format3->startingSymbolIndex; + break; + case NR_PUCCH_Resource__format_PR_format4: + nrofSymbols = resource->format.choice.format4->nrofSymbols; + startingSymbolIndex = resource->format.choice.format4->startingSymbolIndex; + break; + default: + AssertFatal(0, "found NR_PUCCH format index %d\n", resource->format.present); + break; + } + symb_pucch |= ((1 << nrofSymbols) - 1) << startingSymbolIndex; + } + + /* check that TDA index 1 fits into UL slot and does not overlap with PUCCH */ + const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + AssertFatal(tdaList->list.count >= 3, "need to have at least three TDAs for UL slots\n"); + const NR_PUSCH_TimeDomainResourceAllocation_t *tdaP_UL = tdaList->list.array[0]; + const int k2 = get_K2(ubwp, /* tda = */ 0, mu); + int start, len; + SLIV2SL(tdaP_UL->startSymbolAndLength, &start, &len); + const uint16_t symb_tda = ((1 << len) - 1) << start; + // check whether PUCCH and TDA overlap: then, we cannot use it. Note that + // here we assume that the PUCCH is scheduled in every slot, and on all RBs + // (which is mostly not true, this is a simplification) + AssertFatal((symb_pucch & symb_tda) == 0, "TDA index 0 for UL overlaps with PUCCH\n"); + + // get largest time domain allocation (TDA) for UL slot and UL in mixed slot + int tdaMi = -1; + const NR_PUSCH_TimeDomainResourceAllocation_t *tdaP_Mi = tdaList->list.array[1]; + AssertFatal(k2 == get_K2(ubwp, /* tda = */ 1, mu), + "scheduler cannot handle different k2 for UL slot (%d) and UL Mixed slot (%ld)\n", + k2, + get_K2(ubwp, /* tda = */ 1, mu)); + SLIV2SL(tdaP_Mi->startSymbolAndLength, &start, &len); + const uint16_t symb_tda_mi = ((1 << len) - 1) << start; + // check whether PUCCH and TDA overlap: then, we cannot use it. Also, check + // whether TDA is entirely within mixed slot, UL. Note that here we assume + // that the PUCCH is scheduled in every slot, and on all RBs (which is + // mostly not true, this is a simplification) + if ((symb_pucch & symb_tda_mi) == 0 && (symb_ulMixed & symb_tda_mi) == symb_tda_mi) { + tdaMi = 1; + } else { + LOG_E(MAC, + "TDA index 1 UL overlaps with PUCCH or is not entirely in mixed slot (symb_pucch %x symb_ulMixed %x symb_tda_mi %x), won't schedule UL mixed slot\n", + symb_pucch, + symb_ulMixed, + symb_tda_mi); + } + + const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160}; + const int n = slots_per_frame[*scc->ssbSubcarrierSpacing]; + nrmac->preferred_ul_tda[bwp_id] = malloc(n * sizeof(*nrmac->preferred_ul_tda[bwp_id])); + + const int nr_mix_slots = tdd ? tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0 : 0; + const int nr_slots_period = tdd ? tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + nr_mix_slots : n; + for (int slot = 0; slot < n; ++slot) { + const int sched_slot = (slot + k2) % n; + nrmac->preferred_ul_tda[bwp_id][slot] = -1; + if (!tdd || sched_slot % nr_slots_period >= tdd->nrofDownlinkSlots + nr_mix_slots) + nrmac->preferred_ul_tda[bwp_id][slot] = 0; + else if (tdd && nr_mix_slots && sched_slot % nr_slots_period == tdd->nrofDownlinkSlots) + nrmac->preferred_ul_tda[bwp_id][slot] = tdaMi; + LOG_I(MAC, "DL slot %d UL slot %d preferred_ul_tda %d\n", slot, sched_slot, nrmac->preferred_ul_tda[bwp_id][slot]); + } + + if (k2 < tdd->nrofUplinkSlots) + LOG_W(MAC, + "k2 %d < tdd->nrofUplinkSlots %ld: not all UL slots can be scheduled\n", + k2, + tdd->nrofUplinkSlots); +} + +void nr_process_mac_pdu(module_id_t module_idP, + int UE_id, + uint8_t CC_id, + frame_t frameP, + sub_frame_t slot, + uint8_t *pduP, + uint16_t mac_pdu_len) { // This function is adapting code from the old @@ -79,11 +190,6 @@ void nr_process_mac_pdu( NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info; - int UE_id = find_nr_UE_id(module_idP, rnti); - if (UE_id == -1) { - LOG_E(MAC, "%s() UE_id == -1\n",__func__); - return; - } NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; // For both DL/UL-SCH // Except: @@ -145,12 +251,15 @@ void nr_process_mac_pdu( NR_BSR_SHORT *bsr_s = (NR_BSR_SHORT *) ce_ptr; sched_ctrl->estimated_ul_buffer = 0; sched_ctrl->estimated_ul_buffer = NR_SHORT_BSR_TABLE[bsr_s->Buffer_size]; - LOG_D(MAC, "SHORT BSR, LCG ID %d, BS Index %d, BS value < %d, est buf %d\n", + LOG_D(MAC, + "SHORT BSR at %4d.%2d, LCG ID %d, BS Index %d, BS value < %d, est buf %d\n", + frameP, + slot, bsr_s->LcgID, bsr_s->Buffer_size, NR_SHORT_BSR_TABLE[bsr_s->Buffer_size], sched_ctrl->estimated_ul_buffer); - break; + break; case UL_SCH_LCID_L_BSR: case UL_SCH_LCID_L_TRUNCATED_BSR: @@ -170,16 +279,18 @@ void nr_process_mac_pdu( n_Lcg = bsr_l->LcgID7 + bsr_l->LcgID6 + bsr_l->LcgID5 + bsr_l->LcgID4 + bsr_l->LcgID3 + bsr_l->LcgID2 + bsr_l->LcgID1 + bsr_l->LcgID0; - LOG_D(MAC, "LONG BSR, LCG ID(7-0) %d/%d/%d/%d/%d/%d/%d/%d\n", - bsr_l->LcgID7, bsr_l->LcgID6, bsr_l->LcgID5, bsr_l->LcgID4, - bsr_l->LcgID3, bsr_l->LcgID2, bsr_l->LcgID1, bsr_l->LcgID0); - for (int n = 0; n < n_Lcg; n++){ - LOG_D(MAC, "LONG BSR, %d/%d (n/n_Lcg), BS Index %d, BS value < %d", - n, n_Lcg, pdu_ptr[mac_subheader_len + 1 + n], - NR_LONG_BSR_TABLE[pdu_ptr[mac_subheader_len + 1 + n]]); sched_ctrl->estimated_ul_buffer += NR_LONG_BSR_TABLE[pdu_ptr[mac_subheader_len + 1 + n]]; + LOG_D(MAC, + "LONG BSR at %4d.%2d, %d/%d (n/n_Lcg), BS Index %d, BS value < %d, total %d\n", + frameP, + slot, + n, + n_Lcg, + pdu_ptr[mac_subheader_len + 1 + n], + NR_LONG_BSR_TABLE[pdu_ptr[mac_subheader_len + 1 + n]], + sched_ctrl->estimated_ul_buffer); } break; @@ -196,6 +307,20 @@ void nr_process_mac_pdu( //fixed length mac_ce_len = 2; /* Extract SINGLE ENTRY PHR elements for PHR calculation */ + ce_ptr = &pdu_ptr[mac_subheader_len]; + NR_SINGLE_ENTRY_PHR_MAC_CE *phr = (NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr; + /* Save the phr info */ + const int PH = phr->PH; + const int PCMAX = phr->PCMAX; + /* 38.133 Table10.1.17.1-1 */ + if (PH < 55) + sched_ctrl->ph = PH - 32; + else + sched_ctrl->ph = PH - 32 + (PH - 54); + /* 38.133 Table10.1.18.1-1 */ + sched_ctrl->pcmax = PCMAX - 29; + LOG_D(MAC, "SINGLE ENTRY PHR R1 %d PH %d (%d dB) R2 %d PCMAX %d (%d dBm)\n", + phr->R1, PH, sched_ctrl->ph, phr->R2, PCMAX, sched_ctrl->pcmax); break; case UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT: @@ -246,48 +371,51 @@ void nr_process_mac_pdu( break; case UL_SCH_LCID_DTCH: - // check if LCID is valid at current time. - if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ - //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; - mac_subheader_len = 3; - mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L1 & 0x7f) << 8) - | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L2 & 0xff); - - } else { - mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; - mac_subheader_len = 2; - } - - LOG_D(MAC, "[UE %d] Frame %d : ULSCH -> UL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len); - int UE_id = find_nr_UE_id(module_idP, rnti); - RC.nrmac[module_idP]->UE_info.mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len; - #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - log_dump(MAC, pdu_ptr + mac_subheader_len, 32, LOG_DUMP_CHAR, "\n"); - - #endif - - mac_rlc_data_ind(module_idP, - rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - rx_lcid, - (char *) (pdu_ptr + mac_subheader_len), - mac_sdu_len, - 1, - NULL); - - /* Updated estimated buffer when receiving data */ - if (sched_ctrl->estimated_ul_buffer >= mac_sdu_len) - sched_ctrl->estimated_ul_buffer -= mac_sdu_len; - else - sched_ctrl->estimated_ul_buffer = 0; + // check if LCID is valid at current time. + if (((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F) { + // mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + mac_subheader_len = 3; + mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L1 & 0x7f) << 8) + | ((uint16_t)((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2 & 0xff); + + } else { + mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_subheader_len = 2; + } + + LOG_D(MAC, + "[UE %d] Frame %d : ULSCH -> UL-DTCH %d (gNB %d, %d bytes)\n", + module_idP, + frameP, + rx_lcid, + module_idP, + mac_sdu_len); + UE_info->mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len; +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + log_dump(MAC, pdu_ptr + mac_subheader_len, 32, LOG_DUMP_CHAR, "\n"); +#endif - break; + mac_rlc_data_ind(module_idP, + UE_info->rnti[UE_id], + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + rx_lcid, + (char *)(pdu_ptr + mac_subheader_len), + mac_sdu_len, + 1, + NULL); + + /* Updated estimated buffer when receiving data */ + if (sched_ctrl->estimated_ul_buffer >= mac_sdu_len) + sched_ctrl->estimated_ul_buffer -= mac_sdu_len; + else + sched_ctrl->estimated_ul_buffer = 0; + break; default: - LOG_D(MAC, "Received unknown MAC header (LCID = 0x%02x)\n", rx_lcid); + LOG_E(MAC, "Received unknown MAC header (LCID = 0x%02x)\n", rx_lcid); return; break; } @@ -305,6 +433,24 @@ void nr_process_mac_pdu( } } +void abort_nr_ul_harq(module_id_t mod_id, int UE_id, int8_t harq_pid) +{ + NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + NR_UE_ul_harq_t *harq = &sched_ctrl->ul_harq_processes[harq_pid]; + + harq->ndi ^= 1; + harq->round = 0; + UE_info->mac_stats[UE_id].ulsch_errors++; + add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); + + /* the transmission failed: the UE won't send the data we expected initially, + * so retrieve to correctly schedule after next BSR */ + sched_ctrl->sched_ul_bytes -= harq->sched_pusch.tb_size; + if (sched_ctrl->sched_ul_bytes < 0) + sched_ctrl->sched_ul_bytes = 0; +} + void handle_nr_ul_harq(module_id_t mod_id, frame_t frame, sub_frame_t slot, @@ -347,14 +493,11 @@ void handle_nr_ul_harq(module_id_t mod_id, crc_pdu->rnti); add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); } else if (harq->round == MAX_HARQ_ROUNDS) { - harq->ndi ^= 1; - harq->round = 0; + abort_nr_ul_harq(mod_id, UE_id, harq_pid); LOG_D(MAC, "RNTI %04x: Ulharq id %d crc failed in all rounds\n", crc_pdu->rnti, harq_pid); - UE_info->mac_stats[UE_id].ulsch_errors++; - add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); } else { harq->round++; LOG_D(MAC, @@ -407,11 +550,12 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, sduP); // if not missed detection (10dB threshold for now) - if (UE_scheduling_control->ul_rssi < (100+rssi)) { + if (UE_scheduling_control->raw_rssi < 100 + rssi) { UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30); if (timing_advance != 0xffff) UE_scheduling_control->ta_update = timing_advance; - UE_scheduling_control->ul_rssi = rssi; + UE_scheduling_control->raw_rssi = rssi; + UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640; LOG_D(NR_MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update); } else{ @@ -438,17 +582,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, if (UE_scheduling_control->sched_ul_bytes < 0) UE_scheduling_control->sched_ul_bytes = 0; - nr_process_mac_pdu(gnb_mod_idP, current_rnti, CC_idP, frameP, sduP, sdu_lenP); - } - else { - NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid]; - /* reduce sched_ul_bytes when cur_harq->round == 3 */ - if (cur_harq->round == 3){ - const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size; - UE_scheduling_control->sched_ul_bytes -= tb_size; - if (UE_scheduling_control->sched_ul_bytes < 0) - UE_scheduling_control->sched_ul_bytes = 0; - } + nr_process_mac_pdu(gnb_mod_idP, UE_id, CC_idP, frameP, slotP, sduP, sdu_lenP); } } else { if (!sduP) // check that CRC passed @@ -504,7 +638,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, } } -long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) { +long get_K2(const NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) { DevAssert(ubwp); const NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]; if (tda_list->k2) @@ -524,21 +658,142 @@ int next_list_entry_looped(NR_list_t *list, int UE_id) return list->next[UE_id] < 0 ? list->head : list->next[UE_id]; } +bool allocate_ul_retransmission(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + uint8_t *rballoc_mask, + int *n_rb_sched, + int UE_id, + int harq_pid) +{ + const int CC_id = 0; + const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[CC_id].ServingCellConfigCommon; + NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + NR_sched_pusch_t *retInfo = &sched_ctrl->ul_harq_processes[harq_pid].sched_pusch; + int rbStart = + NRRIV2PRBOFFSET(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + const uint16_t bwpSize = + NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + + const uint8_t num_dmrs_cdm_grps_no_data = 1; + const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_ubwp->bwp_Id][slot]; + if (tda == retInfo->time_domain_allocation) { + /* Check the resource is enough for retransmission */ + while (rbStart < bwpSize && !rballoc_mask[rbStart]) + rbStart++; + if (rbStart + retInfo->rbSize >= bwpSize) { + LOG_D(MAC, "cannot allocate retransmission of UE %d/RNTI %04x: no resources\n", UE_id, UE_info->rnti[UE_id]); + return false; + } + /* check whether we need to switch the TDA allocation since tha last + * (re-)transmission */ + NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; + const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats; + const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0; + if (ps->time_domain_allocation != tda + || ps->dci_format != dci_format + || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) + nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps); + LOG_D(MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size); + } else { + /* the retransmission will use a different time domain allocation, check + * that we have enough resources */ + while (rbStart < bwpSize && !rballoc_mask[rbStart]) + rbStart++; + int rbSize = 0; + while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart + rbSize]) + rbSize++; + NR_pusch_semi_static_t temp_ps; + const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats; + const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0; + nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, &temp_ps); + uint32_t new_tbs; + uint16_t new_rbSize; + bool success = nr_find_nb_rb(retInfo->Qm, + retInfo->R, + temp_ps.nrOfSymbols, + temp_ps.N_PRB_DMRS * temp_ps.num_dmrs_symb, + retInfo->tb_size, + rbSize, + &new_tbs, + &new_rbSize); + if (!success || new_tbs != retInfo->tb_size) { + LOG_D(MAC, "%s(): new TBsize %d of new TDA does not match old TBS %d\n", __func__, new_tbs, retInfo->tb_size); + return false; /* the maximum TBsize we might have is smaller than what we need */ + } + LOG_D(MAC, "%s(): retransmission with TDA %d->%d and TBS %d -> %d\n", __func__, retInfo->time_domain_allocation, tda, retInfo->tb_size, new_tbs); + /* we can allocate it. Overwrite the time_domain_allocation, the number + * of RBs, and the new TB size. The rest is done below */ + retInfo->tb_size = new_tbs; + retInfo->rbSize = new_rbSize; + retInfo->time_domain_allocation = tda; + sched_ctrl->pusch_semi_static = temp_ps; + } + + /* Find free CCE */ + bool freeCCE = find_free_CCE(module_id, slot, UE_id); + if (!freeCCE) { + LOG_D(MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]); + return false; + } + + /* frame/slot in sched_pusch has been set previously. In the following, we + * overwrite the information in the retransmission information before storing + * as the new scheduling instruction */ + retInfo->frame = sched_ctrl->sched_pusch.frame; + retInfo->slot = sched_ctrl->sched_pusch.slot; + /* Get previous PSUCH field info */ + sched_ctrl->sched_pusch = *retInfo; + NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; + LOG_D(MAC, + "%4d.%2d Allocate UL retransmission UE %d/RNTI %04x sched %4d.%2d (%d RBs)\n", + frame, + slot, + UE_id, + UE_info->rnti[UE_id], + sched_pusch->frame, + sched_pusch->slot, + sched_pusch->rbSize); + + sched_pusch->rbStart = rbStart; + /* no need to recompute the TBS, it will be the same */ + + /* Mark the corresponding RBs as used */ + n_rb_sched -= sched_pusch->rbSize; + for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++) + rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] = 0; + return true; +} + +void update_ul_ue_R_Qm(NR_sched_pusch_t *sched_pusch, const NR_pusch_semi_static_t *ps) +{ + const int mcs = sched_pusch->mcs; + sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table); + sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table); + if (ps->pusch_Config->tp_pi2BPSK + && ((ps->mcs_table == 3 && mcs < 2) || (ps->mcs_table == 4 && mcs < 6))) { + sched_pusch->R >>= 1; + sched_pusch->Qm <<= 1; + } +} + float ul_thr_ue[MAX_MOBILES_PER_GNB]; +uint32_t ul_pf_tbs[3][28]; // pre-computed, approximate TBS values for PF coefficient int bsr0ue = -1; void pf_ul(module_id_t module_id, frame_t frame, sub_frame_t slot, - int num_slots_per_tdd, NR_list_t *UE_list, + int max_num_ue, int n_rb_sched, - uint8_t *rballoc_mask, - int max_num_ue) { + uint8_t *rballoc_mask) { const int CC_id = 0; - const int tda = 1; - NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[CC_id].ServingCellConfigCommon; - NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; + const uint8_t num_dmrs_cdm_grps_no_data = 1; + gNB_MAC_INST *nrmac = RC.nrmac[module_id]; + NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon; + NR_UE_info_t *UE_info = &nrmac->UE_info; const int min_rb = 5; float coeff_ue[MAX_MOBILES_PER_GNB]; // UEs that could be scheduled @@ -554,86 +809,34 @@ void pf_ul(module_id_t module_id, /* Loop UE_list to calculate throughput and coeff */ for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; - int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int rbStart = + NRRIV2PRBOFFSET(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; + NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; /* Calculate throughput */ const float a = 0.0005f; // corresponds to 200ms window const uint32_t b = UE_info->mac_stats[UE_id].ulsch_current_bytes; ul_thr_ue[UE_id] = (1 - a) * ul_thr_ue[UE_id] + a * b; - /* Save PUSCH field */ - /* we want to avoid a lengthy deduction of DMRS and other parameters in - * every TTI if we can save it, so check whether dci_format, TDA, or - * num_dmrs_cdm_grps_no_data has changed and only then recompute */ - sched_ctrl->sched_pusch.time_domain_allocation = tda; - sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, NR_SearchSpace__searchSpaceType_PR_ue_Specific); - sched_ctrl->coreset = get_coreset(sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */); - const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats; - const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0; - const uint8_t num_dmrs_cdm_grps_no_data = 1; - NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save; - if (ps->time_domain_allocation != tda - || ps->dci_format != dci_format - || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) - nr_save_pusch_fields(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps); - /* Check if retransmission is necessary */ - sched_ctrl->sched_pusch.ul_harq_pid = sched_ctrl->retrans_ul_harq.head; - if (sched_ctrl->sched_pusch.ul_harq_pid >= 0) { - /* RETRANSMISSION: Allocate retransmission*/ - /* Find free CCE */ - bool freeCCE = find_free_CCE(module_id, slot, UE_id); - if (!freeCCE) { - LOG_D(MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]); + sched_pusch->ul_harq_pid = sched_ctrl->retrans_ul_harq.head; + if (sched_pusch->ul_harq_pid >= 0) { + /* Allocate retransmission*/ + bool r = allocate_ul_retransmission( + module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pusch->ul_harq_pid); + if (!r) { + LOG_D(MAC, "%4d.%2d UL retransmission UE RNTI %04x can NOT be allocated\n", frame, slot, UE_info->rnti[UE_id]); continue; } /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ max_num_ue--; if (max_num_ue < 0) return; - - /* Save shced_frame and sched_slot before overwrite by previous PUSCH filed */ - NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[sched_ctrl->sched_pusch.ul_harq_pid]; - cur_harq->sched_pusch.frame = sched_ctrl->sched_pusch.frame; - cur_harq->sched_pusch.slot = sched_ctrl->sched_pusch.slot; - /* Get previous PSUCH filed info */ - sched_ctrl->sched_pusch = cur_harq->sched_pusch; - NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; - LOG_D(MAC, "%4d.%2d Allocate UL retransmission UE %d/RNTI %04x sched %4d.%2d (%d RBs)\n", - frame, slot, UE_id, UE_info->rnti[UE_id], - sched_pusch->frame, sched_pusch->slot, - sched_pusch->rbSize); - - while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++; - if (rbStart + sched_pusch->rbSize >= bwpSize) { - LOG_W(MAC, "cannot allocate UL data for UE %d/RNTI %04x: no resources\n", - UE_id, UE_info->rnti[UE_id]); - return; - } - sched_pusch->rbStart = rbStart; - /* no need to recompute the TBS, it will be the same */ - - /* Mark the corresponding RBs as used */ - n_rb_sched -= sched_pusch->rbSize; - for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++) - rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] = 0; - continue; } - /* Calculate TBS from MCS */ - NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; - const int mcs = 9; - sched_pusch->mcs = mcs; - sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table); - sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table); - if (ps->pusch_Config->tp_pi2BPSK - && ((ps->mcs_table == 3 && mcs < 2) || (ps->mcs_table == 4 && mcs < 6))) { - sched_pusch->R >>= 1; - sched_pusch->Qm <<= 1; - } - /* Check BSR and schedule UE if it is zero to avoid starvation, since we do * not have SR (yet) */ if (sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes <= 0) { @@ -652,10 +855,25 @@ void pf_ul(module_id_t module_id, while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++; if (rbStart + min_rb >= bwpSize) { - LOG_W(MAC, "cannot allocate UL data for UE %d/RNTI %04x: no resources\n", + LOG_D(MAC, "cannot allocate continuous data for UE %d/RNTI %04x: no resources\n", UE_id, UE_info->rnti[UE_id]); - return; + continue; } + + /* Save PUSCH field */ + /* we want to avoid a lengthy deduction of DMRS and other parameters in + * every TTI if we can save it, so check whether dci_format, TDA, or + * num_dmrs_cdm_grps_no_data has changed and only then recompute */ + const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats; + const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0; + const int tda = nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot]; + if (ps->time_domain_allocation != tda + || ps->dci_format != dci_format + || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) + nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps); + NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; + sched_pusch->mcs = 9; + update_ul_ue_R_Qm(sched_pusch, ps); sched_pusch->rbStart = rbStart; sched_pusch->rbSize = min_rb; sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm, @@ -680,15 +898,8 @@ void pf_ul(module_id_t module_id, add_tail_nr_list(&UE_sched, UE_id); /* Calculate coefficient*/ - const uint32_t tbs = nr_compute_tbs(sched_pusch->Qm, - sched_pusch->R, - 1, // rbSize - ps->nrOfSymbols, - ps->N_PRB_DMRS * ps->num_dmrs_symb, - 0, // nb_rb_oh - 0, - 1 /* NrOfLayers */) - >> 3; + sched_pusch->mcs = 9; + const uint32_t tbs = ul_pf_tbs[ps->mcs_table][sched_pusch->mcs]; coeff_ue[UE_id] = (float) tbs / ul_thr_ue[UE_id]; LOG_D(MAC,"b %d, ul_thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n", b, UE_id, ul_thr_ue[UE_id], tbs, UE_id, coeff_ue[UE_id]); @@ -727,35 +938,45 @@ void pf_ul(module_id_t module_id, NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + /* for some reason, the UEs do not like when they are scheduled on the last + * RB. Hence, as a (hopefully temporary) fix, schedule one RB less. */ + const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) - 1; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; - + NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++; sched_pusch->rbStart = rbStart; - if (rbStart + min_rb >= bwpSize) { - LOG_W(MAC, "cannot allocate UL data for UE %d/RNTI %04x: no resources\n", - UE_id, UE_info->rnti[UE_id]); - return; - } + uint16_t max_rbSize = 1; + while (rbStart + max_rbSize < bwpSize && rballoc_mask[rbStart + max_rbSize]) + max_rbSize++; + + /* Save PUSCH field */ + /* we want to avoid a lengthy deduction of DMRS and other parameters in + * every TTI if we can save it, so check whether dci_format, TDA, or + * num_dmrs_cdm_grps_no_data has changed and only then recompute */ + const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats; + const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0; + const int tda = nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot]; + if (ps->time_domain_allocation != tda + || ps->dci_format != dci_format + || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) + nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps); + update_ul_ue_R_Qm(sched_pusch, ps); - /* Calculate the current scheduling bytes */ + /* Calculate the current scheduling bytes and the necessary RBs */ const int B = cmax(sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes, 0); - uint16_t rbSize = min_rb - 1; - do { - rbSize++; - sched_pusch->rbSize = rbSize; - sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm, - sched_pusch->R, - sched_pusch->rbSize, - sched_ctrl->pusch_save.nrOfSymbols, - sched_ctrl->pusch_save.N_PRB_DMRS * sched_ctrl->pusch_save.num_dmrs_symb, - 0, // nb_rb_oh - 0, - 1 /* NrOfLayers */) - >> 3; - } while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart+rbSize] && - sched_pusch->tb_size < B); + uint16_t rbSize = 0; + uint32_t TBS = 0; + nr_find_nb_rb(sched_pusch->Qm, + sched_pusch->R, + ps->nrOfSymbols, + ps->N_PRB_DMRS * ps->num_dmrs_symb, + B, + max_rbSize, + &TBS, + &rbSize); + sched_pusch->rbSize = rbSize; + sched_pusch->tb_size = TBS; LOG_D(MAC,"rbSize %d, TBS %d, est buf %d, sched_ul %d, B %d\n", rbSize, sched_pusch->tb_size, sched_ctrl->estimated_ul_buffer, sched_ctrl->sched_ul_bytes, B); @@ -766,11 +987,8 @@ void pf_ul(module_id_t module_id, } } -bool nr_simple_ulsch_preprocessor(module_id_t module_id, - frame_t frame, - sub_frame_t slot, - int num_slots_per_tdd, - uint64_t ulsch_in_slot_bitmap) { +bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot) +{ gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; NR_COMMON_channels_t *cc = nr_mac->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; @@ -782,31 +1000,25 @@ bool nr_simple_ulsch_preprocessor(module_id_t module_id, const int CC_id = 0; - /* NOT support different K2 in here, Get the K2 for first UE */ + /* Get the K2 for first UE to compute offset. The other UEs are guaranteed to + * have the same K2 (we don't support multiple/different K2s via different + * TDAs yet). If the TDA is negative, it means that there is no UL slot to + * schedule now (slot + k2 is not UL slot) */ int UE_id = UE_info->list.head; NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; - const int tda = 1; - const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = - sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - AssertFatal(tda < tdaList->list.count, - "time domain assignment %d >= %d\n", - tda, - tdaList->list.count); - + const int tda = nr_mac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot]; + if (tda < 0) + return false; int K2 = get_K2(sched_ctrl->active_ubwp, tda, mu); const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]); const int sched_slot = (slot + K2) % nr_slots_per_frame[mu]; - if (!is_xlsch_in_slot(ulsch_in_slot_bitmap, sched_slot)) + if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[slot / 64], sched_slot)) return false; sched_ctrl->sched_pusch.slot = sched_slot; sched_ctrl->sched_pusch.frame = sched_frame; - - /* Confirm all the UE have same K2 as the first UE */ for (UE_id = UE_info->list.next[UE_id]; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; - AssertFatal(K2 == get_K2(sched_ctrl->active_ubwp, tda, mu), - "Different K2, %d(UE%d) != %ld(UE%d)\n", K2, 0, get_K2(sched_ctrl->active_ubwp, tda, mu), UE_id); sched_ctrl->sched_pusch.slot = sched_slot; sched_ctrl->sched_pusch.frame = sched_frame; } @@ -839,28 +1051,53 @@ bool nr_simple_ulsch_preprocessor(module_id_t module_id, pf_ul(module_id, frame, slot, - num_slots_per_tdd, &UE_info->list, + 2, len, - rballoc_mask, - 2); + rballoc_mask); return true; } -void nr_schedule_ulsch(module_id_t module_id, - frame_t frame, - sub_frame_t slot, - int num_slots_per_tdd, - int ul_slots, - uint64_t ulsch_in_slot_bitmap) { +nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(module_id_t module_id, int CC_id) +{ + /* in the PF algorithm, we have to use the TBsize to compute the coefficient. + * This would include the number of DMRS symbols, which in turn depends on + * the time domain allocation. In case we are in a mixed slot, we do not want + * to recalculate all these values, and therefore we provide a look-up table + * which should approximately(!) give us the TBsize. In particular, the + * number of symbols, the number of DMRS symbols, and the exact Qm and R, are + * not correct*/ + for (int mcsTableIdx = 0; mcsTableIdx < 3; ++mcsTableIdx) { + for (int mcs = 0; mcs < 29; ++mcs) { + if (mcs > 27 && mcsTableIdx == 1) + continue; + const uint8_t Qm = nr_get_Qm_dl(mcs, mcsTableIdx); + const uint16_t R = nr_get_code_rate_dl(mcs, mcsTableIdx); + /* note: we do not update R/Qm based on low MCS or pi2BPSK */ + ul_pf_tbs[mcsTableIdx][mcs] = nr_compute_tbs(Qm, + R, + 1, /* rbSize */ + 10, /* hypothetical number of slots */ + 0, /* N_PRB_DMRS * N_DMRS_SLOT */ + 0 /* N_PRB_oh, 0 for initialBWP */, + 0 /* tb_scaling */, + 1 /* nrOfLayers */) + >> 3; + } + } + return nr_fr1_ulsch_preprocessor; +} + +void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) +{ + gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; /* Uplink data ONLY can be scheduled when the current slot is downlink slot, * because we have to schedule the DCI0 first before schedule uplink data */ - if (is_xlsch_in_slot(ulsch_in_slot_bitmap, slot)) { + if (!is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slot / 64], slot)) { LOG_D(MAC, "Current slot %d is NOT DL slot, cannot schedule DCI0 for UL data\n", slot); return; } - bool do_sched = RC.nrmac[module_id]->pre_processor_ul( - module_id, frame, slot, num_slots_per_tdd, ulsch_in_slot_bitmap); + bool do_sched = RC.nrmac[module_id]->pre_processor_ul(module_id, frame, slot); if (!do_sched) return; @@ -915,8 +1152,8 @@ void nr_schedule_ulsch(module_id_t module_id, /* pre-computed PUSCH values that only change if time domain allocation, * DCI format, or DMRS parameters change. Updated in the preprocessor - * through nr_save_pusch_fields() */ - NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save; + * through nr_set_pusch_semi_static() */ + NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; /* Statistics */ UE_info->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++; @@ -925,6 +1162,9 @@ void nr_schedule_ulsch(module_id_t module_id, /* Save information on MCS, TBS etc for the current initial transmission * so we have access to it when retransmitting */ cur_harq->sched_pusch = *sched_pusch; + /* save which time allocation has been used, to be used on + * retransmissions */ + cur_harq->sched_pusch.time_domain_allocation = ps->time_domain_allocation; sched_ctrl->sched_ul_bytes += sched_pusch->tb_size; } else { LOG_D(MAC, @@ -941,7 +1181,7 @@ void nr_schedule_ulsch(module_id_t module_id, UE_info->mac_stats[UE_id].ulsch_current_bytes = sched_pusch->tb_size; LOG_D(MAC, - "%4d.%2d RNTI %04x UL sched %4d.%2d start %d RBS %d MCS %d TBS %d HARQ PID %d round %d NDI %d\n", + "%4d.%2d RNTI %04x UL sched %4d.%2d start %2d RBS %3d startSymbol %2d nb_symbol %2d MCS %2d TBS %4d HARQ PID %2d round %d NDI %d est %6d sched %6d est BSR %6d\n", frame, slot, rnti, @@ -949,11 +1189,17 @@ void nr_schedule_ulsch(module_id_t module_id, sched_pusch->slot, sched_pusch->rbStart, sched_pusch->rbSize, + ps->startSymbolIndex, + ps->nrOfSymbols, sched_pusch->mcs, sched_pusch->tb_size, harq_id, cur_harq->round, - cur_harq->ndi); + cur_harq->ndi, + sched_ctrl->estimated_ul_buffer, + sched_ctrl->sched_ul_bytes, + sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes); + /* PUSCH in a later slot, but corresponding DCI now! */ nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_id]->UL_tti_req_ahead[0][sched_pusch->slot]; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 7f9e2a9a8d0d2a4cf32a87377e342a313d154830..dd4ec15539613b480d1a812310cbae7e1585a7df 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -66,10 +66,16 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB, void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame_rxP, sub_frame_t slot_rxP); +/* \brief main DL scheduler function. Calls a preprocessor to decide on + * resource allocation, then "post-processes" resource allocation (nFAPI + * messages, statistics, HARQ handling, CEs, ... */ void nr_schedule_ue_spec(module_id_t module_id, frame_t frame, sub_frame_t slot); +/* \brief default FR1 DL preprocessor init routine, returns preprocessor to call */ +nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id); + void schedule_control_sib1(module_id_t module_id, int CC_id, int time_domain_allocation, @@ -80,30 +86,19 @@ void schedule_control_sib1(module_id_t module_id, void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); -/* \brief default preprocessor */ -void nr_simple_dlsch_preprocessor(module_id_t module_id, - frame_t frame, - sub_frame_t slot); - void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, uint8_t slots_per_frame, int nb_periods_per_frame); -/// uplink scheduler -void nr_schedule_ulsch(module_id_t module_id, - frame_t frame, - sub_frame_t slot, - int num_slots_per_tdd, - int ul_slots, - uint64_t ulsch_in_slot_bitmap); +/* \brief main UL scheduler function. Calls a preprocessor to decide on + * resource allocation, then "post-processes" resource allocation (nFAPI + * messages, statistics, HARQ handling, ... */ +void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot); -bool nr_simple_ulsch_preprocessor(module_id_t module_id, - frame_t frame, - sub_frame_t slot, - int num_slots_per_tdd, - uint64_t ulsch_in_slot_bitmap); +/* \brief default FR1 UL preprocessor init routine, returns preprocessor to call */ +nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(module_id_t module_id, int CC_id); /////// Random Access MAC-PHY interface functions and primitives /////// @@ -157,11 +152,7 @@ void nr_preprocessor_phytest(module_id_t module_id, sub_frame_t slot); /* \brief UL preprocessor for phytest: schedules UE_id 0 with fixed MCS on a * fixed set of resources */ -bool nr_ul_preprocessor_phytest(module_id_t module_id, - frame_t frame, - sub_frame_t slot, - int num_slots_per_tdd, - uint64_t ulsch_in_slot_bitmap); +bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_t slot); void nr_schedule_css_dlsch_phytest(module_id_t module_idP, frame_t frameP, @@ -260,23 +251,26 @@ void prepare_dci(const NR_CellGroupConfig_t *secondaryCellGroup, int bwp_id); /* find coreset within the search space */ -NR_ControlResourceSet_t *get_coreset(NR_BWP_Downlink_t *bwp, - NR_SearchSpace_t *ss, - int ss_type); +NR_ControlResourceSet_t *get_coreset(const NR_BWP_Downlink_t *bwp, const NR_SearchSpace_t *ss, int ss_type); /* find a search space within a BWP */ -NR_SearchSpace_t *get_searchspace( - NR_BWP_Downlink_t *bwp, - NR_SearchSpace__searchSpaceType_PR target_ss); +NR_SearchSpace_t *get_searchspace(const NR_BWP_Downlink_t *bwp, NR_SearchSpace__searchSpaceType_PR target_ss); + +long get_K2(const NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu); -long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu); +void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc, + const NR_CellGroupConfig_t *secondaryCellGroup, + const NR_BWP_Downlink_t *bwp, + int tda, + uint8_t num_dmrs_cdm_grps_no_data, + NR_pdsch_semi_static_t *ps); -void nr_save_pusch_fields(const NR_ServingCellConfigCommon_t *scc, - const NR_BWP_Uplink_t *ubwp, - long dci_format, - int tda, - uint8_t num_dmrs_cdm_grps_no_data, - NR_sched_pusch_save_t *ps); +void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc, + const NR_BWP_Uplink_t *ubwp, + long dci_format, + int tda, + uint8_t num_dmrs_cdm_grps_no_data, + NR_pusch_semi_static_t *ps); uint8_t nr_get_tpc(int target, uint8_t cqi, int incr); @@ -355,14 +349,6 @@ void config_nr_mib(int Mod_idP, void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra); -void nr_process_mac_pdu( - module_id_t module_idP, - rnti_t rnti, - uint8_t CC_id, - frame_t frameP, - uint8_t *pduP, - uint16_t mac_pdu_len); - int binomial(int n, int k); bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot); @@ -404,5 +390,18 @@ int16_t ssb_index_from_prach(module_id_t module_idP, void find_SSB_and_RO_available(module_id_t module_idP); +void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *bwp); +void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ubwp); + bool find_free_CCE(module_id_t module_id, sub_frame_t slot, int UE_id); + +bool nr_find_nb_rb(uint16_t Qm, + uint16_t R, + uint16_t nb_symb_sch, + uint16_t nb_dmrs_prb, + uint32_t bytes, + uint16_t nb_rb_max, + uint32_t *tbs, + uint16_t *nb_rb); + #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 33e575d2b9ce2ff71bea5e7238faab3826c79e20..60b0cac21525ec5c41cfef67e3328080da785890 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -85,8 +85,8 @@ void mac_top_init_gNB(void) RC.nrmac[i]->pre_processor_dl = nr_preprocessor_phytest; RC.nrmac[i]->pre_processor_ul = nr_ul_preprocessor_phytest; } else { - RC.nrmac[i]->pre_processor_dl = nr_simple_dlsch_preprocessor; - RC.nrmac[i]->pre_processor_ul = nr_simple_ulsch_preprocessor; + RC.nrmac[i]->pre_processor_dl = nr_init_fr1_dlsch_preprocessor(i, 0); + RC.nrmac[i]->pre_processor_ul = nr_init_fr1_ulsch_preprocessor(i, 0); } }//END for (i = 0; i < RC.nb_nr_macrlc_inst; i++) diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 8452ca3c4c334d6bcda7b4c488586e7ed34f460d..a03b34f9e154a1cfec90ba7a2e3816a88b72175f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -305,11 +305,11 @@ typedef struct NR_sched_pucch { uint8_t resource_indicator; } NR_sched_pucch_t; -/* this struct is a helper: as long as the TDA and DCI format remain the same - * over the same uBWP and search space, there is no need to recalculate all - * S/L, MCS table, or DMRS-related parameters over and over again. Hence, we - * store them in this struct for easy reference. */ -typedef struct NR_sched_pusch_save { +/* PUSCH semi-static configuration: as long as the TDA and DCI format remain + * the same over the same uBWP and search space, there is no need to + * recalculate all S/L, MCS table, or DMRS-related parameters over and over + * again. Hence, we store them in this struct for easy reference. */ +typedef struct NR_pusch_semi_static_t { int dci_format; int time_domain_allocation; uint8_t num_dmrs_cdm_grps_no_data; @@ -327,7 +327,7 @@ typedef struct NR_sched_pusch_save { uint16_t ul_dmrs_symb_pos; uint8_t num_dmrs_symb; uint8_t N_PRB_DMRS; -} NR_sched_pusch_save_t; +} NR_pusch_semi_static_t; typedef struct NR_sched_pusch { int frame; @@ -337,9 +337,6 @@ typedef struct NR_sched_pusch { uint16_t rbSize; uint16_t rbStart; - // time-domain allocation for scheduled RBs - int time_domain_allocation; - /// MCS uint8_t mcs; @@ -350,17 +347,68 @@ typedef struct NR_sched_pusch { /// UL HARQ PID to use for this UE, or -1 for "any new" int8_t ul_harq_pid; + + /// the Time Domain Allocation used for this transmission. Note that this is + /// only important for retransmissions; otherwise, the TDA in + /// NR_pusch_semi_static_t has precedence + int time_domain_allocation; } NR_sched_pusch_t; +/* PDSCH semi-static configuratio: as long as the TDA/DMRS/mcsTable remains the + * same, there is no need to recalculate all S/L or DMRS-related parameters + * over and over again. Hence, we store them in this struct for easy + * reference. */ +typedef struct NR_pdsch_semi_static { + int time_domain_allocation; + uint8_t numDmrsCdmGrpsNoData; + + int startSymbolIndex; + int nrOfSymbols; + + uint8_t mcsTableIdx; + + uint8_t N_PRB_DMRS; + uint8_t N_DMRS_SLOT; + uint16_t dl_dmrs_symb_pos; + nfapi_nr_dmrs_type_e dmrsConfigType; +} NR_pdsch_semi_static_t; + +typedef struct NR_sched_pdsch { + /// RB allocation within active BWP + uint16_t rbSize; + uint16_t rbStart; + + /// MCS-related infos + uint8_t mcs; + + /// TBS-related info + uint16_t R; + uint8_t Qm; + uint32_t tb_size; + + /// DL HARQ PID to use for this UE, or -1 for "any new" + int8_t dl_harq_pid; + + /// the Time Domain Allocation used for this transmission. Note that this is + /// only important for retransmissions; otherwise, the TDA in + /// NR_pdsch_semi_static_t has precedence + int time_domain_allocation; +} NR_sched_pdsch_t; + typedef struct NR_UE_harq { bool is_waiting; uint8_t ndi; uint8_t round; + uint16_t feedback_frame; uint16_t feedback_slot; - /* Transport block to be sent using this HARQ process */ + /* Transport block to be sent using this HARQ process, its size is in + * sched_pdsch */ uint32_t tb[16384]; uint32_t tb_size; + + /// sched_pdsch keeps information on MCS etc used for the initial transmission + NR_sched_pdsch_t sched_pdsch; } NR_UE_harq_t; //! fixme : need to enhace for the multiple TB CQI report @@ -441,13 +489,6 @@ typedef struct nr_csi_report { From spec 38.214 section 5.2.1.2 For periodic and semi-persistent CSI Resource Settings, the number of CSI-RS Resource Sets configured is limited to S=1 */ #define MAX_CSI_RESOURCE_SET_IN_CSI_RESOURCE_CONFIG 16 -typedef struct NR_UE_old_sched { - uint16_t rbSize; - int time_domain_allocation; - uint8_t mcsTableIdx; - uint8_t mcs; - uint8_t numDmrsCdmGrpsNoData; -} NR_UE_ret_info_t; typedef enum { INACTIVE = 0, @@ -468,15 +509,18 @@ typedef struct NR_UE_ul_harq { /*! \brief scheduling control information set through an API */ #define MAX_CSI_REPORTS 48 typedef struct { - /// total amount of data awaiting for this UE - uint32_t num_total_bytes; - /// per-LC status data - mac_rlc_status_resp_t rlc_status[MAX_NUM_LCID]; - /// the currently active BWP in DL NR_BWP_Downlink_t *active_bwp; /// the currently active BWP in UL NR_BWP_Uplink_t *active_ubwp; + /// CCE index and aggregation, should be coherent with cce_list + NR_SearchSpace_t *search_space; + NR_ControlResourceSet_t *coreset; + + /// CCE index and Aggr. Level are shared for PUSCH/PDSCH allocation decisions + /// corresponding to the sched_pusch/sched_pdsch structures below + int cce_index; + uint8_t aggregation_level; /// PUCCH scheduling information. Array of three, we assume for the moment: /// HARQ in the first field, SR in second, CSI in third (as fixed by RRC @@ -484,44 +528,40 @@ typedef struct { /// nr_acknack_scheduling()! NR_sched_pucch_t sched_pucch[3]; - NR_sched_pusch_save_t pusch_save; + /// PUSCH semi-static configuration: is not cleared across TTIs + NR_pusch_semi_static_t pusch_semi_static; + /// Sched PDSCH: scheduling decisions, copied into HARQ and cleared every TTI NR_sched_pusch_t sched_pusch; - /// CCE index and aggregation, should be coherent with cce_list - NR_SearchSpace_t *search_space; - NR_ControlResourceSet_t *coreset; - int cce_index; - uint8_t aggregation_level; - - /// RB allocation within active BWP - uint16_t rbSize; - uint16_t rbStart; - /// uplink bytes that are currently scheduled int sched_ul_bytes; /// estimation of the UL buffer size int estimated_ul_buffer; - // time-domain allocation for scheduled RBs - int time_domain_allocation; + /// PHR info: power headroom level (dB) + int ph; + /// PHR info: nominal UE transmit power levels (dBm) + int pcmax; - /// MCS-related infos - uint8_t mcsTableIdx; - uint8_t mcs; - uint8_t numDmrsCdmGrpsNoData; + /// PDSCH semi-static configuration: is not cleared across TTIs + NR_pdsch_semi_static_t pdsch_semi_static; + /// Sched PDSCH: scheduling decisions, copied into HARQ and cleared every TTI + NR_sched_pdsch_t sched_pdsch; - /// Retransmission-related information - NR_UE_ret_info_t retInfo[NR_MAX_NB_HARQ_PROCESSES]; - /// DL HARQ PID to use for this UE, or -1 for "any new" - int8_t dl_harq_pid; + /// total amount of data awaiting for this UE + uint32_t num_total_bytes; + /// per-LC status data + mac_rlc_status_resp_t rlc_status[MAX_NUM_LCID]; uint16_t ta_frame; int16_t ta_update; bool ta_apply; uint8_t tpc0; uint8_t tpc1; - uint16_t ul_rssi; - uint8_t current_harq_pid; + int raw_rssi; + int pusch_snrx10; + int pucch_snrx10; + struct CSI_Report CSI_report[MAX_CSI_REPORTS]; /// information about every HARQ process NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES]; @@ -539,7 +579,6 @@ typedef struct { NR_list_t feedback_ul_harq; /// UL HARQ processes that await retransmission NR_list_t retrans_ul_harq; - int dummy; NR_UE_mac_ce_ctrl_t UE_mac_ce_ctrl;// MAC CE related information } NR_UE_sched_ctrl_t; @@ -591,9 +630,7 @@ typedef void (*nr_pp_impl_dl)(module_id_t mod_id, sub_frame_t slot); typedef bool (*nr_pp_impl_ul)(module_id_t mod_id, frame_t frame, - sub_frame_t slot, - int num_slots_per_tdd, - uint64_t ulsch_in_slot_bitmap); + sub_frame_t slot); /*! \brief top level eNB MAC structure */ typedef struct gNB_MAC_INST_s { @@ -670,6 +707,19 @@ typedef struct gNB_MAC_INST_s { /// highest index not yet been used in a given slot. Dynamically allocated /// so we can have it for every slot as a function of the numerology int *pucch_index_used[MAX_NUM_BWP]; + + /// bitmap of DLSCH slots, can hold up to 160 slots + uint64_t dlsch_slot_bitmap[3]; + /// Lookup for preferred time domain allocation for BWP, in DL, slots + /// dynamically allocated + int *preferred_dl_tda[MAX_NUM_BWP]; + /// bitmap of ULSCH slots, can hold up to 160 slots + uint64_t ulsch_slot_bitmap[3]; + /// Lookup for preferred time domain allocation for UL BWP, dynamically + /// allocated. The index refers to the DL slot, and the indicated TDA's k2 + /// points to the right UL slot + int *preferred_ul_tda[MAX_NUM_BWP]; + /// DL preprocessor for differentiated scheduling nr_pp_impl_dl pre_processor_dl; /// UL preprocessor for differentiated scheduling diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 8e60dafb276ee4ab84614fdc3dddc193c63f8ab0..7ecac9f7e6905c9253da8f38212f21770be59e61 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -186,8 +186,8 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->mac_CellGroupConfig->drx_Config = NULL; secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig = NULL; secondaryCellGroup->mac_CellGroupConfig->bsr_Config=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->bsr_Config)); - secondaryCellGroup->mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf80; - secondaryCellGroup->mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf320; + secondaryCellGroup->mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10; + secondaryCellGroup->mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf160; secondaryCellGroup->mac_CellGroupConfig->tag_Config=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->tag_Config)); secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToReleaseList = NULL; secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList)); @@ -1031,7 +1031,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco long *delay[8]; for (int i=0;i<8;i++) { delay[i] = calloc(1,sizeof(*delay[i])); - *delay[i] = (i<6) ? (i+2) : 0; + *delay[i] = i+2; ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]); } pucch_Config->spatialRelationInfoToAddModList = calloc(1,sizeof(*pucch_Config->spatialRelationInfoToAddModList)); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf index 25edddde86bb9d99cab21ce9e49b2d592b0cd9e5..ec94306b7d909adfacda299927c951c12e14e27d 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf @@ -58,27 +58,14 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=2,L=3 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; - - initialDLBWPk0_3 = 0; - initialDLBWPmappingType_3 = 0; - #this is SS=1,L=4 //5 (4 is for 43, 5 is for 57) - initialDLBWPstartSymbolAndLength_3 = 57; //43; //57; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 257; @@ -133,20 +120,17 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 6; + initialULBWPk2_0 = 6; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 - initialULBWPk2_1 = 6; + initialULBWPk2_1 = 6; # used for mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 - initialULBWPk2_2 = 4; + initialULBWPk2_2 = 4; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; - # this is SS=10 L=4 - initialULBWPstartSymbolAndLength_2 = 52; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf index 182398cd88003df4ba4cb7b84a43d074a2984565..22856200983973f5a9f9fc683d6831f2be511035 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf @@ -56,22 +56,14 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=2,L=3 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot (but is not used here) + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 257; @@ -126,15 +118,17 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 2; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 2; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 + + initialULBWPk2_1 = 2; # used for mixed slot (not used here) initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 + + initialULBWPk2_2 = 7; # used for Msg.3 during RA + initialULBWPmappingType_2 = 1; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 msg3_DeltaPreamble = 1; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf index 535c1fce5a111ab224bc8eec11169c62be22ffe7..908e4501757a1073442287b5e2fa0dd873e26e36 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf @@ -58,27 +58,14 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=2,L=3 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; - - initialDLBWPk0_3 = 0; - initialDLBWPmappingType_3 = 0; - #this is SS=1,L=4 //5 (4 is for 43, 5 is for 57) - initialDLBWPstartSymbolAndLength_3 = 57; //43; //57; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 261; @@ -133,20 +120,17 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 6; + initialULBWPk2_0 = 6; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 - initialULBWPk2_1 = 6; + initialULBWPk2_1 = 6; # used for mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 - initialULBWPk2_2 = 4; + initialULBWPk2_2 = 4; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; - # this is SS=10 L=4 - initialULBWPstartSymbolAndLength_2 = 52; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf index 632ae126cd3774211afdab98f24db10a93083f8e..9576b5eb8f3428cf54bc030624ea0d9add785dda 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf @@ -56,27 +56,14 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=1,L=13 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; - - initialDLBWPk0_3 = 0; - initialDLBWPmappingType_3 = 0; - #this is SS=1,L=4 - initialDLBWPstartSymbolAndLength_3 = 57; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 66; @@ -132,20 +119,18 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 6; + initialULBWPk2_0 = 6; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 - initialULBWPk2_1 = 6; + initialULBWPk2_1 = 6; # used for mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 - initialULBWPk2_2 = 7; + initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; - # this is SS=10 L=4 - initialULBWPstartSymbolAndLength_2 = 52; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 + msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf index 46868d01854cd061595b82e32f53a06a027f3c75..c303ae5a97f6b1cdc5ff787e94cf60df00019953 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf @@ -56,27 +56,14 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=1,L=13 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; - - initialDLBWPk0_3 = 0; - initialDLBWPmappingType_3 = 0; - #this is SS=1,L=4 - initialDLBWPstartSymbolAndLength_3 = 57; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 66; @@ -132,20 +119,18 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 6; + initialULBWPk2_0 = 6; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 - initialULBWPk2_1 = 6; + initialULBWPk2_1 = 6; # used for mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 - initialULBWPk2_2 = 7; + initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; - # this is SS=10 L=4 - initialULBWPstartSymbolAndLength_2 = 52; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 + msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf index cb5249423052d1179588d32255ff66bf60f477ce..8cb31cce65c474492c1ede27253624488b9daaf5 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf @@ -56,22 +56,14 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=2,L=3 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 78; @@ -126,16 +118,17 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 2; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 2; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 + + initialULBWPk2_1 = 2; # used for mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 + initialULBWPk2_2 = 7; # used for Msg.3 during RA + initialULBWPmappingType_2 = 1; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf index 27ade965dc29869e5fcf915f351aea4a04b6a807..f157d886fc2b8fc4f23a730a31eadd355f66e469 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf @@ -56,27 +56,13 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=1,L=13 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; - - initialDLBWPk0_3 = 0; - initialDLBWPmappingType_3 = 0; - #this is SS=1,L=4 - initialDLBWPstartSymbolAndLength_3 = 57; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 #uplinkConfigCommon #frequencyInfoUL @@ -132,21 +118,17 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 2; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 2; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 + + initialULBWPk2_1 = 2; # used for mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 - initialULBWPk2_2 = 7; + initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; - # this is SS=10 L=4 - initialULBWPstartSymbolAndLength_2 = 52; - + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf index 9bb91329173132150f812a867c76919b11f56589..c79133e956586f6aaa950c87d5af4cb096148e66 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf @@ -56,22 +56,14 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=2,L=3 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot (but not used here) + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 78; @@ -126,16 +118,17 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 2; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 2; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 + + initialULBWPk2_1 = 2; # used for mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 63; # this is SS=7 L=5 + initialULBWPk2_2 = 7; # used for Msg.3 during RA + initialULBWPmappingType_2 = 1; + initialULBWPstartSymbolAndLength_2 = 91; # this is SS=7 L=7 msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf index 3b384dd072fa9ee2f9bbc534452433f96f9d6c53..f020efbfdc82d5229786cb41e967cc6ee8119ec0 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf @@ -56,22 +56,14 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=2,L=3 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 78; @@ -126,16 +118,17 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 2; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 2; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 + + initialULBWPk2_1 = 2; # used for mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 + initialULBWPk2_2 = 7; # used for Msg.3 during RA + initialULBWPmappingType_2 = 1; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 0ff7e4aa80e2da5451e8f45923d1082a7e8499d5..53feb26dbc59f818f98c2ec5f7a49ee0576e55fc 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -56,27 +56,13 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=1,L=13 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; - - initialDLBWPk0_3 = 0; - initialDLBWPmappingType_3 = 0; - #this is SS=1,L=5 - initialDLBWPstartSymbolAndLength_3 = 57; + initialDLBWPk0_0 = 0; # used for (full) DL slot + initialDLBWPmappingType_0 = 0; # 0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; # this is SS=1,L=13 + + initialDLBWPk0_1 = 0; # used for DL part mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; # this is SS=1,L=5 #uplinkConfigCommon #frequencyInfoUL @@ -132,20 +118,17 @@ gNBs = restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 6; + initialULBWPk2_0 = 6; # used for (full) UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 - initialULBWPk2_1 = 6; + initialULBWPk2_1 = 6; # used for UL part mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 - initialULBWPk2_2 = 7; + initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; - # this is SS=10 L=4 - initialULBWPstartSymbolAndLength_2 = 52; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf index d0775384c3bacc250a03cd5a7aa0a7828ad1c64c..b3c960dc843f0d7fafad268c12f8f5e671029274 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf @@ -56,27 +56,14 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=1,L=13 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; - - initialDLBWPk0_3 = 0; - initialDLBWPmappingType_3 = 0; - #this is SS=1,L=4 - initialDLBWPstartSymbolAndLength_3 = 57; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + #uplinkConfigCommon #frequencyInfoUL @@ -132,20 +119,17 @@ gNBs = restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 6; + initialULBWPk2_0 = 6; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 + initialULBWPk2_1 = 6; # used for mixed slot - initialULBWPk2_1 = 6; initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 - initialULBWPk2_2 = 7; + initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; - # this is SS=10 L=4 - initialULBWPstartSymbolAndLength_2 = 52; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf index d6110e19d5394bcb1008f9e49357dee0f7934a94..afca060683a84893d6af0829bd48efd234b52a9e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf @@ -56,27 +56,14 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=1,L=13 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; - - initialDLBWPk0_3 = 0; - initialDLBWPmappingType_3 = 0; - #this is SS=1,L=5 - initialDLBWPstartSymbolAndLength_3 = 57; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 78; @@ -131,21 +118,17 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 6; #2; + initialULBWPk2_0 = 6; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 6; #2; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 + + initialULBWPk2_1 = 6; # used for mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 - initialULBWPk2_2 = 7; + initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; - # this is SS=10 L=4 - initialULBWPstartSymbolAndLength_2 = 52; - + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf index 07d04e65f922c0ad74cd0e71b792524541b1bc8e..b310ef952de4222a73232545a7d2fc9dd27e3615 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf @@ -56,27 +56,14 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=1,L=13 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; - - initialDLBWPk0_3 = 0; - initialDLBWPmappingType_3 = 0; - #this is SS=1,L=5 - initialDLBWPstartSymbolAndLength_3 = 57; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 78; @@ -131,16 +118,17 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 2; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 2; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 + + initialULBWPk2_1 = 2; # used for mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 + initialULBWPk2_2 = 7; # used for Msg.3 during RA + initialULBWPmappingType_2 = 1; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf index a42da67df304fa6de7a5d016c3074f78b23dc843..386766c96b821d9f2592b90ee55d973f54068638 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf @@ -56,27 +56,14 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=1,L=13 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; - - initialDLBWPk0_3 = 0; - initialDLBWPmappingType_3 = 0; - #this is SS=1,L=5 - initialDLBWPstartSymbolAndLength_3 = 57; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 78; @@ -131,21 +118,17 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 6;#2; + initialULBWPk2_0 = 6; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 6;#2; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 + + initialULBWPk2_1 = 6; # used for mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 - initialULBWPk2_2 = 7; + initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; - # this is SS=10 L=4 - initialULBWPstartSymbolAndLength_2 = 52; - + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf index b2a765c4476fac7d214e9eb0626b25b84e4a7629..30cce9f7ca3089bafd15350d074b19cf996e5c51 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf @@ -58,27 +58,14 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=1,L=13 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; - - initialDLBWPk0_3 = 0; - initialDLBWPmappingType_3 = 0; - #this is SS=1,L=4 //5 (4 is for 43, 5 is for 57) - initialDLBWPstartSymbolAndLength_3 = 57; //43; //57; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 78; @@ -133,20 +120,17 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 2; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 2; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 + + initialULBWPk2_1 = 2; # used for mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 - initialULBWPk2_2 = 7; + initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; - # this is SS=10 L=4 - initialULBWPstartSymbolAndLength_2 = 52; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf index e8fcced3863b66f546cc48bebb420c60b03c09a6..6441db03289b2f71c843b9d2e0443bf81b47086b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf @@ -56,27 +56,14 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=1,L=13 - initialDLBWPstartSymbolAndLength_0 = 40; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; - - initialDLBWPk0_3 = 0; - initialDLBWPmappingType_3 = 0; - #this is SS=1,L=4 //5 (4 is for 43, 5 is for 57) - initialDLBWPstartSymbolAndLength_3 = 57; //43; //57; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 78; @@ -131,20 +118,17 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 2; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 2; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 + + initialULBWPk2_1 = 2; # used for mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 - initialULBWPk2_2 = 7; + initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; - # this is SS=10 L=4 - initialULBWPstartSymbolAndLength_2 = 52; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf index 42b87d5672729353a594bc4426a3178fc458e50a..35f9b1e7a099c1fcf911ccb02c15737ebe35c45b 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf @@ -60,32 +60,13 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_0 = 53; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=10 - initialDLBWPstartSymbolAndLength_1 = 81; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 95; - - initialDLBWPk0_3 = 0; - initialDLBWPmappingType_3 = 0; - #this is SS=2,L=7 - initialDLBWPstartSymbolAndLength_3 = 86; - - initialDLBWPk0_4 = 0; - initialDLBWPmappingType_4 = 0; - #this is SS=2,L=5 - initialDLBWPstartSymbolAndLength_4 = 58; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 #uplinkConfigCommon #frequencyInfoUL @@ -141,20 +122,17 @@ gNBs = restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 6; + initialULBWPk2_0 = 6; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 - initialULBWPk2_1 = 6; + initialULBWPk2_1 = 6; # used for mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 - initialULBWPk2_2 = 7; + initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; - # this is SS=10 L=4 - initialULBWPstartSymbolAndLength_2 = 52; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf index 96df4a971f7ae73b106c2ed9654f57df02a1340e..6bffa1f01c9f2a7f415fa457bdf5b502b01eafbb 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf @@ -60,27 +60,13 @@ gNBs = initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; - #initialULBWPmappingType - #0=typeA,1=typeB - initialDLBWPmappingType_0 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_0 = 53; - - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=10 - initialDLBWPstartSymbolAndLength_1 = 81; - - initialDLBWPk0_2 = 0; - initialDLBWPmappingType_2 = 0; - #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 54; - - initialDLBWPk0_3 = 0; - initialDLBWPmappingType_3 = 0; - #this is SS=1,L=5 - initialDLBWPstartSymbolAndLength_3 = 57; + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 #uplinkConfigCommon #frequencyInfoUL @@ -136,20 +122,17 @@ gNBs = restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 6; + initialULBWPk2_0 = 6; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 - initialULBWPk2_1 = 6; + initialULBWPk2_1 = 6; # used for mixed slot initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 - initialULBWPk2_2 = 7; + initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; - # this is SS=10 L=4 - initialULBWPstartSymbolAndLength_2 = 52; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90;