gNB_scheduler_phytest.c 19.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

/*! \file gNB_scheduler_phytest.c
 * \brief gNB scheduling procedures in phy_test mode
24
 * \author  Guy De Souza, G. Casati
25
 * \date 07/2018
26
 * \email: desouza@eurecom.fr, guido.casati@iis.fraunhofer.de
27 28 29 30 31
 * \version 1.0
 * @ingroup _mac
 */

#include "nr_mac_gNB.h"
32 33
#include "NR_MAC_gNB/mac_proto.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
34
#include "executables/nr-softmodem.h"
35
#include "LAYER2/NR_MAC_COMMON/nr_mac.h"
36
#include "executables/softmodem-common.h"
Francesco Mani's avatar
Francesco Mani committed
37
#include "common/utils/nr/nr_common.h"
Raymond Knopp's avatar
Raymond Knopp committed
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
#include "NR_SCS-SpecificCarrier.h"
#include "NR_TDD-UL-DL-ConfigCommon.h"
#include "NR_FrequencyInfoUL.h"
#include "NR_RACH-ConfigGeneric.h"
#include "NR_RACH-ConfigCommon.h"
#include "NR_PUSCH-TimeDomainResourceAllocation.h"
#include "NR_PUSCH-ConfigCommon.h"
#include "NR_PUCCH-ConfigCommon.h"
#include "NR_PDSCH-TimeDomainResourceAllocation.h"
#include "NR_PDSCH-ConfigCommon.h"
#include "NR_RateMatchPattern.h"
#include "NR_RateMatchPatternLTE-CRS.h"
#include "NR_SearchSpace.h"
#include "NR_ControlResourceSet.h"

Francesco Mani's avatar
Francesco Mani committed
53
//#define UL_HARQ_PRINT
54
extern RAN_CONTEXT_t RC;
55

56
//#define ENABLE_MAC_PAYLOAD_DEBUG 1
57 58

/*Scheduling of DLSCH with associated DCI in common search space
Guy De Souza's avatar
Guy De Souza committed
59
 * current version has only a DCI for type 1 PDCCH for C_RNTI*/
60 61
void nr_schedule_css_dlsch_phytest(module_id_t   module_idP,
                                   frame_t       frameP,
62
                                   sub_frame_t   slotP) {
63
  uint8_t  CC_id;
Raymond Knopp's avatar
Raymond Knopp committed
64 65
  gNB_MAC_INST                      *nr_mac      = RC.nrmac[module_idP];
  NR_COMMON_channels_t              *cc = &nr_mac->common_channels[0];
Raymond Knopp's avatar
Raymond Knopp committed
66 67 68 69
  nfapi_nr_dl_tti_request_body_t    *dl_req;
  nfapi_nr_dl_tti_request_pdu_t     *dl_tti_pdcch_pdu;
  nfapi_nr_dl_tti_request_pdu_t     *dl_tti_pdsch_pdu;
  nfapi_nr_pdu_t        *TX_req;
70

Guy De Souza's avatar
Guy De Souza committed
71
  uint16_t rnti = 0x1234;
72
  //  int time_domain_assignment,k0;
Raymond Knopp's avatar
Raymond Knopp committed
73 74

  NR_ServingCellConfigCommon_t *scc=cc->ServingCellConfigCommon;
Raymond Knopp's avatar
Raymond Knopp committed
75

cig's avatar
cig committed
76
  int dlBWP_carrier_bandwidth = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
77

78 79
  
  /*
Raymond Knopp's avatar
Raymond Knopp committed
80
  int scs               = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing;
81
  
Raymond Knopp's avatar
Raymond Knopp committed
82
  int slots_per_frame   = 10*(1<<scs);
83

Raymond Knopp's avatar
Raymond Knopp committed
84
  int FR                = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257 ? nr_FR2 : nr_FR1;
85
  */
86

87
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
Raymond Knopp committed
88 89
    LOG_D(MAC, "Scheduling common search space DCI type 1 dlBWP BW.firstRB %d.%d\n",
	  dlBWP_carrier_bandwidth,
cig's avatar
cig committed
90
	  NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE));
