phy_procedures_nr_ue.c 91.1 KB
Newer Older
Agustin's avatar
Agustin committed
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.1  (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 phy_procedures_nr_ue.c
 * \brief Implementation of UE procedures from 36.213 LTE specifications
24
 * \author R. Knopp, F. Kaltenberger, N. Nikaein, A. Mico Pereperez, G. Casati
Agustin's avatar
Agustin committed
25 26 27
 * \date 2018
 * \version 0.1
 * \company Eurecom
28
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr, guido.casati@iis.fraunhofer.de
Agustin's avatar
Agustin committed
29 30 31 32 33 34
 * \note
 * \warning
 */

#define _GNU_SOURCE

rmagueta's avatar
rmagueta committed
35
#include "nr/nr_common.h"
Agustin's avatar
Agustin committed
36 37 38
#include "assertions.h"
#include "defs.h"
#include "PHY/defs_nr_UE.h"
39
#include "PHY/phy_extern_nr_ue.h"
Hongzhi Wang's avatar
Hongzhi Wang committed
40
#include "PHY/MODULATION/modulation_UE.h"
41
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
42 43
#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
Agustin's avatar
Agustin committed
44
#include "SCHED_NR_UE/defs.h"
Sakthivel Velumani's avatar
Sakthivel Velumani committed
45
#include "SCHED_NR_UE/pucch_uci_ue_nr.h"
Agustin's avatar
Agustin committed
46
#include "SCHED_NR/extern.h"
47
#include "SCHED_NR_UE/phy_sch_processing_time.h"
hongzhi wang's avatar
hongzhi wang committed
48
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
49
#include "PHY/NR_TRANSPORT/nr_dci.h"
Agustin's avatar
Agustin committed
50 51 52
#ifdef EMOS
#include "SCHED/phy_procedures_emos.h"
#endif
53
#include "executables/softmodem-common.h"
54
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
Agustin's avatar
Agustin committed
55

56
//#define DEBUG_PHY_PROC
Agustin's avatar
Agustin committed
57
#define NR_PDCCH_SCHED
58
//#define NR_PDCCH_SCHED_DEBUG
59 60
//#define NR_PUCCH_SCHED
//#define NR_PUCCH_SCHED_DEBUG
Agustin's avatar
Agustin committed
61 62 63 64 65

#ifndef PUCCH
#define PUCCH
#endif

66
#include "LAYER2/NR_MAC_UE/mac_defs.h"
67
#include "LAYER2/NR_MAC_UE/mac_proto.h"
68
#include "common/utils/LOG/log.h"
Agustin's avatar
Agustin committed
69 70 71 72 73

#ifdef EMOS
fifo_dump_emos_UE emos_dump_UE;
#endif

74
#include "common/utils/LOG/vcd_signal_dumper.h"
Agustin's avatar
Agustin committed
75
#include "UTIL/OPT/opt.h"
76
#include "intertask_interface.h"
Agustin's avatar
Agustin committed
77 78 79 80 81 82 83
#include "T.h"

#define DLSCH_RB_ALLOC 0x1fbf  // skip DC RB (total 23/25 RBs)
#define DLSCH_RB_ALLOC_12 0x0aaa  // skip DC RB (total 23/25 RBs)

#define NS_PER_SLOT 500000

84
char nr_mode_string[4][20] = {"NOT SYNCHED","PRACH","RAR","PUSCH"};
85

86 87
const uint8_t nr_rv_round_map_ue[4] = {0, 2, 1, 3};

Agustin's avatar
Agustin committed
88 89 90
extern double cpuf;

#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
91
extern uint64_t downlink_frequency[MAX_NUM_CCs][4];
Agustin's avatar
Agustin committed
92 93
#endif

cig's avatar
cig committed
94
unsigned int gain_table[31] = {100,112,126,141,158,178,200,224,251,282,316,359,398,447,501,562,631,708,794,891,1000,1122,1258,1412,1585,1778,1995,2239,2512,2818,3162};
Agustin's avatar
Agustin committed
95

96
int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL){
Agustin's avatar
Agustin committed
97

98
  int gain_dB = power_dBm - power_max_dBm, amp_x_100 = -1;
Agustin's avatar
Agustin committed
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119

  switch (N_RB_UL) {
  case 6:
  amp_x_100 = AMP;      // PRACH is 6 PRBS so no scale
  break;
  case 15:
  amp_x_100 = 158*AMP;  // 158 = 100*sqrt(15/6)
  break;
  case 25:
  amp_x_100 = 204*AMP;  // 204 = 100*sqrt(25/6)
  break;
  case 50:
  amp_x_100 = 286*AMP;  // 286 = 100*sqrt(50/6)
  break;
  case 75:
  amp_x_100 = 354*AMP;  // 354 = 100*sqrt(75/6)
  break;
  case 100:
  amp_x_100 = 408*AMP;  // 408 = 100*sqrt(100/6)
  break;
  default:
120 121
  LOG_E(PHY, "Unknown PRB size %d\n", N_RB_UL);
  return (amp_x_100);
Agustin's avatar
Agustin committed
122
  break;
123
  }
Agustin's avatar
Agustin committed
124
  if (gain_dB < -30) {
125 126 127
    return (amp_x_100/3162);
  } else if (gain_dB > 0)
    return (amp_x_100);
Agustin's avatar
Agustin committed
128
  else
129
    return (amp_x_100/gain_table[-gain_dB]);  // 245 corresponds to the factor sqrt(25/6)
Agustin's avatar
Agustin committed
130

131
  return (amp_x_100);
Agustin's avatar
Agustin committed
132 133
}

cig's avatar
cig committed
134
UE_MODE_t get_nrUE_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t gNB_id){
135 136
  return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[gNB_id]);
}
Agustin's avatar
Agustin committed
137

138 139
// scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
uint16_t get_bw_scaling(uint16_t nb_rb){
140
  uint16_t bw_scaling;
141
  switch (nb_rb) {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
142 143
    case 32:  bw_scaling =  4; break;
    case 66:  bw_scaling =  8; break;
144 145 146 147 148
    case 106: bw_scaling = 16; break;
    case 217: bw_scaling = 32; break;
    case 245: bw_scaling = 32; break;
    case 273: bw_scaling = 32; break;
    default: abort();
Agustin's avatar
Agustin committed
149
  }
cig's avatar
cig committed
150 151
  return bw_scaling;
}
Agustin's avatar
Agustin committed
152

153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
/* UL time alignment
// If the current tx frame and slot match the TA configuration in ul_time_alignment
// then timing advance is processed and set to be applied in the next UL transmission */
void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx){

  if (ue->mac_enabled == 1) {

    uint8_t gNB_id = 0;
    NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[gNB_id];

    if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot) {

      uint8_t numerology = ue->frame_parms.numerology_index;
      uint16_t bwp_ul_NB_RB = ue->frame_parms.N_RB_UL;

      LOG_D(PHY, "In %s: applying timing advance -- frame %d -- slot %d\n", __FUNCTION__, frame_tx, slot_tx);

      nr_process_timing_advance(ue->Mod_id, ue->CC_id, ul_time_alignment->ta_command, numerology, bwp_ul_NB_RB);

      ul_time_alignment->ta_frame = -1;
      ul_time_alignment->ta_slot = -1;

    }
  }
}

cig's avatar
cig committed
179
void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t ta_command, uint8_t mu, uint16_t bwp_ul_NB_RB){
Agustin's avatar
Agustin committed
180

cig's avatar
cig committed
181 182 183 184
  // 3GPP TS 38.213 p4.2
  // scale by the scs numerology
  int factor_mu = 1 << mu;
  uint16_t bw_scaling = get_bw_scaling(bwp_ul_NB_RB);
Agustin's avatar
Agustin committed
185

186
  PHY_vars_UE_g[Mod_id][CC_id]->timing_advance += (ta_command - 31) * bw_scaling / factor_mu;
Agustin's avatar
Agustin committed
187

188
  LOG_D(PHY, "[UE %d] Got timing advance command %u from MAC, new value is %d\n", Mod_id, ta_command, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance);
189
}
Agustin's avatar
Agustin committed
190

cig's avatar
cig committed
191 192
// WIP
// - todo: handle TA application as per ch 4.2 TS 38.213
193
void nr_process_timing_advance_rar(PHY_VARS_NR_UE *ue, int frame_rx, int nr_slot_rx, uint16_t ta_command) {
Agustin's avatar
Agustin committed
194

cig's avatar
cig committed
195 196 197
  int factor_mu = 1 << ue->frame_parms.numerology_index;
  uint16_t bwp_ul_NB_RB = ue->frame_parms.N_RB_UL;
  uint16_t bw_scaling = get_bw_scaling(bwp_ul_NB_RB);
Agustin's avatar
Agustin committed
198

cig's avatar
cig committed
199 200
  // Transmission timing adjustment (TS 38.213 p4.2)
  ue->timing_advance = bw_scaling / factor_mu;
Agustin's avatar
Agustin committed
201

202
  LOG_D(PHY, "[UE %d] Frame %d Slot %d, Received (RAR) timing advance command %d new value is %u \n", ue->Mod_id, frame_rx, nr_slot_rx, ta_command, ue->timing_advance);
Agustin's avatar
Agustin committed
203
}
Agustin's avatar
Agustin committed
204

205
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
206
                            UE_nr_rxtx_proc_t *proc,
207 208
                            uint8_t gNB_id) {
  int slot_tx = proc->nr_slot_tx;
Agustin's avatar
Agustin committed
209
  int frame_tx = proc->frame_tx;
210
  runmode_t mode = normal_txrx;
Agustin's avatar
Agustin committed
211 212 213

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);

214 215
  memset(ue->common_vars.txdataF[0], 0, sizeof(int)*14*ue->frame_parms.ofdm_symbol_size);

216
  LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
Agustin's avatar
Agustin committed
217 218 219 220 221

#if UE_TIMING_TRACE
  start_meas(&ue->phy_proc_tx);
#endif

222
  if (ue->UE_mode[gNB_id] <= PUSCH){
223

224 225 226 227
    for (uint8_t harq_pid = 0; harq_pid < ue->ulsch[proc->thread_id][gNB_id][0]->number_harq_processes_for_pusch; harq_pid++) {
      if (ue->ulsch[proc->thread_id][gNB_id][0]->harq_processes[harq_pid]->status == ACTIVE)
        nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, proc->thread_id, gNB_id);
    }
Agustin's avatar
Agustin committed
228

229
    if (get_softmodem_params()->usim_test==0) {
230
      LOG_D(PHY, "Generating PUCCH\n");
Francesco Mani's avatar
Francesco Mani committed
231 232 233
      pucch_procedures_ue_nr(ue,
                             gNB_id,
                             proc,
234
                             FALSE);
235
    }
236

237
    LOG_D(PHY, "Sending Uplink data \n");
238 239
    nr_ue_pusch_common_procedures(ue,
                                  slot_tx,
240
                                  &ue->frame_parms,1);
241
                                  //ue->ulsch[proc->thread_id][gNB_id][0]->harq_processes[harq_pid]->pusch_pdu.nrOfLayers);
242
  }
243
  //LOG_M("txdata.m","txs",ue->common_vars.txdata[0],1228800,1,1);
244

245
  /* RACH */
246
  if (get_softmodem_params()->do_ra==1) {
247
    if ((ue->UE_mode[gNB_id] > NOT_SYNCHED && ue->UE_mode[gNB_id] < PUSCH) && (ue->prach_vars[gNB_id]->prach_Config_enabled == 1)) {
248
      nr_ue_prach_procedures(ue, proc, gNB_id, mode);
249
    }
250
  }
251
  LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
Agustin's avatar
Agustin committed
252 253 254 255 256

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
#if UE_TIMING_TRACE
  stop_meas(&ue->phy_proc_tx);
#endif
257

Agustin's avatar
Agustin committed
258 259
}

cig's avatar
cig committed
260 261 262 263 264 265
void nr_ue_measurement_procedures(uint16_t l,
                                  PHY_VARS_NR_UE *ue,
                                  UE_nr_rxtx_proc_t *proc,
                                  uint8_t eNB_id,
                                  uint16_t slot,
                                  runmode_t mode){
Agustin's avatar
Agustin committed
266 267

  NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
268 269
  int frame_rx   = proc->frame_rx;
  int nr_slot_rx = proc->nr_slot_rx;
Agustin's avatar
Agustin committed
270 271
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_IN);

Hongzhi Wang's avatar
Hongzhi Wang committed
272
  if (l==2) {
cig's avatar
cig committed
273 274 275 276 277 278 279 280

    LOG_D(PHY,"Doing UE measurement procedures in symbol l %u Ncp %d nr_slot_rx %d, rxdata %p\n",
      l,
      ue->frame_parms.Ncp,
      nr_slot_rx,
      ue->common_vars.rxdata);

    nr_ue_measurements(ue, proc, nr_slot_rx);
Hongzhi Wang's avatar
Hongzhi Wang committed
281

Agustin's avatar
Agustin committed
282 283
#if T_TRACER
    if(slot == 0)
284
      T(T_UE_PHY_MEAS, T_INT(eNB_id),  T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_slot_rx),
285 286 287 288 289 290 291
	T_INT((int)(10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB)),
	T_INT((int)ue->measurements.rx_rssi_dBm[0]),
	T_INT((int)(ue->measurements.rx_power_avg_dB[0] - ue->measurements.n0_power_avg_dB)),
	T_INT((int)ue->measurements.rx_power_avg_dB[0]),
	T_INT((int)ue->measurements.n0_power_avg_dB),
	T_INT((int)ue->measurements.wideband_cqi_avg[0]),
	T_INT((int)ue->common_vars.freq_offset));
Agustin's avatar
Agustin committed
292 293 294
#endif
  }

Hongzhi Wang's avatar
Hongzhi Wang committed
295 296 297 298 299 300 301 302 303 304
  // accumulate and filter timing offset estimation every subframe (instead of every frame)
  if (( slot == 2) && (l==(2-frame_parms->Ncp))) {

    // AGC

    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_IN);


    //printf("start adjust gain power avg db %d\n", ue->measurements.rx_power_avg_dB[eNB_id]);
    phy_adjust_gain_nr (ue,ue->measurements.rx_power_avg_dB[eNB_id],eNB_id);
Hongzhi Wang's avatar
Hongzhi Wang committed
305 306
    
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT);
Hongzhi Wang's avatar
Hongzhi Wang committed
307 308 309

}

Agustin's avatar
Agustin committed
310 311 312
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_OUT);
}

313
void nr_ue_pbch_procedures(uint8_t gNB_id,
314 315 316
			   PHY_VARS_NR_UE *ue,
			   UE_nr_rxtx_proc_t *proc,
			   uint8_t abstraction_flag)
Agustin's avatar
Agustin committed
317 318
{
  //  int i;
Hongzhi Wang's avatar
Hongzhi Wang committed
319 320
  //int pbch_tx_ant=0;
  int ret = 0;
321 322
  //static uint8_t first_run = 1;
  //uint8_t pbch_trials = 0;
Agustin's avatar
Agustin committed
323 324 325 326

  DevAssert(ue);

  int frame_rx = proc->frame_rx;
327
  int nr_slot_rx = proc->nr_slot_rx;
Agustin's avatar
Agustin committed
328 329 330

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN);