Raymond Knopp's avatar
Raymond Knopp committed
91 92
    
    
Raymond Knopp's avatar
Raymond Knopp committed
93 94 95 96 97
    dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body;
    dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
    memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
    dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
    dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
Raymond Knopp's avatar
Raymond Knopp committed
98
    
Mahesh's avatar
Mahesh committed
99
    dl_tti_pdsch_pdu = &nr_mac->DL_req[CC_id].dl_tti_request_body.dl_tti_pdu_list[nr_mac->DL_req[CC_id].dl_tti_request_body.nPDUs+1];
Raymond Knopp's avatar
Raymond Knopp committed
100 101 102
    memset((void *)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
    dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE;
    dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu));
103

Raymond Knopp's avatar
Raymond Knopp committed
104
    
105
    //    nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
Raymond Knopp's avatar
Raymond Knopp committed
106
    nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
Raymond Knopp's avatar
Raymond Knopp committed
107
    
108 109 110
    pdsch_pdu_rel15->pduBitmap = 0;
    pdsch_pdu_rel15->rnti = rnti;
    pdsch_pdu_rel15->pduIndex = 0;
Raymond Knopp's avatar
Raymond Knopp committed
111 112

    // BWP
cig's avatar
cig committed
113 114
    pdsch_pdu_rel15->BWPSize  = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
    pdsch_pdu_rel15->BWPStart = NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
115 116 117
    pdsch_pdu_rel15->SubcarrierSpacing = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing;
    pdsch_pdu_rel15->CyclicPrefix = 0;
    pdsch_pdu_rel15->NrOfCodewords = 1;
Raymond Knopp's avatar
Raymond Knopp committed
118
    int mcsIndex = 9;
119 120 121 122 123 124 125 126 127 128
    pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcsIndex,0);
    pdsch_pdu_rel15->qamModOrder[0] = 2;
    pdsch_pdu_rel15->mcsIndex[0] = mcsIndex;
    pdsch_pdu_rel15->mcsTable[0] = 0;
    pdsch_pdu_rel15->rvIndex[0] = 0;
    pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
    pdsch_pdu_rel15->nrOfLayers = 1;    
    pdsch_pdu_rel15->transmissionScheme = 0;
    pdsch_pdu_rel15->refPoint = 0; // Point A
    
129
    pdsch_pdu_rel15->dmrsConfigType = 0; // Type 1 by default for InitialBWP
130 131 132 133 134 135 136 137
    pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
    pdsch_pdu_rel15->SCID = 0;
    pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 1;
    pdsch_pdu_rel15->dmrsPorts = 1;
    pdsch_pdu_rel15->resourceAlloc = 1;
    pdsch_pdu_rel15->rbStart = 0;
    pdsch_pdu_rel15->rbSize = 6;
    pdsch_pdu_rel15->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP
Raymond Knopp's avatar
Raymond Knopp committed
138 139
    // choose shortest PDSCH
    int startSymbolAndLength=0;
140
    int StartSymbolIndex=-1,NrOfSymbols=14;
Raymond Knopp's avatar
Raymond Knopp committed
141
    int StartSymbolIndex_tmp,NrOfSymbols_tmp;
Laurent THOMAS's avatar
Laurent THOMAS committed
142
    int mappingtype_tmp, mappingtype=0;
Raymond Knopp's avatar
Raymond Knopp committed
143 144 145 146 147 148

    for (int i=0;
	 i<scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count;
	 i++) {
      startSymbolAndLength = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
      SLIV2SL(startSymbolAndLength,&StartSymbolIndex_tmp,&NrOfSymbols_tmp);
149
      mappingtype_tmp = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->mappingType;
Raymond Knopp's avatar
Raymond Knopp committed
150 151 152
      if (NrOfSymbols_tmp < NrOfSymbols) {
	NrOfSymbols = NrOfSymbols_tmp;
        StartSymbolIndex = StartSymbolIndex_tmp;
153
        mappingtype = mappingtype_tmp;
Raymond Knopp's avatar
Raymond Knopp committed
154 155
      }
    }
156
    AssertFatal(StartSymbolIndex>=0,"StartSymbolIndex is negative\n");
157 158 159
    pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex;
    pdsch_pdu_rel15->NrOfSymbols      = NrOfSymbols;
    pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(NULL,
160 161
                                                    scc->dmrs_TypeA_Position,
                                                    NrOfSymbols,
162
                                                    StartSymbolIndex,
163 164
                                                    mappingtype,
                                                    1);
165

Mahesh's avatar
Mahesh committed
166
    nr_mac->DL_req[CC_id].dl_tti_request_body.nPDUs+=2;
Raymond Knopp's avatar
Raymond Knopp committed
167 168 169 170 171 172
    
    TX_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
    TX_req->PDU_length = 6;
    TX_req->PDU_index = nr_mac->pdu_index[CC_id]++;
    TX_req->num_TLV = 1;
    TX_req->TLVs[0].length = 8;
173 174 175
    // why do we copy from RAR_pdu here? Shouldn't we fill some more or less
    // meaningful data, e.g., padding + random data?
    //memcpy((void *)&TX_req->TLVs[0].value.direct[0], (void *)&cc[CC_id].RAR_pdu[0].payload[0], TX_req->TLVs[0].length);
Raymond Knopp's avatar
Raymond Knopp committed
176 177 178
    nr_mac->TX_req[CC_id].Number_of_PDUs++;
    nr_mac->TX_req[CC_id].SFN=frameP;
    nr_mac->TX_req[CC_id].Slot=slotP;
179 180
  }
}
181

182
uint32_t target_dl_mcs = 9;
183
uint32_t target_dl_Nl = 1;
184 185
uint32_t target_dl_bw = 50;
uint64_t dlsch_slot_bitmap = (1<<1);
Robert Schmidt's avatar
Robert Schmidt committed
186 187 188
/* schedules whole bandwidth for first user, all the time */
void nr_preprocessor_phytest(module_id_t module_id,
                             frame_t frame,
189
                             sub_frame_t slot)
Robert Schmidt's avatar
Robert Schmidt committed
190
{
191
  if (!is_xlsch_in_slot(dlsch_slot_bitmap, slot))
Robert Schmidt's avatar
Robert Schmidt committed
192
    return;
Laurent THOMAS's avatar
Laurent THOMAS committed
193
  NR_UE_info_t *UE = RC.nrmac[module_id]->UE_info.list[0];
194
  NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
Laurent THOMAS's avatar
Laurent THOMAS committed
195
  NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
francescomani's avatar
francescomani committed
196
  NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP;
Robert Schmidt's avatar
Robert Schmidt committed
197
  const int CC_id = 0;
198

francescomani's avatar
francescomani committed
199
  const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot);
francescomani's avatar
francescomani committed
200 201
  NR_pdsch_tda_info_t *tda_info = &sched_ctrl->sched_pdsch.tda_info;
  nr_get_pdsch_tda_info(dl_bwp, tda, tda_info);
202

Robert Schmidt's avatar
Robert Schmidt committed
203
  /* find largest unallocated chunk */
francescomani's avatar
francescomani committed
204 205
  const int bwpSize = dl_bwp->BWPSize;
  const int BWPStart = dl_bwp->BWPStart;
206

Robert Schmidt's avatar
Robert Schmidt committed
207 208
  int rbStart = 0;
  int rbSize = 0;
209 210
  if (target_dl_bw>bwpSize)
    target_dl_bw = bwpSize;
211
  uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
212 213
  /* loop ensures that we allocate exactly target_dl_bw, or return */
  while (true) {
Robert Schmidt's avatar
Robert Schmidt committed
214
    /* advance to first free RB */
215
    while (rbStart < bwpSize &&
francescomani's avatar
francescomani committed
216
           (vrb_map[rbStart + BWPStart]&SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols)))
217 218 219
      rbStart++;
    rbSize = 1;
    /* iterate until we are at target_dl_bw or no available RBs */
220
    while (rbStart + rbSize < bwpSize &&
francescomani's avatar
francescomani committed
221
           !(vrb_map[rbStart + rbSize + BWPStart]&SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols)) &&
222
           rbSize < target_dl_bw)
223 224 225 226 227 228 229 230 231
      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;
  }
Robert Schmidt's avatar
Robert Schmidt committed
232 233

  sched_ctrl->num_total_bytes = 0;