331
  LOG_D(PHY,"[UE  %d] Frame %d, Trying PBCH (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,ue->frame_parms.Nid_cell,gNB_id);
332

laurent's avatar
fixes  
laurent committed
333
  ret = nr_rx_pbch(ue, proc,
334
		   ue->pbch_vars[gNB_id],
335
		   &ue->frame_parms,
336
		   gNB_id,
337
		   (ue->frame_parms.ssb_index)&7,
338 339
		   SISO,
		   ue->high_speed_flag);
Agustin's avatar
Agustin committed
340

Hongzhi Wang's avatar
Hongzhi Wang committed
341
  if (ret==0) {
342

343
    ue->pbch_vars[gNB_id]->pdu_errors_conseq = 0;
Agustin's avatar
Agustin committed
344

345
    // Switch to PRACH state if it is first PBCH after initial synch and no timing correction is performed
346
    if (ue->UE_mode[gNB_id] == NOT_SYNCHED && ue->no_timing_correction == 1){
347
      ue->UE_mode[gNB_id] = PRACH;
348 349 350
      ue->prach_resources[gNB_id]->sync_frame = frame_rx;
      ue->prach_resources[gNB_id]->init_msg1 = 0;
    }
Agustin's avatar
Agustin committed
351 352

#ifdef DEBUG_PHY_PROC
353
    uint16_t frame_tx;
354
    LOG_D(PHY,"[UE %d] frame %d, nr_slot_rx %d, Received PBCH (MIB): frame_tx %d. N_RB_DL %d\n",
Agustin's avatar
Agustin committed
355 356
    ue->Mod_id,
    frame_rx,
357
    nr_slot_rx,
Agustin's avatar
Agustin committed
358
    frame_tx,
Hongzhi Wang's avatar
Hongzhi Wang committed
359
    ue->frame_parms.N_RB_DL);
Agustin's avatar
Agustin committed
360 361 362
#endif

  } else {
363 364
    LOG_E(PHY,"[UE %d] frame %d, nr_slot_rx %d, Error decoding PBCH!\n",
	  ue->Mod_id,frame_rx, nr_slot_rx);
365 366 367 368 369 370 371 372 373 374
    /*FILE *fd;
    if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) {
                  fwrite((void *)&ue->common_vars.rxdata[0][0],
                         sizeof(int32_t),
                         ue->frame_parms.samples_per_frame,
                         fd);
                  LOG_I(PHY,"Dummping Frame ... bye bye \n");
                  fclose(fd);
                  exit(0);
                }*/
Agustin's avatar
Agustin committed
375

376
    /*
Agustin's avatar
Agustin committed
377 378 379
    write_output("rxsig0.m","rxs0", ue->common_vars.rxdata[0],ue->frame_parms.samples_per_subframe,1,1);


380 381
      write_output("H00.m","h00",&(ue->common_vars.dl_ch_estimates[0][0][0]),((ue->frame_parms.Ncp==0)?7:6)*(ue->frame_parms.ofdm_symbol_size),1,1);
      write_output("H10.m","h10",&(ue->common_vars.dl_ch_estimates[0][2][0]),((ue->frame_parms.Ncp==0)?7:6)*(ue->frame_parms.ofdm_symbol_size),1,1);
Agustin's avatar
Agustin committed
382

383 384 385 386 387
      write_output("rxsigF0.m","rxsF0", ue->common_vars.rxdataF[0],8*ue->frame_parms.ofdm_symbol_size,1,1);
      write_output("PBCH_rxF0_ext.m","pbch0_ext",ue->pbch_vars[0]->rxdataF_ext[0],12*4*6,1,1);
      write_output("PBCH_rxF0_comp.m","pbch0_comp",ue->pbch_vars[0]->rxdataF_comp[0],12*4*6,1,1);
      write_output("PBCH_rxF_llr.m","pbch_llr",ue->pbch_vars[0]->llr,(ue->frame_parms.Ncp==0) ? 1920 : 1728,1,4);
      exit(-1);
Agustin's avatar
Agustin committed
388 389
    */

390 391
    ue->pbch_vars[gNB_id]->pdu_errors_conseq++;
    ue->pbch_vars[gNB_id]->pdu_errors++;
392

393
    if (ue->pbch_vars[gNB_id]->pdu_errors_conseq>=100) {
394 395
      LOG_E(PHY,"More that 100 consecutive PBCH errors! Exiting!\n");
      exit_fun("More that 100 consecutive PBCH errors! Exiting!\n");
Agustin's avatar
Agustin committed
396 397 398 399
    }
  }

  if (frame_rx % 100 == 0) {
400 401
    ue->pbch_vars[gNB_id]->pdu_fer = ue->pbch_vars[gNB_id]->pdu_errors - ue->pbch_vars[gNB_id]->pdu_errors_last;
    ue->pbch_vars[gNB_id]->pdu_errors_last = ue->pbch_vars[gNB_id]->pdu_errors;
Agustin's avatar
Agustin committed
402 403 404 405
  }

#ifdef DEBUG_PHY_PROC
  LOG_D(PHY,"[UE %d] frame %d, slot %d, PBCH errors = %d, consecutive errors = %d!\n",
406
	ue->Mod_id,frame_rx, nr_slot_rx,
407 408
	ue->pbch_vars[gNB_id]->pdu_errors,
	ue->pbch_vars[gNB_id]->pdu_errors_conseq);
Agustin's avatar
Agustin committed
409 410 411 412 413 414
#endif
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
}



415
unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb)
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
{

  int gain_dB = power_dBm - power_max_dBm;
  double gain_lin;

  gain_lin = pow(10,.1*gain_dB);
  if ((nb_rb >0) && (nb_rb <= N_RB_UL)) {
    return((int)(AMP*sqrt(gain_lin*N_RB_UL/(double)nb_rb)));
  }
  else {
    LOG_E(PHY,"Illegal nb_rb/N_RB_UL combination (%d/%d)\n",nb_rb,N_RB_UL);
    //mac_xface->macphy_exit("");
  }
  return(0);
}

Agustin's avatar
Agustin committed
432
#ifdef NR_PDCCH_SCHED
433

434 435 436
int nr_ue_pdcch_procedures(uint8_t gNB_id,
			   PHY_VARS_NR_UE *ue,
			   UE_nr_rxtx_proc_t *proc)
Agustin's avatar
Agustin committed
437
{
438
  int frame_rx = proc->frame_rx;
439
  int nr_slot_rx = proc->nr_slot_rx;
440 441 442
  unsigned int dci_cnt=0;

  /*
Agustin's avatar
Agustin committed
443
  //  unsigned int dci_cnt=0, i;  //removed for nr_ue_pdcch_procedures and added in the loop for nb_coreset_active
444 445 446
#ifdef NR_PDCCH_SCHED_DEBUG
  printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Entering function nr_ue_pdcch_procedures() \n");
#endif
Agustin's avatar
Agustin committed
447 448

  int frame_rx = proc->frame_rx;
449
  int nr_slot_rx = proc->nr_slot_rx;
Agustin's avatar
Agustin committed
450
  NR_DCI_ALLOC_t dci_alloc_rx[8];
451
  
452
  //uint8_t next1_thread_id = proc->thread_id== (RX_NB_TH-1) ? 0:(proc->thread_id+1);
453 454
  //uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
  
Agustin's avatar
Agustin committed
455

456 457
  // table dci_fields_sizes_cnt contains dci_fields_sizes for each time a dci is decoded in the slot
  // each element represents the size in bits for each dci field, for each decoded dci -> [dci_cnt-1]
458 459
  // each time a dci is decode at dci_cnt, the values of the table dci_fields_sizes[i][j] will be copied at table dci_fields_sizes_cnt[dci_cnt-1][i][j]
  // table dci_fields_sizes_cnt[dci_cnt-1][i][j] will then be used in function nr_extract_dci_info
460
  uint8_t dci_fields_sizes_cnt[MAX_NR_DCI_DECODED_SLOT][NBR_NR_DCI_FIELDS][NBR_NR_FORMATS];
461

Agustin's avatar
Agustin committed
462
  int nb_searchspace_active=0;
463 464
  NR_UE_PDCCH **pdcch_vars = ue->pdcch_vars[proc->thread_id];
  NR_UE_PDCCH *pdcch_vars2 = ue->pdcch_vars[proc->thread_id][gNB_id];
465 466 467
  // s in TS 38.212 Subclause 10.1, for each active BWP the UE can deal with 10 different search spaces
  // Higher layers have updated the number of searchSpaces with are active in the current slot and this value is stored in variable nb_searchspace_total
  int nb_searchspace_total = pdcch_vars2->nb_search_space;
468

cig's avatar
cig committed
469
  pdcch_vars[gNB_id]->crnti = 0x1234; //to be check how to set when using loop memory
470

cig's avatar
cig committed
471
  uint16_t c_rnti=pdcch_vars[gNB_id]->crnti;
472
  uint16_t cs_rnti=0,new_rnti=0,tc_rnti=0;
473 474
  uint16_t p_rnti=P_RNTI;
  uint16_t si_rnti=SI_RNTI;
475
  uint16_t ra_rnti=99;
laurent's avatar
laurent committed
476
  uint16_t sp_csi_rnti=0,sfi_rnti=0,int_rnti=0,tpc_pusch_rnti=0,tpc_pucch_rnti=0,tpc_srs_rnti=0; //FIXME
477
  uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES] =
478
    {c_rnti,cs_rnti,new_rnti,tc_rnti,p_rnti,si_rnti,ra_rnti,sp_csi_rnti,sfi_rnti,int_rnti,tpc_pusch_rnti,tpc_pucch_rnti,tpc_srs_rnti};
479
  #ifdef NR_PDCCH_SCHED_DEBUG
480
  printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> there is a bug in FAPI to calculate nb_searchspace_total=%d\n",nb_searchspace_total);
hongzhi wang's avatar
hongzhi wang committed
481 482 483
  #endif
  if (nb_searchspace_total>1) nb_searchspace_total=1; // to be removed when fixing bug in FAPI
  #ifdef NR_PDCCH_SCHED_DEBUG
484 485
  printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> there is a bug in FAPI to calculate nb_searchspace_total so we set it to 1...\n");
  printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> the number of searchSpaces active in the current slot(%d) is %d) \n",
486
	 nr_slot_rx,nb_searchspace_total);
487
  #endif
488

489 490 491 492
  //FK: we define dci_ind and dl_indication as local variables, this way the call to the mac should be thread safe
  fapi_nr_dci_indication_t dci_ind;
  nr_downlink_indication_t dl_indication;
  
493
  // p in TS 38.212 Subclause 10.1, for each active BWP the UE can deal with 3 different CORESETs (including coresetId 0 for common search space)
494
  //int nb_coreset_total = NR_NBR_CORESET_ACT_BWP;
Guy De Souza's avatar
Guy De Souza committed
495
  unsigned int dci_cnt=0;
496
  // this table contains 56 (NBR_NR_DCI_FIELDS) elements for each dci field and format described in TS 38.212. Each element represents the size in bits for each dci field
497
  //uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS] = {{0}};
498
  // this is the UL bandwidth part. FIXME! To be defined where this value comes from
Raymond Knopp's avatar
Raymond Knopp committed
499
  //  uint16_t n_RB_ULBWP = 106;
500
  // this is the DL bandwidth part. FIXME! To be defined where this value comes from
Agustin's avatar
Agustin committed
501 502 503 504

  // First we have to identify each searchSpace active at a time and do PDCCH monitoring corresponding to current searchSpace
  // Up to 10 searchSpaces can be configured to UE (s<=10)
  for (nb_searchspace_active=0; nb_searchspace_active<nb_searchspace_total; nb_searchspace_active++){
505
    int nb_coreset_active=nb_searchspace_active;
506
    //int do_pdcch_monitoring_current_slot=1; // this variable can be removed and fapi is handling
507 508 509
    
     // The following code has been removed as it is handled by higher layers (fapi)
     //
510
     // Verify that monitoring is required at the slot nr_slot_rx. We will run pdcch procedure only if do_pdcch_monitoring_current_slot=1
511
     // For Type0-PDCCH searchspace, we need to calculate the monitoring slot from Tables 13-1 .. 13-15 in TS 38.213 Subsection 13
512 513 514
     //NR_UE_SLOT_PERIOD_OFFSET_t sl_period_offset_mon = pdcch_vars2->searchSpace[nb_searchspace_active].monitoringSlotPeriodicityAndOffset;
     //if (sl_period_offset_mon == nr_sl1) {
     //do_pdcch_monitoring_current_slot=1; // PDCCH monitoring in every slot
515
     //} else if (nr_slot_rx%(uint16_t)sl_period_offset_mon == pdcch_vars2->searchSpace[nb_searchspace_active].monitoringSlotPeriodicityAndOffset_offset) {
516 517 518 519 520 521 522
     //do_pdcch_monitoring_current_slot=1; // PDCCH monitoring in every monitoringSlotPeriodicityAndOffset slot with offset
     //}
    
     // FIXME
     // For PDCCH monitoring when overlap with SS/PBCH according to 38.213 v15.1.0 Section 10
     // To be implemented LATER !!!
     
523
    //int _offset,_index,_M;
524
    //int searchSpace_id                              = pdcch_vars2->searchSpace[nb_searchspace_active].searchSpaceId;
525 526


Agustin's avatar
Agustin committed
527
    #ifdef NR_PDCCH_SCHED_DEBUG
528
      printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> nb_searchspace_active=%d do_pdcch_monitoring_current_slot=%d (to be removed)\n",
Agustin's avatar
Agustin committed
529 530 531 532
              nb_searchspace_active,
              do_pdcch_monitoring_current_slot);
    #endif

533
//    if (do_pdcch_monitoring_current_slot) {
534
      // the searchSpace indicates that we need to monitor PDCCH in current nr_slot_rx
Agustin's avatar
Agustin committed
535 536
      // get the parameters describing the current SEARCHSPACE
      // the CORESET id applicable to the current SearchSpace
537
      //int searchSpace_coreset_id                      = pdcch_vars2->searchSpace[nb_searchspace_active].controlResourceSetId;
Agustin's avatar
Agustin committed
538 539 540 541
      // FIXME this variable is a bit string (14 bits) identifying every OFDM symbol in a slot.
      // at the moment we will not take into consideration this variable and we will consider that the OFDM symbol offset is always the first OFDM in a symbol
      uint16_t symbol_within_slot_mon                 = pdcch_vars2->searchSpace[nb_searchspace_active].monitoringSymbolWithinSlot;
      // get the remaining parameters describing the current SEARCHSPACE:     // FIXME! To be defined where we get this information from
542 543 544 545 546
      //NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L1         = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel1;
      //NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L2         = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel2;
      //NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L4         = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel4;
      //NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L8         = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel8;
      //NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L16        = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel16;
Agustin's avatar
Agustin committed
547 548
                                                                                                  // FIXME! A table of five enum elements
      // searchSpaceType indicates whether this is a common search space or a UE-specific search space
549
      //int searchSpaceType                             = pdcch_vars2->searchSpace[nb_searchspace_active].searchSpaceType.type;
550
      NR_SEARCHSPACE_TYPE_t searchSpaceType                             = ue_specific;//common;
551 552 553 554 555
      #ifdef NR_PDCCH_SCHED_DEBUG
        printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> searchSpaceType=%d is hardcoded THIS HAS TO BE FIXED!!!\n",
                searchSpaceType);
      #endif

556
      //while ((searchSpace_coreset_id != pdcch_vars2->coreset[nb_coreset_active].controlResourceSetId) && (nb_coreset_active<nb_coreset_total)) {
Agustin's avatar
Agustin committed
557
        // we need to identify the CORESET associated to the active searchSpace
558
        //nb_coreset_active++;
Agustin's avatar
Agustin committed
559
      if (nb_coreset_active >= nb_coreset_total) return 0; // the coreset_id could not be found. There is a problem
560
      }
561

Agustin's avatar
Agustin committed
562

563 564 565
    
     //we do not need these parameters yet
    
566
     // get the parameters describing the current CORESET
567 568 569 570 571 572 573 574 575 576
     //int coreset_duration                                      = pdcch_vars2->coreset[nb_coreset_active].duration;
     //uint64_t coreset_freq_dom                                 = pdcch_vars2->coreset[nb_coreset_active].frequencyDomainResources;
     //int coreset_shift_index                                   = pdcch_vars2->coreset[nb_coreset_active].cce_reg_mappingType.shiftIndex;
    // NR_UE_CORESET_REG_bundlesize_t coreset_bundlesize         = pdcch_vars2->coreset[nb_coreset_active].cce_reg_mappingType.reg_bundlesize;
    // NR_UE_CORESET_interleaversize_t coreset_interleaversize   = pdcch_vars2->coreset[nb_coreset_active].cce_reg_mappingType.interleaversize;
    // NR_UE_CORESET_precoder_granularity_t precoder_granularity = pdcch_vars2->coreset[nb_coreset_active].precoderGranularity;
    // int tci_statesPDCCH                                       = pdcch_vars2->coreset[nb_coreset_active].tciStatesPDCCH;
    // int tci_present                                           = pdcch_vars2->coreset[nb_coreset_active].tciPresentInDCI;
    // uint16_t pdcch_DMRS_scrambling_id                         = pdcch_vars2->coreset[nb_coreset_active].pdcchDMRSScramblingID;
    
Agustin's avatar
Agustin committed
577

578 579 580 581 582 583 584 585 586 587 588 589 590 591
    // A set of PDCCH candidates for a UE to monitor is defined in terms of PDCCH search spaces.
    // Searchspace types:
    // Type0-PDCCH  common search space for a DCI format with CRC scrambled by a SI-RNTI
    // number of consecutive resource blocks and a number of consecutive symbols for
    // the control resource set of the Type0-PDCCH common search space from
    // the four most significant bits of RMSI-PDCCH-Config as described in Tables 13-1 through 13-10
    // and determines PDCCH monitoring occasions
    // from the four least significant bits of RMSI-PDCCH-Config,
    // included in MasterInformationBlock, as described in Tables 13-11 through 13-15
    // Type0A-PDCCH common search space for a DCI format with CRC scrambled by a SI-RNTI
    // Type1-PDCCH  common search space for a DCI format with CRC scrambled by a RA-RNTI, or a TC-RNTI, or a C-RNTI
    // Type2-PDCCH  common search space for a DCI format with CRC scrambled by a P-RNTI
    // Type3-PDCCH  common search space for a DCI format with CRC scrambled by INT-RNTI, or SFI-RNTI,
    // or TPC-PUSCH-RNTI, or TPC-PUCCH-RNTI, or TPC-SRS-RNTI, or C-RNTI, or CS-RNTI(s), or SP-CSI-RNTI
Agustin's avatar
Agustin committed
592 593 594



595
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_IN);
Agustin's avatar
Agustin committed
596
#if UE_TIMING_TRACE
597
      start_meas(&ue->dlsch_rx_pdcch_stats);
Agustin's avatar
Agustin committed
598 599
#endif

600 601
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN);
#ifdef NR_PDCCH_SCHED_DEBUG
cig's avatar
cig committed
602 603
      printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Entering function nr_rx_pdcch with gNB_id=%d (nb_coreset_active=%d, (symbol_within_slot_mon&0x3FFF)=%d, searchSpaceType=%d)\n",
                  gNB_id,nb_coreset_active,(symbol_within_slot_mon&0x3FFF),
Agustin's avatar
Agustin committed
604
                  searchSpaceType);
605
#endif
Agustin's avatar
Agustin committed
606
        nr_rx_pdcch(ue,
607 608
                    frame_rx,
                    nr_slot_rx,
cig's avatar
cig committed
609
                    gNB_id,
610
                    //(ue->frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI,
Agustin's avatar
Agustin committed
611 612 613 614 615 616
                    SISO,
                    ue->high_speed_flag,
                    ue->is_secondary_ue,
                    nb_coreset_active,
                    (symbol_within_slot_mon&0x3FFF),
                    searchSpaceType);
617
#ifdef NR_PDCCH_SCHED_DEBUG
618 619
          printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_rx_pdcch(nb_coreset_active=%d, (symbol_within_slot_mon&0x3FFF)=%d, searchSpaceType=%d)\n",
                  nb_coreset_active,(symbol_within_slot_mon&0x3FFF),
Agustin's avatar
Agustin committed
620
                  searchSpaceType);
621 622
#endif

623 624 625
  */
  
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN);
626
  nr_rx_pdcch(ue, proc);