234
  sched_ctrl->dl_lc_num = 1;
Robert Schmidt's avatar
Robert Schmidt committed
235
  const int lcid = DL_SCH_LCID_DTCH;
236
  sched_ctrl->dl_lc_ids[sched_ctrl->dl_lc_num - 1] = lcid;
Laurent THOMAS's avatar
Laurent THOMAS committed
237
  const uint16_t rnti = UE->rnti;
Robert Schmidt's avatar
Robert Schmidt committed
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
  /* update sched_ctrl->num_total_bytes so that postprocessor schedules data,
   * if available */
  sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id,
                                                    rnti,
                                                    module_id,
                                                    frame,
                                                    slot,
                                                    ENB_FLAG_YES,
                                                    MBMS_FLAG_NO,
                                                    lcid,
                                                    0,
                                                    0);
  sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer;

  uint8_t nr_of_candidates;
253 254 255 256 257 258 259 260 261 262
  for (int i=0; i<5; i++) {
    // for now taking the lowest value among the available aggregation levels
    find_aggregation_candidates(&sched_ctrl->aggregation_level,
                                &nr_of_candidates,
                                sched_ctrl->search_space,
                                1<<i);
    if(nr_of_candidates>0) break;
  }
  AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n");

263
  const uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE->rnti);
264 265 266 267 268

  int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
                                      CC_id,
                                      sched_ctrl->aggregation_level,
                                      nr_of_candidates,
269
                                      &sched_ctrl->sched_pdcch,
270 271 272 273
                                      sched_ctrl->coreset,
                                      Y);

  AssertFatal(CCEIndex >= 0,
Laurent THOMAS's avatar
Laurent THOMAS committed
274
              "%s(): could not find CCE for UE %04x\n",
Robert Schmidt's avatar
Robert Schmidt committed
275
              __func__,
Laurent THOMAS's avatar
Laurent THOMAS committed
276
              UE->rnti);
Robert Schmidt's avatar
Robert Schmidt committed
277

francescomani's avatar
francescomani committed
278
  int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, UE->current_UL_BWP.pucch_Config, CCEIndex);
Laurent THOMAS's avatar
Laurent THOMAS committed
279
  const int alloc = nr_acknack_scheduling(module_id, UE, frame, slot, r_pucch, 0);
280
  if (alloc < 0) {
281
    LOG_D(MAC,
Laurent THOMAS's avatar
Laurent THOMAS committed
282
          "%s(): could not find PUCCH for UE %04x@%d.%d\n",
283 284 285 286 287 288 289
          __func__,
          rnti,
          frame,
          slot);
    return;
  }

290 291 292 293
  sched_ctrl->cce_index = CCEIndex;

  fill_pdcch_vrb_map(RC.nrmac[module_id],
                     CC_id,
294
                     &sched_ctrl->sched_pdcch,
295 296 297
                     CCEIndex,
                     sched_ctrl->aggregation_level);

298 299 300
  //AssertFatal(alloc,
  //            "could not find uplink slot for PUCCH (RNTI %04x@%d.%d)!\n",
  //            rnti, frame, slot);
Robert Schmidt's avatar
Robert Schmidt committed
301

302
  NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
303
  sched_pdsch->pucch_allocation = alloc;
304 305
  sched_pdsch->rbStart = rbStart;
  sched_pdsch->rbSize = rbSize;
francescomani's avatar
francescomani committed
306

francescomani's avatar
francescomani committed
307 308 309 310 311 312
  set_dl_dmrs_params(&sched_pdsch->dmrs_parms,
                     scc,
                     dl_bwp,
                     tda_info,
                     target_dl_Nl);

313
  sched_pdsch->mcs = target_dl_mcs;
francescomani's avatar
francescomani committed
314
  sched_pdsch->nrOfLayers = target_dl_Nl;
francescomani's avatar
francescomani committed
315 316
  sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx);
  sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx);
317
  sched_ctrl->dl_bler_stats.mcs = target_dl_mcs; /* for logging output */