627 628
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_OUT);
  
Agustin's avatar
Agustin committed
629

630
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_IN);
Guy De Souza's avatar
Guy De Souza committed
631

632
#ifdef NR_PDCCH_SCHED_DEBUG
633 634
  printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Entering function nr_dci_decoding_procedure with (nb_searchspace_active=%d)\n",
	 pdcch_vars->nb_search_space);
635
#endif
hongzhi wang's avatar
hongzhi wang committed
636

laurent's avatar
laurent committed
637 638
  fapi_nr_dci_indication_t dci_ind={0};
  nr_downlink_indication_t dl_indication={0};
639
  dci_cnt = nr_dci_decoding_procedure(ue, proc, &dci_ind);
640

641
#ifdef NR_PDCCH_SCHED_DEBUG
642
  LOG_I(PHY,"<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_dci_decoding_procedure() -> dci_cnt=%u\n",dci_cnt);
643
#endif
644 645
  
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_OUT);
646
  //LOG_D(PHY,"[UE  %d][PUSCH] Frame %d nr_slot_rx %d PHICH RX\n",ue->Mod_id,frame_rx,nr_slot_rx);
647 648

  for (int i=0; i<dci_cnt; i++) {
cig's avatar
cig committed
649
    LOG_D(PHY,"[UE  %d] AbsSubFrame %d.%d, Mode %s: DCI %i of %d total DCIs found --> rnti %x : format %d\n",
650
      ue->Mod_id,frame_rx%1024,nr_slot_rx,nr_mode_string[ue->UE_mode[gNB_id]],
cig's avatar
cig committed
651 652 653 654
      i + 1,
      dci_cnt,
      dci_ind.dci_list[i].rnti,
      dci_ind.dci_list[i].dci_format);
655
  }
656
  ue->pdcch_vars[proc->thread_id][gNB_id]->dci_received += dci_cnt;
657

cig's avatar
cig committed
658
  dci_ind.number_of_dcis = dci_cnt;
659
    /*
660
    for (int i=0; i<dci_cnt; i++) {
661
      
662
	memset(&dci_ind.dci_list[i].dci,0,sizeof(fapi_nr_dci_pdu_rel15_t));
663
	
664 665 666 667
	dci_ind.dci_list[i].rnti = dci_alloc_rx[i].rnti;
	dci_ind.dci_list[i].dci_format = dci_alloc_rx[i].format;
	dci_ind.dci_list[i].n_CCE = dci_alloc_rx[i].firstCCE;
	dci_ind.dci_list[i].N_CCE = (int)dci_alloc_rx[i].L;
668 669
	
	status = nr_extract_dci_info(ue,
cig's avatar
cig committed
670
				     gNB_id,
671 672 673 674
				     ue->frame_parms.frame_type,
				     dci_alloc_rx[i].dci_length,
				     dci_alloc_rx[i].rnti,
				     dci_alloc_rx[i].dci_pdu,
675
				     &dci_ind.dci_list[i].dci,
676
				     dci_fields_sizes_cnt[i],
677
				     dci_alloc_rx[i].format,
678
				     nr_slot_rx,
679 680 681
				     pdcch_vars2->n_RB_BWP[nb_searchspace_active],
				     pdcch_vars2->n_RB_BWP[nb_searchspace_active],
				     crc_scrambled_values);
682
	
683 684 685 686 687 688
	if(status == 0) {
	  LOG_W(PHY,"<-NR_PDCCH_PHY_PROCEDURES_UE (nr_ue_pdcch_procedures)-> bad DCI %d !!! \n",dci_alloc_rx[i].format);
	  return(-1);
	}
	
	LOG_D(PHY,"<-NR_PDCCH_PHY_PROCEDURES_UE (nr_ue_pdcch_procedures)-> Ending function nr_extract_dci_info()\n");
689
	
Agustin's avatar
Agustin committed
690

691
        
Agustin's avatar
Agustin committed
692
      } // end for loop dci_cnt
693
    */
Agustin's avatar
Agustin committed
694

695
    // fill dl_indication message
696 697
    dl_indication.module_id = ue->Mod_id;
    dl_indication.cc_id = ue->CC_id;
698
    dl_indication.gNB_index = gNB_id;
699
    dl_indication.frame = frame_rx;
700 701
    dl_indication.slot = nr_slot_rx;
    dl_indication.thread_id = proc->thread_id;
702 703
    dl_indication.rx_ind = NULL; //no data, only dci for now
    dl_indication.dci_ind = &dci_ind; 
704 705
    
    //  send to mac
706
    ue->if_inst->dl_indication(&dl_indication, NULL);
707

Agustin's avatar
Agustin committed
708 709 710
#if UE_TIMING_TRACE
  stop_meas(&ue->dlsch_rx_pdcch_stats);
#endif
711 712
    
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
713
  return(dci_cnt);
Agustin's avatar
Agustin committed
714
}
715
#endif // NR_PDCCH_SCHED
716

717
int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, PDSCH_t pdsch, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1) {
Agustin's avatar
Agustin committed
718

719 720
  int frame_rx = proc->frame_rx;
  int nr_slot_rx = proc->nr_slot_rx;
Agustin's avatar
Agustin committed
721 722 723 724
  int m;
  int i_mod,eNB_id_i,dual_stream_UE;
  int first_symbol_flag=0;

725
  if (!dlsch0)
726
    return 0;
Agustin's avatar
Agustin committed
727
  if (dlsch0->active == 0)
728
    return 0;
Agustin's avatar
Agustin committed
729

730
  if (!dlsch1)  {
731
    int harq_pid = dlsch0->current_harq_pid;
732
    NR_DL_UE_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid];
733 734 735 736 737
    uint16_t BWPStart       = dlsch0_harq->BWPStart;
    uint16_t pdsch_start_rb = dlsch0_harq->start_rb;
    uint16_t pdsch_nb_rb    = dlsch0_harq->nb_rb;
    uint16_t s0             = dlsch0_harq->start_symbol;
    uint16_t s1             = dlsch0_harq->nb_symbols;
738

739
    LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_slot_rx,harq_pid,dlsch0->harq_processes[harq_pid]->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos);
Agustin's avatar
Agustin committed
740

741
    for (m = s0; m < (s0 +s1); m++) {
742
      if (((1<<m)&dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos) > 0) {
743 744
        for (uint8_t aatx=0; aatx<1; aatx++) {//for MIMO Config: it shall loop over no_layers
          nr_pdsch_channel_estimation(ue,
745
                                      proc,
746
                                      0 /*eNB_id*/,
747
                                      nr_slot_rx,
748 749
                                      aatx /*p*/,
                                      m,
rmagueta's avatar
rmagueta committed
750
                                      BWPStart,
751 752
                                      ue->frame_parms.first_carrier_offset+(BWPStart + pdsch_start_rb)*12,
                                      pdsch_nb_rb);
753
          LOG_D(PHY,"PDSCH Channel estimation gNB id %d, PDSCH antenna port %d, slot %d, symbol %d\n",0,aatx,nr_slot_rx,m);
754 755 756 757 758
#if 0
          ///LOG_M: the channel estimation
          int nr_frame_rx = proc->frame_rx;
          char filename[100];
          for (uint8_t aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
759
            sprintf(filename,"PDSCH_CHANNEL_frame%d_slot%d_sym%d_port%d_rx%d.m", nr_frame_rx, nr_slot_rx, m, aatx,aarx);
760
            int **dl_ch_estimates = ue->pdsch_vars[proc->thread_id][eNB_id]->dl_ch_estimates;
761 762 763 764
            LOG_M(filename,"channel_F",&dl_ch_estimates[aatx*ue->frame_parms.nb_antennas_rx+aarx][ue->frame_parms.ofdm_symbol_size*m],ue->frame_parms.ofdm_symbol_size, 1, 1);
          }
#endif
        }
765 766
        if ( ue->high_speed_flag == 0 ) //for slow speed case only estimate the channel once per slot
          break;
767 768
      }
    }
769 770

    uint16_t first_symbol_with_data = s0;
771 772 773 774 775 776 777 778 779
    uint32_t dmrs_data_re;

    if (ue->dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type1)
      dmrs_data_re = 12 - 6 * dlsch0_harq->n_dmrs_cdm_groups;
    else
      dmrs_data_re = 12 - 4 * dlsch0_harq->n_dmrs_cdm_groups;

    while ((dmrs_data_re == 0) && (dlsch0_harq->dlDmrsSymbPos & (1 << first_symbol_with_data))) {
      first_symbol_with_data++;
780 781
    }

782 783
    for (m = s0; m < (s1 + s0); m++) {
 
784 785 786
      dual_stream_UE = 0;
      eNB_id_i = eNB_id+1;
      i_mod = 0;
787
      if (( m==first_symbol_with_data ) && (m<4))
788
        first_symbol_flag = 1;
Agustin's avatar
Agustin committed
789
      else
790
        first_symbol_flag = 0;
791

Agustin's avatar
Agustin committed
792 793
#if UE_TIMING_TRACE
      uint8_t slot = 0;
794
      if(m >= ue->frame_parms.symbols_per_slot>>1)
Agustin's avatar
Agustin committed
795
        slot = 1;
796
      start_meas(&ue->dlsch_llr_stats_parallelization[proc->thread_id][slot]);
Agustin's avatar
Agustin committed
797 798
#endif
      // process DLSCH received in first slot
799
      // skip DMRS symbols (will have to check later if PDSCH/DMRS are multiplexed
800
      if (((1<<m)&dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos) == 0) { 
801
        if (nr_rx_pdsch(ue,
802 803 804 805 806 807 808 809 810 811 812
                    proc,
                    pdsch,
                    eNB_id,
                    eNB_id_i,
                    frame_rx,
                    nr_slot_rx,
                    m,
                    first_symbol_flag,
                    dual_stream_UE,
                    i_mod,
                    dlsch0->current_harq_pid) < 0)
813
                      return -1;
814
        }
815
      else { // This is to adjust the llr offset in the case of skipping over a dmrs symbol (i.e. in case of no PDSCH REs in DMRS)
816
        if (pdsch == RA_PDSCH) ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m]=ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m-1];
817
        else if (pdsch == PDSCH || pdsch == SI_PDSCH) {
818
          if (nr_rx_pdsch(ue,
819
                    proc,
820 821 822
                    pdsch,
                    eNB_id,
                    eNB_id_i,
823 824
                    frame_rx,
                    nr_slot_rx,
825 826 827 828 829 830 831
                    m,
                    first_symbol_flag,
                    dual_stream_UE,
                    i_mod,
                    dlsch0->current_harq_pid) < 0)
                      return -1;
        }
832
        else AssertFatal(1==0,"Not RA_PDSCH, SI_PDSCH or PDSCH\n");
833
      }
834
      if (pdsch == PDSCH)  LOG_D(PHY,"Done processing symbol %d : llr_offset %d\n",m,ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m]);
Agustin's avatar
Agustin committed
835
#if UE_TIMING_TRACE
836
      stop_meas(&ue->dlsch_llr_stats_parallelization[proc->thread_id][slot]);
Agustin's avatar
Agustin committed
837
#if DISABLE_LOG_X
838
      printf("[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",frame_rx,nr_slot_rx,m,ue->dlsch_llr_stats_parallelization[proc->thread_id][slot].p_time/(cpuf*1000.0));
Agustin's avatar
Agustin committed
839
#else
840
      LOG_D(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",frame_rx,nr_slot_rx,m,ue->dlsch_llr_stats_parallelization[proc->thread_id][slot].p_time/(cpuf*1000.0));
Agustin's avatar
Agustin committed
841 842 843 844
#endif
#endif

      if(first_symbol_flag)
845
	{
Agustin's avatar
Agustin committed
846
          proc->first_symbol_available = 1;
847
	}
Agustin's avatar
Agustin committed
848 849
    } // CRNTI active
  }
850
  return 0;
Agustin's avatar
Agustin committed
851 852
}

cig's avatar
cig committed
853
// WIP fix:
cig's avatar
cig committed
854 855 856 857 858 859 860
// - time domain indication hardcoded to 0 for k2 offset
// - extend TS 38.213 ch 8.3 Msg3 PUSCH
// - b buffer
// - ulsch power offset
// - UE_mode == PUSCH case (should be handled by TA updates)
// - harq
// - optimize: mu_pusch, j and table_6_1_2_1_1_2_time_dom_res_alloc_A are already defined in nr_ue_procedures
cig's avatar
cig committed
861
void nr_process_rar(nr_downlink_indication_t *dl_info) {
862

cig's avatar
cig committed
863
  module_id_t module_id = dl_info->module_id;
864
  int cc_id = dl_info->cc_id, frame_rx = dl_info->frame, nr_slot_rx = dl_info->slot, ta_command;
cig's avatar
cig committed
865
  uint8_t gNB_index = dl_info->gNB_index; // *rar;
cig's avatar
cig committed
866 867 868 869
  PHY_VARS_NR_UE *ue = PHY_vars_UE_g[module_id][cc_id];
  NR_UE_DLSCH_t *dlsch0 = ue->dlsch_ra[gNB_index];
  UE_MODE_t UE_mode = ue->UE_mode[gNB_index];
  NR_PRACH_RESOURCES_t *prach_resources = ue->prach_resources[gNB_index];
Agustin's avatar
Agustin committed
870

871
  LOG_D(PHY,"[UE %d][RAPROC] Frame %d slot %d Received RAR mode %d\n", module_id, frame_rx, nr_slot_rx, UE_mode);
Agustin's avatar
Agustin committed
872 873

  if (ue->mac_enabled == 1) {
cig's avatar
cig committed
874 875
    if ((UE_mode != PUSCH) && (prach_resources->Msg3 != NULL)) {

876
      LOG_D(PHY,"[UE %d][RAPROC] Frame %d slot %d Invoking MAC for RAR (current preamble %d)\n", module_id, frame_rx, nr_slot_rx, prach_resources->ra_PreambleIndex);
cig's avatar
cig committed
877

cig's avatar
cig committed
878 879 880
      ta_command = nr_ue_process_rar(ue->Mod_id,
                                     cc_id,
                                     frame_rx,
881
                                     nr_slot_rx,
cig's avatar
cig committed
882
                                     dlsch0->harq_processes[0]->b,
883
                                     &ue->pdcch_vars[dl_info->thread_id][gNB_index]->pdcch_config[0].rnti,
cig's avatar
cig committed
884 885 886
                                     prach_resources->ra_PreambleIndex,
                                     dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload

cig's avatar
cig committed
887
      if (ta_command != 0xffff) {
888
        LOG_D(PHY,"[UE %d][RAPROC] Frame %d slot %d Got Temporary C-RNTI %x and timing advance %d from RAR\n",
cig's avatar
cig committed
889 890
          ue->Mod_id,
          frame_rx,
891 892
          nr_slot_rx,
          ue->pdcch_vars[dl_info->thread_id][gNB_index]->pdcch_config[0].rnti,
cig's avatar
cig committed
893 894
          ta_command);

895
        nr_process_timing_advance_rar(ue, frame_rx, nr_slot_rx, ta_command);
cig's avatar
cig committed
896

cig's avatar
cig committed
897
        if (ue->mode != debug_prach)
cig's avatar
cig committed
898
          ue->UE_mode[gNB_index] = RA_RESPONSE;
cig's avatar
cig committed
899

cig's avatar
cig committed
900 901
      } else {
        LOG_W(PHY,"[UE %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n", ue->Mod_id, prach_resources->ra_PreambleIndex);
Agustin's avatar
Agustin committed
902
      }
cig's avatar
cig committed
903
    }
cig's avatar
cig committed
904
  } else {
cig's avatar
cig committed
905 906
    // rar = dlsch0->harq_processes[0]->b+1;
    // ta_command = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4));
907
    // nr_process_timing_advance_rar(ue, frame_rx, nr_slot_rx, ta_command);
Agustin's avatar
Agustin committed
908
  }
cig's avatar
cig committed
909 910
}

911 912 913 914 915 916 917 918 919 920 921
// if contention resolution fails, go back to UE mode PRACH
void nr_ra_failed(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index) {

  PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
  ue->UE_mode[gNB_index] = PRACH;

  for (int i=0; i <RX_NB_TH_MAX; i++ ) {
    ue->pdcch_vars[i][gNB_index]->pdcch_config[0].rnti = 0;
  }
  LOG_E(PHY,"[UE %d] [RAPROC] Random-access procedure fails, going back to PRACH\n", Mod_id);
}
Agustin's avatar
Agustin committed
922

923 924 925 926 927 928 929 930 931
void nr_ra_succeeded(uint8_t Mod_id,
                     uint8_t CC_id,
                     uint8_t gNB_index){
  LOG_I(PHY,"[UE %d][RAPROC] RA procedure succeeded. UE set to PUSCH mode\n", Mod_id);
  PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
  ue->ulsch_Msg3_active[gNB_index] = 0;
  ue->UE_mode[gNB_index] = PUSCH;
}

Hongzhi Wang's avatar
Hongzhi Wang committed
932
void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
933 934 935 936 937 938 939
       UE_nr_rxtx_proc_t *proc,
       int eNB_id,
       PDSCH_t pdsch,
       NR_UE_DLSCH_t *dlsch0,
       NR_UE_DLSCH_t *dlsch1,
       int *dlsch_errors,
       runmode_t mode) {
Agustin's avatar
Agustin committed
940

941 942 943
  if (dlsch0==NULL)
    AssertFatal(0,"dlsch0 should be defined at this level \n");

Francesco Mani's avatar
Francesco Mani committed
944
  int harq_pid = dlsch0->current_harq_pid;
Agustin's avatar
Agustin committed
945
  int frame_rx = proc->frame_rx;
946
  int nr_slot_rx = proc->nr_slot_rx;
Agustin's avatar
Agustin committed
947 948 949 950
  int ret=0, ret1=0;
  NR_UE_PDSCH *pdsch_vars;
  uint8_t is_cw0_active = 0;
  uint8_t is_cw1_active = 0;
951
  uint8_t dmrs_type, nb_re_dmrs;
952
  uint16_t dmrs_len = get_num_dmrs(dlsch0->harq_processes[dlsch0->current_harq_pid]->dlDmrsSymbPos);
953
  uint16_t nb_symb_sch = 9;
954 955
  nr_downlink_indication_t dl_indication;
  fapi_nr_rx_indication_t rx_ind;
956 957 958
  // params for UL time alignment procedure
  NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[eNB_id];
  uint16_t slots_per_frame = ue->frame_parms.slots_per_frame;
959 960
  uint16_t slots_per_subframe = ue->frame_parms.slots_per_subframe;
  uint8_t numerology = ue->frame_parms.numerology_index, mapping_type_ul, mapping_type_dl;
Raphael Defosseux's avatar
Raphael Defosseux committed
961
  int ul_tx_timing_adjustment, N_TA_max, factor_mu, N_t_1, N_t_2, N_1, N_2, d_1_1 = 0, d_2_1, d;
962 963 964 965 966 967
  uint8_t d_2_2 = 0;// set to 0 because there is only 1 BWP
                    // TODO this should corresponds to the switching time as defined in
                    // TS 38.133
  uint16_t ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size;
  uint16_t nb_prefix_samples = ue->frame_parms.nb_prefix_samples;
  uint32_t t_subframe = 1; // subframe duration of 1 msec
968
  uint16_t start_symbol;
969
  float tc_factor;
Agustin's avatar
Agustin committed
970 971

  is_cw0_active = dlsch0->harq_processes[harq_pid]->status;
972
  nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols;
973
  start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol;
974 975 976 977 978 979 980
  dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType;
  if (dmrs_type==NFAPI_NR_DMRS_TYPE1) {
    nb_re_dmrs = 6*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups;
  }
  else {
    nb_re_dmrs = 4*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups;
  }
981

Agustin's avatar
Agustin committed
982 983 984
  if(dlsch1)
    is_cw1_active = dlsch1->harq_processes[harq_pid]->status;

985 986
  LOG_D(PHY,"AbsSubframe %d.%d Start LDPC Decoder for CW0 [harq_pid %d] ? %d \n", frame_rx%1024, nr_slot_rx, harq_pid, is_cw0_active);
  LOG_D(PHY,"AbsSubframe %d.%d Start LDPC Decoder for CW1 [harq_pid %d] ? %d \n", frame_rx%1024, nr_slot_rx, harq_pid, is_cw1_active);
Agustin's avatar
Agustin committed
987 988

  if(is_cw0_active && is_cw1_active)
989
    {
Agustin's avatar
Agustin committed
990 991
      dlsch0->Kmimo = 2;
      dlsch1->Kmimo = 2;
992
    }
Agustin's avatar
Agustin committed
993
  else
994
    {
Agustin's avatar
Agustin committed
995
      dlsch0->Kmimo = 1;
996
    }
Agustin's avatar
Agustin committed
997 998 999 1000 1001 1002
  if (1) {
    switch (pdsch) {
    case SI_PDSCH:
    case RA_PDSCH:
    case P_PDSCH:
    case PDSCH:
1003
      pdsch_vars = ue->pdsch_vars[proc->thread_id][eNB_id];
Agustin's avatar
Agustin committed
1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019
      break;
    case PMCH:
    case PDSCH1:
      LOG_E(PHY,"Illegal PDSCH %d for ue_pdsch_procedures\n",pdsch);
      pdsch_vars = NULL;
      return;
      break;
    default:
      pdsch_vars = NULL;
      return;
      break;

    }
    if (frame_rx < *dlsch_errors)
      *dlsch_errors=0;

1020
    if (pdsch == RA_PDSCH) {
Agustin's avatar
Agustin committed
1021
      if (ue->prach_resources[eNB_id]!=NULL)
1022
	      dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
Agustin's avatar
Agustin committed
1023
      else {
1024
	      LOG_E(PHY,"[UE %d] Frame %d, nr_slot_rx %d: FATAL, prach_resources is NULL\n", ue->Mod_id, frame_rx, nr_slot_rx);
1025 1026
	      //mac_xface->macphy_exit("prach_resources is NULL");
	      return;
Agustin's avatar
Agustin committed
1027 1028 1029
      }
    }

1030 1031 1032
    // exit dlsch procedures as there are no active dlsch
    if (is_cw0_active != ACTIVE && is_cw1_active != ACTIVE)
      return;
Agustin's avatar
Agustin committed
1033

Francesco Mani's avatar
Francesco Mani committed
1034 1035 1036 1037
    // start ldpc decode for CW 0
    dlsch0->harq_processes[harq_pid]->G = nr_get_G(dlsch0->harq_processes[harq_pid]->nb_rb,
                                                   nb_symb_sch,
                                                   nb_re_dmrs,
1038
                                                   dmrs_len,
Francesco Mani's avatar
Francesco Mani committed
1039 1040
                                                   dlsch0->harq_processes[harq_pid]->Qm,
                                                   dlsch0->harq_processes[harq_pid]->Nl);
Agustin's avatar
Agustin committed
1041 1042 1043
#if UE_TIMING_TRACE
      start_meas(&ue->dlsch_unscrambling_stats);
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
1044
      nr_dlsch_unscrambling(pdsch_vars->llr[0],
cig's avatar
cig committed
1045 1046 1047 1048
                            dlsch0->harq_processes[harq_pid]->G,
                            0,
                            ue->frame_parms.Nid_cell,
                            dlsch0->rnti);
1049
      
Hongzhi Wang's avatar
Hongzhi Wang committed
1050

Agustin's avatar
Agustin committed
1051 1052 1053 1054 1055
#if UE_TIMING_TRACE
      stop_meas(&ue->dlsch_unscrambling_stats);
#endif

#if 0
1056 1057 1058 1059 1060 1061 1062 1063
      LOG_I(PHY," ------ start ldpc decoder for AbsSubframe %d.%d / %d  ------  \n", frame_rx, nr_slot_rx, harq_pid);
      LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb);
      LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> rb_alloc_even %x \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->rb_alloc_even);
      LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> Qm %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Qm);
      LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl);
      LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G);
      LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->Kmimo);
      LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][eNB_id]->num_pdcch_symbols);
Agustin's avatar
Agustin committed
1064 1065 1066
#endif

#if UE_TIMING_TRACE
1067
      start_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
Agustin's avatar
Agustin committed
1068 1069 1070
#endif