318 319 320
  sched_pdsch->tb_size = nr_compute_tbs(sched_pdsch->Qm,
                                        sched_pdsch->R,
                                        sched_pdsch->rbSize,
francescomani's avatar
francescomani committed
321 322
                                        tda_info->nrOfSymbols,
                                        sched_pdsch->dmrs_parms.N_PRB_DMRS * sched_pdsch->dmrs_parms.N_DMRS_SLOT,
323 324
                                        0 /* N_PRB_oh, 0 for initialBWP */,
                                        0 /* tb_scaling */,
francescomani's avatar
francescomani committed
325
                                        sched_pdsch->nrOfLayers)
326 327
                         >> 3;

328
  /* get the PID of a HARQ process awaiting retransmission, or -1 otherwise */
329
  sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
Robert Schmidt's avatar
Robert Schmidt committed
330 331

  /* mark the corresponding RBs as used */
332
  for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
francescomani's avatar
francescomani committed
333
    vrb_map[rb + sched_pdsch->rbStart + BWPStart] = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols);
Eurecom's avatar
Eurecom committed
334

rmagueta's avatar
rmagueta committed
335
  if ((frame&127) == 0) LOG_D(MAC,"phytest: %d.%d DL mcs %d, DL rbStart %d, DL rbSize %d\n", frame, slot, sched_pdsch->mcs, rbStart,rbSize);
Robert Schmidt's avatar
Robert Schmidt committed
336 337
}

338 339
uint32_t target_ul_mcs = 9;
uint32_t target_ul_bw = 50;
340
uint32_t target_ul_Nl = 1;
341
uint64_t ulsch_slot_bitmap = (1 << 8);
342 343
bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_t slot)
{
344 345 346
  gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
  NR_COMMON_channels_t *cc = nr_mac->common_channels;
  NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
Laurent THOMAS's avatar
Laurent THOMAS committed
347
  NR_UE_info_t *UE = nr_mac->UE_info.list[0];
348

Laurent THOMAS's avatar
Laurent THOMAS committed
349 350 351
  AssertFatal(nr_mac->UE_info.list[1] == NULL,
              "cannot handle more than one UE\n");
  if (UE == NULL)
352
    return false;
353 354 355

  const int CC_id = 0;

Laurent THOMAS's avatar
Laurent THOMAS committed
356
  NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
francescomani's avatar
francescomani committed
357 358
  NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
  const int mu = ul_bwp->scs;
359

francescomani's avatar
francescomani committed
360
  const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = ul_bwp->tdaList;
francescomani's avatar
francescomani committed
361 362 363 364
  const int temp_tda = get_ul_tda(nr_mac, scc, slot);
  if (temp_tda < 0)
    return false;
  AssertFatal(temp_tda < tdaList->list.count,
365
              "time domain assignment %d >= %d\n",
francescomani's avatar
francescomani committed
366
              temp_tda,
367
              tdaList->list.count);
francescomani's avatar
francescomani committed
368
  int K2 = get_K2(ul_bwp->tdaList, temp_tda, mu);
ChiehChun's avatar
ChiehChun committed
369 370
  const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]);
  const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
francescomani's avatar
francescomani committed
371 372 373 374 375 376 377
  const int tda = get_ul_tda(nr_mac, scc, sched_slot);
  if (tda < 0)
    return false;
  AssertFatal(tda < tdaList->list.count,
              "time domain assignment %d >= %d\n",
              tda,
              tdaList->list.count);
378 379 380
  /* 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 */
381
  if (!is_xlsch_in_slot(ulsch_slot_bitmap, sched_slot))
382
    return false;
383

384
  uint16_t rbStart = 0;
385 386
  uint16_t rbSize;

francescomani's avatar
francescomani committed
387 388
  const int bw = ul_bwp->BWPSize;
  const int BWPStart = ul_bwp->BWPStart;
389 390 391 392 393

  if (target_ul_bw>bw)
    rbSize = bw;
  else
    rbSize = target_ul_bw;
394

francescomani's avatar
francescomani committed
395 396 397
  NR_pusch_tda_info_t *tda_info = &sched_ctrl->sched_pusch.tda_info;
  nr_get_pusch_tda_info(ul_bwp, tda, tda_info);

398
  uint16_t *vrb_map_UL =