#ifdef UE_DLSCH_PARALLELISATION
1071 1072 1073
		 ret = nr_dlsch_decoding_mthread(ue,
			   proc,
			   eNB_id,
Agustin's avatar
Agustin committed
1074 1075 1076 1077 1078
			   pdsch_vars->llr[0],
			   &ue->frame_parms,
			   dlsch0,
			   dlsch0->harq_processes[harq_pid],
			   frame_rx,
Hongzhi Wang's avatar
Hongzhi Wang committed
1079
			   nb_symb_sch,
1080
			   nr_slot_rx,
Agustin's avatar
Agustin committed
1081 1082 1083
			   harq_pid,
			   pdsch==PDSCH?1:0,
			   dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
1084
		 LOG_T(PHY,"UE_DLSCH_PARALLELISATION is defined, ret = %d\n", ret);
Agustin's avatar
Agustin committed
1085
#else
Hongzhi Wang's avatar
Hongzhi Wang committed
1086
      ret = nr_dlsch_decoding(ue,
1087 1088
			   proc,
			   eNB_id,
Agustin's avatar
Agustin committed
1089 1090 1091 1092 1093
			   pdsch_vars->llr[0],
			   &ue->frame_parms,
			   dlsch0,
			   dlsch0->harq_processes[harq_pid],
			   frame_rx,
Hongzhi Wang's avatar
Hongzhi Wang committed
1094
			   nb_symb_sch,
1095
			   nr_slot_rx,
Agustin's avatar
Agustin committed
1096
			   harq_pid,
1097
			   pdsch==PDSCH?1:0,
Agustin's avatar
Agustin committed
1098
			   dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
1099
      LOG_T(PHY,"UE_DLSCH_PARALLELISATION is NOT defined, ret = %d\n", ret);
Agustin's avatar
Agustin committed
1100 1101 1102 1103
      //printf("start cW0 dlsch decoding\n");
#endif

#if UE_TIMING_TRACE
1104
      stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
Agustin's avatar
Agustin committed
1105 1106 1107
#if DISABLE_LOG_X
      printf(" --> Unscrambling for CW0 %5.3f\n",
              (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
Hongzhi Wang's avatar
Hongzhi Wang committed
1108
      printf("AbsSubframe %d.%d --> LDPC Decoding for CW0 %5.3f\n",
1109
              frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0));
Agustin's avatar
Agustin committed
1110 1111 1112
#else
      LOG_I(PHY, " --> Unscrambling for CW0 %5.3f\n",
              (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
Hongzhi Wang's avatar
Hongzhi Wang committed
1113
      LOG_I(PHY, "AbsSubframe %d.%d --> LDPC Decoding for CW0 %5.3f\n",
1114
              frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0));
Agustin's avatar
Agustin committed
1115 1116 1117 1118 1119
#endif

#endif
      if(is_cw1_active)
      {
Hongzhi Wang's avatar
Hongzhi Wang committed
1120
          // start ldpc decode for CW 1
1121 1122 1123 1124 1125
        dlsch1->harq_processes[harq_pid]->G = nr_get_G(dlsch1->harq_processes[harq_pid]->nb_rb,
                                                       nb_symb_sch,
                                                       nb_re_dmrs,
                                                       dmrs_len,
                                                       dlsch1->harq_processes[harq_pid]->Qm,
1126
							 dlsch1->harq_processes[harq_pid]->Nl);
Agustin's avatar
Agustin committed
1127 1128 1129
#if UE_TIMING_TRACE
          start_meas(&ue->dlsch_unscrambling_stats);
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
1130
          nr_dlsch_unscrambling(pdsch_vars->llr[1],
cig's avatar
cig committed
1131 1132 1133 1134
                                dlsch1->harq_processes[harq_pid]->G,
                                0,
                                ue->frame_parms.Nid_cell,
                                dlsch1->rnti);
Agustin's avatar
Agustin committed
1135 1136 1137 1138 1139
#if UE_TIMING_TRACE
          stop_meas(&ue->dlsch_unscrambling_stats);
#endif

#if 0
1140 1141 1142 1143 1144 1145 1146
          LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->nb_rb);
          LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> rb_alloc_even %x \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->rb_alloc_even);
          LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> Qm %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Qm);
          LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Nl);
          LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->G);
          LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->Kmimo);
          LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][eNB_id]->num_pdcch_symbols);
Agustin's avatar
Agustin committed
1147 1148 1149
#endif

#if UE_TIMING_TRACE
1150
          start_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
Agustin's avatar
Agustin committed
1151 1152 1153
#endif

#ifdef UE_DLSCH_PARALLELISATION
1154
          ret1 = nr_dlsch_decoding_mthread(ue,
cig's avatar
cig committed
1155 1156 1157 1158 1159 1160 1161 1162
                                           proc,
                                           eNB_id,
                                           pdsch_vars->llr[1],
                                           &ue->frame_parms,
                                           dlsch1,
                                           dlsch1->harq_processes[harq_pid],
                                           frame_rx,
                                           nb_symb_sch,
1163
                                           nr_slot_rx,
cig's avatar
cig committed
1164 1165 1166
                                           harq_pid,
                                           pdsch==PDSCH?1:0,
                                           dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
1167
          LOG_T(PHY,"UE_DLSCH_PARALLELISATION is defined, ret1 = %d\n", ret1);
Agustin's avatar
Agustin committed
1168
#else
Hongzhi Wang's avatar
Hongzhi Wang committed
1169
          ret1 = nr_dlsch_decoding(ue,
1170 1171
                                   proc,
                                   eNB_id,
cig's avatar
cig committed
1172 1173 1174 1175 1176 1177
                                   pdsch_vars->llr[1],
                                   &ue->frame_parms,
                                   dlsch1,
                                   dlsch1->harq_processes[harq_pid],
                                   frame_rx,
                                   nb_symb_sch,
1178
                                   nr_slot_rx,
cig's avatar
cig committed
1179 1180 1181
                                   harq_pid,
                                   pdsch==PDSCH?1:0,//proc->decoder_switch,
                                   dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
1182
          LOG_T(PHY,"UE_DLSCH_PARALLELISATION is NOT defined, ret1 = %d\n", ret1);
Agustin's avatar
Agustin committed
1183 1184 1185 1186
          printf("start cw1 dlsch decoding\n");
#endif

#if UE_TIMING_TRACE
1187
          stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
Agustin's avatar
Agustin committed
1188 1189 1190
#if DISABLE_LOG_X
          printf(" --> Unscrambling for CW1 %5.3f\n",
                  (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
Hongzhi Wang's avatar
Hongzhi Wang committed
1191
          printf("AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n",
1192
                  frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0));
Agustin's avatar
Agustin committed
1193 1194 1195
#else
          LOG_D(PHY, " --> Unscrambling for CW1 %5.3f\n",
                  (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
Hongzhi Wang's avatar
Hongzhi Wang committed
1196
          LOG_D(PHY, "AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n",
1197
                  frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0));
Agustin's avatar
Agustin committed
1198 1199 1200
#endif

#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
1201
          LOG_I(PHY,"AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n",
1202
                  frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0));
cig's avatar
cig committed
1203 1204

        LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch1->harq_processes[harq_pid]->TBS);
1205
      }
Agustin's avatar
Agustin committed
1206

1207
      LOG_D(PHY," ------ end ldpc decoder for AbsSubframe %d.%d ------  \n", frame_rx, nr_slot_rx);
cig's avatar
cig committed
1208
      LOG_D(PHY, "harq_pid: %d, TBS expected dlsch0: %d  \n",harq_pid, dlsch0->harq_processes[harq_pid]->TBS);
1209 1210
      
      if(ret<dlsch0->max_ldpc_iterations+1){
1211

cig's avatar
cig committed
1212 1213 1214 1215 1216
        // fill dl_indication message
        dl_indication.module_id = ue->Mod_id;
        dl_indication.cc_id = ue->CC_id;
        dl_indication.gNB_index = eNB_id;
        dl_indication.frame = frame_rx;
1217 1218
        dl_indication.slot = nr_slot_rx;
        dl_indication.thread_id = proc->thread_id;
cig's avatar
cig committed
1219
        dl_indication.rx_ind = &rx_ind; //  hang on rx_ind instance
1220
        dl_indication.dci_ind = NULL;
cig's avatar
cig committed
1221 1222 1223 1224 1225 1226 1227 1228 1229

        //dl_indication.rx_ind->number_pdus
        switch (pdsch) {
          case RA_PDSCH:
          rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_RAR;
          break;
          case PDSCH:
          rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_DLSCH;
          break;
1230 1231 1232
          case SI_PDSCH:
            rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_SIB;
            break;
cig's avatar
cig committed
1233 1234 1235 1236 1237 1238 1239 1240
          default:
          break;
        }

        rx_ind.rx_indication_body[0].pdsch_pdu.pdu = dlsch0->harq_processes[harq_pid]->b;
        rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length = dlsch0->harq_processes[harq_pid]->TBS>>3;
        LOG_D(PHY, "PDU length in bits: %d, in bytes: %d \n", dlsch0->harq_processes[harq_pid]->TBS, rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length);
        rx_ind.number_pdus = 1;
1241

cig's avatar
cig committed
1242 1243 1244
        //  send to mac
        if (ue->if_inst && ue->if_inst->dl_indication)
        ue->if_inst->dl_indication(&dl_indication, ul_time_alignment);
1245
      }
Agustin's avatar
Agustin committed
1246

1247 1248 1249 1250 1251 1252 1253 1254
      // TODO CRC check for CW0

      // Check CRC for CW 0
      /*if (ret == (1+dlsch0->max_turbo_iterations)) {
        *dlsch_errors=*dlsch_errors+1;
        if(dlsch0->rnti != 0xffff){
          LOG_D(PHY,"[UE  %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %d, mcs %d,TBS %d)\n",
          ue->Mod_id,dlsch0->rnti,
1255
          harq_pid,frame_rx,nr_slot_rx,
1256 1257 1258 1259 1260 1261 1262 1263 1264
          dlsch0->harq_processes[harq_pid]->rvidx,
          dlsch0->harq_processes[harq_pid]->round,
          dlsch0->harq_processes[harq_pid]->mcs,
          dlsch0->harq_processes[harq_pid]->TBS);
        }
      } else {
        if(dlsch0->rnti != 0xffff){
          LOG_D(PHY,"[UE  %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,round %d, mcs %d,TBS %d)\n",
          ue->Mod_id,dlsch0->rnti,
1265
          harq_pid,frame_rx,nr_slot_rx,
1266 1267 1268 1269 1270 1271 1272 1273
          dlsch0->harq_processes[harq_pid]->rvidx,
          dlsch0->harq_processes[harq_pid]->round,
          dlsch0->harq_processes[harq_pid]->mcs,
          dlsch0->harq_processes[harq_pid]->TBS);
        }
        if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)){
          int j;
          LOG_D(PHY,"dlsch harq_pid %d (rx): \n",dlsch0->current_harq_pid);
Agustin's avatar
Agustin committed
1274

1275 1276 1277 1278
          for (j=0; j<dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3; j++)
            LOG_T(PHY,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]);
          LOG_T(PHY,"\n");
      }*/
Agustin's avatar
Agustin committed
1279

1280
      if (ue->mac_enabled == 1) {
1281

1282
        uint16_t bw_scaling = get_bw_scaling(ue->frame_parms.N_RB_DL);
1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338

        /* Time Alignment procedure
        // - UE processing capability 1
        // - Setting the TA update to be applied after the reception of the TA command
        // - Timing adjustment computed according to TS 38.213 section 4.2
        // - Durations of N1 and N2 symbols corresponding to PDSCH and PUSCH are
        //   computed according to sections 5.3 and 6.4 of TS 38.214 */
        factor_mu = 1 << numerology;
        N_TA_max = 3846 * bw_scaling / factor_mu;

        /* PDSCH decoding time N_1 for processing capability 1 */
        if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos0)
          N_1 = pdsch_N_1_capability_1[numerology][1];
        else if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos1 || ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == 2) // TODO set to pdsch_dmrs_pos2 when available
          N_1 = pdsch_N_1_capability_1[numerology][2];
        else
          N_1 = pdsch_N_1_capability_1[numerology][3];

        /* PUSCH preapration time N_2 for processing capability 1 */
        N_2 = pusch_N_2_timing_capability_1[numerology][1];
        mapping_type_dl = ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[0]->mappingType;
        mapping_type_ul = ue->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType;

        /* d_1_1 depending on the number of PDSCH symbols allocated */
        d = 0; // TODO number of overlapping symbols of the scheduling PDCCH and the scheduled PDSCH
        if (mapping_type_dl == typeA)
         if (nb_symb_sch + start_symbol < 7)
          d_1_1 = 7 - (nb_symb_sch + start_symbol);
         else
          d_1_1 = 0;
        else // mapping type B
          switch (nb_symb_sch){
            case 7: d_1_1 = 0; break;
            case 4: d_1_1 = 3; break;
            case 2: d_1_1 = 3 + d; break;
            default: break;
          }

        /* d_2_1 */
        if (mapping_type_ul == typeB && start_symbol != 0)
          d_2_1 = 0;
        else
          d_2_1 = 1;

        /* N_t_1 time duration in msec of N_1 symbols corresponding to a PDSCH reception time
        // N_t_2 time duration in msec of N_2 symbols corresponding to a PUSCH preparation time */
        N_t_1 = (N_1 + d_1_1) * (ofdm_symbol_size + nb_prefix_samples) / factor_mu;
        N_t_2 = (N_2 + d_2_1) * (ofdm_symbol_size + nb_prefix_samples) / factor_mu;
        if (N_t_2 < d_2_2) N_t_2 = d_2_2;

        /* Time alignment procedure */
        // N_t_1 + N_t_2 + N_TA_max is in unit of Ts, therefore must be converted to Tc
        // N_t_1 + N_t_2 + N_TA_max must be in msec
        tc_factor = 64 * 0.509 * 10e-7;
        ul_tx_timing_adjustment = 1 + ceil(slots_per_subframe*((N_t_1 + N_t_2 + N_TA_max)*tc_factor + 0.5)/t_subframe);

1339
        if (ul_time_alignment->apply_ta == 1){
1340 1341
          ul_time_alignment->ta_slot = (nr_slot_rx + ul_tx_timing_adjustment) % slots_per_frame;
          if (nr_slot_rx + ul_tx_timing_adjustment > slots_per_frame){
1342 1343 1344 1345 1346 1347
            ul_time_alignment->ta_frame = (frame_rx + 1) % 1024;
          } else {
            ul_time_alignment->ta_frame = frame_rx;
          }
          // reset TA flag
          ul_time_alignment->apply_ta = 0;
1348
          LOG_D(PHY,"Frame %d slot %d -- Starting UL time alignment procedures. TA update will be applied at frame %d slot %d\n", frame_rx, nr_slot_rx, ul_time_alignment->ta_frame, ul_time_alignment->ta_slot);
1349
        }
1350
      }
Agustin's avatar
Agustin committed
1351

1352 1353 1354
      /*ue->total_TBS[eNB_id] =  ue->total_TBS[eNB_id] + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
      ue->total_received_bits[eNB_id] = ue->total_TBS[eNB_id] + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
    }*/
Agustin's avatar
Agustin committed
1355

1356
    // TODO CRC check for CW1
Agustin's avatar
Agustin committed
1357

1358
  }
Agustin's avatar
Agustin committed
1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371
}


/*!
 * \brief This is the UE synchronize thread.
 * It performs band scanning and synchonization.
 * \param arg is a pointer to a \ref PHY_VARS_NR_UE structure.
 * \returns a pointer to an int. The storage is not on the heap and must not be freed.
 */
#ifdef UE_SLOT_PARALLELISATION
#define FIFO_PRIORITY   40
void *UE_thread_slot1_dl_processing(void *arg) {

1372 1373 1374 1375
  static __thread int UE_dl_slot1_processing_retval;
  struct rx_tx_thread_data *rtd = arg;
  UE_nr_rxtx_proc_t *proc = rtd->proc;
  PHY_VARS_NR_UE    *ue   = rtd->UE;
Agustin's avatar
Agustin committed
1376

1377 1378 1379
  uint8_t pilot1;

  proc->instance_cnt_slot1_dl_processing=-1;
1380
  proc->nr_slot_rx = proc->sub_frame_start * ue->frame_parms.slots_per_subframe;
1381 1382 1383

  char threadname[256];
  sprintf(threadname,"UE_thread_slot1_dl_processing_%d", proc->sub_frame_start);
Agustin's avatar
Agustin committed
1384

1385 1386 1387 1388
  cpu_set_t cpuset;
  CPU_ZERO(&cpuset);
  if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.slot1_proc_one != -1 )
    CPU_SET(threads.slot1_proc_one, &cpuset);
1389
  if ( RX_NB_TH > 1 && (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.slot1_proc_two != -1 )
1390
    CPU_SET(threads.slot1_proc_two, &cpuset);
1391
  if ( RX_NB_TH > 2 && (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.slot1_proc_three != -1 )
1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410
    CPU_SET(threads.slot1_proc_three, &cpuset);

  init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset,
	      threadname);

  while (!oai_exit) {
    if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) {
      LOG_E( PHY, "[SCHED][UE] error locking mutex for UE slot1 dl processing\n" );
      exit_fun("nothing to add");
    }
    while (proc->instance_cnt_slot1_dl_processing < 0) {
      // most of the time, the thread is waiting here
      pthread_cond_wait( &proc->cond_slot1_dl_processing, &proc->mutex_slot1_dl_processing );
    }
    if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) {
      LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE slot1 dl processing \n" );
      exit_fun("nothing to add");
    }

1411 1412 1413 1414
    int frame_rx            = proc->frame_rx;
    uint8_t subframe_rx         = proc->nr_slot_rx / ue->frame_parms.slots_per_subframe;
    uint8_t next_subframe_rx    = (1 + subframe_rx) % NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
    uint8_t next_subframe_slot0 = next_subframe_rx * ue->frame_parms.slots_per_subframe;
1415

1416 1417
    uint8_t slot1  = proc->nr_slot_rx + 1;
    uint8_t pilot0 = 0;
1418

1419
    //printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, nr_slot_rx);
1420 1421 1422 1423 1424 1425 1426 1427

    if (ue->frame_parms.Ncp == 0) {  // normal prefix
      pilot1 = 4;
    } else { // extended prefix
      pilot1 = 3;
    }

    /**** Slot1 FE Processing ****/
Agustin's avatar
Agustin committed
1428
#if UE_TIMING_TRACE
1429
    start_meas(&ue->ue_front_end_per_slot_stat[proc->thread_id][1]);
Agustin's avatar
Agustin committed
1430
#endif
1431
    // I- start dl slot1 processing
1432
    // do first symbol of next downlink nr_slot_rx for channel estimation
1433
    /*
1434 1435
    // 1- perform FFT for pilot ofdm symbols first (ofdmSym0 next nr_slot_rx ofdmSym11)
    if (nr_subframe_select(&ue->frame_parms,next_nr_slot_rx) != SF_UL)
1436 1437 1438 1439 1440 1441 1442
    {
    front_end_fft(ue,
    pilot0,
    next_subframe_slot0,
    0,
    0);
    }
Agustin's avatar
Agustin committed
1443

1444 1445 1446 1447 1448 1449 1450
    front_end_fft(ue,
    pilot1,
    slot1,
    0,
    0);
    */
    // 1- perform FFT
1451
    for (int l=1; l<ue->frame_parms.symbols_per_slot>>1; l++)
1452 1453 1454
      {
	//if( (l != pilot0) && (l != pilot1))
	{
Agustin's avatar
Agustin committed
1455
#if UE_TIMING_TRACE
1456
	  start_meas(&ue->ofdm_demod_stats);
Agustin's avatar
Agustin committed
1457
#endif
1458
	  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
1459
	  //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,nr_slot_rx,slot1,l);
1460
	  front_end_fft(ue,
Agustin's avatar
Agustin committed
1461 1462 1463 1464
                        l,
                        slot1,
                        0,
                        0);
1465
	  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
Agustin's avatar
Agustin committed
1466
#if UE_TIMING_TRACE
1467
	  stop_meas(&ue->ofdm_demod_stats);
Agustin's avatar
Agustin committed
1468
#endif
1469 1470
	}
      } // for l=1..l2
Agustin's avatar
Agustin committed
1471

1472
    if (nr_subframe_select(&ue->frame_parms,next_nr_slot_rx) != SF_UL)
1473
      {
1474
	//printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,nr_slot_rx,next_subframe_slot0,pilot0);
1475 1476 1477 1478 1479 1480
	front_end_fft(ue,
		      pilot0,
		      next_subframe_slot0,
		      0,
		      0);
      }
Agustin's avatar
Agustin committed
1481

1482
    // 2- perform Channel Estimation for slot1
1483
    for (int l=1; l<ue->frame_parms.symbols_per_slot>>1; l++)
1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495
      {
	if(l == pilot1)
	  {
	    //wait until channel estimation for pilot0/slot1 is available
	    uint32_t wait = 0;
	    while(proc->chan_est_pilot0_slot1_available == 0)
	      {
		usleep(1);
		wait++;
	      }
	    //printf("[slot1 dl processing] ChanEst symbol %d slot %d wait%d\n",l,slot1,wait);
	  }
1496
	//printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,nr_slot_rx,slot1,l);
1497 1498 1499 1500
	front_end_chanEst(ue,
			  l,
			  slot1,
			  0);
1501
	ue_measurement_procedures(l-1,ue,proc,0,slot1,0,ue->mode);
1502
      }
1503
    //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,nr_slot_rx,next_subframe_slot0,pilot0);
1504 1505 1506 1507
    front_end_chanEst(ue,
		      pilot0,
		      next_subframe_slot0,
		      0);
Agustin's avatar
Agustin committed
1508

1509
    if ( (nr_slot_rx == 0) && (ue->decode_MIB == 1))
1510
      {
1511
	ue_pbch_procedures(0,ue,proc,0);
1512
      }
Agustin's avatar
Agustin committed
1513

1514
    proc->chan_est_slot1_available = 1;
1515 1516
    //printf("Set available slot 1channelEst to 1 AbsSubframe %d.%d \n",frame_rx,nr_slot_rx);
    //printf(" [slot1 dl processing] ==> FFT/CHanEst Done for AbsSubframe %d.%d \n", proc->frame_rx, proc->nr_slot_rx);
Agustin's avatar
Agustin committed
1517

1518
    //printf(" [slot1 dl processing] ==> Start LLR Comuptation slot1 for AbsSubframe %d.%d \n", proc->frame_rx, proc->nr_slot_rx);
Agustin's avatar
Agustin committed
1519 1520 1521


#if UE_TIMING_TRACE
1522
    stop_meas(&ue->ue_front_end_per_slot_stat[proc->thread_id][1]);
Agustin's avatar
Agustin committed
1523
#if DISABLE_LOG_X
1524
    printf("[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,nr_slot_rx,ue->ue_front_end_per_slot_stat[proc->thread_id][1].p_time/(cpuf*1000.0));
Agustin's avatar
Agustin committed
1525
#else
1526
    LOG_D(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,nr_slot_rx,ue->ue_front_end_per_slot_stat[proc->thread_id][1].p_time/(cpuf*1000.0));
Agustin's avatar
Agustin committed
1527 1528 1529 1530 1531 1532 1533
#endif
#endif


    //wait until pdcch is decoded
    uint32_t wait = 0;
    while(proc->dci_slot0_available == 0)
1534
      {
Agustin's avatar
Agustin committed
1535 1536
        usleep(1);
        wait++;
1537
      }
1538
    //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait DCI %d\n",frame_rx,nr_slot_rx,wait);
Agustin's avatar
Agustin committed
1539 1540 1541 1542

    /**** Pdsch Procedure Slot1 ****/
    // start slot1 thread for Pdsch Procedure (slot1)
    // do procedures for C-RNTI
1543
    //printf("AbsSubframe %d.%d Pdsch Procedure (slot1)\n",frame_rx,nr_slot_rx);
Agustin's avatar
Agustin committed
1544 1545 1546


#if UE_TIMING_TRACE
1547
    start_meas(&ue->pdsch_procedures_per_slot_stat[proc->thread_id][1]);
Agustin's avatar
Agustin committed
1548 1549 1550 1551
#endif
    // start slave thread for Pdsch Procedure (slot1)
    // do procedures for C-RNTI
    uint8_t eNB_id = 0;
1552

1553
    if (ue->dlsch[proc->thread_id][eNB_id][0]->active == 1) {
1554 1555 1556 1557 1558 1559 1560
      //wait until first ofdm symbol is processed
      //wait = 0;
      //while(proc->first_symbol_available == 0)
      //{
      //    usleep(1);
      //    wait++;
      //}
1561
      //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait First Ofdm Sym %d\n",frame_rx,nr_slot_rx,wait);
1562 1563 1564 1565 1566 1567

      //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
      ue_pdsch_procedures(ue,
			  proc,
			  eNB_id,
			  PDSCH,
1568
			  ue->dlsch[proc->thread_id][eNB_id][0],
1569
			  NULL,
1570 1571
			  (ue->frame_parms.symbols_per_slot>>1),
			  ue->frame_parms.symbols_per_slot-1,
1572
			  abstraction_flag);
1573 1574
      LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, nr_slot_rx);
      LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------  \n", frame_rx%1024, nr_slot_rx);
Agustin's avatar
Agustin committed
1575 1576 1577 1578
    }

    // do procedures for SI-RNTI
    if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
1579 1580 1581 1582 1583 1584
      ue_pdsch_procedures(ue,
			  proc,
			  eNB_id,
			  SI_PDSCH,
			  ue->dlsch_SI[eNB_id],
			  NULL,
1585 1586
			  (ue->frame_parms.symbols_per_slot>>1),
			  ue->frame_parms.symbols_per_slot-1,
1587
			  abstraction_flag);
Agustin's avatar
Agustin committed
1588 1589 1590 1591
    }

    // do procedures for P-RNTI
    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
1592 1593 1594 1595 1596 1597
      ue_pdsch_procedures(ue,
			  proc,
			  eNB_id,
			  P_PDSCH,
			  ue->dlsch_p[eNB_id],
			  NULL,
1598 1599
			  (ue->frame_parms.symbols_per_slot>>1),
			  ue->frame_parms.symbols_per_slot-1,
1600
			  abstraction_flag);
Agustin's avatar
Agustin committed
1601 1602 1603
    }
    // do procedures for RA-RNTI
    if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
1604 1605 1606 1607 1608 1609
      ue_pdsch_procedures(ue,
			  proc,
			  eNB_id,
			  RA_PDSCH,
			  ue->dlsch_ra[eNB_id],
			  NULL,
1610 1611
			  (ue->frame_parms.symbols_per_slot>>1),
			  ue->frame_parms.symbols_per_slot-1,
1612
			  abstraction_flag);
Agustin's avatar
Agustin committed
1613 1614 1615
    }

    proc->llr_slot1_available=1;
1616
    //printf("Set available LLR slot1 to 1 AbsSubframe %d.%d \n",frame_rx,nr_slot_rx);
Agustin's avatar
Agustin committed
1617 1618

#if UE_TIMING_TRACE
1619
    stop_meas(&ue->pdsch_procedures_per_slot_stat[proc->thread_id][1]);
Agustin's avatar
Agustin committed
1620
#if DISABLE_LOG_X
1621
    printf("[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,nr_slot_rx,ue->pdsch_procedures_per_slot_stat[proc->thread_id][1].p_time/(cpuf*1000.0));
Agustin's avatar
Agustin committed
1622
#else
1623
    LOG_D(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,nr_slot_rx,ue->pdsch_procedures_per_slot_stat[proc->thread_id][1].p_time/(cpuf*1000.0));
Agustin's avatar
Agustin committed
1624 1625 1626
#endif
#endif

1627 1628 1629 1630 1631 1632 1633 1634
    if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) {
      LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
      exit_fun("noting to add");
    }
    proc->instance_cnt_slot1_dl_processing--;
    if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) {
      LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE FEP Slo1\n" );
      exit_fun("noting to add");
Agustin's avatar
Agustin committed
1635
    }
1636 1637 1638 1639
  }
  // thread finished
  free(arg);
  return &UE_dl_slot1_processing_retval;
Agustin's avatar
Agustin committed
1640 1641 1642
}
#endif

1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690
int is_ssb_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL_FRAME_PARMS *fp)
{
  int mu = fp->numerology_index;
  //uint8_t half_frame_index = fp->half_frame_bit;
  //uint8_t i_ssb = fp->ssb_index;
  uint8_t Lmax = fp->Lmax;

  if (!(frame%(1<<(config->ssb_table.ssb_period-1)))){

    if(Lmax <= 8) {
      if(slot <=3 && (((config->ssb_table.ssb_mask_list[0].ssb_mask << 2*slot)&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[0].ssb_mask << (2*slot +1))&0x80000000) == 0x80000000))
      return 1;
      else return 0;
    
    }
    else if(Lmax == 64) {
      if (mu == NR_MU_3){

        if (slot>=0 && slot <= 7){
          if(((config->ssb_table.ssb_mask_list[0].ssb_mask << 2*slot)&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[0].ssb_mask << (2*slot +1))&0x80000000) == 0x80000000)
          return 1;
          else return 0;
        }
      else if (slot>=10 && slot <=17){
         if(((config->ssb_table.ssb_mask_list[0].ssb_mask << 2*(slot-2))&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[0].ssb_mask << (2*(slot-2) +1))&0x80000000) == 0x80000000)
         return 1;
         else return 0;
      }
      else if (slot>=20 && slot <=27){
         if(((config->ssb_table.ssb_mask_list[1].ssb_mask << 2*(slot-20))&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[1].ssb_mask << (2*(slot-20) +1))&0x80000000) == 0x80000000)
         return 1;
         else return 0;
      }
      else if (slot>=30 && slot <=37){
         if(((config->ssb_table.ssb_mask_list[1].ssb_mask << 2*(slot-22))&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[1].ssb_mask << (2*(slot-22) +1))&0x80000000) == 0x80000000)
         return 1;
         else return 0;
       }
      else return 0;

    }


    else if (mu == NR_MU_4) {
         AssertFatal(0==1, "not implemented for mu =  %d yet\n", mu);
    }
    else AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu);
   }
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1691
   else AssertFatal(0==1, "Invalid Lmax %u for the synchronization block\n", Lmax);
1692 1693 1694 1695
  }
  else return 0;

}
Agustin's avatar
Agustin committed
1696

1697
int is_pbch_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL_FRAME_PARMS *fp)  {
1698

1699
  int ssb_slot_decoded = (fp->ssb_index>>1) + ((fp->ssb_index>>4)<<1); //slot in which the decoded SSB can be found
Agustin's avatar
Agustin committed
1700

1701
  if (config->ssb_table.ssb_period == 0) {  
1702
    // check for pbch in corresponding slot each half frame
1703 1704
    if (fp->half_frame_bit)
      return(slot == ssb_slot_decoded || slot == ssb_slot_decoded - fp->slots_per_frame/2);
1705
    else
1706
      return(slot == ssb_slot_decoded || slot == ssb_slot_decoded + fp->slots_per_frame/2);
1707 1708 1709
  }
  else {
    // if the current frame is supposed to contain ssb
1710
    if (!(frame%(1<<(config->ssb_table.ssb_period-1))))
1711 1712 1713
      return(slot == ssb_slot_decoded);
    else
      return 0;
1714 1715 1716
  }
}

Agustin's avatar
Agustin committed
1717

1718 1719
int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                           UE_nr_rxtx_proc_t *proc,
cig's avatar
cig committed
1720
                           uint8_t gNB_id,