cig's avatar
cig committed
399
      &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE];
400
  for (int i = rbStart; i < rbStart + rbSize; ++i) {
francescomani's avatar
francescomani committed
401
    if ((vrb_map_UL[i+BWPStart] & SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols)) != 0) {
402 403 404 405 406 407
      LOG_E(MAC,
            "%s(): %4d.%2d RB %d is already reserved, cannot schedule UE\n",
            __func__,
            frame,
            slot,
            i);
408
      return false;
409 410 411
    }
  }

412 413
  sched_ctrl->sched_pusch.slot = sched_slot;
  sched_ctrl->sched_pusch.frame = sched_frame;
414 415

  uint8_t nr_of_candidates;
416 417 418 419 420 421 422 423 424 425
  for (int i=0; i<5; i++) {
    // for now taking the lowest value among the available aggregation levels
    find_aggregation_candidates(&sched_ctrl->aggregation_level,
                                &nr_of_candidates,
                                sched_ctrl->search_space,
                                1<<i);
    if(nr_of_candidates>0) break;
  }
  AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n");

426
  const uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE->rnti);
427 428 429 430 431

  int CCEIndex = find_pdcch_candidate(nr_mac,
                                      CC_id,
                                      sched_ctrl->aggregation_level,
                                      nr_of_candidates,
432
                                      &sched_ctrl->sched_pdcch,
433 434 435
                                      sched_ctrl->coreset,
                                      Y);

436
  if (CCEIndex < 0) {
437
    LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__);
438
    return false;
439 440
  }

441 442
  sched_ctrl->cce_index = CCEIndex;

443
  const int mcs = target_ul_mcs;
444 445
  NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
  sched_pusch->mcs = mcs;
446
  sched_ctrl->ul_bler_stats.mcs = mcs; /* for logging output */
447 448
  sched_pusch->rbStart = rbStart;
  sched_pusch->rbSize = rbSize;
449 450
  /* get the PID of a HARQ process awaiting retransmission, or -1 for "any new" */
  sched_pusch->ul_harq_pid = sched_ctrl->retrans_ul_harq.head;
451 452

  /* Calculate TBS from MCS */
francescomani's avatar
francescomani committed
453
  sched_pusch->nrOfLayers = target_ul_Nl;
francescomani's avatar
francescomani committed
454 455 456 457
  sched_pusch->R = nr_get_code_rate_ul(mcs, ul_bwp->mcs_table);
  sched_pusch->Qm = nr_get_Qm_ul(mcs, ul_bwp->mcs_table);
  if (ul_bwp->pusch_Config->tp_pi2BPSK
      && ((ul_bwp->mcs_table == 3 && mcs < 2) || (ul_bwp->mcs_table == 4 && mcs < 6))) {
458 459 460
    sched_pusch->R >>= 1;
    sched_pusch->Qm <<= 1;
  }
francescomani's avatar
francescomani committed
461 462 463 464 465 466 467 468

  NR_pusch_dmrs_t *dmrs = &sched_ctrl->sched_pusch.dmrs_info;
  set_ul_dmrs_params(dmrs,
                     scc,
                     ul_bwp,
                     tda_info,
                     sched_pusch->nrOfLayers);

469 470 471
  sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm,
                                        sched_pusch->R,
                                        sched_pusch->rbSize,
francescomani's avatar
francescomani committed
472 473
                                        tda_info->nrOfSymbols,
                                        dmrs->N_PRB_DMRS * dmrs->num_dmrs_symb,
474 475
                                        0, // nb_rb_oh
                                        0,
francescomani's avatar
francescomani committed
476
                                        sched_pusch->nrOfLayers /* NrOfLayers */)
477
                         >> 3;
478 479

  /* mark the corresponding RBs as used */
480 481
  fill_pdcch_vrb_map(nr_mac,
                     CC_id,
482
                     &sched_ctrl->sched_pdcch,
483 484 485
                     CCEIndex,
                     sched_ctrl->aggregation_level);

486
  for (int rb = rbStart; rb < rbStart + rbSize; rb++)
francescomani's avatar
francescomani committed
487
    vrb_map_UL[rb+BWPStart] |= SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols);
488
  return true;
489
}