1721 1722
                           runmode_t mode)
{
Agustin's avatar
Agustin committed
1723
  int frame_rx = proc->frame_rx;
1724
  int nr_slot_rx = proc->nr_slot_rx;
1725
  int slot_pbch;
Hongzhi Wang's avatar
Hongzhi Wang committed
1726
  int slot_ssb;
1727
  NR_UE_PDCCH *pdcch_vars  = ue->pdcch_vars[proc->thread_id][0];
1728
  fapi_nr_config_request_t *cfg = &ue->nrUE_config;
1729

1730
  uint8_t nb_symb_pdcch = pdcch_vars->nb_search_space > 0 ? pdcch_vars->pdcch_config[0].coreset.duration : 0;
1731
  uint8_t dci_cnt = 0;
1732
  NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
1733
  
Hongzhi Wang's avatar
Hongzhi Wang committed
1734
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
cig's avatar
cig committed
1735

1736
  LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ******  \n", frame_rx%1024, nr_slot_rx);
Agustin's avatar
Agustin committed
1737

1738
  /*
1739
  uint8_t next1_thread_id = proc->thread_id== (RX_NB_TH-1) ? 0:(proc->thread_id+1);
Agustin's avatar
Agustin committed
1740
  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
1741
  */
Agustin's avatar
Agustin committed
1742

1743 1744
  int coreset_nb_rb=0;
  int coreset_start_rb=0;
1745

1746 1747
  if (pdcch_vars->nb_search_space > 0)
    get_coreset_rballoc(pdcch_vars->pdcch_config[0].coreset.frequency_domain_resource,&coreset_nb_rb,&coreset_start_rb);
1748

1749
  slot_pbch = is_pbch_in_slot(cfg, frame_rx, nr_slot_rx, fp);
1750
  slot_ssb  = is_ssb_in_slot(cfg, frame_rx, nr_slot_rx, fp);
Hongzhi Wang's avatar
Hongzhi Wang committed
1751 1752

  // looking for pbch only in slot where it is supposed to be
1753
  if (slot_ssb) {
1754
    LOG_D(PHY," ------  PBCH ChannelComp/LLR: frame.slot %d.%d ------  \n", frame_rx%1024, nr_slot_rx);
1755
    for (int i=1; i<4; i++) {
Hongzhi Wang's avatar
Hongzhi Wang committed
1756

1757
      nr_slot_fep(ue,
1758
                  proc,
1759
                  (ue->symbol_offset+i)%(fp->symbols_per_slot),
1760
                  nr_slot_rx,
1761 1762
                  0,
                  0);
Hongzhi Wang's avatar
Hongzhi Wang committed
1763 1764

#if UE_TIMING_TRACE
1765
      start_meas(&ue->dlsch_channel_estimation_stats);
Hongzhi Wang's avatar
Hongzhi Wang committed
1766
#endif
1767
      nr_pbch_channel_estimation(ue,proc,0,nr_slot_rx,(ue->symbol_offset+i)%(fp->symbols_per_slot),i-1,(fp->ssb_index)&7,fp->half_frame_bit);
Hongzhi Wang's avatar
Hongzhi Wang committed
1768
#if UE_TIMING_TRACE
1769
      stop_meas(&ue->dlsch_channel_estimation_stats);
Hongzhi Wang's avatar
Hongzhi Wang committed
1770
#endif
1771
    }
1772

1773
    //if (mac->csirc->reportQuantity.choice.ssb_Index_RSRP){
1774
    nr_ue_rsrp_measurements(ue,proc,nr_slot_rx,0);
1775
    //}
1776

1777
    if ((ue->decode_MIB == 1) && slot_pbch) {
1778

1779
      LOG_D(PHY," ------  Decode MIB: frame.slot %d.%d ------  \n", frame_rx%1024, nr_slot_rx);
cig's avatar
cig committed
1780
      nr_ue_pbch_procedures(gNB_id, ue, proc, 0);
Hongzhi Wang's avatar
Hongzhi Wang committed
1781 1782

      if (ue->no_timing_correction==0) {
1783
        LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction);
1784
        nr_adjust_synch_ue(fp,
cig's avatar
cig committed
1785
                           ue,
cig's avatar
cig committed
1786
                           gNB_id,
1787
                           frame_rx,
1788
                           nr_slot_rx,
cig's avatar
cig committed
1789 1790
                           0,
                           16384);
Hongzhi Wang's avatar
Hongzhi Wang committed
1791
      }
cig's avatar
cig committed
1792 1793 1794

      LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__);
      nr_ue_rrc_measurements(ue, proc, nr_slot_rx);
Hongzhi Wang's avatar
Hongzhi Wang committed
1795
    }
1796
  }
1797

1798
  if ((frame_rx%64 == 0) && (nr_slot_rx==0)) {
1799 1800 1801 1802 1803
    printf("============================================\n");
    LOG_I(PHY,"Harq round stats for Downlink: %d/%d/%d/%d DLSCH errors: %d\n",ue->dl_stats[0],ue->dl_stats[1],ue->dl_stats[2],ue->dl_stats[3],ue->dl_stats[4]);
    printf("============================================\n");
  }

1804
#ifdef NR_PDCCH_SCHED
1805
  nr_gold_pdcch(ue, 0, 2);
1806

1807
  LOG_D(PHY," ------ --> PDCCH ChannelComp/LLR Frame.slot %d.%d ------  \n", frame_rx%1024, nr_slot_rx);
1808
  for (uint16_t l=0; l<nb_symb_pdcch; l++) {
cig's avatar
cig committed
1809

Agustin's avatar
Agustin committed
1810
#if UE_TIMING_TRACE
1811
    start_meas(&ue->ofdm_demod_stats);
Agustin's avatar
Agustin committed
1812
#endif
1813 1814
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
    nr_slot_fep(ue,
1815
                proc,
cig's avatar
cig committed
1816
                l,
1817
                nr_slot_rx,
cig's avatar
cig committed
1818 1819
                0,
                0);
1820

1821 1822 1823
    dci_cnt = 0;
    for(int n_ss = 0; n_ss<pdcch_vars->nb_search_space; n_ss++) {

1824
    // note: this only works if RBs for PDCCH are contigous!
1825 1826 1827
    LOG_D(PHY, "pdcch_channel_estimation: first_carrier_offset %d, BWPStart %d, coreset_start_rb %d\n",
          fp->first_carrier_offset, pdcch_vars->pdcch_config[n_ss].BWPStart, coreset_start_rb);

1828 1829
    if (coreset_nb_rb > 0)
      nr_pdcch_channel_estimation(ue,
1830
                                  proc,
1831
                                  0,
1832
                                  nr_slot_rx,
1833
                                  l,
rmagueta's avatar
rmagueta committed
1834
                                  fp->first_carrier_offset+(pdcch_vars->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12,
1835 1836
                                  coreset_nb_rb);

1837
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
Agustin's avatar
Agustin committed
1838
#if UE_TIMING_TRACE
1839
    stop_meas(&ue->ofdm_demod_stats);
Agustin's avatar
Agustin committed
1840
#endif
1841

rmagueta's avatar
rmagueta committed
1842
      dci_cnt = dci_cnt + nr_ue_pdcch_procedures(gNB_id, ue, proc);
1843 1844
    }
  }
1845 1846 1847

  if (dci_cnt > 0) {

1848
    LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_slot_rx, dci_cnt);
Hongzhi Wang's avatar
Hongzhi Wang committed
1849

Raphael Defosseux's avatar
Raphael Defosseux committed
1850
    NR_UE_DLSCH_t *dlsch = NULL;
1851 1852
    if (ue->dlsch[proc->thread_id][gNB_id][0]->active == 1){
      dlsch = ue->dlsch[proc->thread_id][gNB_id][0];
1853 1854
    } else if (ue->dlsch_SI[0]->active == 1){
      dlsch = ue->dlsch_SI[0];
cig's avatar
cig committed
1855 1856 1857
    } else if (ue->dlsch_ra[0]->active == 1){
      dlsch = ue->dlsch_ra[0];
    }
1858 1859 1860 1861 1862 1863 1864 1865

    if (dlsch) {
      uint8_t harq_pid = dlsch->current_harq_pid;
      NR_DL_UE_HARQ_t *dlsch0_harq = dlsch->harq_processes[harq_pid];
      uint16_t nb_symb_sch = dlsch0_harq->nb_symbols;
      uint16_t start_symb_sch = dlsch0_harq->start_symbol;
      int symb_dmrs = -1;

1866
      LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------  \n", frame_rx%1024, nr_slot_rx);
1867 1868 1869 1870
      //to update from pdsch config

      for (int i=0;i<4;i++) if (((1<<i)&dlsch0_harq->dlDmrsSymbPos) > 0) {symb_dmrs=i;break;}
      AssertFatal(symb_dmrs>=0,"no dmrs in 0..3\n");
1871 1872
      LOG_D(PHY,"Initializing dmrs for slot %d DMRS mask %x\n", nr_slot_rx, dlsch0_harq->dlDmrsSymbPos);
      nr_gold_pdsch(ue, nr_slot_rx, 0);
1873
    
1874 1875
      for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){
        nr_slot_fep(ue,
1876 1877 1878 1879 1880
                    proc,
                    m,  //to be updated from higher layer
                    nr_slot_rx,
                    0,
                    0);
1881
      }
1882
    }
cig's avatar
cig committed
1883
  } else {
1884
    LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: No DCIs found\n", ue->Mod_id, frame_rx, nr_slot_rx);
hongzhi wang's avatar
hongzhi wang committed
1885
  }
cig's avatar
cig committed
1886 1887

#endif //NR_PDCCH_SCHED
1888

Agustin's avatar
Agustin committed
1889 1890
#if UE_TIMING_TRACE
  start_meas(&ue->generic_stat);
1891
#endif
Agustin's avatar
Agustin committed
1892
  // do procedures for C-RNTI
1893
  int ret_pdsch = 0;
1894
  if (ue->dlsch[proc->thread_id][gNB_id][0]->active == 1) {
1895
    //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
1896
    ret_pdsch = nr_ue_pdsch_procedures(ue,
1897
			   proc,
cig's avatar
cig committed
1898
			   gNB_id,
1899
			   PDSCH,
1900
			   ue->dlsch[proc->thread_id][gNB_id][0],
1901
			   NULL);
cig's avatar
cig committed
1902

cig's avatar
cig committed
1903
    nr_ue_measurement_procedures(2, ue, proc, gNB_id, nr_slot_rx, mode);
Agustin's avatar
Agustin committed
1904
  }
1905

Agustin's avatar
Agustin committed
1906
  // do procedures for SI-RNTI
cig's avatar
cig committed
1907
  if ((ue->dlsch_SI[gNB_id]) && (ue->dlsch_SI[gNB_id]->active == 1)) {
Agustin's avatar
Agustin committed
1908
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
1909
    nr_ue_pdsch_procedures(ue,
1910 1911 1912 1913 1914
                           proc,
                           gNB_id,
                           SI_PDSCH,
                           ue->dlsch_SI[gNB_id],
                           NULL);
1915
    
1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927
    nr_ue_dlsch_procedures(ue,
                           proc,
                           gNB_id,
                           SI_PDSCH,
                           ue->dlsch_SI[gNB_id],
                           NULL,
                           &ue->dlsch_SI_errors[gNB_id],
                           mode);

    // deactivate dlsch once dlsch proc is done
    ue->dlsch_SI[gNB_id]->active = 0;

Agustin's avatar
Agustin committed
1928 1929
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
  }
1930

1931
  // do procedures for P-RNTI
cig's avatar
cig committed
1932
  if ((ue->dlsch_p[gNB_id]) && (ue->dlsch_p[gNB_id]->active == 1)) {
Agustin's avatar
Agustin committed
1933
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN);
1934
    nr_ue_pdsch_procedures(ue,
1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951
                           proc,
                           gNB_id,
                           P_PDSCH,
                           ue->dlsch_p[gNB_id],
                           NULL);

    nr_ue_dlsch_procedures(ue,
                           proc,
                           gNB_id,
                           P_PDSCH,
                           ue->dlsch_p[gNB_id],
                           NULL,
                           &ue->dlsch_p_errors[gNB_id],
                           mode);

    // deactivate dlsch once dlsch proc is done
    ue->dlsch_p[gNB_id]->active = 0;
1952

Agustin's avatar
Agustin committed
1953 1954
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
  }
1955

Agustin's avatar
Agustin committed
1956
  // do procedures for RA-RNTI
cig's avatar
cig committed
1957
  if ((ue->dlsch_ra[gNB_id]) && (ue->dlsch_ra[gNB_id]->active == 1)) {
Agustin's avatar
Agustin committed
1958
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN);
1959
    nr_ue_pdsch_procedures(ue,
1960 1961 1962 1963 1964
                           proc,
                           gNB_id,
                           RA_PDSCH,
                           ue->dlsch_ra[gNB_id],
                           NULL);
1965

1966 1967
    nr_ue_dlsch_procedures(ue,
                           proc,
cig's avatar
cig committed
1968
                           gNB_id,
1969
                           RA_PDSCH,
cig's avatar
cig committed
1970
                           ue->dlsch_ra[gNB_id],
1971
                           NULL,
cig's avatar
cig committed
1972
                           &ue->dlsch_ra_errors[gNB_id],
1973 1974
                           mode);

1975 1976 1977 1978
    // deactivate dlsch once dlsch proc is done
    ue->dlsch_ra[gNB_id]->active = 0;

    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
Agustin's avatar
Agustin committed
1979
  }
Raymond Knopp's avatar
Raymond Knopp committed
1980
    
1981
  // do procedures for C-RNTI
1982
  if (ue->dlsch[proc->thread_id][gNB_id][0]->active == 1) {
1983

1984
    LOG_D(PHY, "DLSCH data reception at nr_slot_rx: %d \n \n", nr_slot_rx);
1985 1986 1987
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);

#if UE_TIMING_TRACE
1988
    start_meas(&ue->dlsch_procedures_stat[proc->thread_id]);
1989 1990 1991 1992 1993 1994 1995
#endif

    if (ret_pdsch >= 0)
      nr_ue_dlsch_procedures(ue,
			   proc,
			   gNB_id,
			   PDSCH,
1996 1997
			   ue->dlsch[proc->thread_id][gNB_id][0],
			   ue->dlsch[proc->thread_id][gNB_id][1],
1998 1999 2000 2001 2002
			   &ue->dlsch_errors[gNB_id],
			   mode);


#if UE_TIMING_TRACE
2003
  stop_meas(&ue->dlsch_procedures_stat[proc->thread_id]);
2004
#if DISABLE_LOG_X
2005 2006
  printf("[SFN %d] Slot1:       Pdsch Proc %5.2f\n",nr_slot_rx,ue->pdsch_procedures_stat[proc->thread_id].p_time/(cpuf*1000.0));
  printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",nr_slot_rx,ue->dlsch_procedures_stat[proc->thread_id].p_time/(cpuf*1000.0));
2007
#else
2008 2009
  LOG_D(PHY, "[SFN %d] Slot1:       Pdsch Proc %5.2f\n",nr_slot_rx,ue->pdsch_procedures_stat[proc->thread_id].p_time/(cpuf*1000.0));
  LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",nr_slot_rx,ue->dlsch_procedures_stat[proc->thread_id].p_time/(cpuf*1000.0));
2010 2011 2012 2013 2014
#endif

#endif

  // deactivate dlsch once dlsch proc is done
2015
  ue->dlsch[proc->thread_id][gNB_id][0]->active = 0;
2016 2017 2018 2019

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);

 }
Agustin's avatar
Agustin committed
2020
#if UE_TIMING_TRACE
2021
start_meas(&ue->generic_stat);
Agustin's avatar
Agustin committed
2022 2023 2024
#endif

#if 0
2025

2026
  if(nr_slot_rx==5 &&  ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid]->nb_rb > 20){
Agustin's avatar
Agustin committed
2027
       //write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
2028
       //write_output("llr.m","llr",  &ue->pdsch_vars[proc->thread_id][gNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0);
2029

2030
       write_output("rxdataF0_current.m"    , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF[0][0],14*fp->ofdm_symbol_size,1,1);
2031
       //write_output("rxdataF0_previous.m"    , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*fp->ofdm_symbol_size,1,1);
2032

2033
       //write_output("rxdataF0_previous.m"    , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*fp->ofdm_symbol_size,1,1);
2034

2035
       write_output("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].dl_ch_estimates[0][0][0],14*fp->ofdm_symbol_size,1,1);
2036 2037 2038 2039
       write_output("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates_ext[0][0],14*fp->N_RB_DL*12,1,1);
       write_output("rxdataF_comp00.m","rxdataF_comp00",         &ue->pdsch_vars[proc->thread_id][gNB_id]->rxdataF_comp0[0][0],14*fp->N_RB_DL*12,1,1);
       //write_output("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_mag0[0][0],14*fp->N_RB_DL*12,1,1);
       //write_output("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_magb0[0][0],14*fp->N_RB_DL*12,1,1);
2040

Agustin's avatar
Agustin committed
2041 2042 2043
       AssertFatal (0,"");
  }
#endif
2044

Agustin's avatar
Agustin committed
2045
  // duplicate harq structure
2046
/*
2047 2048
  uint8_t          current_harq_pid        = ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid;
  NR_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[current_harq_pid];
cig's avatar
cig committed
2049 2050
  NR_DL_UE_HARQ_t *harq_processes_dest    = ue->dlsch[next1_thread_id][gNB_id][0]->harq_processes[current_harq_pid];
  NR_DL_UE_HARQ_t *harq_processes_dest1    = ue->dlsch[next2_thread_id][gNB_id][0]->harq_processes[current_harq_pid];
2051
  */
2052 2053 2054
  /*nr_harq_status_t *current_harq_ack = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_ack[nr_slot_rx];
  nr_harq_status_t *harq_ack_dest    = &ue->dlsch[next1_thread_id][gNB_id][0]->harq_ack[nr_slot_rx];
  nr_harq_status_t *harq_ack_dest1    = &ue->dlsch[next2_thread_id][gNB_id][0]->harq_ack[nr_slot_rx];
2055
*/
Agustin's avatar
Agustin committed
2056

2057
  //copy_harq_proc_struct(harq_processes_dest, current_harq_processes);
2058
//copy_ack_struct(harq_ack_dest, current_harq_ack);
Agustin's avatar
Agustin committed
2059

2060
//copy_harq_proc_struct(harq_processes_dest1, current_harq_processes);
2061
//copy_ack_struct(harq_ack_dest1, current_harq_ack);
Agustin's avatar
Agustin committed
2062

2063
if (nr_slot_rx==9) {
2064
  if (frame_rx % 10 == 0) {
cig's avatar
cig committed
2065 2066
    if ((ue->dlsch_received[gNB_id] - ue->dlsch_received_last[gNB_id]) != 0)
      ue->dlsch_fer[gNB_id] = (100*(ue->dlsch_errors[gNB_id] - ue->dlsch_errors_last[gNB_id]))/(ue->dlsch_received[gNB_id] - ue->dlsch_received_last[gNB_id]);
Agustin's avatar
Agustin committed
2067

cig's avatar
cig committed
2068 2069
    ue->dlsch_errors_last[gNB_id] = ue->dlsch_errors[gNB_id];
    ue->dlsch_received_last[gNB_id] = ue->dlsch_received[gNB_id];
2070
  }
Agustin's avatar
Agustin committed
2071 2072


cig's avatar
cig committed
2073 2074
  ue->bitrate[gNB_id] = (ue->total_TBS[gNB_id] - ue->total_TBS_last[gNB_id])*100;
  ue->total_TBS_last[gNB_id] = ue->total_TBS[gNB_id];
2075
  LOG_D(PHY,"[UE %d] Calculating bitrate Frame %d: total_TBS = %d, total_TBS_last = %d, bitrate %f kbits\n",
cig's avatar
cig committed
2076 2077
	ue->Mod_id,frame_rx,ue->total_TBS[gNB_id],
	ue->total_TBS_last[gNB_id],(float) ue->bitrate[gNB_id]/1000.0);
Agustin's avatar
Agustin committed
2078

2079 2080
#if UE_AUTOTEST_TRACE
  if ((frame_rx % 100 == 0)) {
cig's avatar
cig committed
2081
    LOG_I(PHY,"[UE  %d] AUTOTEST Metric : UE_DLSCH_BITRATE = %5.2f kbps (frame = %d) \n", ue->Mod_id, (float) ue->bitrate[gNB_id]/1000.0, frame_rx);
Agustin's avatar
Agustin committed
2082
  }
2083 2084 2085
#endif

 }
Agustin's avatar
Agustin committed
2086 2087

#if UE_TIMING_TRACE
2088 2089
stop_meas(&ue->generic_stat);
printf("after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0));
Agustin's avatar
Agustin committed
2090 2091
#endif

2092
#ifdef EMOS
cig's avatar
cig committed
2093
phy_procedures_emos_UE_RX(ue,slot,gNB_id);
2094
#endif
Agustin's avatar
Agustin committed
2095 2096


2097
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
Agustin's avatar
Agustin committed
2098 2099

#if UE_TIMING_TRACE
2100
stop_meas(&ue->phy_proc_rx[proc->thread_id]);
Agustin's avatar
Agustin committed
2101
#if DISABLE_LOG_X
2102
printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",nr_slot_rx,ue->phy_proc_rx[proc->thread_id].p_time/(cpuf*1000.0));
Agustin's avatar
Agustin committed
2103
#else
2104
LOG_D(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",nr_slot_rx,ue->phy_proc_rx[proc->thread_id].p_time/(cpuf*1000.0));
Agustin's avatar
Agustin committed
2105 2106 2107
#endif
#endif

2108
//#endif //pdsch
2109

2110
LOG_D(PHY," ****** end RX-Chain  for AbsSubframe %d.%d ******  \n", frame_rx%1024, nr_slot_rx);
2111
return (0);
Agustin's avatar
Agustin committed
2112
}
2113 2114


2115
uint8_t nr_is_cqi_TXOp(PHY_VARS_NR_UE *ue,
2116 2117 2118
		            UE_nr_rxtx_proc_t *proc,
					uint8_t gNB_id)
{
2119
  int subframe = proc->nr_slot_tx / ue->frame_parms.slots_per_subframe;
2120 2121
  int frame    = proc->frame_tx;
  CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[gNB_id].CQI_ReportPeriodic;
2122

2123 2124 2125 2126
  //LOG_I(PHY,"[UE %d][CRNTI %x] AbsSubFrame %d.%d Checking for CQI TXOp (cqi_ConfigIndex %d) isCQIOp %d\n",
  //      ue->Mod_id,ue->pdcch_vars[gNB_id]->crnti,frame,subframe,
  //      cqirep->cqi_PMI_ConfigIndex,
  //      (((10*frame + subframe) % cqirep->Npd) == cqirep->N_OFFSET_CQI));
2127

2128 2129 2130 2131 2132 2133
  if (cqirep->cqi_PMI_ConfigIndex==-1)
    return(0);
  else if (((10*frame + subframe) % cqirep->Npd) == cqirep->N_OFFSET_CQI)
    return(1);
  else
    return(0);
2134 2135 2136
}


2137
uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue,
2138 2139 2140
		           UE_nr_rxtx_proc_t *proc,
				   uint8_t gNB_id)
{
2141
  int subframe = proc->nr_slot_tx / ue->frame_parms.slots_per_subframe;
2142 2143 2144 2145
  int frame    = proc->frame_tx;
  CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[gNB_id].CQI_ReportPeriodic;
  int log2Mri = cqirep->ri_ConfigIndex/161;
  int N_OFFSET_RI = cqirep->ri_ConfigIndex % 161;
2146

2147 2148 2149 2150 2151 2152 2153 2154 2155 2156
  //LOG_I(PHY,"[UE %d][CRNTI %x] AbsSubFrame %d.%d Checking for RI TXOp (ri_ConfigIndex %d) isRIOp %d\n",
  //      ue->Mod_id,ue->pdcch_vars[gNB_id]->crnti,frame,subframe,
  //      cqirep->ri_ConfigIndex,
  //      (((10*frame + subframe + cqirep->N_OFFSET_CQI - N_OFFSET_RI) % (cqirep->Npd<<log2Mri)) == 0));
  if (cqirep->ri_ConfigIndex==-1)
    return(0);
  else if (((10*frame + subframe + cqirep->N_OFFSET_CQI - N_OFFSET_RI) % (cqirep->Npd<<log2Mri)) == 0)
    return(1);
  else
    return(0);
2157 2158
}

cig's avatar
cig committed
2159 2160 2161 2162
// WIP
// todo:
// - set tx_total_RE
// - power control as per 38.213 ch 7.4
cig's avatar
cig committed
2163
void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, runmode_t runmode) {
cig's avatar
cig committed
2164

2165
  int frame_tx = proc->frame_tx, nr_slot_tx = proc->nr_slot_tx, prach_power; // tx_amp
2166
  uint16_t /*preamble_tx = 50,*/ pathloss;
2167 2168
  uint8_t mod_id = ue->Mod_id;
  UE_MODE_t UE_mode = get_nrUE_mode(mod_id, ue->CC_id, gNB_id);
cig's avatar
cig committed
2169
  NR_PRACH_RESOURCES_t * prach_resources = ue->prach_resources[gNB_id];
2170
  uint8_t nr_prach = 0;
2171 2172 2173

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);

2174
  if (!prach_resources->init_msg1 && ((MAX_FRAME_NUMBER+frame_tx-ue->prach_resources[gNB_id]->sync_frame)% MAX_FRAME_NUMBER)>150){
2175 2176 2177 2178
    ue->prach_cnt = 0;
    prach_resources->init_msg1 = 1;
  }

cig's avatar
cig committed
2179
  if (ue->mac_enabled == 0){
2180
    //    prach_resources->ra_PreambleIndex = preamble_tx;
cig's avatar
cig committed
2181 2182 2183
    prach_resources->ra_TDD_map_index = 0;
    prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = 10;
    prach_resources->ra_RNTI = 0x1234;
cig's avatar
cig committed
2184
    nr_prach = 1;
cig's avatar
cig committed
2185
  } else {
2186
    // ask L2 for RACH transport
cig's avatar
cig committed
2187
    if ((runmode != rx_calib_ue) && (runmode != rx_calib_ue_med) && (runmode != rx_calib_ue_byp) && (runmode != no_L2_connect) ) {
2188
      LOG_D(PHY, "Getting PRACH resources. Frame %d Slot %d \n", frame_tx, nr_slot_tx);
2189
      // flush Msg3 Buffer
cig's avatar
cig committed
2190
      if (prach_resources->Msg3 == NULL){
2191 2192 2193 2194
        for(int i = 0; i<NUMBER_OF_CONNECTED_gNB_MAX; i++) {
          ue->ulsch_Msg3_active[i] = 0;
        }
      }
2195
      nr_prach = nr_ue_get_rach(ue->prach_resources[gNB_id], &ue->prach_vars[0]->prach_pdu, mod_id, ue->CC_id, UE_mode, frame_tx, gNB_id, nr_slot_tx);
2196 2197 2198
    }
  }

cig's avatar
cig committed
2199
  if (ue->prach_resources[gNB_id] != NULL && nr_prach == 1 && prach_resources->init_msg1) {
2200

2201
    pathloss = get_nr_PL(mod_id, ue->CC_id, gNB_id);
cig's avatar
cig committed
2202
    LOG_D(PHY,"runmode %d\n",runmode);
2203

cig's avatar
cig committed
2204
    if ((ue->mac_enabled == 1) && (runmode != calib_prach_tx)) {
2205
      ue->tx_power_dBm[nr_slot_tx] = prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER + pathloss;
cig's avatar
cig committed
2206
    }
2207

2208
    LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_slot_tx %d : Generating PRACH, preamble %d, PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x\n",
cig's avatar
cig committed
2209 2210
      ue->Mod_id,
      frame_tx,
2211
      nr_slot_tx,
cig's avatar
cig committed
2212
      prach_resources->ra_PreambleIndex,
cig's avatar
cig committed
2213
      pathloss,
2214
      ue->tx_power_dBm[nr_slot_tx],
cig's avatar
cig committed
2215 2216
      prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER,
      prach_resources->ra_RNTI);
2217

2218
    //ue->tx_total_RE[nr_slot_tx] = 96; // todo
cig's avatar
cig committed
2219
    ue->prach_vars[gNB_id]->amp = AMP;
2220

cig's avatar
cig committed
2221
    /* #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
2222
      tx_amp = get_tx_amp_prach(ue->tx_power_dBm[nr_slot_tx], ue->tx_power_max_dBm, ue->frame_parms.N_RB_UL);
2223 2224
      if (tx_amp != -1)
        ue->prach_vars[gNB_id]->amp = tx_amp;
2225
    #else
cig's avatar
cig committed
2226
      ue->prach_vars[gNB_id]->amp = AMP;
cig's avatar
cig committed
2227
    #endif */
2228

cig's avatar
cig committed
2229
    if ((runmode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0))
2230
      LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_slot_tx %d : PRACH TX power %d dBm, amp %d\n", ue->Mod_id,
2231
        proc->frame_rx,
2232 2233
        proc->nr_slot_tx,
        ue->tx_power_dBm[nr_slot_tx],
2234 2235 2236 2237
        ue->prach_vars[gNB_id]->amp);

    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);

2238
    prach_power = generate_nr_prach(ue, gNB_id, nr_slot_tx);
2239 2240

    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT);
cig's avatar
cig committed
2241 2242

    LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n",
2243
      ue->Mod_id,
2244
      pathloss,
2245
      ue->tx_power_dBm[nr_slot_tx],
2246 2247 2248 2249
      dB_fixed(prach_power),
      ue->prach_vars[gNB_id]->amp);

    if (ue->mac_enabled == 1)
cig's avatar
cig committed
2250
      nr_Msg1_transmitted(ue->Mod_id, ue->CC_id, frame_tx, gNB_id);
2251

2252
    LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_slot_tx %d: Generated PRACH Msg1 (gNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB) \n",
cig's avatar
cig committed
2253 2254
      ue->Mod_id,
      frame_tx,
2255
      nr_slot_tx,
cig's avatar
cig committed
2256
      gNB_id,
cig's avatar
cig committed
2257
      prach_resources->ra_PreambleIndex,
2258
      ue->tx_power_dBm[nr_slot_tx],
cig's avatar
cig committed
2259
      pathloss);
cig's avatar
cig committed
2260

2261
    LOG_D(PHY,"[UE %d] frame %d nr_slot_tx %d : prach_cnt %d\n", ue->Mod_id, frame_tx, nr_slot_tx, ue->prach_cnt);
cig's avatar
cig committed
2262 2263 2264 2265 2266

    ue->prach_cnt++;

    if (ue->prach_cnt == 3)
      ue->prach_cnt = 0;
2267 2268
  } else if (nr_prach == 2) {
    nr_ra_succeeded(mod_id, ue->CC_id, gNB_id);
2269 2270 2271
  }

  // if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue
cig's avatar
cig committed
2272
  if (runmode == calib_prach_tx)
2273
    ue->prach_resources[gNB_id] = NULL;
2274 2275

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
2276
}